/** Copyright (C) 2008-2012 Josh Ventura
***
*** This file is a part of the ENIGMA Development Environment.
***
*** ENIGMA is free software: you can redistribute it and/or modify it under the
*** terms of the GNU General Public License as published by the Free Software
*** Foundation, version 3 of the license or any later version.
***
*** This application and its source code is distributed AS-IS, WITHOUT ANY
*** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
*** details.
***
*** You should have received a copy of the GNU General Public License along
*** with this code. If not, see <http://www.gnu.org/licenses/>
**/
#include <string>
#include <cstdio>
#include "OpenGLHeaders.h"
#include "GSbackground.h"
#include "GSscreen.h"
#include "GSd3d.h"
using namespace std;
#include "Universal_System/var4.h"
#define __GETR(x) (((unsigned int)x & 0x0000FF))
#define __GETG(x) (((unsigned int)x & 0x00FF00) >> 8)
#define __GETB(x) (((unsigned int)x & 0xFF0000) >> 16)
#include "Universal_System/roomsystem.h"
#include "Universal_System/instance_system.h"
#include "Universal_System/graphics_object.h"
#include "Universal_System/depth_draw.h"
#include "Platforms/platforms_mandatory.h"
#include "Graphics_Systems/graphics_mandatory.h"
using namespace enigma;
static inline void draw_back()
{
//Draw backgrounds
for (int back_current=0; back_current<7; back_current++)
{
if (background_visible[back_current] == 1)
{
// if (background_stretched) draw_background_stretched(back, x, y, w, h);
draw_background_tiled(background_index[back_current], background_x[back_current], background_y[back_current]);
}
// background_foreground, background_index, background_x, background_y, background_htiled,
// background_vtiled, background_hspeed, background_vspeed;
}
}
namespace enigma
{
extern std::map<int,roomstruct*> roomdata;
}
void screen_redraw()
{
int FBO;
if (!view_enabled)
{
glViewport(0, 0, window_get_width(), window_get_height());
glLoadIdentity();
if (GLEW_EXT_framebuffer_object)
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &FBO);
glScalef(1, (FBO==0?-1:1), 1);
}
else
{
glScalef(1, -1, 1);
}
glOrtho(0, room_width, 0, room_height, 0, 1);
glGetDoublev(GL_MODELVIEW_MATRIX,projection_matrix);
glMultMatrixd(transformation_matrix);
if (background_showcolor)
{
int clearcolor = ((int)background_color) & 0x00FFFFFF;
glClearColor(__GETR(clearcolor) / 255.0, __GETG(clearcolor) / 255.0, __GETB(clearcolor) / 255.0, 1);
glClear(GL_COLOR_BUFFER_BIT);
}
glClear(GL_DEPTH_BUFFER_BIT);
draw_back();
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++)
{
//loop tiles
for(std::vector<tile>::size_type i = 0; i != dit->second.tiles.size(); i++)
{
tile t = dit->second.tiles[i];
draw_background_part(t.bckid, t.bgx, t.bgy, t.width, t.height, t.roomX, t.roomY);
}
enigma::inst_iter* push_it = enigma::instance_event_iterator;
for (enigma::instance_event_iterator = dit->second.draw_events->next; enigma::instance_event_iterator != NULL; enigma::instance_event_iterator = enigma::instance_event_iterator->next)
enigma::instance_event_iterator->inst->myevent_draw();
enigma::instance_event_iterator = push_it;
}
}
else
{
int total_width = 0, total_height = 0;
for (int i = 0; i < 7; ++i) {
if (view_xview[i] + view_wview[i] > total_width) total_width = view_xview[i] + view_wview[i];
if (view_yview[i] + view_hview[i] > total_height) total_height = view_yview[i] + view_hview[i];
}
const double vxscale = window_get_width() / (double)total_width, vyscale = window_get_height() / (double)total_height;
for (view_current = 0; view_current < 7; view_current++)
{
if (view_visible[(int)view_current])
{
int vc = (int)view_current;
int vob = (int)view_object[vc];
if (vob != -1)
{
object_basic *instanceexists = fetch_instance_by_int(vob);
if (instanceexists)
{
object_planar* vobr = (object_planar*)instanceexists;
int vobx = (int)(vobr->x), voby = (int)(vobr->y);
//int bbl=*vobr.x+*vobr.bbox_left,bbr=*vobr.x+*vobr.bbox_right,bbt=*vobr.y+*vobr.bbox_top,bbb=*vobr.y+*vobr.bbox_bottom;
//if (bbl<view_xview[vc]+view_hbor[vc]) view_xview[vc]=bbl-view_hbor[vc];
int vbc_h, vbc_v;
(view_hborder[vc] > view_wview[vc]/2) ? vbc_h = int(view_wview[vc]/2) : vbc_h = view_hborder[vc];
(view_vborder[vc] > view_hview[vc]/2) ? vbc_v = int(view_hview[vc]/2) : vbc_v = view_vborder[vc];
if (view_hspeed[vc] == -1)
{
if (vobx < view_xview[vc] + vbc_h)
view_xview[vc] = vobx - vbc_h;
else if (vobx > view_xview[vc] + view_wview[vc] - vbc_h)
view_xview[vc] = vobx + vbc_h - view_wview[vc];
}
else
{
if (vobx < view_xview[vc] + vbc_h)
{
view_xview[vc] -= view_hspeed[vc];
if (view_xview[vc] < vobx - vbc_h)
view_xview[vc] = vobx - vbc_h;
}
else if (vobx > view_xview[vc] + view_wview[vc] - vbc_h)
{
view_xview[vc] += view_hspeed[vc];
if (view_xview[vc] > vobx + vbc_h - view_wview[vc])
view_xview[vc] = vobx + vbc_h - view_wview[vc];
}
}
if (view_vspeed[vc] == -1)
{
if (voby < view_yview[vc] + vbc_v)
view_yview[vc] = voby - vbc_v;
else if (voby > view_yview[vc] + view_hview[vc] - vbc_v)
view_yview[vc] = voby + vbc_v - view_hview[vc];
}
else
{
if (voby < view_yview[vc] + vbc_v)
{
view_yview[vc] -= view_vspeed[vc];
if (view_yview[vc] < voby - vbc_v)
view_yview[vc] = voby - vbc_v;
}
if (voby > view_yview[vc] + view_hview[vc] - vbc_v)
{
view_yview[vc] += view_vspeed[vc];
if (view_yview[vc] > voby + vbc_v - view_hview[vc])
view_yview[vc] = voby + vbc_v - view_hview[vc];
}
}
if (view_xview[vc] < 0)
view_xview[vc] = 0;
else if (view_xview[vc] > room_width - view_wview[vc])
view_xview[vc] = room_width - view_wview[vc];
if (view_yview[vc] < 0)
view_yview[vc] = 0;
else if (view_yview[vc] > room_height - view_hview[vc])
view_yview[vc] = room_height - view_hview[vc];
}
}
glViewport((int)(view_xport[vc] * vxscale),(int)(view_yport[vc] * vyscale),(int)(view_wport[vc] * vxscale),(int)(view_hport[vc] * vyscale));
glLoadIdentity();
if (GLEW_EXT_framebuffer_object)
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &FBO);
glScalef(1, (FBO==0?-1:1), 1);
}
else
{
glScalef(1, -1, 1);
}
glOrtho(view_xview[vc], view_wview[vc] + view_xview[vc], view_yview[vc], view_hview[vc] + view_yview[vc], 0, 1);
glGetDoublev(GL_MODELVIEW_MATRIX,projection_matrix);
glMultMatrixd(transformation_matrix);
if (background_showcolor)
{
int clearcolor = ((int)background_color) & 0x00FFFFFF;
glClearColor(__GETR(clearcolor) / 255.0, __GETG(clearcolor) / 255.0, __GETB(clearcolor) / 255.0, 1);
glClear(GL_COLOR_BUFFER_BIT);
}
glClear(GL_DEPTH_BUFFER_BIT);
draw_back();
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++)
{
//loop tiles
for(std::vector<tile>::size_type i = 0; i != dit->second.tiles.size(); i++)
{
tile t = dit->second.tiles[i];
if (t.roomX + t.width < view_xview[vc] || t.roomY + t.height < view_yview[vc] || t.roomX > view_xview[vc] + view_wview[vc] || t.roomY > view_yview[vc] + view_hview[vc])
continue;
draw_background_part(t.bckid, t.bgx, t.bgy, t.width, t.height, t.roomX, t.roomY);
}
enigma::inst_iter* push_it = enigma::instance_event_iterator;
//loop instances
for (enigma::instance_event_iterator = dit->second.draw_events->next; enigma::instance_event_iterator != NULL; enigma::instance_event_iterator = enigma::instance_event_iterator->next)
enigma::instance_event_iterator->inst->myevent_draw();
enigma::instance_event_iterator = push_it;
}
}
}
view_current = 0;
}
}
void screen_init()
{
if (!view_enabled)
{
glMatrixMode(GL_PROJECTION);
glClearColor(0,0,0,0);
glLoadIdentity();
gluPerspective(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, window_get_width(), window_get_height());
glLoadIdentity();
glScalef(1, -1, 1);
glOrtho(0, room_width, 0, room_height, 0, 1);
glGetDoublev(GL_MODELVIEW_MATRIX,projection_matrix);
glMultMatrixd(transformation_matrix);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_ALWAYS,0);
glColor4f(0,0,0,1);
glBindTexture(GL_TEXTURE_2D,0);
}
else
{
for (view_current = 0; view_current < 7; view_current++)
{
if (view_visible[(int)view_current])
{
int vc = (int)view_current;
glMatrixMode(GL_PROJECTION);
glClearColor(0,0,0,0);
glLoadIdentity();
gluPerspective(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glViewport(view_xport[vc], view_yport[vc], view_wport[vc], view_hport[vc]);
glLoadIdentity();
glScalef(1, -1, 1);
glOrtho(view_xview[vc], view_wview[vc] + view_xview[vc], view_yview[vc], view_hview[vc] + view_yview[vc], 0, 1);
glGetDoublev(GL_MODELVIEW_MATRIX,projection_matrix);
glMultMatrixd(transformation_matrix);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_ALWAYS,0);
glColor4f(0,0,0,1);
glBindTexture(GL_TEXTURE_2D,0);
break;
}
}
}
}