gpu-gles from psx4m
[pcsx_rearmed.git] / plugins / gpu-gles / gpuDraw.c
diff --git a/plugins/gpu-gles/gpuDraw.c b/plugins/gpu-gles/gpuDraw.c
new file mode 100644 (file)
index 0000000..3d09c33
--- /dev/null
@@ -0,0 +1,1345 @@
+/***************************************************************************\r
+                           draw.c  -  description\r
+                             -------------------\r
+    begin                : Sun Mar 08 2009\r
+    copyright            : (C) 1999-2009 by Pete Bernert\r
+    web                  : www.pbernert.com   \r
+ ***************************************************************************/\r
+\r
+/***************************************************************************\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version. See also the license.txt file for *\r
+ *   additional informations.                                              *\r
+ *                                                                         *\r
+ ***************************************************************************/\r
+\r
+//*************************************************************************// \r
+// History of changes:\r
+//\r
+// 2009/03/08 - Pete  \r
+// - generic cleanup for the Peops release\r
+//\r
+//*************************************************************************// \r
+\r
+\r
+#define _IN_DRAW\r
+\r
+#ifdef _WINDOWS\r
+#include "stdafx.h"\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <math.h>\r
+#include "externals.h"\r
+#include "gpu.h"\r
+#include "draw.h"\r
+#include "prim.h"\r
+#include "texture.h"\r
+#else\r
+#include "gpuExternals.h"\r
+#include "GPUPlugin.h"\r
+#include "gpuDraw.h"\r
+#include "gpuPrim.h"\r
+#include "gpuTexture.h"\r
+#include "gpuStdafx.h"\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <math.h>\r
+#endif\r
+//#include "menu.h"\r
+            \r
+////////////////////////////////////////////////////////////////////////////////////\r
+// defines\r
+\r
+#define SIGNBIT 0x800\r
+#define S_MASK  0xf000\r
+#define L_MASK  0xfffff000\r
+\r
+// ownscale: some ogl drivers have buggy texture matrix funcs, so it\r
+//           is safer to calc sow/tow ourselves\r
+\r
+#ifdef OWNSCALE\r
+\r
+///////////////////////////////////////////////////////////////\r
+\r
+#define ST_FACSPRITE       255.99f\r
+#define ST_BFFACSPRITE     0.5f/256.0f\r
+#define ST_BFFACSPRITESORT 0.333f/256.0f\r
+\r
+#define ST_OFFSET          0.5f/256.0f;\r
+\r
+#define ST_FAC             255.99f\r
+#define ST_BFFAC           0.5f/256.0f\r
+#define ST_BFFACSORT       0.333f/256.0f\r
+\r
+#define ST_FACTRI          255.99f\r
+#define ST_BFFACTRI        0.5f/256.0f\r
+#define ST_BFFACTRISORT    0.333f/256.0f\r
+\r
+#define ST_FACVRAMX        255.0f\r
+#define ST_FACVRAM         256.0f\r
+\r
+///////////////////////////////////////////////////////////////\r
+\r
+#else\r
+\r
+#define ST_BFFACSPRITE     0.5f\r
+#define ST_BFFACSPRITESORT 0.333f\r
+\r
+#define ST_BFFAC           0.5f\r
+#define ST_BFFACSORT       0.333f\r
+\r
+#define ST_BFFACTRI        0.5f\r
+#define ST_BFFACTRISORT    0.333f\r
+\r
+#define ST_OFFSET          0.5f;\r
+                \r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////////////////\r
+// draw globals\r
+\r
+#ifdef _WINDOWS\r
+HDC            dcGlobal=NULL;\r
+HWND           hWWindow;\r
+#else\r
+void  glBlendEquationEXT(GLenum mode);\r
+void  glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);\r
+#endif\r
+\r
+// draw globals; most will be initialized again later (by config or checks) \r
+\r
+BOOL           bIsFirstFrame=TRUE;\r
+\r
+// resolution/ratio vars\r
+\r
+int            iResX;\r
+int            iResY;\r
+BOOL           bKeepRatio=FALSE;\r
+RECT           rRatioRect;\r
+\r
+// psx mask related vars\r
+\r
+BOOL           bCheckMask=FALSE;\r
+int            iUseMask=0;\r
+int            iSetMask=0;\r
+unsigned short sSetMask=0;\r
+unsigned long  lSetMask=0;\r
+\r
+// drawing/coord vars\r
+\r
+OGLVertex      vertex[4];\r
+GLubyte        gl_ux[8];\r
+GLubyte        gl_vy[8];\r
+short          sprtY,sprtX,sprtH,sprtW;\r
+\r
+// drawing options\r
+\r
+BOOL           bOpaquePass;\r
+BOOL           bAdvancedBlend;\r
+\r
+// OGL extension support\r
+\r
+\r
+// gfx card buffer infos\r
+\r
+int            iDepthFunc=0;\r
+int            iZBufferDepth=0;\r
+GLbitfield     uiBufferBits=GL_COLOR_BUFFER_BIT;\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Set OGL pixel format\r
+////////////////////////////////////////////////////////////////////////\r
\r
+#ifdef _WINDOWS\r
+BOOL bSetupPixelFormat(HDC hDC)\r
+{\r
+ int pixelformat;\r
+ static PIXELFORMATDESCRIPTOR pfd = \r
+  {\r
+   sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd\r
+    1,                               // version number\r
+    PFD_DRAW_TO_WINDOW |             // support window\r
+      PFD_SUPPORT_OPENGL |           // support OpenGL\r
+      PFD_DOUBLEBUFFER,              // double buffered\r
+    PFD_TYPE_RGBA,                   // RGBA type\r
+    16,                              // 16-bit color depth  (adjusted later)\r
+    0, 0, 0, 0, 0, 0,                // color bits ignored\r
+    0,                               // no alpha buffer\r
+    0,                               // shift bit ignored\r
+    0,                               // no accumulation buffer\r
+    0, 0, 0, 0,                      // accum bits ignored\r
+    0,                               // z-buffer    \r
+    0,\r
+    0,                               // no auxiliary buffer\r
+    PFD_MAIN_PLANE,                  // main layer\r
+    0,                               // reserved\r
+    0, 0, 0                          // layer masks ignored\r
+  };\r
\r
+ pfd.cColorBits=iColDepth;                             // set user color depth\r
+ pfd.cDepthBits=iZBufferDepth;                         // set user zbuffer (by psx mask)\r
+\r
+ if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0)     \r
+  {\r
+   MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);\r
+   return FALSE;\r
+  }\r
+\r
+ if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)\r
+  {\r
+   MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);\r
+   return FALSE;\r
+  }\r
+\r
+ return TRUE;\r
+}\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Get extension infos (f.e. pal textures / packed pixels)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void GetExtInfos(void)                              \r
+{\r
+ BOOL bPacked=FALSE;                                   // default: no packed pixel support\r
+\r
+ if(strstr((s8 *)glGetString(GL_EXTENSIONS),         // packed pixels available?\r
+    "GL_EXT_packed_pixels"))                          \r
+  bPacked=TRUE;                                        // -> ok\r
+\r
\r
+ #ifdef _WINDOWS\r
+ iClampType=GL_CLAMP;\r
+#else\r
+ iClampType=GL_CLAMP_TO_EDGE;\r
+#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Setup some stuff depending on user settings or in-game toggle\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetExtGLFuncs(void)\r
+{\r
+ //----------------------------------------------------//\r
+\r
+ SetFixes();                                           // update fix infos\r
+\r
+ //----------------------------------------------------//\r
+\r
+  {\r
+   if(bAdvancedBlend) bUseMultiPass=TRUE;              // -> pseudo-advanced with 2 passes\r
+   else               bUseMultiPass=FALSE;             // -> or simple 'bright color' mode\r
+//   bGLBlend=FALSE;                                     // -> no ext blending!\r
+\r
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);    \r
+  }\r
+\r
+ if(bOpaquePass)                                        // opaque mode?\r
+  {\r
+   if(dwActFixes&32) \r
+    {\r
+     TCF[0]=CP8RGBA_0;\r
+     PalTexturedColourFn=CP8RGBA;                      // -> init col func\r
+    }\r
+   else\r
+    {\r
+     TCF[0]=XP8RGBA_0;\r
+     PalTexturedColourFn=XP8RGBA;                      // -> init col func\r
+    }\r
+\r
+   TCF[1]=XP8RGBA_1;\r
+   glAlphaFuncx(GL_GREATER,0.49f);\r
+  }\r
+ else                                                  // no opaque mode?\r
+  {\r
+   TCF[0]=TCF[1]=P8RGBA;\r
+   PalTexturedColourFn=P8RGBA;                         // -> init col func\r
+   glAlphaFuncx(GL_NOTEQUAL,0);                         // --> set alpha func\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+\r
+ LoadSubTexFn=LoadSubTexturePageSort;                  // init load tex ptr\r
+\r
+ bBlendEnable=FALSE;                                   // init blending: off\r
+ glDisable(GL_BLEND);\r
+\r
+ SetScanTrans();                                       // init scan lines (if wanted)\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// setup scan lines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define R_TSP 0x00,0x45,0x00,0xff\r
+#define G_TSP 0x00,0x00,0x45,0xff\r
+#define B_TSP 0x45,0x00,0x00,0xff\r
+#define O_TSP 0x45,0x45,0x45,0xff\r
+#define N_TSP 0x00,0x00,0x00,0xff\r
+\r
+GLuint  gTexScanName=0;\r
+\r
+GLubyte texscan[4][16]= \r
+{\r
+{R_TSP, G_TSP, B_TSP, N_TSP},\r
+{O_TSP, N_TSP, O_TSP, N_TSP},\r
+{B_TSP, N_TSP, R_TSP, G_TSP},\r
+{O_TSP, N_TSP, O_TSP, N_TSP}\r
+};\r
+\r
+void CreateScanLines(void)\r
+{\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Initialize OGL\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS    \r
+HGLRC GLCONTEXT=NULL;\r
+#endif\r
+\r
+#ifdef MAEMO_CHANGES\r
+bool TestEGLError(const char* pszLocation)\r
+{\r
+       /*\r
+               eglGetError returns the last error that has happened using egl,\r
+               not the status of the last called function. The user has to\r
+               check after every single egl call or at least once every frame.\r
+       */\r
+       EGLint iErr = eglGetError();\r
+       if (iErr != EGL_SUCCESS)\r
+       {\r
+               printf("%s failed (%d).\n", pszLocation, iErr);\r
+               return false;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+void maemoGLinit(){\r
+       iResX= 800;\r
+    iResY =480;\r
+\r
+       \r
+       printf ("maemo GL init\n");\r
+       long int winxid=GDK_WINDOW_XID(GTK_WIDGET(windowG)->window);\r
+       printf ("%d\n",winxid);\r
+       \r
+       EGLContext                      context = 0;\r
+       EGLConfig                       eglConfig       = 0;\r
+       EGLContext                      eglContext      = 0;\r
+       display = eglGetDisplay( EGL_DEFAULT_DISPLAY );\r
+       \r
+       if( eglInitialize( display, NULL, NULL ) == EGL_FALSE )\r
+            {            \r
+                printf( "EGL Initialize failed!\n" );\r
+                               \r
+                       }\r
+\r
+const EGLint attributeList[] = { \r
+                                     EGL_SURFACE_TYPE, EGL_WINDOW_BIT, \r
+                                     /*EGL_BUFFER_SIZE, 32, */\r
+                                     EGL_NONE \r
+                                   };\r
+                                                          \r
+       EGLint pi32ConfigAttribs[5];\r
+       pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;\r
+       pi32ConfigAttribs[1] = EGL_WINDOW_BIT;\r
+       pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;\r
+       pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;      \r
+       pi32ConfigAttribs[4] = EGL_NONE;\r
+\r
+       EGLint pi32ContextAttribs[3];\r
+       pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;\r
+       pi32ContextAttribs[1] = 2;\r
+       pi32ContextAttribs[2] = EGL_NONE;\r
+\r
+       int iConfigs;\r
+       if (!eglChooseConfig(display, attributeList, &eglConfig, 1, &iConfigs) || (iConfigs != 1))\r
+       {\r
+               printf("Error: eglChooseConfig() failed.\n");\r
+       }\r
+       printf ("%d\n",iConfigs);\r
+       surface = eglCreateWindowSurface(display, eglConfig, (void*)winxid, NULL);\r
+       printf ("%d\n",surface);\r
+    if (!TestEGLError("eglCreateWindowSurface"))\r
+       {\r
+               printf ("eglCreateWindowSurface fail");\r
+       }\r
+\r
+       //context = eglCreateContext(display, eglConfig, NULL, pi32ContextAttribs);\r
+       context =eglCreateContext( display, eglConfig,\r
+                                    EGL_NO_CONTEXT, NULL \r
+                                  );\r
+printf ("%d\n",context);\r
+       if (!TestEGLError("eglCreateContext"))\r
+       {\r
+               printf("error eglCreateContext");\r
+       }\r
+\r
+       eglMakeCurrent(display, surface, surface, context);\r
+\r
+       if (!TestEGLError("eglMakeCurrent"))\r
+       {\r
+               printf("error eglMakeCurrent");\r
+       }\r
+}\r
+#endif\r
+\r
+int GLinitialize() \r
+{\r
+ //----------------------------------------------------// \r
+#ifdef _WINDOWS\r
+ HGLRC objectRC;\r
+ // init\r
+ dcGlobal = GetDC(hWWindow);                           // FIRST: dc/rc stuff\r
+ objectRC = wglCreateContext(dcGlobal); \r
+ GLCONTEXT=objectRC;\r
+ wglMakeCurrent(dcGlobal, objectRC);\r
+ // CheckWGLExtensions(dcGlobal);\r
+ if(bWindowMode) ReleaseDC(hWWindow,dcGlobal);         // win mode: release dc again\r
+#endif\r
+#ifdef MAEMO_CHANGES\r
+        maemoGLinit();\r
+#endif\r
+ //----------------------------------------------------// \r
+\r
+ glViewport(rRatioRect.left,                           // init viewport by ratio rect\r
+            iResY-(rRatioRect.top+rRatioRect.bottom),\r
+            rRatioRect.right, \r
+            rRatioRect.bottom);         \r
+                                                      \r
+ glScissor(0, 0, iResX, iResY);                        // init clipping (fullscreen)\r
+ glEnable(GL_SCISSOR_TEST);                       \r
+\r
+#ifndef OWNSCALE\r
+ glMatrixMode(GL_TEXTURE);                             // init psx tex sow and tow if not "ownscale"\r
+ glLoadIdentity();\r
+ glScalef(1.0f/255.99f,1.0f/255.99f,1.0f);             // geforce precision hack\r
+#endif \r
+\r
+ glMatrixMode(GL_PROJECTION);                          // init projection with psx resolution\r
+ glLoadIdentity();\r
+ glOrtho(0,PSXDisplay.DisplayMode.x,\r
+         PSXDisplay.DisplayMode.y, 0, -1, 1);\r
+\r
+ if(iZBufferDepth)                                     // zbuffer?\r
+  {\r
+   uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;\r
+   glEnable(GL_DEPTH_TEST);    \r
+   glDepthFunc(GL_ALWAYS);\r
+   iDepthFunc=1;\r
+  }\r
+ else                                                  // no zbuffer?\r
+  {\r
+   uiBufferBits=GL_COLOR_BUFFER_BIT;\r
+   glDisable(GL_DEPTH_TEST);\r
+  }\r
+\r
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                 // first buffer clear\r
+ glClear(uiBufferBits);\r
+\r
+ GetExtInfos();                                        // get ext infos\r
+ SetExtGLFuncs();                                      // init all kind of stuff (tex function pointers)\r
\r
+ glEnable(GL_ALPHA_TEST);                              // wanna alpha test\r
+\r
+  {\r
+   glDisable(GL_LINE_SMOOTH);\r
+   glDisable(GL_POINT_SMOOTH);\r
+  }\r
+\r
+ ubGloAlpha=127;                                       // init some drawing vars\r
+ ubGloColAlpha=127;\r
+ TWin.UScaleFactor = 1;\r
+ TWin.VScaleFactor = 1;\r
+ bDrawMultiPass=FALSE;\r
+ bTexEnabled=FALSE;\r
+ bUsingTWin=FALSE;\r
+      \r
+ if(bDrawDither)  glEnable(GL_DITHER);                 // dither mode\r
+ else             glDisable(GL_DITHER); \r
+\r
+ glDisable(GL_FOG);                                    // turn all (currently) unused modes off\r
+ glDisable(GL_LIGHTING);  \r
+ glDisable(GL_STENCIL_TEST);  \r
+ glDisable(GL_TEXTURE_2D);\r
+ glDisable(GL_CULL_FACE);\r
+\r
+ glFlush();                                            // we are done...\r
+ glFinish();                           \r
+\r
+ CreateScanLines();                                    // setup scanline stuff (if wanted)\r
+\r
+ CheckTextureMemory();                                 // check available tex memory\r
+\r
+ if(bKeepRatio) SetAspectRatio();                      // set ratio\r
+\r
\r
+ bIsFirstFrame = FALSE;                                // we have survived the first frame :)\r
+\r
+ return 0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// clean up OGL stuff\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void GLcleanup() \r
+{                                                     \r
+ CleanupTextureStore();                                // bye textures\r
+\r
+#ifdef _WINDOWS \r
+ wglMakeCurrent(NULL, NULL);                           // bye context\r
+ if(GLCONTEXT) wglDeleteContext(GLCONTEXT);\r
+ if(!bWindowMode && dcGlobal) \r
+  ReleaseDC(hWWindow,dcGlobal);\r
+#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Offset stuff\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+// please note: it is hardly do-able in a hw/accel plugin to get the \r
+//              real psx polygon coord mapping right... the following\r
+//              works not to bad with many games, though\r
+\r
+__inline BOOL CheckCoord4()\r
+{\r
+ if(lx0<0)\r
+  {\r
+   if(((lx1-lx0)>CHKMAX_X) ||\r
+      ((lx2-lx0)>CHKMAX_X)) \r
+    {\r
+     if(lx3<0)\r
+      {\r
+       if((lx1-lx3)>CHKMAX_X) return TRUE;\r
+       if((lx2-lx3)>CHKMAX_X) return TRUE;\r
+      }\r
+    }\r
+  }\r
+ if(lx1<0)\r
+  {\r
+   if((lx0-lx1)>CHKMAX_X) return TRUE;\r
+   if((lx2-lx1)>CHKMAX_X) return TRUE;\r
+   if((lx3-lx1)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(lx2<0)\r
+  {\r
+   if((lx0-lx2)>CHKMAX_X) return TRUE;\r
+   if((lx1-lx2)>CHKMAX_X) return TRUE;\r
+   if((lx3-lx2)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(lx3<0)\r
+  {\r
+   if(((lx1-lx3)>CHKMAX_X) ||\r
+      ((lx2-lx3)>CHKMAX_X))\r
+    {\r
+     if(lx0<0)\r
+      {\r
+       if((lx1-lx0)>CHKMAX_X) return TRUE;\r
+       if((lx2-lx0)>CHKMAX_X) return TRUE;\r
+      }\r
+    }\r
+  }\r
\r
+\r
+ if(ly0<0)\r
+  {\r
+   if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
+   if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly1<0)\r
+  {\r
+   if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
+   if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
+   if((ly3-ly1)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly2<0)\r
+  {\r
+   if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
+   if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
+   if((ly3-ly2)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly3<0)\r
+  {\r
+   if((ly1-ly3)>CHKMAX_Y) return TRUE;\r
+   if((ly2-ly3)>CHKMAX_Y) return TRUE;\r
+  }\r
+\r
+ return FALSE;\r
+}\r
+\r
+__inline BOOL CheckCoord3()\r
+{\r
+ if(lx0<0)\r
+  {\r
+   if((lx1-lx0)>CHKMAX_X) return TRUE;\r
+   if((lx2-lx0)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(lx1<0)\r
+  {\r
+   if((lx0-lx1)>CHKMAX_X) return TRUE;\r
+   if((lx2-lx1)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(lx2<0)\r
+  {\r
+   if((lx0-lx2)>CHKMAX_X) return TRUE;\r
+   if((lx1-lx2)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(ly0<0)\r
+  {\r
+   if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
+   if((ly2-ly0)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly1<0)\r
+  {\r
+   if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
+   if((ly2-ly1)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly2<0)\r
+  {\r
+   if((ly0-ly2)>CHKMAX_Y) return TRUE;\r
+   if((ly1-ly2)>CHKMAX_Y) return TRUE;\r
+  }\r
+\r
+ return FALSE;\r
+}\r
+\r
+\r
+__inline BOOL CheckCoord2()\r
+{\r
+ if(lx0<0)\r
+  {\r
+   if((lx1-lx0)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(lx1<0)\r
+  {\r
+   if((lx0-lx1)>CHKMAX_X) return TRUE;\r
+  }\r
+ if(ly0<0)\r
+  {\r
+   if((ly1-ly0)>CHKMAX_Y) return TRUE;\r
+  }\r
+ if(ly1<0)\r
+  {\r
+   if((ly0-ly1)>CHKMAX_Y) return TRUE;\r
+  }\r
+\r
+ return FALSE;\r
+}\r
+\r
+// Pete's way: a very easy (and hopefully fast) approach for lines\r
+// without sqrt... using a small float -> short cast trick :)\r
+\r
+#define VERTEX_OFFX 0.2f\r
+#define VERTEX_OFFY 0.2f\r
+\r
+BOOL offsetline(void)           \r
+{\r
+ short x0,x1,y0,y1,dx,dy;float px,py;\r
+\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(!(dwActFixes&16))\r
+  {\r
+   lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
+\r
+   if(CheckCoord2()) return TRUE;\r
+  }\r
+\r
+ x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;\r
+ x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;\r
+ y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;\r
+ y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;\r
\r
+ dx=x1-x0;\r
+ dy=y1-y0;\r
\r
+ if(dx>=0)\r
+  {\r
+   if(dy>=0)\r
+    {\r
+     px=0.5f;\r
+          if(dx>dy) py=-0.5f;\r
+     else if(dx<dy) py= 0.5f;\r
+     else           py= 0.0f;\r
+    }\r
+   else\r
+    {\r
+     py=-0.5f;\r
+     dy=-dy;\r
+          if(dx>dy) px= 0.5f;\r
+     else if(dx<dy) px=-0.5f;\r
+     else           px= 0.0f;\r
+    }\r
+  }\r
+ else\r
+  {\r
+   if(dy>=0)\r
+    {\r
+     py=0.5f;\r
+     dx=-dx;\r
+          if(dx>dy) px=-0.5f;\r
+     else if(dx<dy) px= 0.5f;\r
+     else           px= 0.0f;\r
+    }\r
+   else\r
+    {\r
+     px=-0.5f;\r
+          if(dx>dy) py=-0.5f;\r
+     else if(dx<dy) py= 0.5f;\r
+     else           py= 0.0f;\r
+    }\r
+  } \r
\r
+ vertex[0].x=(short)((float)x0-px);\r
+ vertex[3].x=(short)((float)x0+py);\r
\r
+ vertex[0].y=(short)((float)y0-py);\r
+ vertex[3].y=(short)((float)y0-px);\r
\r
+ vertex[1].x=(short)((float)x1-py);\r
+ vertex[2].x=(short)((float)x1+px);\r
+\r
+ vertex[1].y=(short)((float)y1+px);\r
+ vertex[2].y=(short)((float)y1+py);\r
+\r
+ if(vertex[0].x==vertex[3].x &&                        // ortho rect? done\r
+    vertex[1].x==vertex[2].x &&\r
+    vertex[0].y==vertex[1].y &&\r
+    vertex[2].y==vertex[3].y) return FALSE;\r
+ if(vertex[0].x==vertex[1].x &&\r
+    vertex[2].x==vertex[3].x &&\r
+    vertex[0].y==vertex[3].y &&\r
+    vertex[1].y==vertex[2].y) return FALSE;\r
+\r
+ vertex[0].x-=VERTEX_OFFX;                             // otherwise a small offset\r
+ vertex[0].y-=VERTEX_OFFY;                             // to get better accuracy\r
+ vertex[1].x-=VERTEX_OFFX;\r
+ vertex[1].y-=VERTEX_OFFY;\r
+ vertex[2].x-=VERTEX_OFFX;\r
+ vertex[2].y-=VERTEX_OFFY;\r
+ vertex[3].x-=VERTEX_OFFX;\r
+ vertex[3].y-=VERTEX_OFFY;\r
+\r
+ return FALSE;\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+BOOL offset2(void)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(!(dwActFixes&16))\r
+  {\r
+   lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
+\r
+   if(CheckCoord2()) return TRUE;\r
+  }\r
+\r
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
+\r
+ return FALSE;\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+BOOL offset3(void)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(!(dwActFixes&16))\r
+  {\r
+   lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
+\r
+   if(CheckCoord3()) return TRUE;\r
+  }\r
+\r
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
+\r
+ return FALSE;\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+BOOL offset4(void)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(!(dwActFixes&16))\r
+  {\r
+   lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);\r
+   lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);\r
+\r
+   if(CheckCoord4()) return TRUE;\r
+  }\r
+\r
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
+ vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
+ vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
+\r
+ return FALSE;\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+void offsetST(void)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(!(dwActFixes&16))\r
+  {\r
+   lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);\r
+   ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);\r
+\r
+   if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)\r
+    lx0+=2048;\r
+\r
+   if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)\r
+    ly0+=2048;\r
+  }\r
+\r
+ ly1 = ly0;\r
+ ly2 = ly3 = ly0+sprtH;\r
+ lx3 = lx0;\r
+ lx1 = lx2 = lx0+sprtW;\r
+\r
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;\r
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;\r
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;\r
+ vertex[3].x=lx3+PSXDisplay.CumulOffset.x;\r
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;\r
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;\r
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;\r
+ vertex[3].y=ly3+PSXDisplay.CumulOffset.y;\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+void offsetScreenUpload(long Position)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+\r
+ if(Position==-1)\r
+  {\r
+   long lmdx,lmdy;\r
+\r
+   lmdx=xrUploadArea.x0;\r
+   lmdy=xrUploadArea.y0;\r
+\r
+   lx0-=lmdx;\r
+   ly0-=lmdy;\r
+   lx1-=lmdx;\r
+   ly1-=lmdy;\r
+   lx2-=lmdx;\r
+   ly2-=lmdy;\r
+   lx3-=lmdx;\r
+   ly3-=lmdy;\r
+  }\r
+ else\r
+ if(Position)\r
+  {\r
+   lx0-=PSXDisplay.DisplayPosition.x;\r
+   ly0-=PSXDisplay.DisplayPosition.y;\r
+   lx1-=PSXDisplay.DisplayPosition.x;\r
+   ly1-=PSXDisplay.DisplayPosition.y;\r
+   lx2-=PSXDisplay.DisplayPosition.x;\r
+   ly2-=PSXDisplay.DisplayPosition.y;\r
+   lx3-=PSXDisplay.DisplayPosition.x;\r
+   ly3-=PSXDisplay.DisplayPosition.y;\r
+  }\r
+ else\r
+  {\r
+   lx0-=PreviousPSXDisplay.DisplayPosition.x;\r
+   ly0-=PreviousPSXDisplay.DisplayPosition.y;\r
+   lx1-=PreviousPSXDisplay.DisplayPosition.x;\r
+   ly1-=PreviousPSXDisplay.DisplayPosition.y;\r
+   lx2-=PreviousPSXDisplay.DisplayPosition.x;\r
+   ly2-=PreviousPSXDisplay.DisplayPosition.y;\r
+   lx3-=PreviousPSXDisplay.DisplayPosition.x;\r
+   ly3-=PreviousPSXDisplay.DisplayPosition.y;\r
+  }\r
+\r
+ vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;\r
+ vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;\r
+ vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;\r
+ vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;\r
+ vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;\r
+ vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;\r
+ vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;\r
+ vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;\r
+\r
+ if(iUseMask)\r
+  {\r
+   vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
+   gl_z+=0.00004f;\r
+  }\r
+}\r
\r
+///////////////////////////////////////////////////////// \r
+\r
+void offsetBlk(void)\r
+{\r
+ if(bDisplayNotSet)\r
+  SetOGLDisplaySettings(1);\r
+                                            \r
+ vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
+ vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
+ vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
+ vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
+ vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
+ vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
+ vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
+ vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
+\r
+ if(iUseMask)\r
+  {\r
+   vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
+   gl_z+=0.00004f;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// texture sow/tow calculations\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void assignTextureVRAMWrite(void)\r
+{\r
+#ifdef OWNSCALE\r
+\r
+ vertex[0].sow=0.5f/ ST_FACVRAMX;\r
+ vertex[0].tow=0.5f/ ST_FACVRAM;\r
+\r
+ vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;\r
+ vertex[1].tow=0.5f/ ST_FACVRAM;\r
+\r
+ vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;\r
+ vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;\r
+\r
+ vertex[3].sow=0.5f/ ST_FACVRAMX;\r
+ vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;\r
+\r
+#else\r
+\r
+ if(gl_ux[1]==255)\r
+  {\r
+   vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;\r
+   vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;\r
+   vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;\r
+   vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;\r
+  }\r
+ else\r
+  {\r
+   vertex[0].sow=gl_ux[0];\r
+   vertex[1].sow=gl_ux[1];\r
+   vertex[2].sow=gl_ux[2];\r
+   vertex[3].sow=gl_ux[3];\r
+  }\r
+\r
+ vertex[0].tow=gl_vy[0];\r
+ vertex[1].tow=gl_vy[1];\r
+ vertex[2].tow=gl_vy[2];\r
+ vertex[3].tow=gl_vy[3];\r
+\r
+#endif\r
+}\r
+\r
+GLuint  gLastTex=0;\r
+GLuint  gLastFMode=(GLuint)-1;\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+void assignTextureSprite(void)\r
+{\r
+ if(bUsingTWin)\r
+  {\r
+   vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
+   vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;\r
+   vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
+   vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;\r
+   gLastTex=gTexName;\r
+  }\r
+ else\r
+  {\r
+#ifdef OWNSCALE\r
+\r
+   vertex[0].sow=vertex[3].sow=(float)gl_ux[0]     / ST_FACSPRITE;\r
+   vertex[1].sow=vertex[2].sow=(float)sSprite_ux2  / ST_FACSPRITE;\r
+   vertex[0].tow=vertex[1].tow=(float)gl_vy[0]     / ST_FACSPRITE;\r
+   vertex[2].tow=vertex[3].tow=(float)sSprite_vy2  / ST_FACSPRITE;\r
+\r
+#else\r
\r
+   vertex[0].sow=vertex[3].sow=gl_ux[0];\r
+   vertex[1].sow=vertex[2].sow=sSprite_ux2;\r
+   vertex[0].tow=vertex[1].tow=gl_vy[0];\r
+   vertex[2].tow=vertex[3].tow=sSprite_vy2;\r
+\r
+#endif\r
+\r
+   if(iFilterType>2) \r
+    {\r
+     if(gLastTex!=gTexName || gLastFMode!=0)\r
+      {\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+       gLastTex=gTexName;gLastFMode=0;\r
+      }\r
+    }\r
+  }\r
+\r
+ if(usMirror & 0x1000) \r
+  {\r
+   vertex[0].sow=vertex[1].sow;\r
+   vertex[1].sow=vertex[2].sow=vertex[3].sow;\r
+   vertex[3].sow=vertex[0].sow;\r
+  }\r
+\r
+ if(usMirror & 0x2000) \r
+  {\r
+   vertex[0].tow=vertex[3].tow;\r
+   vertex[2].tow=vertex[3].tow=vertex[1].tow;\r
+   vertex[1].tow=vertex[0].tow;\r
+  }\r
+\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+void assignTexture3(void)\r
+{\r
+ if(bUsingTWin)\r
+  {\r
+   vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
+   vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
+   vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
+   vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
+   vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
+   vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
+   gLastTex=gTexName;\r
+  }\r
+ else\r
+  {\r
+#ifdef OWNSCALE\r
+   vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;\r
+   vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;\r
+   vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;\r
+\r
+   vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;\r
+   vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;\r
+   vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;\r
+#else\r
+   vertex[0].sow=gl_ux[0];\r
+   vertex[0].tow=gl_vy[0];\r
+   vertex[1].sow=gl_ux[1];\r
+   vertex[1].tow=gl_vy[1];\r
+   vertex[2].sow=gl_ux[2];\r
+   vertex[2].tow=gl_vy[2];\r
+#endif\r
+\r
+   if(iFilterType>2) \r
+    {\r
+     if(gLastTex!=gTexName || gLastFMode!=1)\r
+      {\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+       gLastTex=gTexName;gLastFMode=1;\r
+      }\r
+    }\r
+\r
+   if(iFilterType) \r
+    {\r
+     float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
+     for(i=0;i<3;i++)\r
+      {\r
+       if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
+       if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
+       if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
+       if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
+      }\r
+\r
+     for(i=0;i<3;i++)\r
+      {\r
+       if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
+       if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
+       if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
+       if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+void assignTexture4(void)\r
+{\r
+ if(bUsingTWin)\r
+  {\r
+   vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;\r
+   vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;\r
+   vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;\r
+   vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;\r
+   vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;\r
+   vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;\r
+   vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;\r
+   vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;\r
+   gLastTex=gTexName;\r
+  }\r
+ else\r
+  {\r
+#ifdef OWNSCALE\r
+   vertex[0].sow=(float)gl_ux[0] / ST_FAC;\r
+   vertex[0].tow=(float)gl_vy[0] / ST_FAC;\r
+   vertex[1].sow=(float)gl_ux[1] / ST_FAC;\r
+   vertex[1].tow=(float)gl_vy[1] / ST_FAC;\r
+   vertex[2].sow=(float)gl_ux[2] / ST_FAC;\r
+   vertex[2].tow=(float)gl_vy[2] / ST_FAC;\r
+   vertex[3].sow=(float)gl_ux[3] / ST_FAC;\r
+   vertex[3].tow=(float)gl_vy[3] / ST_FAC;\r
+#else\r
+   vertex[0].sow=gl_ux[0];\r
+   vertex[0].tow=gl_vy[0];\r
+   vertex[1].sow=gl_ux[1];\r
+   vertex[1].tow=gl_vy[1];\r
+   vertex[2].sow=gl_ux[2];\r
+   vertex[2].tow=gl_vy[2];\r
+   vertex[3].sow=gl_ux[3];\r
+   vertex[3].tow=gl_vy[3];\r
+#endif\r
+\r
+   if(iFilterType>2) \r
+    {\r
+     if(gLastTex!=gTexName || gLastFMode!=1)\r
+      {\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+       gLastTex=gTexName;gLastFMode=1;\r
+      }\r
+    }\r
+\r
+   if(iFilterType) \r
+    {\r
+     float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;\r
+     for(i=0;i<4;i++)\r
+      {\r
+       if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;\r
+       if(vertex[i].tow<fymin) fymin=vertex[i].tow;\r
+       if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;\r
+       if(vertex[i].tow>fymax) fymax=vertex[i].tow; \r
+      }\r
+\r
+     for(i=0;i<4;i++)\r
+      {\r
+       if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;\r
+       if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;\r
+       if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;\r
+       if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// render pos / buffers\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WINDOWS\r
+#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// SetDisplaySettings: "simply" calcs the new drawing area and updates\r
+//                     the ogl clipping (scissor) \r
+\r
+BOOL bSetClip=FALSE;\r
+\r
+void SetOGLDisplaySettings(BOOL DisplaySet)\r
+{\r
+ static RECT rprev={0,0,0,0};\r
+ static RECT rC   ={0,0,0,0};\r
+ static int iOldX=0;\r
+ static int iOldY=0;\r
+ RECT r;float XS,YS;\r
+\r
+ bDisplayNotSet = FALSE;\r
+\r
+ //----------------------------------------------------// that's a whole screen upload\r
+ if(!DisplaySet)\r
+  {\r
+   RECT rX;\r
+   PSXDisplay.GDrawOffset.x=0;\r
+   PSXDisplay.GDrawOffset.y=0;\r
+\r
+   PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;\r
+   PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;\r
+\r
+   rprev.left=rprev.left+1;\r
+\r
+   rX=rRatioRect;\r
+   rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);\r
+\r
+   if(bSetClip || !EqualRect(&rC,&rX))\r
+    {\r
+     rC=rX;\r
+     glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
+     bSetClip=FALSE; \r
+    }\r
+   return;\r
+  }\r
+ //----------------------------------------------------// \r
+\r
+ PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;\r
+ PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;\r
+ PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;\r
+ PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;\r
+\r
+ r.top   =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;\r
+ r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;\r
+\r
+ if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)\r
+  {\r
+   r.top   =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;\r
+   r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;\r
+  }\r
+\r
+ r.left  =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;\r
+ r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;\r
+\r
+ if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)\r
+  {\r
+   r.left  =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;\r
+   r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;\r
+  }\r
+\r
+ if(!bSetClip && EqualRect(&r,&rprev) &&\r
+    iOldX == PSXDisplay.DisplayMode.x &&\r
+    iOldY == PSXDisplay.DisplayMode.y)\r
+  return;\r
+\r
+ rprev = r;\r
+ iOldX = PSXDisplay.DisplayMode.x;\r
+ iOldY = PSXDisplay.DisplayMode.y;\r
+\r
+ XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
+ YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
+\r
+ if(PreviousPSXDisplay.Range.x0)\r
+  {\r
+   short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;\r
+\r
+   r.left+=PreviousPSXDisplay.Range.x0+1;\r
+\r
+   r.right+=PreviousPSXDisplay.Range.x0;\r
+\r
+   if(r.left>s)  r.left=s;\r
+   if(r.right>s) r.right=s;\r
+  }\r
+\r
+ if(PreviousPSXDisplay.Range.y0)\r
+  {\r
+   short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;\r
+\r
+   r.top+=PreviousPSXDisplay.Range.y0+1;\r
+   r.bottom+=PreviousPSXDisplay.Range.y0;\r
+\r
+   if(r.top>s)    r.top=s;\r
+   if(r.bottom>s) r.bottom=s;\r
+  }\r
+\r
+ // Set the ClipArea variables to reflect the new screen,\r
+ // offset from zero (since it is a new display buffer)\r
+ r.left   = (int)(((float)(r.left))      *XS);\r
+ r.top    = (int)(((float)(r.top))       *YS);\r
+ r.right  = (int)(((float)(r.right  + 1))*XS);\r
+ r.bottom = (int)(((float)(r.bottom + 1))*YS);\r
+\r
+ // Limit clip area to the screen size\r
+ if (r.left   > iResX)   r.left   = iResX;\r
+ if (r.left   < 0)       r.left   = 0;\r
+ if (r.top    > iResY)   r.top    = iResY;\r
+ if (r.top    < 0)       r.top    = 0;\r
+ if (r.right  > iResX)   r.right  = iResX;\r
+ if (r.right  < 0)       r.right  = 0;\r
+ if (r.bottom > iResY)   r.bottom = iResY;\r
+ if (r.bottom < 0)       r.bottom = 0;\r
+\r
+ r.right -=r.left;\r
+ r.bottom-=r.top;\r
+ r.top=iResY-(r.top+r.bottom);\r
+\r
+ r.left+=rRatioRect.left;\r
+ r.top -=rRatioRect.top;\r
+\r
+ if(bSetClip || !EqualRect(&r,&rC))\r
+  {\r
+   glScissor(r.left,r.top,r.right,r.bottom);\r
+   rC=r;\r
+   bSetClip=FALSE;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r