gpu-gles from psx4m
authornotaz <notasas@gmail.com>
Fri, 31 Dec 2010 14:57:02 +0000 (16:57 +0200)
committernotaz <notasas@gmail.com>
Fri, 31 Dec 2010 14:57:02 +0000 (16:57 +0200)
12 files changed:
plugins/gpu-gles/gpuDraw.c [new file with mode: 0644]
plugins/gpu-gles/gpuDraw.h [new file with mode: 0644]
plugins/gpu-gles/gpuExternals.h [new file with mode: 0644]
plugins/gpu-gles/gpuFps.c [new file with mode: 0644]
plugins/gpu-gles/gpuFps.h [new file with mode: 0644]
plugins/gpu-gles/gpuPlugin.c [new file with mode: 0644]
plugins/gpu-gles/gpuPlugin.h [new file with mode: 0644]
plugins/gpu-gles/gpuPrim.c [new file with mode: 0644]
plugins/gpu-gles/gpuPrim.h [new file with mode: 0644]
plugins/gpu-gles/gpuStdafx.h [new file with mode: 0644]
plugins/gpu-gles/gpuTexture.c [new file with mode: 0644]
plugins/gpu-gles/gpuTexture.h [new file with mode: 0644]

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
diff --git a/plugins/gpu-gles/gpuDraw.h b/plugins/gpu-gles/gpuDraw.h
new file mode 100644 (file)
index 0000000..f5f0426
--- /dev/null
@@ -0,0 +1,83 @@
+/***************************************************************************\r
+                            draw.h  -  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
+#ifndef _GL_DRAW_H_\r
+#define _GL_DRAW_H_\r
+\r
+\r
+#ifdef __cplusplus\r
+\r
+extern "C" {\r
+#endif\r
+       \r
+#include "minimal.h"\r
+#include <gdk/gdkx.h>\r
+\r
+// internally used defines\r
+\r
+#define GPUCOMMAND(x) ((x>>24) & 0xff)\r
+#define RED(x) (x & 0xff)\r
+#define BLUE(x) ((x>>16) & 0xff)\r
+#define GREEN(x) ((x>>8) & 0xff)\r
+#define COLOR(x) (x & 0xffffff)\r
+\r
+// prototypes\r
+\r
+#ifdef _WINDOWS\r
+BOOL bSetupPixelFormat(HDC hDC);\r
+#endif\r
+\r
+int  GLinitialize();\r
+void GLcleanup();\r
+#ifdef _WINDOWS\r
+BOOL offset2(void);\r
+BOOL offset3(void);\r
+BOOL offset4(void);\r
+BOOL offsetline(void);\r
+#else\r
+unsigned short offset2(void);\r
+unsigned short offset3(void);\r
+unsigned short offset4(void);\r
+unsigned short offsetline(void);\r
+#endif\r
+void offsetST(void);\r
+void offsetBlk(void);\r
+void offsetScreenUpload(long Position);\r
+void assignTexture3(void);\r
+void assignTexture4(void);\r
+void assignTextureSprite(void);\r
+void assignTextureVRAMWrite(void);\r
+void SetOGLDisplaySettings (unsigned short DisplaySet);\r
+void ReadConfig(void);\r
+void WriteConfig(void);\r
+void SetExtGLFuncs(void);\r
+///////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // _GL_DRAW_H_\r
diff --git a/plugins/gpu-gles/gpuExternals.h b/plugins/gpu-gles/gpuExternals.h
new file mode 100644 (file)
index 0000000..f24c31a
--- /dev/null
@@ -0,0 +1,570 @@
+/***************************************************************************\r
+                          external.h  -  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
+\r
+#ifndef __GPU_EX__\r
+#define __GPU_EX__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+#define _GPU_API_\r
+#ifndef _WINDOWS\r
+#ifdef __NANOGL__\r
+#include <gl/gl.h>\r
+#include <gl/egl.h>\r
+#else\r
+#ifdef SOFT_LINKAGE\r
+#pragma softfp_linkage\r
+#endif\r
+#include <gles/gl.h> // for opengl es types \r
+#ifdef SOFT_LINKAGE\r
+#pragma no_softfp_linkage\r
+#endif\r
+#endif\r
+#endif\r
+\r
+#ifdef MAEMO_CHANGES\r
+       #include "../psxCommon.h"\r
+#else\r
+       #include "psxCommon.h"\r
+#endif\r
+\r
+#ifdef __NANOGL__\r
+#define glTexParameteri(x,y,z) glTexParameterf(x,y,z) \r
+#define glAlphaFuncx(x,y) glAlphaFunc(x,y) \r
+#ifndef APIENTRY\r
+#define APIENTRY\r
+#endif\r
+extern  void ( APIENTRY * glPixelStorei )(GLenum pname, GLint param);\r
+#endif\r
+\r
+\r
+#define MIRROR_TEST 1\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define SCISSOR_TEST 1\r
+         \r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// for own sow/tow scaling\r
+#define OWNSCALE 1\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define CLUTUSED     0x80000000\r
+//glColor4ubv(x.c.col)\r
+#define SETCOL(x)  if(x.c.lcol!=ulOLDCOL) {ulOLDCOL=x.c.lcol;glColor4ub(x.c.col[0],x.c.col[1],x.c.col[2],x.c.col[3]);} \r
+//#define SETPCOL(x)  if(x->c.lcol!=ulOLDCOL) {ulOLDCOL=x->c.lcol;glColor4ub(x->c.col[0],x->c.col[1],x->c.col[2],x->c.col[3]);}\r
+\r
+#define INFO_TW        0\r
+#define INFO_DRAWSTART 1\r
+#define INFO_DRAWEND   2\r
+#define INFO_DRAWOFF   3\r
+\r
+#define SIGNSHIFT 21\r
+#define CHKMAX_X 1024\r
+#define CHKMAX_Y 512\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// GPU STATUS REGISTER bit values (c) Lewpy\r
+\r
+#define DR_NORMAL 0\r
+#define DR_VRAMTRANSFER 1\r
+\r
+#define GPUSTATUS_ODDLINES            0x80000000\r
+#define GPUSTATUS_DMABITS             0x60000000 // Two bits\r
+#define GPUSTATUS_READYFORCOMMANDS    0x10000000\r
+#define GPUSTATUS_READYFORVRAM        0x08000000\r
+#define GPUSTATUS_IDLE                0x04000000\r
+#define GPUSTATUS_DISPLAYDISABLED     0x00800000\r
+#define GPUSTATUS_INTERLACED          0x00400000\r
+#define GPUSTATUS_RGB24               0x00200000\r
+#define GPUSTATUS_PAL                 0x00100000\r
+#define GPUSTATUS_DOUBLEHEIGHT        0x00080000\r
+#define GPUSTATUS_WIDTHBITS           0x00070000 // Three bits\r
+#define GPUSTATUS_MASKENABLED         0x00001000\r
+#define GPUSTATUS_MASKDRAWN           0x00000800\r
+#define GPUSTATUS_DRAWINGALLOWED      0x00000400\r
+#define GPUSTATUS_DITHER              0x00000200\r
+\r
+#define STATUSREG lGPUstatusRet\r
+\r
+#define GPUIsBusy (STATUSREG &= ~GPUSTATUS_IDLE)\r
+#define GPUIsIdle (STATUSREG |= GPUSTATUS_IDLE)\r
+\r
+#define GPUIsNotReadyForCommands (STATUSREG &= ~GPUSTATUS_READYFORCOMMANDS)\r
+#define GPUIsReadyForCommands (STATUSREG |= GPUSTATUS_READYFORCOMMANDS)\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define KEY_RESETTEXSTORE   1\r
+#define KEY_SHOWFPS         2\r
+#define KEY_RESETOPAQUE     4\r
+#define KEY_RESETDITHER     8\r
+#define KEY_RESETFILTER     16\r
+#define KEY_RESETADVBLEND   32\r
+#define KEY_BLACKWHITE      64\r
+#define KEY_TOGGLEFBTEXTURE 128\r
+#define KEY_STEPDOWN        256\r
+#define KEY_TOGGLEFBREAD    512\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Linux is missing some stuff, eh? ;)\r
+\r
+#ifndef _WINDOWS\r
+#ifndef FALSE\r
+#define FALSE 0\r
+#endif\r
+#ifndef TRUE\r
+#define TRUE  1\r
+#endif\r
+#ifndef BOOL\r
+#define BOOL unsigned short\r
+#endif\r
+#ifndef bool\r
+#define bool unsigned short\r
+#endif\r
+#define LOWORD(l)           ((unsigned short)(l))\r
+#define HIWORD(l)           ((unsigned short)(((unsigned long)(l) >> 16) & 0xFFFF))\r
+#define max(a,b)            (((a) > (b)) ? (a) : (b))\r
+#define min(a,b)            (((a) < (b)) ? (a) : (b))\r
+#define DWORD unsigned long\r
+\r
+typedef struct RECTTAG\r
+{\r
+ int left;\r
+ int top;\r
+ int right;\r
+ int bottom;\r
+}RECT;\r
+\r
+#endif\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+typedef struct VRAMLOADTAG\r
+{\r
+ short x;\r
+ short y;\r
+ short Width;\r
+ short Height;\r
+ short RowsRemaining;\r
+ short ColsRemaining;\r
+ unsigned short *ImagePtr;\r
+} VRAMLoad_t;\r
+\r
+typedef struct PSXPOINTTAG\r
+{\r
+ long x;\r
+ long y;\r
+} PSXPoint_t;\r
+\r
+typedef struct PSXSPOINTTAG\r
+{\r
+ short x;\r
+ short y;\r
+} PSXSPoint_t;\r
+\r
+typedef struct PSXRECTTAG\r
+{\r
+ short x0;\r
+ short x1;\r
+ short y0;\r
+ short y1;\r
+} PSXRect_t;\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+typedef struct TWINTAG\r
+{\r
+ PSXRect_t  Position;\r
+ PSXRect_t  OPosition;\r
+ PSXPoint_t TextureSize;\r
+ float      UScaleFactor;\r
+ float      VScaleFactor;\r
+} TWin_t;\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+typedef struct PSXDISPLAYTAG\r
+{\r
+ PSXPoint_t  DisplayModeNew;\r
+ PSXPoint_t  DisplayMode;\r
+ PSXPoint_t  DisplayPosition;\r
+ PSXPoint_t  DisplayEnd;\r
\r
+ long        Double;\r
+ long        Height;\r
+ long        PAL;\r
+ long        InterlacedNew;\r
+ long        Interlaced;\r
+ long        InterlacedTest;\r
+ long        RGB24New;\r
+ long        RGB24;\r
+ PSXSPoint_t DrawOffset;\r
+ PSXRect_t   DrawArea;\r
+ PSXPoint_t  GDrawOffset;\r
+ PSXPoint_t  CumulOffset;\r
+ long        Disabled;\r
+ PSXRect_t   Range;\r
+} PSXDisplay_t;\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+typedef struct OGLVertexTag \r
+{\r
+ GLfloat x;\r
+ GLfloat y;\r
+ GLfloat z;\r
+\r
+ GLfloat sow;\r
+ GLfloat tow;\r
+\r
+ union\r
+COLTAG\r
+  {\r
+   u8 col[4];\r
+   unsigned long lcol;\r
+  } c;\r
+\r
+} OGLVertex;\r
+\r
+typedef union EXShortTag\r
+{\r
+ u8  c[2];\r
+ unsigned short s;\r
+} EXShort;\r
+\r
+typedef union EXLongTag\r
+{\r
+ u8 c[4];\r
+ unsigned long l;\r
+ EXShort       s[2];\r
+} EXLong;\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+\r
+extern HINSTANCE hInst;\r
+\r
+#endif\r
+                                                      \r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_DRAW\r
+\r
+extern int            iResX;\r
+extern int            iResY;\r
+extern BOOL           bKeepRatio;\r
+extern RECT           rRatioRect;\r
+extern BOOL           bOpaquePass;\r
+extern BOOL           bAdvancedBlend;\r
+\r
+//extern PFNGLBLENDEQU      glBlendEquationEXTEx;\r
+//extern PFNGLCOLORTABLEEXT glColorTableEXTEx;\r
+\r
+extern u8  gl_ux[8];\r
+extern u8  gl_vy[8];\r
+extern OGLVertex      vertex[4];\r
+extern short          sprtY,sprtX,sprtH,sprtW;\r
+#ifdef _WINDOWS\r
+extern HWND           hWWindow;\r
+#endif\r
+extern BOOL           bIsFirstFrame;\r
+extern int            iWinSize;\r
+extern int            iZBufferDepth;\r
+extern GLbitfield     uiBufferBits;\r
+extern int            iUseMask;\r
+extern int            iSetMask;\r
+extern int            iDepthFunc;\r
+extern BOOL           bCheckMask;\r
+extern unsigned short sSetMask;\r
+extern unsigned long  lSetMask;\r
+extern BOOL           bSetClip;\r
+extern GLuint         gTexScanName;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_SOFT\r
+\r
+extern long           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;\r
+extern long           GlobalTextREST,GlobalTextABR,GlobalTextPAGE;\r
+extern short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;\r
+extern short          g_m1;\r
+extern short          g_m2;\r
+extern short          g_m3;\r
+extern short          DrawSemiTrans;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_PRIMDRAW\r
+\r
+extern BOOL          bNeedUploadTest;\r
+extern BOOL          bNeedUploadAfter;\r
+extern BOOL          bTexEnabled;\r
+extern BOOL          bBlendEnable;\r
+extern BOOL          bDrawDither;\r
+extern int           iFilterType; \r
+extern BOOL          bFullVRam;\r
+extern BOOL          bUseMultiPass;\r
+extern int           iOffscreenDrawing;\r
+extern BOOL          bOldSmoothShaded;\r
+extern BOOL          bUsingTWin;\r
+extern BOOL          bUsingMovie;\r
+extern PSXRect_t     xrMovieArea;\r
+extern PSXRect_t     xrUploadArea;\r
+extern PSXRect_t     xrUploadAreaIL;\r
+extern PSXRect_t     xrUploadAreaRGB24;\r
+extern GLuint        gTexName;\r
+extern BOOL          bDrawNonShaded;\r
+extern BOOL          bDrawMultiPass;\r
+extern GLubyte       ubGloColAlpha;\r
+extern GLubyte       ubGloAlpha;\r
+extern short         sSprite_ux2;\r
+extern short         sSprite_vy2;\r
+extern BOOL          bRenderFrontBuffer;\r
+extern unsigned long ulOLDCOL;\r
+extern unsigned long ulClutID;\r
+extern void (*primTableJ[256])(u8 *);\r
+extern void (*primTableSkip[256])(u8 *);\r
+extern unsigned short  usMirror;\r
+extern unsigned long dwCfgFixes;\r
+extern unsigned long dwActFixes;\r
+extern unsigned long dwEmuFixes;\r
+extern BOOL          bUseFixes;\r
+extern int           iSpriteTex;\r
+extern int           iDrawnSomething;\r
+\r
+extern long drawX;\r
+extern long drawY;\r
+extern long drawW;\r
+extern long drawH;\r
+extern short sxmin;\r
+extern short sxmax;\r
+extern short symin;\r
+extern short symax;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_TEXTURE\r
+\r
+extern u8  ubOpaqueDraw;\r
+extern GLint          giWantedRGBA;\r
+extern GLint          giWantedFMT;\r
+extern GLint          giWantedTYPE;\r
+extern void           (*LoadSubTexFn) (int,int,short,short);\r
+extern long           GlobalTexturePage;\r
+extern unsigned long  (*TCF[]) (unsigned long);\r
+extern unsigned short (*PTCF[]) (unsigned short);\r
+extern unsigned long  (*PalTexturedColourFn) (unsigned long);\r
+extern BOOL           bUseFastMdec;\r
+extern BOOL           bUse15bitMdec;\r
+extern int            iFrameTexType;\r
+extern int            iFrameReadType;\r
+extern int            iClampType;\r
+extern int            iSortTexCnt;\r
+extern BOOL           bFakeFrontBuffer; \r
+extern GLuint         gTexFrameName;\r
+extern GLuint         gTexBlurName;\r
+extern int            iVRamSize;\r
+extern int            iTexGarbageCollection;\r
+extern int            iFTexA;\r
+extern int            iFTexB;\r
+extern BOOL           bIgnoreNextTile;\r
+\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_GPU\r
+\r
+extern VRAMLoad_t     VRAMWrite;\r
+extern VRAMLoad_t     VRAMRead;\r
+extern int            iDataWriteMode;\r
+extern int            iDataReadMode;\r
+extern int            iColDepth;\r
+extern BOOL           bChangeRes;\r
+extern BOOL           bWindowMode;\r
+extern s8           szDispBuf[];\r
+extern s8           szGPUKeys[];\r
+extern PSXDisplay_t   PSXDisplay;\r
+extern PSXDisplay_t   PreviousPSXDisplay;\r
+//extern unsigned long  ulKeybits;\r
+extern TWin_t         TWin;\r
+extern BOOL           bDisplayNotSet;\r
+extern long           lGPUstatusRet;\r
+extern short          imageX0,imageX1;\r
+extern short          imageY0,imageY1;\r
+extern long           lClearOnSwap,lClearOnSwapColor;\r
+extern u8  * psxVub;\r
+extern s8    * psxVsb;\r
+extern unsigned short * psxVuw;\r
+extern signed short   * psxVsw;\r
+extern unsigned long  * psxVul;\r
+extern signed long    * psxVsl;\r
+extern GLfloat        gl_z;\r
+extern BOOL           bNeedRGB24Update;\r
+extern BOOL           bChangeWinMode;\r
+extern GLuint         uiScanLine;\r
+extern int            iUseScanLines;\r
+extern long           lSelectedSlot;\r
+extern int            iScanBlend;\r
+extern BOOL           bInitCap;\r
+extern int            iBlurBuffer;\r
+extern int            iLastRGB24;\r
+extern int            iRenderFVR;\r
+extern int            iNoScreenSaver;\r
+extern unsigned long  ulGPUInfoVals[];\r
+extern BOOL           bNeedInterlaceUpdate;\r
+extern BOOL           bNeedWriteUpload;\r
+extern BOOL           bSkipNextFrame;\r
+\r
+\r
+#ifndef _WINDOWS\r
+extern int bFullScreen;\r
+#endif\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_MENU\r
+\r
+//extern unsigned long  dwCoreFlags;\r
+extern GLuint         gTexPicName;\r
+//extern PSXPoint_t     ptCursorPoint[];\r
+//extern unsigned short usCursorActive;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_CFG\r
+\r
+#ifndef _WINDOWS\r
+extern s8 * pConfigFile;\r
+#endif\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_FPS\r
+\r
+extern BOOL           bUseFrameLimit;\r
+extern BOOL           bUseFrameSkip;\r
+extern float          fFrameRate;\r
+extern float          fFrameRateHz;\r
+extern int            iFrameLimit;\r
+extern float          fps_skip;\r
+extern float          fps_cur;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+typedef struct {\r
+u8 r;\r
+u8 g;\r
+u8 b;\r
+u8 a;\r
+} Vec4f;\r
+\r
+/**/\r
+typedef struct {\r
+float x;\r
+float y;\r
+float z;\r
+} Vec3f;\r
+\r
+typedef struct {\r
+float x;\r
+float y;\r
+} Vec2f;\r
+\r
+/*\r
+typedef struct {\r
+int x;\r
+int y;\r
+int z;\r
+} Vec3f;\r
+\r
+typedef struct {\r
+int x;\r
+int y;\r
+} Vec2f;\r
+/**/\r
+\r
+typedef struct {\r
+  Vec3f xyz;\r
+  Vec2f st;\r
+} Vertex;\r
+\r
+typedef struct {\r
+  Vec3f xyz;\r
+  Vec2f st;\r
+  Vec4f rgba;\r
+} Vertex2;\r
+\r
+#ifndef _IN_KEY\r
+\r
+//extern unsigned long  ulKeybits;\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
+\r
+#ifndef _IN_ZN\r
+\r
+extern unsigned long dwGPUVersion;\r
+extern int           iGPUHeight;\r
+extern int           iGPUHeightMask;\r
+extern int           GlobalTextIL;\r
+extern int           iTileCheat;\r
+\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif\r
+\r
+//-----------------------------------------------------//\r
diff --git a/plugins/gpu-gles/gpuFps.c b/plugins/gpu-gles/gpuFps.c
new file mode 100644 (file)
index 0000000..1012ecb
--- /dev/null
@@ -0,0 +1,991 @@
+/***************************************************************************\r
+                          fps.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
+#ifdef _WINDOWS\r
+#include "Stdafx.h"\r
+#include "Externals.h"\r
+#include "plugin.h"\r
+#include "Fps.h"\r
+#include "Prim.h"\r
+#else\r
+#include "gpuStdafx.h"\r
+#include "gpuExternals.h"\r
+//#include "plugins.h"\r
+#include "gpuFps.h"\r
+#include "gpuPrim.h"\r
+#endif\r
+\r
+#define _IN_FPS\r
+\r
+#define CALLBACK\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// FPS stuff\r
+////////////////////////////////////////////////////////////////////////\r
+#ifdef _WINDOWS\r
+LARGE_INTEGER  liCPUFrequency;\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// FPS skipping / limit\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL           bIsPerformanceCounter;\r
+float          fFrameRateHz;\r
+DWORD          dwFrameRateTicks;\r
+float          fFrameRate;\r
+int            iFrameLimit;\r
+BOOL           bUseFrameLimit;\r
+BOOL           bUseFrameSkip;\r
+DWORD          dwLaceCnt;\r
+\r
+BOOL         bInitCap; \r
+float        fps_skip;\r
+float        fps_cur;\r
+\r
+#ifdef _WINDOWS\r
+\r
+void FrameCap (void)\r
+{\r
+ static DWORD curticks, lastticks, _ticks_since_last_update;\r
+ static DWORD TicksToWait = 0;\r
+ static LARGE_INTEGER  CurrentTime;\r
+ static LARGE_INTEGER  LastTime;\r
+ static BOOL SkipNextWait = FALSE;\r
+ BOOL Waiting = TRUE;\r
+\r
+ //---------------------------------------------------------\r
+ // init some static vars... \r
+ // bInitCap is TRUE on startup and everytime the user\r
+ // is toggling the frame limit\r
+ //---------------------------------------------------------\r
+\r
+ if(bInitCap)\r
+  {\r
+   bInitCap=FALSE;\r
+   if (bIsPerformanceCounter)\r
+    QueryPerformanceCounter(&LastTime);\r
+   lastticks = timeGetTime();\r
+   TicksToWait=0;\r
+   return;\r
+  }\r
+\r
+ //---------------------------------------------------------\r
+\r
+ if(bIsPerformanceCounter)\r
+  {\r
+   QueryPerformanceCounter(&CurrentTime);\r
+   _ticks_since_last_update = CurrentTime.LowPart - LastTime.LowPart;\r
+\r
+   //---------------------------------------------------------\r
+   // check if diff > 1/2 sec, if yes: take mm timer value\r
+   //---------------------------------------------------------\r
+\r
+   curticks = timeGetTime();\r
+   if(_ticks_since_last_update>(liCPUFrequency.LowPart>>1))   \r
+    {\r
+     if(curticks < lastticks)\r
+          _ticks_since_last_update = dwFrameRateTicks+TicksToWait+1;\r
+     else _ticks_since_last_update = (liCPUFrequency.LowPart * (curticks - lastticks))/1000;\r
+    }\r
+\r
+   //---------------------------------------------------------\r
+\r
+   if ((_ticks_since_last_update > TicksToWait) || \r
+       (CurrentTime.LowPart < LastTime.LowPart))\r
+    {\r
+     LastTime.HighPart = CurrentTime.HighPart;\r
+     LastTime.LowPart  = CurrentTime.LowPart;\r
+\r
+     lastticks=curticks;\r
+\r
+     if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks)\r
+          TicksToWait=0;\r
+     else TicksToWait=dwFrameRateTicks-(_ticks_since_last_update-TicksToWait);\r
+    }\r
+   else\r
+    {\r
+     while (Waiting)\r
+      {\r
+       QueryPerformanceCounter(&CurrentTime);\r
+       _ticks_since_last_update = CurrentTime.LowPart - LastTime.LowPart;\r
+\r
+       //---------------------------------------------------------\r
+       // check if diff > 1/2 sec, if yes: take mm timer value\r
+       //---------------------------------------------------------\r
+       curticks = timeGetTime();\r
+       if(_ticks_since_last_update>(liCPUFrequency.LowPart>>1))   \r
+        {\r
+         if(curticks < lastticks)\r
+              _ticks_since_last_update = TicksToWait+1;\r
+         else _ticks_since_last_update = (liCPUFrequency.LowPart * (curticks - lastticks))/1000;\r
+        }\r
+       //---------------------------------------------------------\r
+\r
+       if ((_ticks_since_last_update > TicksToWait) || \r
+           (CurrentTime.LowPart < LastTime.LowPart))\r
+        {\r
+         Waiting = FALSE;\r
+\r
+         lastticks=curticks;\r
+\r
+         LastTime.HighPart = CurrentTime.HighPart;\r
+         LastTime.LowPart = CurrentTime.LowPart;\r
+         TicksToWait = dwFrameRateTicks;\r
+        }\r
+      }\r
+    }\r
+  }\r
+ else\r
+  {\r
+   curticks = timeGetTime();\r
+   _ticks_since_last_update = curticks - lastticks;\r
+\r
+   if ((_ticks_since_last_update > TicksToWait) || \r
+       (curticks < lastticks))\r
+    {\r
+     lastticks = curticks;\r
+\r
+     if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks)\r
+          TicksToWait=0;\r
+     else TicksToWait=dwFrameRateTicks-(_ticks_since_last_update-TicksToWait);\r
+    }\r
+   else\r
+    {\r
+     while (Waiting)\r
+      {\r
+       curticks = timeGetTime();\r
+       _ticks_since_last_update = curticks - lastticks;\r
+       if ((_ticks_since_last_update > TicksToWait) ||\r
+           (curticks < lastticks))\r
+        {\r
+         Waiting = FALSE;\r
+         lastticks = curticks;\r
+         TicksToWait = dwFrameRateTicks;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define MAXSKIP 120\r
+#define MAXLACE 16\r
+\r
+void FrameSkip(void)\r
+{\r
+ static int   iNumSkips=0,iAdditionalSkip=0;           // number of additional frames to skip\r
+ static DWORD dwLastLace=0;                            // helper var for frame limitation\r
+ static DWORD curticks, lastticks, _ticks_since_last_update;\r
+ static LARGE_INTEGER  CurrentTime;\r
+ static LARGE_INTEGER  LastTime;\r
+\r
+ if(!dwLaceCnt) return;                                // important: if no updatelace happened, we ignore it completely\r
+\r
+ if(iNumSkips)                                         // we are in skipping mode?\r
+  {\r
+   dwLastLace+=dwLaceCnt;                              // -> calc frame limit helper (number of laces)\r
+   bSkipNextFrame = TRUE;                              // -> we skip next frame\r
+   iNumSkips--;                                        // -> ok, one done\r
+  }\r
+ else                                                  // ok, no additional skipping has to be done... \r
+  {                                                    // we check now, if some limitation is needed, or a new skipping has to get started\r
+   DWORD dwWaitTime;\r
+\r
+   if(bInitCap || bSkipNextFrame)                      // first time or we skipped before?\r
+    {\r
+     if(bUseFrameLimit && !bInitCap)                   // frame limit wanted and not first time called?\r
+      {\r
+       DWORD dwT=_ticks_since_last_update;             // -> that's the time of the last drawn frame\r
+       dwLastLace+=dwLaceCnt;                          // -> and that's the number of updatelace since the start of the last drawn frame\r
+\r
+       if(bIsPerformanceCounter)                       // -> now we calc the time of the last drawn frame + the time we spent skipping\r
+        {\r
+         QueryPerformanceCounter(&CurrentTime);\r
+         _ticks_since_last_update= dwT+CurrentTime.LowPart - LastTime.LowPart;\r
+        }\r
+       else\r
+        {\r
+         curticks = timeGetTime();\r
+         _ticks_since_last_update= dwT+curticks - lastticks;\r
+        }\r
+\r
+       dwWaitTime=dwLastLace*dwFrameRateTicks;         // -> and now we calc the time the real psx would have needed\r
+\r
+       if(_ticks_since_last_update<dwWaitTime)         // -> we were too fast?\r
+        {                                    \r
+         if((dwWaitTime-_ticks_since_last_update)>     // -> some more security, to prevent\r
+            (60*dwFrameRateTicks))                     //    wrong waiting times\r
+          _ticks_since_last_update=dwWaitTime;\r
+\r
+         while(_ticks_since_last_update<dwWaitTime)    // -> loop until we have reached the real psx time\r
+          {                                            //    (that's the additional limitation, yup)\r
+           if(bIsPerformanceCounter)\r
+            {\r
+             QueryPerformanceCounter(&CurrentTime);\r
+             _ticks_since_last_update = dwT+CurrentTime.LowPart - LastTime.LowPart;\r
+            }\r
+           else\r
+            {\r
+             curticks = timeGetTime();\r
+             _ticks_since_last_update = dwT+curticks - lastticks;\r
+            }\r
+          }\r
+        }\r
+       else                                            // we were still too slow ?!!?\r
+        {\r
+         if(iAdditionalSkip<MAXSKIP)                   // -> well, somewhen we really have to stop skipping on very slow systems\r
+          {\r
+           iAdditionalSkip++;                          // -> inc our watchdog var\r
+           dwLaceCnt=0;                                // -> reset lace count\r
+           if(bIsPerformanceCounter)                   // -> ok, start time of the next frame\r
+            QueryPerformanceCounter(&LastTime);\r
+           lastticks = timeGetTime();\r
+           return;                                     // -> done, we will skip next frame to get more speed\r
+          } \r
+        }\r
+      }\r
+\r
+     bInitCap=FALSE;                                   // -> ok, we have inited the frameskip func\r
+     iAdditionalSkip=0;                                // -> init additional skip\r
+     bSkipNextFrame=FALSE;                              // -> we don't skip the next frame\r
+     if(bIsPerformanceCounter)                         // -> we store the start time of the next frame\r
+      QueryPerformanceCounter(&LastTime);\r
+     lastticks = timeGetTime();\r
+     dwLaceCnt=0;                                      // -> and we start to count the laces \r
+     dwLastLace=0;      \r
+     _ticks_since_last_update=0;\r
+     return;                                           // -> done, the next frame will get drawn\r
+    }\r
+\r
+   bSkipNextFrame=FALSE;                                // init the frame skip signal to 'no skipping' first\r
+\r
+   if(bIsPerformanceCounter)                           // get the current time (we are now at the end of one drawn frame)\r
+    {\r
+     QueryPerformanceCounter(&CurrentTime);\r
+     _ticks_since_last_update = CurrentTime.LowPart - LastTime.LowPart;\r
+    }\r
+   else\r
+    {\r
+     curticks = timeGetTime();\r
+     _ticks_since_last_update = curticks - lastticks;\r
+    }\r
+\r
+   dwLastLace=dwLaceCnt;                               // store curr count (frame limitation helper)\r
+   dwWaitTime=dwLaceCnt*dwFrameRateTicks;              // calc the 'real psx lace time'\r
+\r
+   if(_ticks_since_last_update>dwWaitTime)             // hey, we needed way too long for that frame...\r
+    {\r
+     if(bUseFrameLimit)                                // if limitation, we skip just next frame,\r
+      {                                                // and decide after, if we need to do more\r
+       iNumSkips=0;\r
+      }\r
+     else\r
+      {\r
+       iNumSkips=_ticks_since_last_update/dwWaitTime;  // -> calc number of frames to skip to catch up\r
+       iNumSkips--;                                    // -> since we already skip next frame, one down\r
+       if(iNumSkips>MAXSKIP) iNumSkips=MAXSKIP;        // -> well, somewhere we have to draw a line\r
+      }\r
+     bSkipNextFrame = TRUE;                            // -> signal for skipping the next frame\r
+    }\r
+   else                                                // we were faster than real psx? fine :)\r
+   if(bUseFrameLimit)                                  // frame limit used? so we wait til the 'real psx time' has been reached\r
+    {\r
+     if(dwLaceCnt>MAXLACE)                             // -> security check\r
+      _ticks_since_last_update=dwWaitTime;\r
+\r
+     while(_ticks_since_last_update<dwWaitTime)        // just do a waiting loop...\r
+      {\r
+       if(bIsPerformanceCounter)\r
+        {\r
+         QueryPerformanceCounter(&CurrentTime);\r
+         _ticks_since_last_update = CurrentTime.LowPart - LastTime.LowPart;\r
+        }\r
+       else\r
+        {\r
+         curticks = timeGetTime();\r
+         _ticks_since_last_update = curticks - lastticks;\r
+        }\r
+      }\r
+    }\r
+\r
+   if(bIsPerformanceCounter)                           // ok, start time of the next frame\r
+    QueryPerformanceCounter(&LastTime);\r
+   lastticks = timeGetTime();\r
+  }\r
+\r
+ dwLaceCnt=0;                                          // init lace counter\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void calcfps(void)\r
+{\r
+ static DWORD curticks,_ticks_since_last_update,lastticks;\r
+ static long   fps_cnt = 0;\r
+ static DWORD  fps_tck = 1;\r
+ static LARGE_INTEGER  CurrentTime;\r
+ static LARGE_INTEGER  LastTime;\r
+ static long   fpsskip_cnt = 0;\r
+ static DWORD  fpsskip_tck = 1;\r
+\r
+ if(bIsPerformanceCounter)\r
+  {\r
+   QueryPerformanceCounter(&CurrentTime);\r
+   _ticks_since_last_update=CurrentTime.LowPart-LastTime.LowPart;\r
+                                                        \r
+   //--------------------------------------------------//\r
+   curticks = timeGetTime();\r
+   if(_ticks_since_last_update>(liCPUFrequency.LowPart>>1))\r
+    _ticks_since_last_update = (liCPUFrequency.LowPart * (curticks - lastticks))/1000;\r
+   lastticks=curticks;\r
+   //--------------------------------------------------//\r
+\r
+   if(bUseFrameSkip && !bUseFrameLimit && _ticks_since_last_update)                                    \r
+    fps_skip=min(fps_skip,(((float)liCPUFrequency.LowPart) / ((float)_ticks_since_last_update) +1.0f));\r
+\r
+   LastTime.HighPart = CurrentTime.HighPart;\r
+   LastTime.LowPart = CurrentTime.LowPart;\r
+  }\r
+ else\r
+  {\r
+   curticks = timeGetTime();\r
+   _ticks_since_last_update=curticks-lastticks;\r
+\r
+   if(bUseFrameSkip && !bUseFrameLimit && _ticks_since_last_update)\r
+    fps_skip=min(fps_skip,((float)1000/(float)_ticks_since_last_update+1.0f));\r
+\r
+   lastticks = curticks;\r
+  }\r
+\r
+ if(bUseFrameSkip && bUseFrameLimit)\r
+  {\r
+   fpsskip_tck += _ticks_since_last_update;\r
+\r
+   if(++fpsskip_cnt==2)\r
+    {\r
+     if(bIsPerformanceCounter)\r
+      fps_skip = ((float)liCPUFrequency.LowPart) / ((float)fpsskip_tck) *2.0f;\r
+     else\r
+      fps_skip = (float)2000/(float)fpsskip_tck;\r
+\r
+     fps_skip +=6.0f;\r
+\r
+     fpsskip_cnt = 0;\r
+     fpsskip_tck = 1;\r
+    }\r
+  }\r
+\r
+ fps_tck += _ticks_since_last_update;\r
+\r
+ if(++fps_cnt==10)\r
+  {\r
+   if(bIsPerformanceCounter)\r
+    fps_cur = ((float)liCPUFrequency.LowPart) / ((float)fps_tck) *10.0f;\r
+   else\r
+    fps_cur = (float)10000/(float)fps_tck;\r
+\r
+   fps_cnt = 0;\r
+   fps_tck = 1;\r
+\r
+   if(bUseFrameLimit && fps_cur>fFrameRateHz)            // optical adjust ;) avoids flickering fps display\r
+    fps_cur=fFrameRateHz;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// PC FPS skipping / limit\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PCFrameCap(void)\r
+{\r
+ static DWORD curticks, lastticks, _ticks_since_last_update;\r
+ static DWORD TicksToWait = 0;\r
+ static LARGE_INTEGER  CurrentTime;\r
+ static LARGE_INTEGER  LastTime;\r
+ BOOL Waiting = TRUE;\r
+\r
+ while (Waiting)\r
+  {\r
+   if(bIsPerformanceCounter)\r
+    {\r
+     QueryPerformanceCounter(&CurrentTime);\r
+     _ticks_since_last_update = CurrentTime.LowPart - LastTime.LowPart;\r
+\r
+     //------------------------------------------------//\r
+     curticks = timeGetTime();\r
+     if(_ticks_since_last_update>(liCPUFrequency.LowPart>>1))   \r
+      {\r
+       if(curticks < lastticks)\r
+            _ticks_since_last_update = TicksToWait+1;\r
+       else _ticks_since_last_update = (liCPUFrequency.LowPart * (curticks - lastticks))/1000;\r
+      }\r
+     //------------------------------------------------//\r
+\r
+     if ((_ticks_since_last_update > TicksToWait) ||\r
+         (CurrentTime.LowPart < LastTime.LowPart))\r
+      {\r
+       Waiting = FALSE;\r
+\r
+       lastticks=curticks; \r
+\r
+       LastTime.HighPart = CurrentTime.HighPart;\r
+       LastTime.LowPart = CurrentTime.LowPart;\r
+       TicksToWait = (liCPUFrequency.LowPart / fFrameRateHz);\r
+      }\r
+    }\r
+   else\r
+    {\r
+     curticks = timeGetTime();\r
+     _ticks_since_last_update = curticks - lastticks;\r
+     if ((_ticks_since_last_update > TicksToWait) || \r
+         (curticks < lastticks))\r
+      {\r
+       Waiting = FALSE;\r
+       lastticks = curticks;\r
+       TicksToWait = (1000 / (DWORD)fFrameRateHz);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PCcalcfps(void)\r
+{\r
+ static DWORD curticks,_ticks_since_last_update,lastticks;\r
+ static long  fps_cnt = 0;\r
+ static float fps_acc = 0;\r
+ static LARGE_INTEGER  CurrentTime;\r
+ static LARGE_INTEGER  LastTime;\r
+ float CurrentFPS=0;    \r
\r
+ if(bIsPerformanceCounter)\r
+  {\r
+   QueryPerformanceCounter(&CurrentTime);\r
+   _ticks_since_last_update=CurrentTime.LowPart-LastTime.LowPart;\r
+\r
+   //--------------------------------------------------//\r
+   curticks = timeGetTime();\r
+   if(_ticks_since_last_update>(liCPUFrequency.LowPart>>1))   \r
+    _ticks_since_last_update = (liCPUFrequency.LowPart * (curticks - lastticks))/1000;\r
+   lastticks=curticks;\r
+   //--------------------------------------------------//\r
+\r
+   if(_ticks_since_last_update)\r
+    {\r
+     CurrentFPS = ((float)liCPUFrequency.LowPart) / ((float)_ticks_since_last_update);\r
+    }\r
+   else CurrentFPS = 0;\r
+   LastTime.HighPart = CurrentTime.HighPart;\r
+   LastTime.LowPart = CurrentTime.LowPart;\r
+  }\r
+ else\r
+  {\r
+   curticks = timeGetTime();\r
+   if(_ticks_since_last_update=curticks-lastticks)\r
+        CurrentFPS=(float)1000/(float)_ticks_since_last_update;\r
+   else CurrentFPS = 0;\r
+   lastticks = curticks;\r
+  }\r
+\r
+ fps_acc += CurrentFPS;\r
+\r
+ if(++fps_cnt==10)\r
+  {\r
+   fps_cur = fps_acc / 10;\r
+   fps_acc = 0;\r
+   fps_cnt = 0;\r
+  }\r
\r
+ fps_skip=CurrentFPS+1.0f;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetAutoFrameCap(void)\r
+{\r
+ if(iFrameLimit==1)\r
+  {\r
+   fFrameRateHz = fFrameRate;\r
+   if(bIsPerformanceCounter)\r
+        dwFrameRateTicks=(liCPUFrequency.LowPart / fFrameRateHz);\r
+   else dwFrameRateTicks=(1000 / (DWORD)fFrameRateHz);\r
+   return;\r
+  }\r
+\r
+ if(dwActFixes&128)\r
+  {\r
+   if (PSXDisplay.Interlaced)\r
+        fFrameRateHz = PSXDisplay.PAL?50.0f:60.0f;\r
+   else fFrameRateHz = PSXDisplay.PAL?25.0f:30.0f;\r
+  }\r
+ else\r
+  {\r
+   //fFrameRateHz = PSXDisplay.PAL?50.0f:59.94f;\r
+\r
+   if(PSXDisplay.PAL)\r
+    {\r
+     if (STATUSREG&GPUSTATUS_INTERLACED)\r
+           fFrameRateHz=33868800.0f/677343.75f;        // 50.00238\r
+      else fFrameRateHz=33868800.0f/680595.00f;        // 49.76351\r
+    }                                                     \r
+   else\r
+    {\r
+     if (STATUSREG&GPUSTATUS_INTERLACED)\r
+           fFrameRateHz=33868800.0f/565031.25f;        // 59.94146\r
+      else fFrameRateHz=33868800.0f/566107.50f;        // 59.82750\r
+    }\r
+\r
+   if(bIsPerformanceCounter)\r
+        dwFrameRateTicks=(liCPUFrequency.LowPart / fFrameRateHz);\r
+   else dwFrameRateTicks=(1000 / (DWORD)fFrameRateHz);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InitFrameCap(void)                                // inits cpu frequency info (on gpu startup)\r
+{\r
+ if (QueryPerformanceFrequency (&liCPUFrequency))\r
+      bIsPerformanceCounter = TRUE;\r
+ else bIsPerformanceCounter = FALSE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ReInitFrameCap(void)\r
+{\r
+ BOOL bOldPerformanceCounter=bIsPerformanceCounter;    // store curr timer mode\r
+\r
+ if(dwActFixes&0x10000)                                // check game fix... high performance counters are bad on some mb chipsets\r
+      bIsPerformanceCounter=FALSE;\r
+ else \r
+  {\r
+   if (QueryPerformanceFrequency (&liCPUFrequency))\r
+        bIsPerformanceCounter = TRUE;\r
+   else bIsPerformanceCounter = FALSE;\r
+  }\r
+           \r
+ if(bOldPerformanceCounter!=bIsPerformanceCounter)     // changed?\r
+  {\r
+   bInitCap = TRUE;\r
+   SetAutoFrameCap();\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetFrameRateConfig(void)\r
+{\r
+ if(fFrameRateHz==0) \r
+  {\r
+   if(iFrameLimit==2) fFrameRateHz=59.94f;           // auto framerate? set some init val (no pal/ntsc known yet)\r
+   else               fFrameRateHz=fFrameRate;       // else set user framerate\r
+  }\r
+\r
+ if(bIsPerformanceCounter)\r
+      dwFrameRateTicks=(liCPUFrequency.LowPart / fFrameRateHz);\r
+ else dwFrameRateTicks=(1000 / (DWORD)fFrameRateHz);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+// LINUX ---------------------------------------------\r
+\r
+#else\r
+\r
+#define TIMEBASE 100000\r
+\r
+// hehehe... using same func name as with win32 ;) wow, are we genius ;)\r
+unsigned long timeGetTime()\r
+{\r
+ struct timeval tv;\r
+ gettimeofday(&tv, 0);                                // well, maybe there are better ways\r
+ return tv.tv_sec * 100000 + tv.tv_usec/10;           // to do that in linux, but at least it works\r
+}\r
+\r
+void FrameCap(void)\r
+{\r
+ static unsigned long curticks, lastticks, _ticks_since_last_update;\r
+ static unsigned long TicksToWait = 0;\r
+ bool Waiting = TRUE;\r
+\r
+  {\r
+   curticks = timeGetTime();\r
+   _ticks_since_last_update = curticks - lastticks;\r
+\r
+    if((_ticks_since_last_update > TicksToWait) ||\r
+       (curticks <lastticks))\r
+    {\r
+     lastticks = curticks;\r
+\r
+     if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks)\r
+          TicksToWait=0;\r
+     else TicksToWait=dwFrameRateTicks-(_ticks_since_last_update-TicksToWait);\r
+    }\r
+   else\r
+    {\r
+     while (Waiting) \r
+      {\r
+       curticks = timeGetTime(); \r
+       _ticks_since_last_update = curticks - lastticks; \r
+       if ((_ticks_since_last_update > TicksToWait) ||\r
+           (curticks < lastticks)) \r
+        { \r
+         Waiting = FALSE;\r
+         lastticks = curticks;\r
+         TicksToWait = dwFrameRateTicks; \r
+        } \r
+      } \r
+    } \r
+  } \r
+} \r
\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define MAXSKIP 120\r
+#define MAXLACE 16\r
+\r
+void FrameSkip(void)\r
+{\r
+ static int   iNumSkips=0,iAdditionalSkip=0;           // number of additional frames to skip\r
+ static DWORD dwLastLace=0;                            // helper var for frame limitation\r
+ static DWORD curticks, lastticks, _ticks_since_last_update;\r
+\r
+ if(!dwLaceCnt) return;                                // important: if no updatelace happened, we ignore it completely\r
+\r
+ if(iNumSkips)                                         // we are in skipping mode?\r
+  {\r
+   dwLastLace+=dwLaceCnt;                              // -> calc frame limit helper (number of laces)\r
+   bSkipNextFrame = TRUE;                              // -> we skip next frame\r
+   iNumSkips--;                                        // -> ok, one done\r
+  }\r
+ else                                                  // ok, no additional skipping has to be done... \r
+  {                                                    // we check now, if some limitation is needed, or a new skipping has to get started\r
+   DWORD dwWaitTime;\r
+\r
+   if(bInitCap || bSkipNextFrame)                      // first time or we skipped before?\r
+    {\r
+     if(bUseFrameLimit && !bInitCap)                   // frame limit wanted and not first time called?\r
+      {\r
+       DWORD dwT=_ticks_since_last_update;             // -> that's the time of the last drawn frame\r
+       dwLastLace+=dwLaceCnt;                          // -> and that's the number of updatelace since the start of the last drawn frame\r
+\r
+       curticks = timeGetTime();\r
+       _ticks_since_last_update= dwT+curticks - lastticks;\r
+\r
+       dwWaitTime=dwLastLace*dwFrameRateTicks;         // -> and now we calc the time the real psx would have needed\r
+\r
+       if(_ticks_since_last_update<dwWaitTime)         // -> we were too fast?\r
+        {                                    \r
+         if((dwWaitTime-_ticks_since_last_update)>     // -> some more security, to prevent\r
+            (60*dwFrameRateTicks))                     //    wrong waiting times\r
+          _ticks_since_last_update=dwWaitTime;\r
+\r
+         while(_ticks_since_last_update<dwWaitTime)    // -> loop until we have reached the real psx time\r
+          {                                            //    (that's the additional limitation, yup)\r
+           curticks = timeGetTime();\r
+           _ticks_since_last_update = dwT+curticks - lastticks;\r
+          }\r
+        }\r
+       else                                            // we were still too slow ?!!?\r
+        {\r
+         if(iAdditionalSkip<MAXSKIP)                   // -> well, somewhen we really have to stop skipping on very slow systems\r
+          {\r
+           iAdditionalSkip++;                          // -> inc our watchdog var\r
+           dwLaceCnt=0;                                // -> reset lace count\r
+           lastticks = timeGetTime();\r
+           return;                                     // -> done, we will skip next frame to get more speed\r
+          }\r
+        }\r
+      }\r
+\r
+     bInitCap=FALSE;                                   // -> ok, we have inited the frameskip func\r
+     iAdditionalSkip=0;                                // -> init additional skip\r
+     bSkipNextFrame=FALSE;                             // -> we don't skip the next frame\r
+     lastticks = timeGetTime();\r
+     dwLaceCnt=0;                                      // -> and we start to count the laces \r
+     dwLastLace=0;      \r
+     _ticks_since_last_update=0;\r
+     return;                                           // -> done, the next frame will get drawn\r
+    }\r
+\r
+   bSkipNextFrame=FALSE;                               // init the frame skip signal to 'no skipping' first\r
+\r
+   curticks = timeGetTime();\r
+   _ticks_since_last_update = curticks - lastticks;\r
+\r
+   dwLastLace=dwLaceCnt;                               // store curr count (frame limitation helper)\r
+   dwWaitTime=dwLaceCnt*dwFrameRateTicks;              // calc the 'real psx lace time'\r
+\r
+   if(_ticks_since_last_update>dwWaitTime)             // hey, we needed way too long for that frame...\r
+    {\r
+     if(bUseFrameLimit)                                // if limitation, we skip just next frame,\r
+      {                                                // and decide after, if we need to do more\r
+       iNumSkips=0;\r
+      }\r
+     else\r
+      {\r
+       iNumSkips=_ticks_since_last_update/dwWaitTime;  // -> calc number of frames to skip to catch up\r
+       iNumSkips--;                                    // -> since we already skip next frame, one down\r
+       if(iNumSkips>MAXSKIP) iNumSkips=MAXSKIP;        // -> well, somewhere we have to draw a line\r
+      }\r
+     bSkipNextFrame = TRUE;                            // -> signal for skipping the next frame\r
+    }\r
+   else                                                // we were faster than real psx? fine :)\r
+   if(bUseFrameLimit)                                  // frame limit used? so we wait til the 'real psx time' has been reached\r
+    {\r
+     if(dwLaceCnt>MAXLACE)                             // -> security check\r
+      _ticks_since_last_update=dwWaitTime;\r
+\r
+     while(_ticks_since_last_update<dwWaitTime)        // just do a waiting loop...\r
+      {\r
+       curticks = timeGetTime();\r
+       _ticks_since_last_update = curticks - lastticks;\r
+      }\r
+    }\r
+\r
+   lastticks = timeGetTime();\r
+  }\r
+\r
+ dwLaceCnt=0;                                          // init lace counter\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////// \r
\r
+void calcfps(void) \r
+{ \r
+ static unsigned long curticks,_ticks_since_last_update,lastticks; \r
+ static long   fps_cnt = 0;\r
+ static unsigned long  fps_tck = 1; \r
+ static long           fpsskip_cnt = 0;\r
+ static unsigned long  fpsskip_tck = 1;\r
\r
+  { \r
+   curticks = timeGetTime(); \r
+   _ticks_since_last_update=curticks-lastticks; \r
\r
+   if(bUseFrameSkip && !bUseFrameLimit && _ticks_since_last_update) \r
+    fps_skip=min(fps_skip,((float)TIMEBASE/(float)_ticks_since_last_update+1.0f));\r
\r
+   lastticks = curticks; \r
+  } \r
\r
+ if(bUseFrameSkip && bUseFrameLimit)\r
+  {\r
+   fpsskip_tck += _ticks_since_last_update;\r
+\r
+   if(++fpsskip_cnt==2)\r
+    {\r
+     fps_skip = (float)2000/(float)fpsskip_tck;\r
+\r
+     fps_skip +=6.0f;\r
+\r
+     fpsskip_cnt = 0;\r
+     fpsskip_tck = 1;\r
+    }\r
+  }\r
+\r
+ fps_tck += _ticks_since_last_update; \r
\r
+ if(++fps_cnt==10) \r
+  { \r
+   fps_cur = (float)(TIMEBASE*10)/(float)fps_tck; \r
+\r
+   fps_cnt = 0; \r
+   fps_tck = 1; \r
\r
+   if(bUseFrameLimit && fps_cur>fFrameRateHz)            // optical adjust ;) avoids flickering fps display \r
+    fps_cur=fFrameRateHz; \r
+  } \r
+} \r
+\r
+void PCFrameCap (void) \r
+{\r
+ static unsigned long curticks, lastticks, _ticks_since_last_update;\r
+ static unsigned long TicksToWait = 0;\r
+ bool Waiting = TRUE; \r
\r
+ while (Waiting) \r
+  {\r
+   curticks = timeGetTime(); \r
+   _ticks_since_last_update = curticks - lastticks; \r
+   if ((_ticks_since_last_update > TicksToWait) ||  \r
+       (curticks < lastticks)) \r
+    { \r
+     Waiting = FALSE; \r
+     lastticks = curticks; \r
+     TicksToWait = (TIMEBASE / (unsigned long)fFrameRateHz); \r
+    } \r
+  } \r
+} \r
\r
+//////////////////////////////////////////////////////////////////////// \r
\r
+void PCcalcfps(void) \r
+{ \r
+ static unsigned long curticks,_ticks_since_last_update,lastticks; \r
+ static long  fps_cnt = 0; \r
+ static float fps_acc = 0;\r
+ float CurrentFPS=0;     \r
+  \r
+ curticks = timeGetTime(); \r
+ _ticks_since_last_update=curticks-lastticks;\r
+ if(_ticks_since_last_update) \r
+      CurrentFPS=(float)TIMEBASE/(float)_ticks_since_last_update;\r
+ else CurrentFPS = 0;\r
+ lastticks = curticks; \r
\r
+ fps_acc += CurrentFPS;\r
+\r
+ if(++fps_cnt==10)\r
+  {\r
+   fps_cur = fps_acc / 10;\r
+   fps_acc = 0;\r
+   fps_cnt = 0;\r
+  }\r
+\r
+ fps_skip=CurrentFPS+1.0f;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetAutoFrameCap(void)\r
+{\r
+ if(iFrameLimit==1)\r
+  {\r
+   fFrameRateHz = fFrameRate;\r
+   dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);\r
+   return;\r
+  }\r
+\r
+ if(dwActFixes&128)\r
+  {\r
+   if (PSXDisplay.Interlaced)\r
+        fFrameRateHz = PSXDisplay.PAL?50.0f:60.0f;\r
+   else fFrameRateHz = PSXDisplay.PAL?25.0f:30.0f;\r
+  }\r
+ else\r
+  {\r
+   //fFrameRateHz = PSXDisplay.PAL?50.0f:59.94f;\r
+\r
+   if(PSXDisplay.PAL)\r
+    {\r
+     if (STATUSREG&GPUSTATUS_INTERLACED)\r
+           fFrameRateHz=33868800.0f/677343.75f;        // 50.00238\r
+      else fFrameRateHz=33868800.0f/680595.00f;        // 49.76351\r
+    }                                                     \r
+   else\r
+    {\r
+     if (STATUSREG&GPUSTATUS_INTERLACED)\r
+           fFrameRateHz=33868800.0f/565031.25f;        // 59.94146\r
+      else fFrameRateHz=33868800.0f/566107.50f;        // 59.82750\r
+    }\r
+\r
+   dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetFrameRateConfig(void)\r
+{\r
+ if(!fFrameRate) fFrameRate=200.0f;\r
+\r
+ if(fFrameRateHz==0) \r
+  {                                                    \r
+   if(iFrameLimit==2) fFrameRateHz=59.94f;             // auto framerate? set some init val (no pal/ntsc known yet)\r
+   else               fFrameRateHz=fFrameRate;         // else set user framerate\r
+  }\r
+\r
+ dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);\r
+\r
+ if(iFrameLimit==2) SetAutoFrameCap();\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InitFrameCap(void)\r
+{\r
+ // nothing on linux\r
+}\r
+\r
+void ReInitFrameCap(void)\r
+{\r
+ // nothing on linux\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CheckFrameRate(void)                              // called in updatelace (on every emulated psx vsync)\r
+{\r
+ if(bUseFrameSkip) \r
+  {\r
+   if(!(dwActFixes&0x100))\r
+    {\r
+     dwLaceCnt++;                                      // -> and store cnt of vsync between frames\r
+     if(dwLaceCnt>=MAXLACE && bUseFrameLimit) \r
+      {\r
+       if(dwLaceCnt==MAXLACE) bInitCap=TRUE;\r
+       FrameCap();\r
+      }\r
+    }\r
+   else if(bUseFrameLimit) FrameCap();\r
+   calcfps();                                          // -> calc fps display in skipping mode\r
+  }                                                  \r
+ else                                                  // -> non-skipping mode:\r
+  {\r
+   if(bUseFrameLimit) FrameCap();\r
+   calcfps();  \r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CALLBACK GPUsetframelimit(unsigned long option)   // new EPSXE interface func: main emu can enable/disable fps limitation this way\r
+{\r
+ bInitCap = TRUE;\r
+\r
+ if(option==1)                                         // emu says: limit\r
+  {\r
+   bUseFrameLimit=TRUE;bUseFrameSkip=FALSE;iFrameLimit=2;\r
+   SetAutoFrameCap();\r
+  }\r
+ else                                                  // emu says: no limit\r
+  {\r
+   bUseFrameLimit=FALSE;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
diff --git a/plugins/gpu-gles/gpuFps.h b/plugins/gpu-gles/gpuFps.h
new file mode 100644 (file)
index 0000000..a44a05f
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef __GPU_FPS__\r
+#define __GPU_FPS__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/***************************************************************************\r
+                          fps.h  -  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
+extern BOOL           bIsPerformanceCounter;\r
+extern float          fFrameRateHz;\r
+extern DWORD          dwFrameRateTicks;\r
+extern float          fFrameRate;\r
+extern int            iFrameLimit;\r
+extern BOOL           bUseFrameLimit;\r
+extern BOOL           bUseFrameSkip;\r
+extern DWORD          dwLaceCnt;\r
+\r
+extern BOOL         bInitCap; \r
+extern float        fps_skip;\r
+extern float        fps_cur;\r
+\r
+\r
+void InitFrameCap(void);\r
+void SetFrameRateConfig(void);\r
+void PCFrameCap(void);\r
+void PCcalcfps(void);\r
+void FrameSkip(void);\r
+void CheckFrameRate(void);\r
+void ReInitFrameCap(void);\r
+void SetAutoFrameCap(void);\r
+#ifndef _WINDOWS\r
+unsigned long timeGetTime();\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif\r
diff --git a/plugins/gpu-gles/gpuPlugin.c b/plugins/gpu-gles/gpuPlugin.c
new file mode 100644 (file)
index 0000000..07f158c
--- /dev/null
@@ -0,0 +1,2960 @@
+/***************************************************************************\r
+                           gpu.c  -  description\r
+                             -------------------\r
+    begin                : Sun Mar 08 2009\r
+    copyright            : (C) 1999-2009 by Pete Bernert\r
+    email                : BlackDove@addcom.de\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
+//#include "gpuStdafx.h"\r
+\r
+//#include <mmsystem.h>\r
+\r
+#define _IN_GPU\r
+\r
+#ifdef _WINDOWS\r
+#include "stdafx.h"\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <mmsystem.h>\r
+\r
+#include "externals.h"\r
+#include "gpu.h"\r
+#include "draw.h"\r
+#include "prim.h"\r
+#include "texture.h"\r
+#include "fps.h"\r
+#include "resource.h"\r
+#else\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include "gpuExternals.h"\r
+#include "gpuPlugin.h"\r
+#include "gpuDraw.h"\r
+#include "gpuTexture.h"\r
+#include "gpuFps.h"\r
+#include "gpuPrim.h"\r
+\r
+//#include "NoPic.h"\r
+\r
+#include "gpuStdafx.h"\r
+#endif\r
+\r
+extern void ProcessEvents();\r
+               \r
+short g_m1=255,g_m2=255,g_m3=255;\r
+short DrawSemiTrans=FALSE;\r
+short Ymin;\r
+short Ymax;\r
+\r
+short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;        // global psx vertex coords\r
+long           GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;\r
+long           GlobalTextREST,GlobalTextABR,GlobalTextPAGE;\r
+\r
+unsigned long dwGPUVersion=0;\r
+int           iGPUHeight=512;\r
+int           iGPUHeightMask=511;\r
+int           GlobalTextIL=0;\r
+int           iTileCheat=0;\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// memory image of the PSX vram\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8  *psxVSecure;\r
+u8  *psxVub;\r
+signed   char  *psxVsb;\r
+unsigned short *psxVuw;\r
+unsigned short *psxVuw_eom;\r
+signed   short *psxVsw;\r
+unsigned long  *psxVul;\r
+signed   long  *psxVsl;\r
+\r
+// macro for easy access to packet information\r
+#define GPUCOMMAND(x) ((x>>24) & 0xff)\r
+\r
+GLfloat         gl_z=0.0f;\r
+BOOL            bNeedInterlaceUpdate=FALSE;\r
+BOOL            bNeedRGB24Update=FALSE;\r
+BOOL            bChangeWinMode=FALSE;\r
+\r
+#ifdef _WINDOWS\r
+extern HGLRC    GLCONTEXT;\r
+#endif\r
+\r
+unsigned long   ulStatusControl[256];\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// global GPU vars\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+static long     GPUdataRet;\r
+long            lGPUstatusRet;\r
+s8            szDispBuf[64];\r
+\r
+static unsigned long gpuDataM[256];\r
+static u8 gpuCommand = 0;\r
+static long          gpuDataC = 0;\r
+static long          gpuDataP = 0;\r
+\r
+VRAMLoad_t      VRAMWrite;\r
+VRAMLoad_t      VRAMRead;\r
+int             iDataWriteMode;\r
+int             iDataReadMode;\r
+\r
+long            lClearOnSwap;\r
+long            lClearOnSwapColor;\r
+BOOL            bSkipNextFrame = FALSE;\r
+int             iColDepth;\r
+BOOL            bChangeRes;\r
+BOOL            bWindowMode;\r
+int             iWinSize;\r
+\r
+// possible psx display widths\r
+short dispWidths[8] = {256,320,512,640,368,384,512,640};\r
+\r
+PSXDisplay_t    PSXDisplay;\r
+PSXDisplay_t    PreviousPSXDisplay;\r
+TWin_t          TWin;\r
+short           imageX0,imageX1;\r
+short           imageY0,imageY1;\r
+BOOL            bDisplayNotSet = TRUE;\r
+GLuint          uiScanLine=0;\r
+int             iUseScanLines=0;\r
+long            lSelectedSlot=0;\r
+u8 * pGfxCardScreen=0;\r
+int             iBlurBuffer=0;\r
+int             iScanBlend=0;\r
+int             iRenderFVR=0;\r
+int             iNoScreenSaver=0;\r
+unsigned long   ulGPUInfoVals[16];\r
+int             iFakePrimBusy = 0;\r
+int             iRumbleVal    = 0;\r
+int             iRumbleTime   = 0;\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// stuff to make this a true PDK module\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+s8 * CALLBACK PSEgetLibName(void)\r
+{\r
+ return "name";\r
+}\r
+\r
+unsigned long CALLBACK PSEgetLibType(void)\r
+{\r
+ return  1;\r
+}\r
+\r
+unsigned long CALLBACK PSEgetLibVersion(void)\r
+{\r
+ return 1<<16|1<<8|1;\r
+}\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// snapshot funcs (saves screen to bitmap / text infos into file)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ResizeWindow()\r
+{\r
+ rRatioRect.left   = rRatioRect.top=0;\r
+ rRatioRect.right  = iResX;\r
+ rRatioRect.bottom = iResY;\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
+ if (bKeepRatio)\r
+ SetAspectRatio();\r
+}\r
+\r
+s8 * GetConfigInfos(int hW)\r
+{\r
+#ifdef _WINDOWS\r
+ HDC hdc;HGLRC hglrc;\r
+#endif\r
+ s8 szO[2][4]={"off","on "};\r
+ s8 szTxt[256];\r
+ s8 * pB=(s8 *)malloc(32767);\r
+/*\r
+ if(!pB) return NULL;\r
+ *pB=0;\r
+ //----------------------------------------------------//\r
+ strcat(pB,szTxt);\r
+ strcat(pB,szTxt);\r
+#ifdef _WINDOWS\r
+ if(hW)\r
+  {\r
+   hdc = GetDC(hW);\r
+   bSetupPixelFormat(hdc);\r
+   hglrc = wglCreateContext(hdc);\r
+   wglMakeCurrent(hdc, hglrc);\r
+  }\r
+#endif\r
+ sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));\r
+ strcat(pB,szTxt);\r
+ //strcat(pB,(s8 *)glGetString(GL_EXTENSIONS));\r
+ //strcat(pB,"\r\n\r\n");\r
+\r
+#ifdef _WINDOWS\r
+ if(hW)\r
+  {\r
+   wglMakeCurrent(NULL, NULL);\r
+   wglDeleteContext(hglrc);\r
+   ReleaseDC(hW,hdc);\r
+  }\r
+ //----------------------------------------------------//\r
+#endif\r
+ if(hW && bWindowMode)\r
+  sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));\r
+ else\r
+  sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);\r
+ strcat(pB,szTxt);\r
+ if(bWindowMode) sprintf(szTxt,"Window mode\r\n");\r
+ else\r
+  {\r
+   sprintf(szTxt,"Fullscreen ");\r
+   strcat(pB,szTxt);\r
+   if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);\r
+   else           sprintf(szTxt,"- NO desktop changing\r\n");\r
+  }                                                                                   \r
+ strcat(pB,szTxt);\r
+\r
+// if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);\r
+// else               strcpy(szTxt,"- V-Sync: Driver\r\n");\r
+ strcat(pB,szTxt); \r
+ sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);\r
+ strcat(pB,szTxt);\r
+ //----------------------------------------------------//\r
+ strcpy(szTxt,"Textures:\r\n- ");\r
+/*! if(iTexQuality==0)      strcat(szTxt,"Default");\r
+ else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");\r
+ else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");\r
+ else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");\r
+ else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");\r
+ if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");\r
+ else              strcat(szTxt,"\r\n");\r
+ strcat(pB,szTxt);\r
+ if(!hW)\r
+  {\r
+   sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);\r
+   if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");\r
+   else                             strcat(szTxt,"NOT supported\r\n");\r
+  }\r
+ else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);\r
+ strcat(pB,szTxt); \r
+ if(!hW)\r
+  {\r
+   sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);\r
+   strcat(pB,szTxt); \r
+  }\r
+ !*/\r
+ /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);\r
+ if(!hW)\r
+      sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);\r
+ else strcat(szTxt,"\r\n\r\n");\r
+ strcat(pB,szTxt);\r
+ //----------------------------------------------------//\r
+ sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);\r
+ strcat(pB,szTxt);\r
+ if(iFrameLimit==2)\r
+      strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");\r
+ else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);\r
+ strcat(pB,szTxt);\r
+ //----------------------------------------------------//\r
+ sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);\r
+ if(!hW && iFrameTexType==2)\r
+  {\r
+   if(gTexFrameName) strcat(szTxt," - texture created\r\n");\r
+   else              strcat(szTxt," - not used yet\r\n");\r
+  }\r
+ else strcat(szTxt,"\r\n");\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);\r
+ strcat(pB,szTxt);\r
+// sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);\r
+ strcat(pB,szTxt);\r
+ //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);\r
+ //if(!hW && bAdvancedBlend)\r
+//  {\r
+//   if(bGLBlend) strcat(szTxt," (hardware)\r\n");\r
+//   else         strcat(szTxt," (software)\r\n");\r
+//  }\r
+ strcat(szTxt,"\r\n");\r
+ strcat(pB,szTxt);\r
+\r
+ if(!hW)\r
+  {\r
+   strcpy(szTxt,"- Subtractive blending: ");\r
+//   if(glBlendEquationEXTEx)\r
+//    {\r
+//     if(bUseMultiPass) strcat(szTxt,"supported, but not used!");\r
+//     else              strcat(szTxt,"activated");\r
+//    }\r
+   strcat(szTxt," NOT supported!");\r
+   strcat(szTxt,"\r\n\r\n");\r
+  }\r
+ else strcpy(szTxt,"\r\n");\r
\r
+ strcat(pB,szTxt);             \r
+ //----------------------------------------------------//\r
+ sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);\r
+ strcat(pB,szTxt);\r
+ if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);\r
+ else strcpy(szTxt,"\r\n");\r
+ strcat(pB,szTxt);\r
+// sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);\r
+ strcat(pB,szTxt);\r
+// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);\r
+// fwrite(szTxt,lstrlen(szTxt),1,txtfile);\r
+ sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);\r
+ strcat(pB,szTxt);\r
+ sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);\r
+ strcat(pB,szTxt);\r
+ if(!hW && iBlurBuffer) \r
+  {\r
+   if(gTexBlurName) strcat(pB," - supported\r\n");\r
+   else             strcat(pB," - not supported\r\n");\r
+  }\r
+ else strcat(pB,"\r\n");\r
+ sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);\r
+ strcat(pB,szTxt);\r
+ //----------------------------------------------------//\r
+*/ return pB;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// save text infos to file\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DoTextSnapShot(int iNum)\r
+{\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// saves screen bitmap to file\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DoSnapShot(void)\r
+{\r
+}       \r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUmakeSnapshot(void)\r
+#else\r
+void CALLBACK GPU_makeSnapshot(void)\r
+#endif\r
+{\r
+ //bSnapShot = TRUE;\r
+}        \r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// GPU INIT... here starts it all (first func called by emu)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUinit()\r
+#else\r
+long CALLBACK GPU_init()\r
+#endif\r
+{\r
+memset(ulStatusControl,0,256*sizeof(unsigned long));\r
+\r
+#ifdef _WINDOWS\r
+iResX=240;iResY=320;\r
+#endif\r
+bChangeRes=FALSE;\r
+#ifdef _WINDOWS\r
+bWindowMode=TRUE;\r
+#else\r
+bWindowMode=FALSE;\r
+#endif \r
+#ifdef _WINDOWS\r
+iWinSize=MAKELONG(iResX,iResY);\r
+#endif\r
+\r
+bKeepRatio = TRUE;\r
+// different ways of accessing PSX VRAM\r
+\r
+psxVSecure=(u8 *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security\r
+if(!psxVSecure) return -1;\r
+\r
+psxVub=psxVSecure+512*1024;                           // security offset into double sized psx vram!\r
+psxVsb=(signed char *)psxVub;\r
+psxVsw=(signed short *)psxVub;\r
+psxVsl=(signed long *)psxVub;\r
+psxVuw=(unsigned short *)psxVub;\r
+psxVul=(unsigned long *)psxVub;\r
+\r
+psxVuw_eom=psxVuw+1024*iGPUHeight;                    // pre-calc of end of vram\r
+\r
+memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));\r
+memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
+\r
+InitFrameCap();                                       // init frame rate stuff\r
+\r
+PSXDisplay.RGB24        = 0;                          // init vars\r
+PreviousPSXDisplay.RGB24= 0;\r
+PSXDisplay.Interlaced   = 0;\r
+PSXDisplay.InterlacedTest=0;\r
+PSXDisplay.DrawOffset.x = 0;\r
+PSXDisplay.DrawOffset.y = 0;\r
+PSXDisplay.DrawArea.x0  = 0;\r
+PSXDisplay.DrawArea.y0  = 0;\r
+PSXDisplay.DrawArea.x1  = 320;\r
+PSXDisplay.DrawArea.y1  = 240;\r
+PSXDisplay.DisplayMode.x= 320;\r
+PSXDisplay.DisplayMode.y= 240;\r
+PSXDisplay.Disabled     = FALSE;\r
+PreviousPSXDisplay.Range.x0 =0;\r
+PreviousPSXDisplay.Range.x1 =0;\r
+PreviousPSXDisplay.Range.y0 =0;\r
+PreviousPSXDisplay.Range.y1 =0;\r
+PSXDisplay.Range.x0=0;\r
+PSXDisplay.Range.x1=0;\r
+PSXDisplay.Range.y0=0;\r
+PSXDisplay.Range.y1=0;\r
+PreviousPSXDisplay.DisplayPosition.x = 1;\r
+PreviousPSXDisplay.DisplayPosition.y = 1;\r
+PSXDisplay.DisplayPosition.x = 1;\r
+PSXDisplay.DisplayPosition.y = 1;\r
+PreviousPSXDisplay.DisplayModeNew.y=0;\r
+PSXDisplay.Double=1;\r
+GPUdataRet=0x400;\r
+\r
+PSXDisplay.DisplayModeNew.x=0;\r
+PSXDisplay.DisplayModeNew.y=0;\r
+\r
+//PreviousPSXDisplay.Height = PSXDisplay.Height = 239;\r
+\r
+iDataWriteMode = DR_NORMAL;\r
+\r
+// Reset transfer values, to prevent mis-transfer of data\r
+memset(&VRAMWrite,0,sizeof(VRAMLoad_t));\r
+memset(&VRAMRead,0,sizeof(VRAMLoad_t));\r
+\r
+// device initialised already !\r
+//lGPUstatusRet = 0x74000000;\r
+\r
+STATUSREG = 0x14802000;\r
+GPUIsIdle;\r
+GPUIsReadyForCommands;\r
+\r
+return 0;\r
+}                             \r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// GPU OPEN: funcs to open up the gpu display (Windows)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+\r
+void ChangeDesktop()                                   // change destop resolution\r
+{\r
+ DEVMODE dv;long lRes,iTry=0;                       \r
+\r
+ while(iTry<10)                                        // keep on hammering...\r
+  {\r
+   memset(&dv,0,sizeof(DEVMODE));\r
+   dv.dmSize=sizeof(DEVMODE);\r
+   dv.dmBitsPerPel=iColDepth;\r
+   dv.dmPelsWidth=iResX;\r
+   dv.dmPelsHeight=iResY;\r
+\r
+   dv.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;\r
+\r
+   lRes=ChangeDisplaySettings(&dv,0);                  // ...hammering the anvil\r
+\r
+   if(lRes==DISP_CHANGE_SUCCESSFUL) return;\r
+   iTry++;Sleep(10);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// OPEN interface func: attention! \r
+// some emus are calling this func in their main Window thread,\r
+// but all other interface funcs (to draw stuff) in a different thread!\r
+// that's a problem, since OGL is thread safe! Therefore we cannot \r
+// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"\r
+// flag, to initialize OGL on the first real draw call.\r
+// btw, we also call this open func ourselfes, each time when the user \r
+// is changing between fullscreen/window mode (ENTER key)\r
+// btw part 2: in windows the plugin gets the window handle from the\r
+// main emu, and doesn't create it's own window (if it would do it,\r
+// some PAD or SPU plugins would not work anymore)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+HMENU hPSEMenu=NULL;\r
+\r
+long CALLBACK GPUopen(HWND hwndGPU)                    \r
+#else\r
+long CALLBACK GPU_open(int hwndGPU)                    \r
+#endif\r
+{\r
+       #ifdef _WINDOWS\r
+       HDC hdc;RECT r;DEVMODE dv;\r
+\r
+        hWWindow = hwndGPU;                                   // store hwnd globally\r
+       #endif\r
+       // InitKeyHandler();                                     // init key handler (subclass window)\r
+\r
+\r
+\r
+                \r
+                \r
+       #ifdef _WINDOWS\r
+        iResX=240;iResY=320;\r
+       #endif\r
+        iColDepth=32;\r
+        bChangeRes=FALSE;\r
+       #ifdef _WINDOWS\r
+        bWindowMode=TRUE;\r
+       #else\r
+        bWindowMode=FALSE;\r
+       #endif \r
+        bFullVRam=FALSE;\r
+        iFilterType=0;\r
+       // bAdvancedBlend=FALSE;\r
+        bDrawDither=FALSE;\r
+       // bUseLines=FALSE;\r
+        bUseFrameLimit=FALSE;\r
+        bUseFrameSkip=FALSE;\r
+        iFrameLimit=0;\r
+        fFrameRate=50.0f;\r
+        iOffscreenDrawing=0;\r
+        //bOpaquePass=FALSE;\r
+        //bUseAntiAlias=FALSE;\r
+        //iTexQuality=0;\r
+       #ifdef _WINDOWS\r
+        iWinSize=MAKELONG(iResX,iResY);\r
+       #endif\r
+        iUseMask=0;\r
+        iZBufferDepth=0;\r
+        bUseFastMdec=FALSE;\r
+        bUse15bitMdec=FALSE;\r
+        dwCfgFixes=0;\r
+        bUseFixes=FALSE;\r
+       // iUseScanLines=0;\r
+        iFrameTexType=0;\r
+        iFrameReadType=0;\r
+        //iShowFPS=0;\r
+        bKeepRatio=TRUE;\r
+        iScanBlend=0;\r
+        iVRamSize=0;\r
+        iTexGarbageCollection=0;\r
+        iBlurBuffer=0; \r
+        //iHiResTextures=0;\r
+        iNoScreenSaver=0;\r
+ //iForceVSync=0;\r
+\r
+\r
+\r
+#ifdef _WINDOWS\r
+ memset(&dv,0,sizeof(DEVMODE));\r
+ dv.dmSize=sizeof(DEVMODE);\r
+ EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dv);\r
+#endif\r
+ bIsFirstFrame = TRUE;                                 // flag: we have to init OGL later in windows!\r
+\r
+#ifdef _WINDOWS\r
+ if(bWindowMode)                                       // win mode?\r
+  {\r
+   DWORD dw=GetWindowLong(hWWindow, GWL_STYLE);        // -> adjust wnd style (owndc needed by some stupid ogl drivers)\r
+   dw&=~WS_THICKFRAME;\r
+   dw|=WS_BORDER|WS_CAPTION|CS_OWNDC;\r
+   SetWindowLong(hWWindow, GWL_STYLE, dw);\r
+\r
+   hPSEMenu=GetMenu(hWWindow);                         // -> hide emu menu (if any)\r
+   if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);\r
+\r
+   iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize);\r
+   ShowWindow(hWWindow,SW_SHOWNORMAL);\r
+\r
+   MoveWindow(hWWindow,                                // -> center wnd\r
+      GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2,\r
+      GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2,\r
+      iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3,\r
+      iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3,\r
+      TRUE);\r
+   UpdateWindow(hWWindow);                             // -> let windows do some update\r
+\r
+   if(dv.dmBitsPerPel==16 || dv.dmBitsPerPel==32)      // -> overwrite user color info with desktop color info\r
+    iColDepth=dv.dmBitsPerPel;\r
+  }\r
+ else                                                  // fullscreen mode:\r
+  {\r
+   if(dv.dmBitsPerPel!=(unsigned int)iColDepth ||      // -> check, if we have to change resolution\r
+      dv.dmPelsWidth !=(unsigned int)iResX ||\r
+      dv.dmPelsHeight!=(unsigned int)iResY)\r
+    bChangeRes=TRUE; else bChangeRes=FALSE;\r
+\r
+   if(bChangeRes) ChangeDesktop();                     // -> change the res (had to do an own func because of some MS 'optimizations')\r
+\r
+   SetWindowLong(hWWindow, GWL_STYLE, CS_OWNDC);       // -> adjust wnd style as well (to be sure)\r
+                \r
+   hPSEMenu=GetMenu(hWWindow);                         // -> hide menu\r
+   if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);\r
+   ShowWindow(hWWindow,SW_SHOWMAXIMIZED);              // -> max mode\r
+  }\r
+#endif\r
+ rRatioRect.left   = rRatioRect.top=0;\r
+ rRatioRect.right  = iResX;\r
+ rRatioRect.bottom = iResY;\r
+\r
+#ifdef _WINDOWS\r
+ r.left=r.top=0;r.right=iResX;r.bottom=iResY;          // hack for getting a clean black window until OGL gets initialized\r
+ hdc = GetDC(hWWindow);\r
+ FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));\r
+ bSetupPixelFormat(hdc);\r
+ ReleaseDC(hWWindow,hdc);\r
+#endif\r
+ bDisplayNotSet = TRUE; \r
+ bSetClip=TRUE;\r
+\r
+ SetFixes();                                           // setup game fixes\r
+\r
+ InitializeTextureStore();                             // init texture mem\r
+\r
+// lGPUstatusRet = 0x74000000;\r
+\r
+// with some emus, we could do the OGL init right here... oh my\r
+// if(bIsFirstFrame) GLinitialize();\r
+\r
+ return 0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// close\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUclose()                               // WINDOWS CLOSE\r
+{\r
+// ExitKeyHandler();\r
+\r
+ GLcleanup();                                          // close OGL\r
+\r
+ if(bChangeRes)                                        // change res back\r
+  ChangeDisplaySettings(NULL,0);\r
+\r
+ if(hPSEMenu)                                          // set menu again\r
+  SetMenu(hWWindow,hPSEMenu);\r
+\r
+ if(pGfxCardScreen) free(pGfxCardScreen);              // free helper memory\r
+ pGfxCardScreen=0;\r
+\r
+// if(iNoScreenSaver) EnableScreenSaver(TRUE);           // enable screen saver again\r
+\r
+ return 0;\r
+}\r
+\r
+#else\r
+\r
+long GPU_close()                                        // LINUX CLOSE\r
+{\r
+ GLcleanup();                                          // close OGL\r
+\r
+ if(pGfxCardScreen) free(pGfxCardScreen);              // free helper memory\r
+ pGfxCardScreen=0;\r
+\r
+// osd_close_display();                                  // destroy display\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// I shot the sheriff... last function called from emu \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUshutdown()\r
+#else\r
+long CALLBACK GPU_shutdown()\r
+#endif\r
+{\r
+ if(psxVSecure) free(psxVSecure);                      // kill emulated vram memory\r
+ psxVSecure=0;\r
+\r
+ return 0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// paint it black: simple func to clean up optical border garbage\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PaintBlackBorders(void)\r
+{\r
+ short s;\r
+\r
+ glDisable(GL_SCISSOR_TEST);\r
+ if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;}\r
+ if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}\r
+ if(bBlendEnable)     {glDisable(GL_BLEND);bBlendEnable=FALSE;}\r
+ glDisable(GL_ALPHA_TEST);\r
+\r
+ glEnable(GL_ALPHA_TEST);\r
+ glEnable(GL_SCISSOR_TEST);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// helper to draw scanlines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+__inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                    OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// scanlines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetScanLines(void)\r
+{\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// blur, babe, blur (heavy performance hit for a so-so fullscreen effect)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Update display (swap buffers)... called in interlaced mode on \r
+// every emulated vsync, otherwise whenever the displayed screen region\r
+// has been changed\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+int iLastRGB24=0;                                      // special vars for checking when to skip two display updates\r
+int iSkipTwo=0;\r
+void GPU_vSinc(void){\r
+updateDisplay();\r
+}\r
+void updateDisplay(void)                               // UPDATE DISPLAY\r
+{\r
+BOOL bBlur=FALSE;\r
+\r
+#ifdef _WINDOWS\r
+HDC hdc=GetDC(hWWindow);                              // windows:\r
+wglMakeCurrent(hdc,GLCONTEXT);                        // -> make context current again\r
+#endif\r
+\r
+bFakeFrontBuffer=FALSE;\r
+bRenderFrontBuffer=FALSE;\r
+\r
+if(iRenderFVR)                                        // frame buffer read fix mode still active?\r
+ {\r
+  iRenderFVR--;                                       // -> if some frames in a row without read access: turn off mode\r
+  if(!iRenderFVR) bFullVRam=FALSE;\r
+ }\r
+\r
+if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1)      // (mdec) garbage check\r
+ {\r
+  iSkipTwo=2;                                         // -> skip two frames to avoid garbage if color mode changes\r
+ }\r
+iLastRGB24=0;\r
+\r
+if(PSXDisplay.RGB24)// && !bNeedUploadAfter)          // (mdec) upload wanted?\r
+ {\r
+  PrepareFullScreenUpload(-1);\r
+  UploadScreen(PSXDisplay.Interlaced);                // -> upload whole screen from psx vram\r
+  bNeedUploadTest=FALSE;\r
+  bNeedInterlaceUpdate=FALSE;\r
+  bNeedUploadAfter=FALSE;\r
+  bNeedRGB24Update=FALSE;\r
+ }\r
+else\r
+if(bNeedInterlaceUpdate)                              // smaller upload?\r
+ {\r
+  bNeedInterlaceUpdate=FALSE;\r
+  xrUploadArea=xrUploadAreaIL;                        // -> upload this rect\r
+  UploadScreen(TRUE);\r
+ }\r
+\r
+if(dwActFixes&512) bCheckFF9G4(NULL);                 // special game fix for FF9 \r
+\r
+if(PreviousPSXDisplay.Range.x0||                      // paint black borders around display area, if needed\r
+   PreviousPSXDisplay.Range.y0)\r
+ PaintBlackBorders();\r
+\r
+if(PSXDisplay.Disabled)                               // display disabled?\r
+ {\r
+  // moved here\r
+  glDisable(GL_SCISSOR_TEST);                       \r
+  glClearColor(0,0,0,128);                            // -> clear whole backbuffer\r
+  glClear(uiBufferBits);\r
+  glEnable(GL_SCISSOR_TEST);                       \r
+  gl_z=0.0f;\r
+  bDisplayNotSet = TRUE;\r
+ }\r
+\r
+if(iSkipTwo)                                          // we are in skipping mood?\r
+ {\r
+  iSkipTwo--;\r
+  iDrawnSomething=0;                                  // -> simply lie about something drawn\r
+ }\r
+\r
+//if(iBlurBuffer && !bSkipNextFrame)                    // "blur display" activated?\r
+// {BlurBackBuffer();bBlur=TRUE;}                       // -> blur it\r
+\r
+// if(iUseScanLines) SetScanLines();                     // "scan lines" activated? do it\r
+\r
+// if(usCursorActive) ShowGunCursor();                   // "gun cursor" wanted? show 'em\r
+\r
+if(dwActFixes&128)                                    // special FPS limitation mode?\r
+ {\r
+  if(bUseFrameLimit) PCFrameCap();                    // -> ok, do it\r
+//   if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS)  \r
+   PCcalcfps();         \r
+ }\r
+\r
+// if(gTexPicName) DisplayPic();                         // some gpu info picture active? display it\r
+\r
+// if(bSnapShot) DoSnapShot();                           // snapshot key pressed? cheeeese :)\r
+\r
+// if(ulKeybits&KEY_SHOWFPS)                             // wanna see FPS?\r
+ {\r
+//   sprintf(szDispBuf,"%06.1f",fps_cur);\r
+//   DisplayText();                                      // -> show it\r
+ }\r
+\r
+//----------------------------------------------------//\r
+// main buffer swapping (well, or skip it)\r
+\r
+if(bUseFrameSkip)                                     // frame skipping active ?\r
+ {\r
+  if(!bSkipNextFrame) \r
+   {\r
+    if(iDrawnSomething)\r
+#ifdef _WINDOWS\r
+     SwapBuffers(wglGetCurrentDC());                  // -> to skip or not to skip\r
+#else\r
+     eglSwapBuffers(display,surface);\r
+#endif\r
+   }\r
+  if(dwActFixes&0x180)                                // -> special old frame skipping: skip max one in a row\r
+   {\r
+    if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) \r
+     {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}\r
+    else bSkipNextFrame = FALSE;\r
+   }\r
+  else FrameSkip();\r
+ }\r
+else                                                  // no skip ?\r
+ {\r
+  if(iDrawnSomething)\r
+#ifdef _WINDOWS\r
+   SwapBuffers(wglGetCurrentDC());                    // -> swap\r
+#else\r
+  eglSwapBuffers(display,surface);\r
+#endif\r
+ }\r
+\r
+iDrawnSomething=0;\r
+\r
+//----------------------------------------------------//\r
+\r
+if(lClearOnSwap)                                      // clear buffer after swap?\r
+ {\r
+  GLclampf g,b,r;\r
+\r
+  if(bDisplayNotSet)                                  // -> set new vals\r
+   SetOGLDisplaySettings(1);\r
+\r
+  g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f;      // -> get col\r
+  b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;\r
+  r=((GLclampf)RED(lClearOnSwapColor))/255.0f;\r
+  \r
+  glDisable(GL_SCISSOR_TEST);                       \r
+  glClearColor(r,g,b,128);                            // -> clear \r
+  glClear(uiBufferBits);\r
+  glEnable(GL_SCISSOR_TEST);                       \r
+  lClearOnSwap=0;                                     // -> done\r
+ }\r
+else \r
+ {\r
+//  if(bBlur) UnBlurBackBuffer();                       // unblur buff, if blurred before\r
+\r
+  if(iZBufferDepth)                                   // clear zbuffer as well (if activated)\r
+   {\r
+    glDisable(GL_SCISSOR_TEST);                       \r
+    glClear(GL_DEPTH_BUFFER_BIT);\r
+    glEnable(GL_SCISSOR_TEST);                       \r
+   }\r
+ }\r
+gl_z=0.0f;\r
+\r
+//----------------------------------------------------//\r
+// additional uploads immediatly after swapping\r
+\r
+if(bNeedUploadAfter)                                  // upload wanted?\r
+ {\r
+  bNeedUploadAfter=FALSE;                           \r
+  bNeedUploadTest=FALSE;\r
+  UploadScreen(-1);                                   // -> upload\r
+ }\r
+\r
+if(bNeedUploadTest)\r
+ {\r
+  bNeedUploadTest=FALSE;\r
+  if(PSXDisplay.InterlacedTest &&\r
+     //iOffscreenDrawing>2 &&\r
+     PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
+     PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
+     PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
+     PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
+   {\r
+    PrepareFullScreenUpload(TRUE);\r
+    UploadScreen(TRUE);\r
+   }\r
+ }\r
+\r
+//----------------------------------------------------//\r
+// rumbling (main emu pad effect)\r
+\r
+if(iRumbleTime)                                       // shake screen by modifying view port\r
+ {\r
+  int i1=0,i2=0,i3=0,i4=0;\r
+\r
+  iRumbleTime--;\r
+  if(iRumbleTime) \r
+   {\r
+    i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
+    i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
+    i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
+    i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
+   }\r
+\r
+  glViewport(rRatioRect.left+i1,                      \r
+             iResY-(rRatioRect.top+rRatioRect.bottom)+i2,\r
+             rRatioRect.right+i3, \r
+             rRatioRect.bottom+i4);            \r
+ }\r
+\r
+//----------------------------------------------------//\r
+\r
+\r
+\r
+// if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff();         // reset on gpu mode changes? do it before next frame is filled\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// update front display: smaller update func, if something has changed \r
+// in the frontbuffer... dirty, but hey... real men know no pain\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void updateFrontDisplay(void)\r
+{\r
+if(PreviousPSXDisplay.Range.x0||\r
+   PreviousPSXDisplay.Range.y0)\r
+ PaintBlackBorders();\r
+\r
+//if(iBlurBuffer) BlurBackBuffer();\r
+\r
+//if(iUseScanLines) SetScanLines();\r
+\r
+// if(usCursorActive) ShowGunCursor();\r
+\r
+bFakeFrontBuffer=FALSE;\r
+bRenderFrontBuffer=FALSE;\r
+\r
+// if(gTexPicName) DisplayPic();\r
+// if(ulKeybits&KEY_SHOWFPS) DisplayText();\r
+\r
+#ifdef _WINDOWS\r
+ {                                                    // windows: \r
+  HDC hdc=GetDC(hWWindow);\r
+  wglMakeCurrent(hdc,GLCONTEXT);                      // -> make current again\r
+  if(iDrawnSomething)\r
+   SwapBuffers(wglGetCurrentDC());                    // -> swap\r
+  ReleaseDC(hWWindow,hdc);                            // -> ! important !\r
+ }\r
+#else\r
+if(iDrawnSomething)                                   // linux:\r
+ eglSwapBuffers(display,surface);\r
+#endif\r
+\r
+//if(iBlurBuffer) UnBlurBackBuffer();\r
+}\r
+                                             \r
+////////////////////////////////////////////////////////////////////////\r
+// check if update needed\r
+////////////////////////////////////////////////////////////////////////\r
+void ChangeDispOffsetsX(void)                          // CENTER X\r
+{\r
+long lx,l;short sO;\r
+\r
+if(!PSXDisplay.Range.x1) return;                      // some range given?\r
+\r
+l=PSXDisplay.DisplayMode.x;\r
+\r
+l*=(long)PSXDisplay.Range.x1;                         // some funky calculation\r
+l/=2560;lx=l;l&=0xfffffff8;\r
+\r
+if(l==PreviousPSXDisplay.Range.x1) return;            // some change?\r
+\r
+sO=PreviousPSXDisplay.Range.x0;                       // store old\r
+\r
+if(lx>=PSXDisplay.DisplayMode.x)                      // range bigger?\r
+ {\r
+  PreviousPSXDisplay.Range.x1=                        // -> take display width\r
+   PSXDisplay.DisplayMode.x;\r
+  PreviousPSXDisplay.Range.x0=0;                      // -> start pos is 0\r
+ }\r
+else                                                  // range smaller? center it\r
+ {\r
+  PreviousPSXDisplay.Range.x1=l;                      // -> store width (8 pixel aligned)\r
+   PreviousPSXDisplay.Range.x0=                       // -> calc start pos\r
+   (PSXDisplay.Range.x0-500)/8;\r
+  if(PreviousPSXDisplay.Range.x0<0)                   // -> we don't support neg. values yet\r
+   PreviousPSXDisplay.Range.x0=0;\r
+\r
+  if((PreviousPSXDisplay.Range.x0+lx)>                // -> uhuu... that's too much\r
+     PSXDisplay.DisplayMode.x)\r
+   {\r
+    PreviousPSXDisplay.Range.x0=                      // -> adjust start\r
+     PSXDisplay.DisplayMode.x-lx;\r
+    PreviousPSXDisplay.Range.x1+=lx-l;                // -> adjust width\r
+   }                   \r
+ }\r
+\r
+if(sO!=PreviousPSXDisplay.Range.x0)                   // something changed?\r
+ {\r
+  bDisplayNotSet=TRUE;                                // -> recalc display stuff\r
+ }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ChangeDispOffsetsY(void)                          // CENTER Y\r
+{\r
+int iT;short sO;                                      // store previous y size\r
+\r
+if(PSXDisplay.PAL) iT=48; else iT=28;                 // different offsets on PAL/NTSC\r
+\r
+if(PSXDisplay.Range.y0>=iT)                           // crossed the security line? :)\r
+ {\r
+  PreviousPSXDisplay.Range.y1=                        // -> store width\r
+   PSXDisplay.DisplayModeNew.y;\r
+  \r
+  sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double;    // -> calc offset\r
+  if(sO<0) sO=0;\r
+\r
+  PSXDisplay.DisplayModeNew.y+=sO;                    // -> add offset to y size, too\r
+ }\r
+else sO=0;                                            // else no offset\r
+\r
+if(sO!=PreviousPSXDisplay.Range.y0)                   // something changed?\r
+ {\r
+  PreviousPSXDisplay.Range.y0=sO;\r
+  bDisplayNotSet=TRUE;                                // -> recalc display stuff\r
+ }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Aspect ratio of ogl screen: simply adjusting ogl view port\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetAspectRatio(void)\r
+{\r
+float xs,ys,s;RECT r;\r
+\r
+if(!PSXDisplay.DisplayModeNew.x) return;\r
+if(!PSXDisplay.DisplayModeNew.y) return;\r
+\r
+xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;\r
+ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;\r
+\r
+s=min(xs,ys);\r
+r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);\r
+r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);\r
+if(r.right  > iResX) r.right  = iResX;\r
+if(r.bottom > iResY) r.bottom = iResY;\r
+if(r.right  < 1)     r.right  = 1;\r
+if(r.bottom < 1)     r.bottom = 1;\r
+\r
+r.left = (iResX-r.right)/2;\r
+r.top  = (iResY-r.bottom)/2;\r
+\r
+if(r.bottom<rRatioRect.bottom ||\r
+   r.right <rRatioRect.right)\r
+ {\r
+  RECT rC;\r
+  glClearColor(0,0,0,128);                         \r
+\r
+  if(r.right <rRatioRect.right)\r
+   {\r
+    rC.left=0;\r
+    rC.top=0;\r
+    rC.right=r.left;\r
+    rC.bottom=iResY;\r
+    glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
+    glClear(uiBufferBits);\r
+    rC.left=iResX-rC.right;\r
+    glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
+    glClear(uiBufferBits);\r
+   }\r
+\r
+  if(r.bottom <rRatioRect.bottom)\r
+   {\r
+    rC.left=0;\r
+    rC.top=0;\r
+    rC.right=iResX;\r
+    rC.bottom=r.top;\r
+    glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
+    glClear(uiBufferBits);\r
+    rC.top=iResY-rC.bottom;\r
+    glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
+    glClear(uiBufferBits);\r
+   }\r
+  \r
+  bSetClip=TRUE;\r
+  bDisplayNotSet=TRUE;\r
+ }\r
+\r
+rRatioRect=r;\r
+\r
+\r
+glViewport(rRatioRect.left,\r
+           iResY-(rRatioRect.top+rRatioRect.bottom),\r
+           rRatioRect.right,\r
+           rRatioRect.bottom);                         // init viewport\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// big ass check, if an ogl swap buffer is needed\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void updateDisplayIfChanged(void)\r
+{\r
+BOOL bUp;\r
+\r
+if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && \r
+    (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))\r
+ {\r
+  if((PSXDisplay.RGB24      == PSXDisplay.RGB24New) && \r
+     (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) \r
+     return;                                          // nothing has changed? fine, no swap buffer needed\r
+ }\r
+else                                                  // some res change?\r
+ {\r
+  glLoadIdentity();\r
+  glOrtho(0,PSXDisplay.DisplayModeNew.x,              // -> new psx resolution\r
+            PSXDisplay.DisplayModeNew.y, 0, -1, 1);\r
+  if(bKeepRatio) SetAspectRatio();\r
+ }\r
+\r
+bDisplayNotSet = TRUE;                                // re-calc offsets/display area\r
+\r
+bUp=FALSE;\r
+if(PSXDisplay.RGB24!=PSXDisplay.RGB24New)             // clean up textures, if rgb mode change (usually mdec on/off)\r
+ {\r
+  PreviousPSXDisplay.RGB24=0;                         // no full 24 frame uploaded yet\r
+  ResetTextureArea(FALSE);\r
+  bUp=TRUE;\r
+ }\r
+\r
+PSXDisplay.RGB24         = PSXDisplay.RGB24New;       // get new infos\r
+PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;\r
+PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;\r
+PSXDisplay.Interlaced    = PSXDisplay.InterlacedNew;\r
+   \r
+PSXDisplay.DisplayEnd.x=                              // calc new ends\r
+ PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
+PSXDisplay.DisplayEnd.y=\r
+ PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
+PreviousPSXDisplay.DisplayEnd.x=\r
+ PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
+PreviousPSXDisplay.DisplayEnd.y=\r
+ PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
+\r
+ChangeDispOffsetsX();\r
+\r
+if(iFrameLimit==2) SetAutoFrameCap();                 // set new fps limit vals (depends on interlace)\r
+\r
+if(bUp) updateDisplay();                              // yeah, real update (swap buffer)\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// window mode <-> fullscreen mode (windows)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void ChangeWindowMode(void)\r
+{\r
+ GPUclose();\r
+ bWindowMode=!bWindowMode;\r
+ GPUopen(hWWindow);\r
+ bChangeWinMode=FALSE;\r
+}\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// swap update check (called by psx vsync function)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL bSwapCheck(void)\r
+{\r
+static int iPosCheck=0;\r
+static PSXPoint_t pO;\r
+static PSXPoint_t pD;\r
+static int iDoAgain=0;\r
+\r
+if(PSXDisplay.DisplayPosition.x==pO.x &&\r
+   PSXDisplay.DisplayPosition.y==pO.y &&\r
+   PSXDisplay.DisplayEnd.x==pD.x &&\r
+   PSXDisplay.DisplayEnd.y==pD.y)\r
+     iPosCheck++;\r
+else iPosCheck=0;\r
+\r
+pO=PSXDisplay.DisplayPosition;\r
+pD=PSXDisplay.DisplayEnd;\r
+\r
+if(iPosCheck<=4) return FALSE;\r
+\r
+iPosCheck=4;\r
+\r
+if(PSXDisplay.Interlaced) return FALSE;\r
+\r
+if (bNeedInterlaceUpdate||\r
+    bNeedRGB24Update ||\r
+    bNeedUploadAfter|| \r
+    bNeedUploadTest || \r
+    iDoAgain\r
+   )\r
+ {\r
+  iDoAgain=0;\r
+  if(bNeedUploadAfter) \r
+   iDoAgain=1;\r
+  if(bNeedUploadTest && PSXDisplay.InterlacedTest)\r
+   iDoAgain=1;\r
+\r
+  bDisplayNotSet = TRUE;\r
+  updateDisplay();\r
+\r
+  PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;\r
+  PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;\r
+  PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;\r
+  PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;\r
+  pO=PSXDisplay.DisplayPosition;\r
+  pD=PSXDisplay.DisplayEnd;\r
+\r
+  return TRUE;\r
+ }\r
+\r
+return FALSE;\r
+} \r
+////////////////////////////////////////////////////////////////////////\r
+// gun cursor func: player=0-7, x=0-511, y=0-255\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// update lace is called every VSync. Basically we limit frame rate \r
+// here, and in interlaced mode we swap ogl display buffers.\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+static unsigned short usFirstPos=2;\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUupdateLace(void)\r
+#else\r
+void CALLBACK GPU_updateLace(void)\r
+#endif\r
+{\r
+if(!(dwActFixes&0x1000))                               \r
+ STATUSREG^=0x80000000;                               // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)\r
+\r
+if(!(dwActFixes&128))                                 // normal frame limit func\r
+ CheckFrameRate();\r
+\r
+if(iOffscreenDrawing==4)                              // special check if high offscreen drawing is on\r
+ {\r
+  if(bSwapCheck()) return;\r
+ }\r
+\r
+if(PSXDisplay.Interlaced)                             // interlaced mode?\r
+ {\r
+  if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)\r
+   {\r
+    updateDisplay();                                  // -> swap buffers (new frame)\r
+   }\r
+ }\r
+else if(bRenderFrontBuffer)                           // no interlace mode? and some stuff in front has changed?\r
+ {\r
+  updateFrontDisplay();                               // -> update front buffer\r
+ }\r
+else if(usFirstPos==1)                                // initial updates (after startup)\r
+ {\r
+  updateDisplay();\r
+ }\r
+\r
+#ifdef _WINDOWS\r
+if(bChangeWinMode) ChangeWindowMode();\r
+#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// process read request from GPU status register\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+unsigned long CALLBACK GPUreadStatus(void)\r
+#else\r
+unsigned long CALLBACK GPU_readStatus(void)\r
+#endif\r
+{\r
+if(dwActFixes&0x1000)                                 // CC game fix\r
+ {\r
+  static int iNumRead=0;\r
+  if((iNumRead++)==2)\r
+   {\r
+    iNumRead=0;\r
+    STATUSREG^=0x80000000;                            // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)\r
+   }\r
+ }\r
+\r
+if(iFakePrimBusy)                                     // 27.10.2007 - emulating some 'busy' while drawing... pfff... not perfect, but since our emulated dma is not done in an extra thread...\r
+ {\r
+  iFakePrimBusy--;\r
+\r
+  if(iFakePrimBusy&1)                                 // we do a busy-idle-busy-idle sequence after/while drawing prims\r
+   {\r
+    GPUIsBusy;\r
+    GPUIsNotReadyForCommands;\r
+   }\r
+  else\r
+   {\r
+    GPUIsIdle;\r
+    GPUIsReadyForCommands;\r
+   }\r
+ }\r
+\r
+return STATUSREG;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// processes data send to GPU status register\r
+// these are always single packet commands.\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUwriteStatus(unsigned long gdata)\r
+#else\r
+void CALLBACK GPU_writeStatus(unsigned long gdata)\r
+#endif\r
+{\r
+unsigned long lCommand=(gdata>>24)&0xff;\r
+\r
+#ifdef _WINDOWS\r
+if(bIsFirstFrame) GLinitialize();                     // real ogl startup (needed by some emus)\r
+#endif\r
+\r
+ulStatusControl[lCommand]=gdata;\r
+\r
+switch(lCommand)\r
+ {\r
+  //--------------------------------------------------//\r
+  // reset gpu\r
+  case 0x00:\r
+   memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
+   lGPUstatusRet=0x14802000;\r
+   PSXDisplay.Disabled=1;\r
+   iDataWriteMode=iDataReadMode=DR_NORMAL;\r
+   PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;\r
+   drawX=drawY=0;drawW=drawH=0;\r
+   sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;\r
+   usMirror=0;\r
+   GlobalTextAddrX=0;GlobalTextAddrY=0;\r
+   GlobalTextTP=0;GlobalTextABR=0;\r
+   PSXDisplay.RGB24=FALSE;\r
+   PSXDisplay.Interlaced=FALSE;\r
+   bUsingTWin = FALSE;\r
+   return;\r
+\r
+  // dis/enable display\r
+  case 0x03:  \r
+   PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;\r
+   PSXDisplay.Disabled = (gdata & 1);\r
+\r
+   if(PSXDisplay.Disabled) \r
+        STATUSREG|=GPUSTATUS_DISPLAYDISABLED;\r
+   else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;\r
+\r
+   if (iOffscreenDrawing==4 &&\r
+        PreviousPSXDisplay.Disabled && \r
+       !(PSXDisplay.Disabled))\r
+    {\r
+\r
+     if(!PSXDisplay.RGB24)\r
+      {\r
+       PrepareFullScreenUpload(TRUE);\r
+       UploadScreen(TRUE); \r
+       updateDisplay();\r
+      }\r
+    }\r
+\r
+   return;\r
+\r
+  // setting transfer mode\r
+  case 0x04:\r
+   gdata &= 0x03;                                     // only want the lower two bits\r
+\r
+   iDataWriteMode=iDataReadMode=DR_NORMAL;\r
+   if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;\r
+   if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;\r
+\r
+   STATUSREG&=~GPUSTATUS_DMABITS;                     // clear the current settings of the DMA bits\r
+   STATUSREG|=(gdata << 29);                          // set the DMA bits according to the received data\r
+\r
+   return;\r
+\r
+  // setting display position\r
+  case 0x05: \r
+   {\r
+    short sx=(short)(gdata & 0x3ff);\r
+    short sy;\r
+\r
+    if(iGPUHeight==1024)\r
+     {\r
+      if(dwGPUVersion==2) \r
+           sy = (short)((gdata>>12)&0x3ff);\r
+      else sy = (short)((gdata>>10)&0x3ff);\r
+     }\r
+    else sy = (short)((gdata>>10)&0x3ff);             // really: 0x1ff, but we adjust it later\r
+\r
+    if (sy & 0x200) \r
+     {\r
+      sy|=0xfc00;\r
+      PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;\r
+      sy=0;\r
+     }\r
+    else PreviousPSXDisplay.DisplayModeNew.y=0;\r
+\r
+    if(sx>1000) sx=0;\r
+\r
+    if(usFirstPos)\r
+     {\r
+      usFirstPos--;\r
+      if(usFirstPos)\r
+       {\r
+        PreviousPSXDisplay.DisplayPosition.x = sx;\r
+        PreviousPSXDisplay.DisplayPosition.y = sy;\r
+        PSXDisplay.DisplayPosition.x = sx;\r
+        PSXDisplay.DisplayPosition.y = sy;\r
+       }\r
+     }\r
+\r
+    if(dwActFixes&8) \r
+     {\r
+      if((!PSXDisplay.Interlaced) &&\r
+         PreviousPSXDisplay.DisplayPosition.x == sx  &&\r
+         PreviousPSXDisplay.DisplayPosition.y == sy)\r
+       return;\r
+\r
+      PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;\r
+      PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;\r
+      PreviousPSXDisplay.DisplayPosition.x = sx;\r
+      PreviousPSXDisplay.DisplayPosition.y = sy;\r
+     }\r
+    else\r
+     {\r
+      if((!PSXDisplay.Interlaced) &&\r
+         PSXDisplay.DisplayPosition.x == sx  &&\r
+         PSXDisplay.DisplayPosition.y == sy)\r
+       return;\r
+      PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
+      PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
+      PSXDisplay.DisplayPosition.x = sx;\r
+      PSXDisplay.DisplayPosition.y = sy;\r
+     }\r
+\r
+    PSXDisplay.DisplayEnd.x=\r
+     PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
+    PSXDisplay.DisplayEnd.y=\r
+     PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
+\r
+    PreviousPSXDisplay.DisplayEnd.x=\r
+     PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
+    PreviousPSXDisplay.DisplayEnd.y=\r
+     PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
+\r
+    bDisplayNotSet = TRUE;\r
+\r
+    if (!(PSXDisplay.Interlaced))\r
+     {\r
+      updateDisplay();\r
+     }\r
+    else\r
+    if(PSXDisplay.InterlacedTest && \r
+       ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||\r
+        (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))\r
+     PSXDisplay.InterlacedTest--;\r
+\r
+    return;\r
+   }\r
+\r
+  // setting width\r
+  case 0x06:\r
+\r
+   PSXDisplay.Range.x0=gdata & 0x7ff;      //0x3ff;\r
+   PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;\r
+\r
+   PSXDisplay.Range.x1-=PSXDisplay.Range.x0;\r
+\r
+   ChangeDispOffsetsX();\r
+\r
+   return;\r
+\r
+  // setting height\r
+  case 0x07:\r
+\r
+   PreviousPSXDisplay.Height = PSXDisplay.Height;\r
+\r
+   PSXDisplay.Range.y0=gdata & 0x3ff;\r
+   PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;\r
+\r
+   PSXDisplay.Height = PSXDisplay.Range.y1 - \r
+                       PSXDisplay.Range.y0 +\r
+                       PreviousPSXDisplay.DisplayModeNew.y;\r
+\r
+   if (PreviousPSXDisplay.Height != PSXDisplay.Height)\r
+    {\r
+     PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;\r
+     ChangeDispOffsetsY();\r
+     updateDisplayIfChanged();\r
+    }\r
+   return;\r
+\r
+  // setting display infos\r
+  case 0x08:\r
+\r
+   PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];\r
+\r
+   if (gdata&0x04) PSXDisplay.Double=2;\r
+   else            PSXDisplay.Double=1;\r
+   PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;\r
+\r
+   ChangeDispOffsetsY();\r
\r
+   PSXDisplay.PAL           = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC\r
+   PSXDisplay.RGB24New      = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor\r
+   PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace\r
+\r
+   STATUSREG&=~GPUSTATUS_WIDTHBITS;                   // clear the width bits\r
+\r
+   STATUSREG|=\r
+              (((gdata & 0x03) << 17) | \r
+              ((gdata & 0x40) << 10));                // set the width bits\r
+\r
+   PreviousPSXDisplay.InterlacedNew=FALSE;\r
+   if (PSXDisplay.InterlacedNew)\r
+    {\r
+     if(!PSXDisplay.Interlaced)\r
+      {\r
+       PSXDisplay.InterlacedTest=2;\r
+       PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
+       PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
+       PreviousPSXDisplay.InterlacedNew=TRUE;\r
+      }\r
+\r
+     STATUSREG|=GPUSTATUS_INTERLACED;\r
+    }\r
+   else \r
+    {\r
+     PSXDisplay.InterlacedTest=0;\r
+     STATUSREG&=~GPUSTATUS_INTERLACED;\r
+    }\r
+\r
+   if (PSXDisplay.PAL)\r
+        STATUSREG|=GPUSTATUS_PAL;\r
+   else STATUSREG&=~GPUSTATUS_PAL;\r
+\r
+   if (PSXDisplay.Double==2)\r
+        STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;\r
+   else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;\r
+\r
+   if (PSXDisplay.RGB24New)\r
+        STATUSREG|=GPUSTATUS_RGB24;\r
+   else STATUSREG&=~GPUSTATUS_RGB24;\r
+\r
+   updateDisplayIfChanged();\r
+\r
+   return;\r
+\r
+  //--------------------------------------------------//\r
+  // ask about GPU version and other stuff\r
+  case 0x10: \r
+\r
+   gdata&=0xff;\r
+\r
+   switch(gdata) \r
+    {\r
+     case 0x02:\r
+      GPUdataRet=ulGPUInfoVals[INFO_TW];              // tw infos\r
+      return;\r
+     case 0x03:\r
+      GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART];       // draw start\r
+      return;\r
+     case 0x04:\r
+      GPUdataRet=ulGPUInfoVals[INFO_DRAWEND];         // draw end\r
+      return;\r
+     case 0x05:\r
+     case 0x06:\r
+      GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF];         // draw offset\r
+      return;\r
+     case 0x07:\r
+      if(dwGPUVersion==2)\r
+           GPUdataRet=0x01;\r
+      else GPUdataRet=0x02;                           // gpu type\r
+      return;\r
+     case 0x08:\r
+     case 0x0F:                                       // some bios addr?\r
+      GPUdataRet=0xBFC03720;\r
+      return;\r
+    }\r
+   return;\r
+  //--------------------------------------------------//\r
+ }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// vram read/write helpers\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL bNeedWriteUpload=FALSE;\r
+\r
+__inline void FinishedVRAMWrite(void)\r
+{\r
+ if(bNeedWriteUpload)\r
+  {\r
+   bNeedWriteUpload=FALSE;\r
+   CheckWriteUpdate();\r
+  }\r
+\r
+ // set register to NORMAL operation\r
+ iDataWriteMode = DR_NORMAL;\r
+\r
+ // reset transfer values, to prevent mis-transfer of data\r
+ VRAMWrite.ColsRemaining = 0;\r
+ VRAMWrite.RowsRemaining = 0;\r
+}\r
+\r
+__inline void FinishedVRAMRead(void)\r
+{\r
+ // set register to NORMAL operation\r
+ iDataReadMode = DR_NORMAL;\r
+ // reset transfer values, to prevent mis-transfer of data\r
+ VRAMRead.x = 0;\r
+ VRAMRead.y = 0;\r
+ VRAMRead.Width = 0;\r
+ VRAMRead.Height = 0;\r
+ VRAMRead.ColsRemaining = 0;\r
+ VRAMRead.RowsRemaining = 0;\r
+\r
+ // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER\r
+ STATUSREG&=~GPUSTATUS_READYFORVRAM;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// vram read check ex (reading from card's back/frontbuffer if needed...\r
+// slow!)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CheckVRamReadEx(int x, int y, int dx, int dy)\r
+{\r
+ unsigned short sArea;\r
+ int ux,uy,udx,udy,wx,wy;\r
+ unsigned short * p1, *p2;\r
+ float XS,YS;\r
+ u8 * ps;\r
+ u8 * px;\r
+ unsigned short s,sx;\r
+\r
+ if(STATUSREG&GPUSTATUS_RGB24) return;\r
+\r
+ if(((dx  > PSXDisplay.DisplayPosition.x) &&\r
+     (x   < PSXDisplay.DisplayEnd.x) &&\r
+     (dy  > PSXDisplay.DisplayPosition.y) &&\r
+     (y   < PSXDisplay.DisplayEnd.y)))\r
+  sArea=0;\r
+ else\r
+ if((!(PSXDisplay.InterlacedTest) &&\r
+     (dx  > PreviousPSXDisplay.DisplayPosition.x) &&\r
+     (x   < PreviousPSXDisplay.DisplayEnd.x) &&\r
+     (dy  > PreviousPSXDisplay.DisplayPosition.y) &&\r
+     (y   < PreviousPSXDisplay.DisplayEnd.y)))\r
+  sArea=1;\r
+ else \r
+  {\r
+   return;\r
+  }\r
+\r
+ //////////////\r
+\r
+ if(iRenderFVR)\r
+  {\r
+   bFullVRam=TRUE;iRenderFVR=2;return;\r
+  }\r
+ bFullVRam=TRUE;iRenderFVR=2;\r
+\r
+ //////////////\r
+\r
+ p2=0;\r
+\r
+ if(sArea==0)\r
+  {\r
+   ux=PSXDisplay.DisplayPosition.x;\r
+   uy=PSXDisplay.DisplayPosition.y;\r
+   udx=PSXDisplay.DisplayEnd.x-ux;\r
+   udy=PSXDisplay.DisplayEnd.y-uy;\r
+   if((PreviousPSXDisplay.DisplayEnd.x-\r
+       PreviousPSXDisplay.DisplayPosition.x)==udx &&\r
+      (PreviousPSXDisplay.DisplayEnd.y-\r
+       PreviousPSXDisplay.DisplayPosition.y)==udy)\r
+    p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + \r
+        PreviousPSXDisplay.DisplayPosition.x);\r
+  }\r
+ else\r
+  {\r
+   ux=PreviousPSXDisplay.DisplayPosition.x;\r
+   uy=PreviousPSXDisplay.DisplayPosition.y;\r
+   udx=PreviousPSXDisplay.DisplayEnd.x-ux;\r
+   udy=PreviousPSXDisplay.DisplayEnd.y-uy;\r
+   if((PSXDisplay.DisplayEnd.x-\r
+       PSXDisplay.DisplayPosition.x)==udx &&\r
+      (PSXDisplay.DisplayEnd.y-\r
+       PSXDisplay.DisplayPosition.y)==udy)\r
+    p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + \r
+        PSXDisplay.DisplayPosition.x);\r
+  }\r
+\r
+ p1=(psxVuw + (1024*uy) + ux);\r
+ if(p1==p2) p2=0;\r
+\r
+ x=0;y=0;\r
+ wx=dx=udx;wy=dy=udy;\r
+\r
+ if(udx<=0) return;\r
+ if(udy<=0) return;\r
+ if(dx<=0)  return;\r
+ if(dy<=0)  return;\r
+ if(wx<=0)  return;\r
+ if(wy<=0)  return;\r
+\r
+ XS=(float)rRatioRect.right/(float)wx;\r
+ YS=(float)rRatioRect.bottom/(float)wy;\r
+\r
+ dx=(int)((float)(dx)*XS);\r
+ dy=(int)((float)(dy)*YS);\r
+\r
+ if(dx>iResX) dx=iResX;\r
+ if(dy>iResY) dy=iResY;\r
+\r
+ if(dx<=0) return;\r
+ if(dy<=0) return;\r
+\r
+ // ogl y adjust\r
+ y=iResY-y-dy;\r
+\r
+ x+=rRatioRect.left;\r
+ y-=rRatioRect.top;\r
+\r
+ if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
+\r
+ if(!pGfxCardScreen)\r
+  {\r
+   glPixelStorei(GL_PACK_ALIGNMENT,1);\r
+   pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
+  }\r
+\r
+ ps=pGfxCardScreen;\r
\r
+ //if(!sArea) glReadBuffer(GL_FRONT);\r
+\r
+ glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
+               \r
+ //if(!sArea) glReadBuffer(GL_BACK);\r
+\r
+ s=0;\r
+\r
+ XS=(float)dx/(float)(udx);\r
+ YS=(float)dy/(float)(udy+1);\r
+    \r
+ for(y=udy;y>0;y--)\r
+  {\r
+   for(x=0;x<udx;x++)\r
+    {\r
+     if(p1>=psxVuw && p1<psxVuw_eom)\r
+      {\r
+       px=ps+(3*((int)((float)x * XS))+\r
+             (3*dx)*((int)((float)y*YS)));\r
+       sx=(*px)>>3;px++;\r
+       s=sx;\r
+       sx=(*px)>>3;px++;\r
+       s|=sx<<5;\r
+       sx=(*px)>>3;\r
+       s|=sx<<10;\r
+       s&=~0x8000;\r
+       *p1=s;\r
+      }\r
+     if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;\r
+\r
+     p1++;\r
+     if(p2) p2++;\r
+    }\r
+\r
+   p1 += 1024 - udx;\r
+   if(p2) p2 += 1024 - udx;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// vram read check (reading from card's back/frontbuffer if needed... \r
+// slow!)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)\r
+{\r
+ unsigned short sArea;unsigned short * p;\r
+ int ux,uy,udx,udy,wx,wy;float XS,YS;\r
+ u8 * ps, * px;\r
+ unsigned short s=0,sx;\r
+\r
+ if(STATUSREG&GPUSTATUS_RGB24) return;\r
+\r
+ if(((dx  > PSXDisplay.DisplayPosition.x) &&\r
+     (x   < PSXDisplay.DisplayEnd.x) &&\r
+     (dy  > PSXDisplay.DisplayPosition.y) &&\r
+     (y   < PSXDisplay.DisplayEnd.y)))\r
+  sArea=0;\r
+ else\r
+ if((!(PSXDisplay.InterlacedTest) &&\r
+     (dx  > PreviousPSXDisplay.DisplayPosition.x) &&\r
+     (x   < PreviousPSXDisplay.DisplayEnd.x) &&\r
+     (dy  > PreviousPSXDisplay.DisplayPosition.y) &&\r
+     (y   < PreviousPSXDisplay.DisplayEnd.y)))\r
+  sArea=1;\r
+ else \r
+  {\r
+   return;\r
+  }\r
+\r
+ if(dwActFixes&0x40)\r
+  {\r
+   if(iRenderFVR)\r
+    {\r
+     bFullVRam=TRUE;iRenderFVR=2;return;\r
+    }\r
+   bFullVRam=TRUE;iRenderFVR=2;\r
+  }\r
+\r
+ ux=x;uy=y;udx=dx;udy=dy;\r
+\r
+ if(sArea==0)\r
+  {\r
+   x -=PSXDisplay.DisplayPosition.x;\r
+   dx-=PSXDisplay.DisplayPosition.x;\r
+   y -=PSXDisplay.DisplayPosition.y;\r
+   dy-=PSXDisplay.DisplayPosition.y;\r
+   wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;\r
+   wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;\r
+  }\r
+ else\r
+  {\r
+   x -=PreviousPSXDisplay.DisplayPosition.x;\r
+   dx-=PreviousPSXDisplay.DisplayPosition.x;\r
+   y -=PreviousPSXDisplay.DisplayPosition.y;\r
+   dy-=PreviousPSXDisplay.DisplayPosition.y;\r
+   wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;\r
+   wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;\r
+  }\r
+ if(x<0) {ux-=x;x=0;}\r
+ if(y<0) {uy-=y;y=0;}\r
+ if(dx>wx) {udx-=(dx-wx);dx=wx;}\r
+ if(dy>wy) {udy-=(dy-wy);dy=wy;}\r
+ udx-=ux;\r
+ udy-=uy;\r
+  \r
+ p=(psxVuw + (1024*uy) + ux);\r
+\r
+ if(udx<=0) return;\r
+ if(udy<=0) return;\r
+ if(dx<=0)  return;\r
+ if(dy<=0)  return;\r
+ if(wx<=0)  return;\r
+ if(wy<=0)  return;\r
+\r
+ XS=(float)rRatioRect.right/(float)wx;\r
+ YS=(float)rRatioRect.bottom/(float)wy;\r
+\r
+ dx=(int)((float)(dx)*XS);\r
+ dy=(int)((float)(dy)*YS);\r
+ x=(int)((float)x*XS);\r
+ y=(int)((float)y*YS);\r
+\r
+ dx-=x;\r
+ dy-=y;\r
+\r
+ if(dx>iResX) dx=iResX;\r
+ if(dy>iResY) dy=iResY;\r
+\r
+ if(dx<=0) return;\r
+ if(dy<=0) return;\r
+\r
+ // ogl y adjust\r
+ y=iResY-y-dy;\r
+\r
+ x+=rRatioRect.left;\r
+ y-=rRatioRect.top;\r
+\r
+ if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
+\r
+ if(!pGfxCardScreen)\r
+  {\r
+   glPixelStorei(GL_PACK_ALIGNMENT,1);\r
+   pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
+  }\r
+\r
+ ps=pGfxCardScreen;\r
\r
+// if(bFront) glReadBuffer(GL_FRONT);\r
+\r
+ glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
+               \r
+// if(bFront) glReadBuffer(GL_BACK);\r
+\r
+ XS=(float)dx/(float)(udx);\r
+ YS=(float)dy/(float)(udy+1);\r
+    \r
+ for(y=udy;y>0;y--)\r
+  {\r
+   for(x=0;x<udx;x++)\r
+    {\r
+     if(p>=psxVuw && p<psxVuw_eom)\r
+      {\r
+       px=ps+(3*((int)((float)x * XS))+\r
+             (3*dx)*((int)((float)y*YS)));\r
+       sx=(*px)>>3;px++;\r
+       s=sx;\r
+       sx=(*px)>>3;px++;\r
+       s|=sx<<5;\r
+       sx=(*px)>>3;\r
+       s|=sx<<10;\r
+       s&=~0x8000;\r
+       *p=s;\r
+      }\r
+     p++;\r
+    }\r
+   p += 1024 - udx;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// core read from vram\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUreadDataMem(unsigned int * pMem, int iSize)\r
+#else\r
+void CALLBACK GPU_readDataMem(unsigned long * pMem, int iSize)\r
+#endif\r
+{\r
+int i;\r
+\r
+if(iDataReadMode!=DR_VRAMTRANSFER) return;\r
+\r
+GPUIsBusy;\r
+\r
+// adjust read ptr, if necessary\r
+while(VRAMRead.ImagePtr>=psxVuw_eom)\r
+ VRAMRead.ImagePtr-=iGPUHeight*1024;\r
+while(VRAMRead.ImagePtr<psxVuw)\r
+ VRAMRead.ImagePtr+=iGPUHeight*1024;\r
+\r
+if((iFrameReadType&1 && iSize>1) &&\r
+   !(iDrawnSomething==2 &&\r
+     VRAMRead.x      == VRAMWrite.x     &&\r
+     VRAMRead.y      == VRAMWrite.y     &&\r
+     VRAMRead.Width  == VRAMWrite.Width &&\r
+     VRAMRead.Height == VRAMWrite.Height))\r
+ CheckVRamRead(VRAMRead.x,VRAMRead.y,\r
+               VRAMRead.x+VRAMRead.RowsRemaining,\r
+               VRAMRead.y+VRAMRead.ColsRemaining,\r
+               TRUE);\r
+\r
+for(i=0;i<iSize;i++)\r
+ {\r
+  // do 2 seperate 16bit reads for compatibility (wrap issues)\r
+  if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))\r
+   {\r
+    // lower 16 bit\r
+    GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;\r
+\r
+    VRAMRead.ImagePtr++;\r
+    if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
+    VRAMRead.RowsRemaining --;\r
+\r
+    if(VRAMRead.RowsRemaining<=0)\r
+     {\r
+      VRAMRead.RowsRemaining = VRAMRead.Width;\r
+      VRAMRead.ColsRemaining--;\r
+      VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
+      if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
+     }\r
+\r
+    // higher 16 bit (always, even if it's an odd width)\r
+    GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;\r
+    *pMem++=GPUdataRet;\r
+\r
+    if(VRAMRead.ColsRemaining <= 0)\r
+     {FinishedVRAMRead();goto ENDREAD;}\r
+\r
+    VRAMRead.ImagePtr++;\r
+    if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
+    VRAMRead.RowsRemaining--;\r
+    if(VRAMRead.RowsRemaining<=0)\r
+     {\r
+      VRAMRead.RowsRemaining = VRAMRead.Width;\r
+      VRAMRead.ColsRemaining--;\r
+      VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
+      if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
+     }\r
+    if(VRAMRead.ColsRemaining <= 0)\r
+     {FinishedVRAMRead();goto ENDREAD;}\r
+   }\r
+  else {FinishedVRAMRead();goto ENDREAD;}\r
+ }\r
+\r
+ENDREAD:\r
+GPUIsIdle;\r
+}\r
+\r
+#ifdef _WINDOWS\r
+unsigned long CALLBACK GPUreadData(void)\r
+#else\r
+unsigned long CALLBACK GPU_readData(void)\r
+#endif\r
+{\r
+ unsigned long l;\r
+#ifdef _WINDOWS\r
+ GPUreadDataMem(&l,1);\r
+#else\r
+ GPU_readDataMem(&l,1);\r
+#endif \r
+ return GPUdataRet;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// helper table to know how much data is used by drawing commands\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+const u8 primTableCX[256] =\r
+{\r
+    // 00\r
+    0,0,3,0,0,0,0,0,\r
+    // 08\r
+    0,0,0,0,0,0,0,0,\r
+    // 10\r
+    0,0,0,0,0,0,0,0,\r
+    // 18\r
+    0,0,0,0,0,0,0,0,\r
+    // 20\r
+    4,4,4,4,7,7,7,7,\r
+    // 28\r
+    5,5,5,5,9,9,9,9,\r
+    // 30\r
+    6,6,6,6,9,9,9,9,\r
+    // 38\r
+    8,8,8,8,12,12,12,12,\r
+    // 40\r
+    3,3,3,3,0,0,0,0,\r
+    // 48\r
+//    5,5,5,5,6,6,6,6,      //FLINE\r
+    254,254,254,254,254,254,254,254,\r
+    // 50\r
+    4,4,4,4,0,0,0,0,\r
+    // 58\r
+//    7,7,7,7,9,9,9,9,    //    LINEG3    LINEG4\r
+    255,255,255,255,255,255,255,255,\r
+    // 60\r
+    3,3,3,3,4,4,4,4,    //    TILE    SPRT\r
+    // 68\r
+    2,2,2,2,3,3,3,3,    //    TILE1\r
+    // 70\r
+    2,2,2,2,3,3,3,3,\r
+    // 78\r
+    2,2,2,2,3,3,3,3,\r
+    // 80\r
+    4,0,0,0,0,0,0,0,\r
+    // 88\r
+    0,0,0,0,0,0,0,0,\r
+    // 90\r
+    0,0,0,0,0,0,0,0,\r
+    // 98\r
+    0,0,0,0,0,0,0,0,\r
+    // a0\r
+    3,0,0,0,0,0,0,0,\r
+    // a8\r
+    0,0,0,0,0,0,0,0,\r
+    // b0\r
+    0,0,0,0,0,0,0,0,\r
+    // b8\r
+    0,0,0,0,0,0,0,0,\r
+    // c0\r
+    3,0,0,0,0,0,0,0,\r
+    // c8\r
+    0,0,0,0,0,0,0,0,\r
+    // d0\r
+    0,0,0,0,0,0,0,0,\r
+    // d8\r
+    0,0,0,0,0,0,0,0,\r
+    // e0\r
+    0,1,1,1,1,1,1,0,\r
+    // e8\r
+    0,0,0,0,0,0,0,0,\r
+    // f0\r
+    0,0,0,0,0,0,0,0,\r
+    // f8\r
+    0,0,0,0,0,0,0,0\r
+};\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// processes data send to GPU data register\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
+#else\r
+void CALLBACK GPU_writeDataMem(unsigned long * pMem, int iSize)\r
+#endif\r
+{\r
+u8 command;\r
+unsigned long gdata=0;\r
+int i=0;\r
+GPUIsBusy;\r
+GPUIsNotReadyForCommands;\r
+\r
+STARTVRAM:\r
+\r
+if(iDataWriteMode==DR_VRAMTRANSFER)\r
+ {\r
+  // make sure we are in vram\r
+  while(VRAMWrite.ImagePtr>=psxVuw_eom)\r
+   VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
+  while(VRAMWrite.ImagePtr<psxVuw)\r
+   VRAMWrite.ImagePtr+=iGPUHeight*1024;\r
+\r
+  // now do the loop\r
+  while(VRAMWrite.ColsRemaining>0)\r
+   {\r
+    while(VRAMWrite.RowsRemaining>0)\r
+     {\r
+      if(i>=iSize) {goto ENDVRAM;}\r
+      i++;\r
+\r
+      gdata=*pMem++;\r
+\r
+      *VRAMWrite.ImagePtr++ = (unsigned short)gdata;\r
+      if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
+      VRAMWrite.RowsRemaining --;\r
+\r
+      if(VRAMWrite.RowsRemaining <= 0)\r
+       {\r
+        VRAMWrite.ColsRemaining--;\r
+        if (VRAMWrite.ColsRemaining <= 0)             // last pixel is odd width\r
+         {\r
+          gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);\r
+          FinishedVRAMWrite();\r
+          goto ENDVRAM;\r
+         }\r
+        VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
+        VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
+       }\r
+\r
+      *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);\r
+      if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
+      VRAMWrite.RowsRemaining --;\r
+     }\r
+\r
+    VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
+    VRAMWrite.ColsRemaining--;\r
+    VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
+   }\r
+\r
+  FinishedVRAMWrite();\r
+ }\r
+\r
+ENDVRAM:\r
+\r
+if(iDataWriteMode==DR_NORMAL)\r
+ {\r
+  void (* *primFunc)(u8 *);\r
+  if(bSkipNextFrame) primFunc=primTableSkip;\r
+  else               primFunc=primTableJ;\r
+\r
+  for(;i<iSize;)\r
+   {\r
+    if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;\r
+\r
+    gdata=*pMem++;i++;\r
+\r
+    if(gpuDataC == 0)\r
+     {\r
+      command = (u8)((gdata>>24) & 0xff);\r
+\r
+      if(primTableCX[command])\r
+       {\r
+        gpuDataC = primTableCX[command];\r
+        gpuCommand = command;\r
+        gpuDataM[0] = gdata;\r
+        gpuDataP = 1;\r
+       }\r
+      else continue;\r
+     }\r
+    else\r
+     {\r
+      gpuDataM[gpuDataP] = gdata;\r
+      if(gpuDataC>128)\r
+       {\r
+        if((gpuDataC==254 && gpuDataP>=3) ||\r
+           (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))\r
+         {\r
+          if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)\r
+           gpuDataP=gpuDataC-1;\r
+         }\r
+       }\r
+      gpuDataP++;\r
+     }\r
+\r
+    if(gpuDataP == gpuDataC)\r
+     {\r
+      gpuDataC=gpuDataP=0;\r
+      primFunc[gpuCommand]((u8 *)gpuDataM);\r
+\r
+      if(dwEmuFixes&0x0001 || dwActFixes&0x20000)     // hack for emulating "gpu busy" in some games\r
+       iFakePrimBusy=4;\r
+     }\r
+   } \r
+ }\r
+\r
+GPUdataRet=gdata;\r
+\r
+GPUIsReadyForCommands;\r
+GPUIsIdle;                \r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUwriteData(unsigned long gdata)\r
+#else\r
+void CALLBACK GPU_writeData(unsigned long gdata)\r
+#endif\r
+{\r
+#ifdef _WINDOWS\r
+ GPUwriteDataMem(&gdata,1);\r
+#else\r
+ GPU_writeDataMem(&gdata,1);\r
+#endif \r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// this function will be removed soon (or 'soonish') (or never)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CALLBACK GPUsetMode(unsigned int gdata)\r
+{\r
+ // ignore old psemu setmode:\r
+\r
+ // imageTransfer = gdata;\r
+ // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;\r
+ // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;\r
+}\r
+\r
+// and this function will be removed soon as well, hehehe...\r
+long CALLBACK GPUgetMode(void)\r
+{\r
+ // ignore old psemu setmode\r
+ // return imageTransfer;\r
+\r
+long iT=0;\r
+\r
+if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;\r
+if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;\r
+\r
+return iT;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// call config dlg (Windows + Linux)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WINDOWS\r
+\r
+/*#include <unistd.h>\r
+\r
+void StartCfgTool(s8 * pCmdLine)                     // linux: start external cfg tool\r
+{\r
+ FILE * cf;s8 filename[255],t[255];\r
+\r
+ strcpy(filename,"cfg/cfgPeopsMesaGL");                 // look in cfg sub folder first\r
+ cf=fopen(filename,"rb");\r
+ if(cf!=NULL)\r
+  {\r
+   fclose(cf);\r
+   getcwd(t,255);\r
+   chdir("cfg");\r
+   sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
+   system(filename);\r
+   chdir(t);\r
+  }\r
+ else\r
+  {\r
+   strcpy(filename,"cfgPeopsMesaGL");                   // look in current folder\r
+   cf=fopen(filename,"rb");\r
+   if(cf!=NULL)\r
+    {\r
+     fclose(cf);\r
+     sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
+     system(filename);\r
+    }\r
+   else\r
+    {\r
+     sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder\r
+     cf=fopen(filename,"rb");\r
+     if(cf!=NULL)\r
+      {\r
+       fclose(cf);\r
+       getcwd(t,255);\r
+       chdir(getenv("HOME"));\r
+       sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
+       system(filename);\r
+       chdir(t);\r
+      }\r
+     else printf("cfgPeopsMesaGL not found!\n");\r
+    }\r
+  }\r
+}\r
+*/\r
+#endif\r
+\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUconfigure(void)\r
+#else\r
+long CALLBACK GPU_configure(void)\r
+#endif\r
+{\r
+\r
+#ifdef _WINDOWS\r
+// HWND hWP=GetActiveWindow();\r
+// DialogBox(hInst,MAKEINTRESOURCE(IDD_CFGDLG),\r
+//           hWP,(DLGPROC)CfgDlgProc);\r
+#else\r
+\r
+// StartCfgTool("CFG");\r
+\r
+#endif\r
+\r
+ return 0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// sets all kind of act fixes\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetFixes(void)\r
+{\r
+ ReInitFrameCap();\r
+\r
+ if(dwActFixes & 0x2000) \r
+      dispWidths[4]=384;\r
+ else dispWidths[4]=368;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Pete Special: make an 'intelligent' dma chain check (<-Tekken3)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+unsigned long lUsedAddr[3];\r
+\r
+__inline BOOL CheckForEndlessLoop(unsigned long laddr)\r
+{\r
+if(laddr==lUsedAddr[1]) return TRUE;\r
+if(laddr==lUsedAddr[2]) return TRUE;\r
+\r
+if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;\r
+else                   lUsedAddr[2]=laddr;\r
+lUsedAddr[0]=laddr;\r
+return FALSE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// core gives a dma chain to gpu: same as the gpuwrite interface funcs\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
+#else\r
+long CALLBACK GPU_dmaChain(unsigned long * baseAddrL, unsigned long addr)\r
+#endif\r
+{\r
+unsigned long dmaMem;\r
+u8 * baseAddrB;\r
+short count;unsigned int DMACommandCounter = 0;\r
+\r
+if(bIsFirstFrame) GLinitialize();\r
+\r
+GPUIsBusy;\r
+\r
+lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;\r
+\r
+baseAddrB = (u8*) baseAddrL;\r
+\r
+do\r
+ {\r
+  if(iGPUHeight==512) addr&=0x1FFFFC;\r
+\r
+  if(DMACommandCounter++ > 2000000) break;\r
+  if(CheckForEndlessLoop(addr)) break;\r
+\r
+  count = baseAddrB[addr+3];\r
+\r
+  dmaMem=addr+4;\r
+\r
+#ifdef _WINDOWS\r
+  if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
+#else\r
+  if(count>0) GPU_writeDataMem(&baseAddrL[dmaMem>>2],count);\r
+#endif\r
+  \r
+  addr = baseAddrL[addr>>2]&0xffffff;\r
+ }\r
+while (addr != 0xffffff);\r
+\r
+GPUIsIdle;\r
+\r
+return 0;\r
+}\r
+           \r
+////////////////////////////////////////////////////////////////////////\r
+// show about dlg\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUabout(void)\r
+#else\r
+void CALLBACK GPU_about(void)\r
+#endif\r
+{\r
+\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// We are ever fine ;)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUtest(void)\r
+#else\r
+long CALLBACK GPU_test(void)\r
+#endif\r
+{\r
+ // if test fails this function should return negative value for error (unable to continue)\r
+ // and positive value for warning (can continue but output might be crappy)\r
+\r
+ return 0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// save state funcs\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
+#else\r
+long CALLBACK GPU_freeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
+#endif\r
+{\r
+if(ulGetFreezeData==2) \r
+ {\r
+  long lSlotNum=*((long *)pF);\r
+  if(lSlotNum<0) return 0;\r
+  if(lSlotNum>8) return 0;\r
+  lSelectedSlot=lSlotNum+1;\r
+  return 1;\r
+ }\r
+\r
+if(!pF)                    return 0; \r
+if(pF->ulFreezeVersion!=1) return 0;\r
+\r
+if(ulGetFreezeData==1)\r
+ {\r
+  pF->ulStatus=STATUSREG;\r
+  memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));\r
+  memcpy(pF->psxVRam,  psxVub,         1024*iGPUHeight*2);\r
+\r
+  return 1;\r
+ }\r
+\r
+if(ulGetFreezeData!=0) return 0;\r
+\r
+STATUSREG=pF->ulStatus;\r
+memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));\r
+memcpy(psxVub,         pF->psxVRam,  1024*iGPUHeight*2);\r
+\r
+ResetTextureArea(TRUE);\r
+\r
+#ifdef _WINDOWS\r
+ GPUwriteStatus(ulStatusControl[0]);\r
+ GPUwriteStatus(ulStatusControl[1]);\r
+ GPUwriteStatus(ulStatusControl[2]);\r
+ GPUwriteStatus(ulStatusControl[3]);\r
+ GPUwriteStatus(ulStatusControl[8]);\r
+ GPUwriteStatus(ulStatusControl[6]);\r
+ GPUwriteStatus(ulStatusControl[7]);\r
+ GPUwriteStatus(ulStatusControl[5]);\r
+ GPUwriteStatus(ulStatusControl[4]);\r
+#else\r
+ GPU_writeStatus(ulStatusControl[0]);\r
+ GPU_writeStatus(ulStatusControl[1]);\r
+ GPU_writeStatus(ulStatusControl[2]);\r
+ GPU_writeStatus(ulStatusControl[3]);\r
+ GPU_writeStatus(ulStatusControl[8]);\r
+ GPU_writeStatus(ulStatusControl[6]);\r
+ GPU_writeStatus(ulStatusControl[7]);\r
+ GPU_writeStatus(ulStatusControl[5]);\r
+ GPU_writeStatus(ulStatusControl[4]);\r
+#endif\r
+ return 1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// special "emu infos" / "emu effects" functions\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+//00 = black\r
+//01 = white\r
+//10 = red\r
+//11 = transparent\r
+\r
+u8 cFont[10][120]=\r
+{\r
+// 0\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 1\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x05,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x05,0x55,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 2\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x01,0x40,0x00,0x00,\r
+ 0x80,0x00,0x05,0x00,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x15,0x55,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 3\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x01,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 4\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x54,0x00,0x00,\r
+ 0x80,0x00,0x01,0x54,0x00,0x00,\r
+ 0x80,0x00,0x01,0x54,0x00,0x00,\r
+ 0x80,0x00,0x05,0x14,0x00,0x00,\r
+ 0x80,0x00,0x14,0x14,0x00,0x00,\r
+ 0x80,0x00,0x15,0x55,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x55,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 5\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x15,0x55,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x15,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 6\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x01,0x54,0x00,0x00,\r
+ 0x80,0x00,0x05,0x00,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x14,0x00,0x00,0x00,\r
+ 0x80,0x00,0x15,0x54,0x00,0x00,\r
+ 0x80,0x00,0x15,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 7\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x15,0x55,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x50,0x00,0x00,\r
+ 0x80,0x00,0x01,0x40,0x00,0x00,\r
+ 0x80,0x00,0x01,0x40,0x00,0x00,\r
+ 0x80,0x00,0x05,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 8\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+},\r
+// 9\r
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x05,0x54,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x05,0x00,0x00,\r
+ 0x80,0x00,0x14,0x15,0x00,0x00,\r
+ 0x80,0x00,0x05,0x55,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x05,0x00,0x00,\r
+ 0x80,0x00,0x00,0x14,0x00,0x00,\r
+ 0x80,0x00,0x05,0x50,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0x80,0x00,0x00,0x00,0x00,0x00,\r
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
+}\r
+};\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PaintPicDot(u8 * p,u8 c)\r
+{\r
+ if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}\r
+ if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}\r
+ if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUgetScreenPic(u8 * pMem)\r
+#else\r
+long CALLBACK GPU_getScreenPic(u8 * pMem)\r
+#endif\r
+{\r
+ float XS,YS;int x,y,v;\r
+ u8 * ps, * px, * pf;\r
+ u8 c;\r
+\r
+ if(!pGfxCardScreen)\r
+  {\r
+   glPixelStorei(GL_PACK_ALIGNMENT,1);\r
+   pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
+  }\r
+\r
+ ps=pGfxCardScreen;\r
+\r
+// glReadBuffer(GL_FRONT);\r
+\r
+ glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
+               \r
+// glReadBuffer(GL_BACK);\r
+\r
+ XS=(float)iResX/128;\r
+ YS=(float)iResY/96;\r
+ pf=pMem;\r
+\r
+ for(y=96;y>0;y--)\r
+  {\r
+   for(x=0;x<128;x++)\r
+    {\r
+     px=ps+(3*((int)((float)x * XS))+\r
+           (3*iResX)*((int)((float)y*YS)));\r
+     *(pf+0)=*(px+2);\r
+     *(pf+1)=*(px+1);\r
+     *(pf+2)=*(px+0);\r
+     pf+=3;\r
+    }\r
+  }\r
+\r
+ /////////////////////////////////////////////////////////////////////\r
+ // generic number/border painter\r
+\r
+ pf=pMem+(103*3);\r
+\r
+ for(y=0;y<20;y++)\r
+  {\r
+   for(x=0;x<6;x++)\r
+    {\r
+     c=cFont[lSelectedSlot][x+y*6];\r
+     v=(c&0xc0)>>6;\r
+     PaintPicDot(pf,(u8)v);pf+=3;                // paint the dots into the rect\r
+     v=(c&0x30)>>4;\r
+     PaintPicDot(pf,(u8)v);pf+=3;\r
+     v=(c&0x0c)>>2;\r
+     PaintPicDot(pf,(u8)v);pf+=3;\r
+     v=c&0x03;\r
+     PaintPicDot(pf,(u8)v);pf+=3;\r
+    }\r
+   pf+=104*3;\r
+  }\r
+\r
+ pf=pMem;\r
+ for(x=0;x<128;x++)\r
+  {\r
+   *(pf+(95*128*3))=0x00;*pf++=0x00;\r
+   *(pf+(95*128*3))=0x00;*pf++=0x00;\r
+   *(pf+(95*128*3))=0xff;*pf++=0xff;\r
+  }\r
+ pf=pMem;\r
+ for(y=0;y<96;y++)\r
+  {\r
+   *(pf+(127*3))=0x00;*pf++=0x00;\r
+   *(pf+(127*3))=0x00;*pf++=0x00;\r
+   *(pf+(127*3))=0xff;*pf++=0xff;\r
+   pf+=127*3;\r
+  }\r
+\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+void CALLBACK GPUshowScreenPic(u8 * pMem)\r
+#else\r
+long CALLBACK GPU_showScreenPic(u8 * pMem)\r
+#endif\r
+{\r
+// DestroyPic();\r
+// if(pMem==0) return;\r
+// CreatePic(pMem);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CALLBACK GPUsetfix(unsigned long dwFixBits)\r
+{\r
+ dwEmuFixes=dwFixBits;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
\r
+void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)\r
+{\r
+ int iVibVal;\r
+\r
+ if(PSXDisplay.DisplayModeNew.x)                       // calc min "shake pixel" from screen width\r
+      iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);\r
+ else iVibVal=1;\r
+                                                       // big rumble: 4...15 sp ; small rumble 1...3 sp\r
+ if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig  *iVibVal)/10));\r
+ else     iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));\r
+\r
+ srand(timeGetTime());                                 // init rand (will be used in BufferSwap)\r
+\r
+ iRumbleTime=15;                                       // let the rumble last 16 buffer swaps\r
+}\r
+                                                       \r
+////////////////////////////////////////////////////////////////////////\r
+// main emu can set display infos (A/M/G/D) \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CALLBACK GPUdisplayFlags(unsigned long dwFlags)\r
+{\r
+// dwCoreFlags=dwFlags;\r
+}\r
diff --git a/plugins/gpu-gles/gpuPlugin.h b/plugins/gpu-gles/gpuPlugin.h
new file mode 100644 (file)
index 0000000..c452032
--- /dev/null
@@ -0,0 +1,134 @@
+/***************************************************************************\r
+                            gpu.h  -  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
+#ifndef _GPU_PLUGIN_H\r
+#define _GPU_PLUGIN_H\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif \r
+\r
+#if !defined(_WINDOWS) && !defined(__NANOGL__)\r
+#define glOrtho(x,y,z,xx,yy,zz) glOrthof(x,y,z,xx,yy,zz)\r
+#endif\r
+\r
+#define PRED(x)   ((x << 3) & 0xF8)\r
+#define PBLUE(x)  ((x >> 2) & 0xF8)\r
+#define PGREEN(x) ((x >> 7) & 0xF8)\r
+\r
+#define RED(x) (x & 0xff)\r
+#define BLUE(x) ((x>>16) & 0xff)\r
+#define GREEN(x) ((x>>8) & 0xff)\r
+#define COLOR(x) (x & 0xffffff)\r
+\r
+#ifdef _WINDOWS\r
+#include "Externals.h"\r
+#include "plugin.h"\r
+#include <gl/gl.h>\r
+#else\r
+#ifndef MAEMO_CHANGES\r
+       #include "psxCommon.h"\r
+#else\r
+       #include "../psxCommon.h"\r
+#endif \r
+#include "gpuExternals.h"\r
+#ifdef __NANOGL__\r
+#include <gl/gl.h>\r
+#else\r
+#ifdef SOFT_LINKAGE\r
+#pragma softfp_linkage\r
+#endif\r
+#ifndef MAEMO_CHANGES\r
+       #include <gles/gl.h> // for opengl es types \r
+       #include <gles/egltypes.h>\r
+#else\r
+#include "gpuStdafx.h"\r
+#endif\r
+#ifdef SOFT_LINKAGE\r
+#pragma no_softfp_linkage\r
+#endif\r
+#endif\r
+#endif\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define CALLBACK\r
+\r
+#define bool unsigned short\r
+\r
+typedef struct {\r
+       u32 ulFreezeVersion;\r
+       u32 ulStatus;\r
+       u32 ulControl[256];\r
+       u8 psxVRam[1024*1024*2];\r
+} GPUFreeze_t;\r
+\r
+long CALLBACK GPU_init();\r
+long CALLBACK GPU_shutdown();\r
+long CALLBACK GPU_open(int hwndGPU);                    \r
+long CALLBACK GPU_close();\r
+unsigned long CALLBACK GPU_readData(void);\r
+void CALLBACK GPU_readDataMem(unsigned long * pMem, int iSize);\r
+unsigned long CALLBACK GPU_readStatus(void);\r
+void CALLBACK GPU_writeData(unsigned long gdata);\r
+void CALLBACK GPU_writeDataMem(unsigned long * pMem, int iSize);\r
+void CALLBACK GPU_writeStatus(unsigned long gdata);\r
+long CALLBACK GPU_dmaChain(unsigned long * baseAddrL, unsigned long addr);\r
+void CALLBACK GPU_updateLace(void);\r
+void CALLBACK GPU_makeSnapshot(void);\r
+long CALLBACK GPU_freeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF);\r
+long CALLBACK GPU_getScreenPic(u8 * pMem);\r
+long CALLBACK GPU_showScreenPic(u8 * pMem);\r
+//void CALLBACK GPU_keypressed(int keycode);\r
+//void CALLBACK GPU_displayText(s8 * pText);\r
+//void CALLBACK GPU_clearDynarec(void (CALLBACK *callback)(void));\r
+long CALLBACK GPU_configure(void);\r
+long CALLBACK GPU_test(void);\r
+void CALLBACK GPU_about(void);\r
+\r
+\r
+void           DoSnapShot(void);\r
+void              GPU_vSinc(void);\r
+void           updateDisplay(void);\r
+void           updateFrontDisplay(void);\r
+void           SetAutoFrameCap(void);\r
+void           SetAspectRatio(void);\r
+void           CheckVRamRead(int x, int y, int dx, int dy, bool bFront);\r
+void           CheckVRamReadEx(int x, int y, int dx, int dy);\r
+void           SetFixes(void);\r
+\r
+void PaintPicDot(u8 * p,u8 c);\r
+//void DrawNumBorPic(u8 *pMem, int lSelectedSlot);\r
+void ResizeWindow();\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+#ifdef __cplusplus\r
+}\r
+#endif \r
+\r
+\r
+#endif // _GPU_INTERNALS_H\r
diff --git a/plugins/gpu-gles/gpuPrim.c b/plugins/gpu-gles/gpuPrim.c
new file mode 100644 (file)
index 0000000..9b718a5
--- /dev/null
@@ -0,0 +1,5022 @@
+/***************************************************************************\r
+                          prim.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
+#define _IN_PRIMDRAW\r
+\r
+#ifdef _WINDOWS\r
+#include "stdafx.h"\r
+#include "externals.h"\r
+#include "gpu.h"\r
+#include "draw.h"\r
+#include "texture.h"\r
+#else\r
+#include "gpuStdafx.h"\r
+#include "gpuExternals.h"\r
+#include "gpuPlugin.h"\r
+#include "gpuDraw.h"\r
+#include "gpuTexture.h"\r
+#include "gpuPrim.h"\r
+\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// defines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define DEFOPAQUEON  glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND);                                \r
+#define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f);\r
+#define fpoint(x) x\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// globals\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WINDOWS\r
+EGLSurface surface;\r
+EGLDisplay display;\r
+#endif\r
+\r
+BOOL           bDrawTextured;                          // current active drawing states\r
+BOOL           bDrawSmoothShaded;\r
+BOOL           bOldSmoothShaded;\r
+BOOL           bDrawNonShaded;\r
+BOOL           bDrawMultiPass;\r
+int            iOffscreenDrawing;\r
+int            iDrawnSomething=0;\r
+\r
+BOOL           bRenderFrontBuffer=FALSE;               // flag for front buffer rendering\r
+\r
+GLubyte        ubGloAlpha;                             // texture alpha\r
+GLubyte        ubGloColAlpha;                          // color alpha\r
+int            iFilterType;                            // type of filter\r
+BOOL           bFullVRam=FALSE;                        // sign for tex win\r
+BOOL           bDrawDither;                            // sign for dither\r
+BOOL           bUseMultiPass;                          // sign for multi pass\r
+GLuint         gTexName;                               // binded texture\r
+BOOL           bTexEnabled;                            // texture enable flag\r
+BOOL           bBlendEnable;                           // blend enable flag\r
+PSXRect_t      xrUploadArea;                           // rect to upload\r
+PSXRect_t      xrUploadAreaIL;                         // rect to upload\r
+PSXRect_t      xrUploadAreaRGB24;                      // rect to upload rgb24\r
+int            iSpriteTex=0;                           // flag for "hey, it's a sprite"\r
+unsigned short usMirror;                               // mirror, mirror on the wall\r
+\r
+BOOL           bNeedUploadAfter=FALSE;                 // sign for uploading in next frame\r
+BOOL           bNeedUploadTest=FALSE;                  // sign for upload test\r
+BOOL           bUsingTWin=FALSE;                       // tex win active flag\r
+BOOL           bUsingMovie=FALSE;                      // movie active flag\r
+PSXRect_t      xrMovieArea;                            // rect for movie upload\r
+short          sSprite_ux2;                            // needed for sprire adjust\r
+short          sSprite_vy2;                            // \r
+unsigned long  ulOLDCOL=0;                             // active color\r
+unsigned long  ulClutID;                               // clut\r
+\r
+unsigned long dwCfgFixes;                              // game fixes\r
+unsigned long dwActFixes=0;\r
+unsigned long dwEmuFixes=0;\r
+BOOL          bUseFixes;\r
+\r
+long          drawX,drawY,drawW,drawH;                 // offscreen drawing checkers\r
+short         sxmin,sxmax,symin,symax;\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Update global TP infos\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void UpdateGlobalTP(unsigned short gdata)\r
+{\r
+ GlobalTextAddrX = (gdata << 6) & 0x3c0;\r
+\r
+ if(iGPUHeight==1024)                                  // ZN mode\r
+  {\r
+   if(dwGPUVersion==2)                                 // very special zn gpu\r
+    {\r
+     GlobalTextAddrY =((gdata & 0x60 ) << 3);\r
+     GlobalTextIL    =(gdata & 0x2000) >> 13;\r
+     GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);\r
+     GlobalTextTP = (gdata >> 9) & 0x3;\r
+     if(GlobalTextTP==3) GlobalTextTP=2;             \r
+     GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);\r
+     usMirror =0;\r
+     STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff );\r
+     return;\r
+    }\r
+   else                                                // "enhanced" psx gpu\r
+    {\r
+     GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));\r
+    }\r
+  }\r
+ else GlobalTextAddrY = (gdata << 4) & 0x100;          // "normal" psx gpu\r
+\r
+ usMirror=gdata&0x3000;\r
\r
+ GlobalTextTP = (gdata >> 7) & 0x3;                    // tex mode (4,8,15)\r
+ if(GlobalTextTP==3) GlobalTextTP=2;                   // seen in Wild9 :(\r
+ GlobalTextABR = (gdata >> 5) & 0x3;                   // blend mode\r
+\r
+ GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);\r
+\r
+ STATUSREG&=~0x07ff;                                   // Clear the necessary bits\r
+ STATUSREG|=(gdata & 0x07ff);                          // set the necessary bits\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Some ASM color convertion... Lewpy's special...\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+#pragma warning  (disable : 4035)\r
+\r
+unsigned long DoubleBGR2RGB (unsigned long BGR)\r
+{\r
+\r
+    __asm\r
+    {\r
+        mov eax, BGR                /* this can hold the G value */\r
+        mov ebx, eax                /* this can hold the R value */\r
+        mov edx, eax                /* this can hold the B value */\r
+        and ebx, 000000ffh          /* mask the R value */\r
+        shl ebx, 1\r
+        test ebx, 00000100h\r
+        jz    RSKIP\r
+        mov ebx, 000000ffh\r
+\r
+RSKIP: \r
+        and eax, 0000ff00h          /* mask the G value */\r
+        shl eax, 1\r
+        test eax, 00010000h\r
+        jz    GSKIP\r
+        mov eax, 0000ff00h\r
+\r
+GSKIP: \r
+        and edx, 00ff0000h          /* mask the B value */\r
+        shl edx, 1\r
+        test edx, 01000000h\r
+        jz    BSKIP\r
+        mov edx, 00ff0000h\r
+        \r
+BSKIP: \r
+        or  eax, ebx                /* add R to G value */\r
+        or  eax, edx                /* add B to RG value */\r
+    }\r
+    /* Result returned in EAX */\r
+}\r
+\r
+unsigned short BGR24to16 (unsigned long BGR)\r
+{\r
+    __asm\r
+    {\r
+        mov eax, BGR                /* this can hold the G value */\r
+        mov ebx, eax                /* this can hold the R value */\r
+        mov edx, eax                /* this can hold the B value */\r
+        shr ebx, 3                  /* move the R value */\r
+        and edx, 00f80000h          /* mask the B value */\r
+        shr edx, 9                  /* move the B value */\r
+        and eax, 00f800h            /* mask the G value */\r
+        shr eax, 6                  /* move the G value */\r
+        and ebx, 0000001fh          /* mask the R value */\r
+        or  eax, ebx                /* add R to G value */\r
+        or  eax, edx                /* add B to RG value */\r
+    }\r
+    /* Result returned in AX */\r
+}\r
+\r
+#pragma warning  (default : 4035)\r
+\r
+#else\r
+\r
+unsigned long DoubleBGR2RGB (unsigned long BGR)\r
+{\r
+ unsigned long ebx,eax,edx;\r
+\r
+ ebx=(BGR&0x000000ff)<<1;\r
+ if(ebx&0x00000100) ebx=0x000000ff;\r
+\r
+ eax=(BGR&0x0000ff00)<<1;\r
+ if(eax&0x00010000) eax=0x0000ff00;\r
+\r
+ edx=(BGR&0x00ff0000)<<1;\r
+ if(edx&0x01000000) edx=0x00ff0000;\r
+\r
+ return (ebx|eax|edx);\r
+}\r
+\r
+unsigned short BGR24to16 (unsigned long BGR)\r
+{\r
+ return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6);\r
+}\r
+\r
+#endif\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// OpenGL primitive drawing commands\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+__inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                   OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+\r
+\r
+Vertex v[4];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].st.x = fpoint(vertex1->sow);\r
+v[0].st.y = fpoint(vertex1->tow);\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].st.x = fpoint(vertex2->sow);\r
+v[1].st.y = fpoint(vertex2->tow);\r
+\r
+v[2].xyz.x = fpoint(vertex4->x);\r
+v[2].xyz.y = fpoint(vertex4->y);\r
+v[2].xyz.z = fpoint(vertex4->z);\r
+v[2].st.x = fpoint(vertex4->sow);\r
+v[2].st.y = fpoint(vertex4->tow);\r
+\r
+v[3].xyz.x = fpoint(vertex3->x);\r
+v[3].xyz.y = fpoint(vertex3->y);\r
+v[3].xyz.z = fpoint(vertex3->z);\r
+v[3].st.x = fpoint(vertex3->sow);\r
+v[3].st.y = fpoint(vertex3->tow);\r
+\r
+glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glDisableClientState(GL_VERTEX_ARRAY); \r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                  OGLVertex* vertex3) \r
+{\r
+Vertex v[3];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].st.x = fpoint(vertex1->sow);\r
+v[0].st.y = fpoint(vertex1->tow);\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].st.x = fpoint(vertex2->sow);\r
+v[1].st.y = fpoint(vertex2->tow);\r
+\r
+v[2].xyz.x = fpoint(vertex3->x);\r
+v[2].xyz.y = fpoint(vertex3->y);\r
+v[2].xyz.z = fpoint(vertex3->z);\r
+v[2].st.x = fpoint(vertex3->sow);\r
+v[2].st.y = fpoint(vertex3->tow);\r
+\r
+glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glDrawArrays(GL_TRIANGLES, 0, 3);\r
+glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                         OGLVertex* vertex3) \r
+{\r
+\r
+Vertex2 v[3];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].st.x = fpoint(vertex1->sow);\r
+v[0].st.y = fpoint(vertex1->tow);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].st.x = fpoint(vertex2->sow);\r
+v[1].st.y = fpoint(vertex2->tow);\r
+v[1].rgba.r = vertex2->c.col[0];\r
+v[1].rgba.g = vertex2->c.col[1];\r
+v[1].rgba.b = vertex2->c.col[2];\r
+v[1].rgba.a = vertex2->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex3->x);\r
+v[2].xyz.y = fpoint(vertex3->y);\r
+v[2].xyz.z = fpoint(vertex3->z);\r
+v[2].st.x = fpoint(vertex3->sow);\r
+v[2].st.y = fpoint(vertex3->tow);\r
+v[2].rgba.r = vertex3->c.col[0];\r
+v[2].rgba.g = vertex3->c.col[1];\r
+v[2].rgba.b = vertex3->c.col[2];\r
+v[2].rgba.a = vertex3->c.col[3];\r
+\r
+glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLES, 0, 3);\r
+glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                             OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+Vertex2 v[4];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].st.x = fpoint(vertex1->sow);\r
+v[0].st.y = fpoint(vertex1->tow);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].st.x = fpoint(vertex2->sow);\r
+v[1].st.y = fpoint(vertex2->tow);\r
+v[1].rgba.r = vertex2->c.col[0];\r
+v[1].rgba.g = vertex2->c.col[1];\r
+v[1].rgba.b = vertex2->c.col[2];\r
+v[1].rgba.a = vertex2->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex4->x);\r
+v[2].xyz.y = fpoint(vertex4->y);\r
+v[2].xyz.z = fpoint(vertex4->z);\r
+v[2].st.x = fpoint(vertex4->sow);\r
+v[2].st.y = fpoint(vertex4->tow);\r
+v[2].rgba.r = vertex4->c.col[0];\r
+v[2].rgba.g = vertex4->c.col[1];\r
+v[2].rgba.b = vertex4->c.col[2];\r
+v[2].rgba.a = vertex4->c.col[3];\r
+\r
+v[3].xyz.x = fpoint(vertex3->x);\r
+v[3].xyz.y = fpoint(vertex3->y);\r
+v[3].xyz.z = fpoint(vertex3->z);\r
+v[3].st.x = fpoint(vertex3->sow);\r
+v[3].st.y = fpoint(vertex3->tow);\r
+v[3].rgba.r = vertex3->c.col[0];\r
+v[3].rgba.g = vertex3->c.col[1];\r
+v[3].rgba.b = vertex3->c.col[2];\r
+v[3].rgba.a = vertex3->c.col[3];\r
+\r
+glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glTexCoordPointer(2, GL_FLOAT, sizeof(v[0]), &v[0].st);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3) \r
+{\r
+Vec3f v[3];\r
+\r
+v[0].x = fpoint(vertex1->x);\r
+v[0].y = fpoint(vertex1->y);\r
+v[0].z = fpoint(vertex1->z);\r
+\r
+v[1].x = fpoint(vertex2->x);\r
+v[1].y = fpoint(vertex2->y);\r
+v[1].z = fpoint(vertex2->z);\r
+\r
+v[2].x = fpoint(vertex3->x);\r
+v[2].y = fpoint(vertex3->y);\r
+v[2].z = fpoint(vertex3->z);\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
+glDrawArrays(GL_TRIANGLES, 0, 3);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                           OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+Vec3f v[4];\r
+\r
+v[0].x = fpoint(vertex1->x);\r
+v[0].y = fpoint(vertex1->y);\r
+v[0].z = fpoint(vertex1->z);\r
+\r
+v[1].x = fpoint(vertex3->x);\r
+v[1].y = fpoint(vertex3->y);\r
+v[1].z = fpoint(vertex3->z);\r
+\r
+v[2].x = fpoint(vertex2->x);\r
+v[2].y = fpoint(vertex2->y);\r
+v[2].z = fpoint(vertex2->z);\r
+\r
+v[3].x = fpoint(vertex4->x);\r
+v[3].y = fpoint(vertex4->y);\r
+v[3].z = fpoint(vertex4->z);\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                      OGLVertex* vertex3) \r
+{\r
+Vertex2 v[3];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].rgba.r = vertex2->c.col[0];\r
+v[1].rgba.g = vertex2->c.col[1];\r
+v[1].rgba.b = vertex2->c.col[2];\r
+v[1].rgba.a = vertex2->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex3->x);\r
+v[2].xyz.y = fpoint(vertex3->y);\r
+v[2].xyz.z = fpoint(vertex3->z);\r
+v[2].rgba.r = vertex3->c.col[0];\r
+v[2].rgba.g = vertex3->c.col[1];\r
+v[2].rgba.b = vertex3->c.col[2];\r
+v[2].rgba.a = vertex3->c.col[3];\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLES, 0, 3);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                                       OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+Vertex2 v[4];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].rgba.r = vertex2->c.col[0];\r
+v[1].rgba.g = vertex2->c.col[1];\r
+v[1].rgba.b = vertex2->c.col[2];\r
+v[1].rgba.a = vertex2->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex3->x);\r
+v[2].xyz.y = fpoint(vertex3->y);\r
+v[2].xyz.z = fpoint(vertex3->z);\r
+v[2].rgba.r = vertex3->c.col[0];\r
+v[2].rgba.g = vertex3->c.col[1];\r
+v[2].rgba.b = vertex3->c.col[2];\r
+v[2].rgba.a = vertex3->c.col[3];\r
+\r
+v[3].xyz.x = fpoint(vertex4->x);\r
+v[3].xyz.y = fpoint(vertex4->y);\r
+v[3].xyz.z = fpoint(vertex4->z);\r
+v[3].rgba.r = vertex4->c.col[0];\r
+v[3].rgba.g = vertex4->c.col[1];\r
+v[3].rgba.b = vertex4->c.col[2];\r
+v[3].rgba.a = vertex4->c.col[3];\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+\r
+__inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)\r
+{\r
+Vertex2 v[4];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].rgba.r = vertex1->c.col[0];\r
+v[1].rgba.g = vertex1->c.col[1];\r
+v[1].rgba.b = vertex1->c.col[2];\r
+v[1].rgba.a = vertex1->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex4->x);\r
+v[2].xyz.y = fpoint(vertex4->y);\r
+v[2].xyz.z = fpoint(vertex4->z);\r
+v[2].rgba.r = vertex1->c.col[0];\r
+v[2].rgba.g = vertex1->c.col[1];\r
+v[2].rgba.b = vertex1->c.col[2];\r
+v[2].rgba.a = vertex1->c.col[3];\r
+\r
+v[3].xyz.x = fpoint(vertex3->x);\r
+v[3].xyz.y = fpoint(vertex3->y);\r
+v[3].xyz.z = fpoint(vertex3->z);\r
+v[3].rgba.r = vertex1->c.col[0];\r
+v[3].rgba.g = vertex1->c.col[1];\r
+v[3].rgba.b = vertex1->c.col[2];\r
+v[3].rgba.a = vertex1->c.col[3];\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+\r
+\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+     \r
+__inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)\r
+{\r
+       Vertex2 v[4];\r
+\r
+v[0].xyz.x = fpoint(vertex1->x);\r
+v[0].xyz.y = fpoint(vertex1->y);\r
+v[0].xyz.z = fpoint(vertex1->z);\r
+v[0].rgba.r = vertex1->c.col[0];\r
+v[0].rgba.g = vertex1->c.col[1];\r
+v[0].rgba.b = vertex1->c.col[2];\r
+v[0].rgba.a = vertex1->c.col[3];\r
+\r
+v[1].xyz.x = fpoint(vertex2->x);\r
+v[1].xyz.y = fpoint(vertex2->y);\r
+v[1].xyz.z = fpoint(vertex2->z);\r
+v[1].rgba.r = vertex2->c.col[0];\r
+v[1].rgba.g = vertex2->c.col[1];\r
+v[1].rgba.b = vertex2->c.col[2];\r
+v[1].rgba.a = vertex2->c.col[3];\r
+\r
+v[3].xyz.x = fpoint(vertex3->x);\r
+v[3].xyz.y = fpoint(vertex3->y);\r
+v[3].xyz.z = fpoint(vertex3->z);\r
+v[3].rgba.r = vertex3->c.col[0];\r
+v[3].rgba.g = vertex3->c.col[1];\r
+v[3].rgba.b = vertex3->c.col[2];\r
+v[3].rgba.a = vertex3->c.col[3];\r
+\r
+v[2].xyz.x = fpoint(vertex4->x);\r
+v[2].xyz.y = fpoint(vertex4->y);\r
+v[2].xyz.z = fpoint(vertex4->z);\r
+v[2].rgba.r = vertex4->c.col[0];\r
+v[2].rgba.g = vertex4->c.col[1];\r
+v[2].rgba.b = vertex4->c.col[2];\r
+v[2].rgba.a = vertex4->c.col[3];\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glEnableClientState(GL_COLOR_ARRAY);\r
+\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0].xyz);\r
+glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(v[0]), &v[0].rgba);\r
+\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+glDisableClientState(GL_COLOR_ARRAY);\r
+}\r
+\r
+///////////////////////////////////////////////////////// \r
+             \r
+__inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
+                           OGLVertex* vertex3, OGLVertex* vertex4) \r
+{\r
+Vec3f v[4];\r
+\r
+v[0].x = fpoint(vertex1->x);\r
+v[0].y = fpoint(vertex1->y);\r
+v[0].z = fpoint(vertex1->z);\r
+\r
+v[1].x = fpoint(vertex2->x);\r
+v[1].y = fpoint(vertex2->y);\r
+v[1].z = fpoint(vertex2->z);\r
+\r
+v[2].x = fpoint(vertex4->x);\r
+v[2].y = fpoint(vertex4->y);\r
+v[2].z = fpoint(vertex4->z);\r
+\r
+v[3].x = fpoint(vertex3->x);\r
+v[3].y = fpoint(vertex3->y);\r
+v[3].z = fpoint(vertex3->z);\r
+\r
+glEnableClientState(GL_VERTEX_ARRAY);\r
+glVertexPointer(3, GL_FLOAT, sizeof(v[0]), &v[0]);\r
+glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);\r
+glDisableClientState(GL_VERTEX_ARRAY);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Transparent blending settings\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+static GLenum obm1=GL_ZERO;\r
+static GLenum obm2=GL_ZERO;\r
+\r
+typedef struct SEMITRANSTAG\r
+{\r
+ GLenum  srcFac;\r
+ GLenum  dstFac;\r
+ GLubyte alpha;\r
+} SemiTransParams;\r
+\r
+SemiTransParams TransSets[4]=\r
+{\r
+ {GL_SRC_ALPHA,GL_SRC_ALPHA,          127},\r
+ {GL_ONE,      GL_ONE,                255},\r
+ {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
+ {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      192}\r
+}; \r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetSemiTrans(void)\r
+{\r
+/*\r
+* 0.5 x B + 0.5 x F\r
+* 1.0 x B + 1.0 x F\r
+* 1.0 x B - 1.0 x F\r
+* 1.0 x B +0.25 x F\r
+*/\r
+\r
+ if(!DrawSemiTrans)                                    // no semi trans at all?\r
+  {\r
+   if(bBlendEnable)\r
+    {glDisable(GL_BLEND);bBlendEnable=FALSE;}          // -> don't wanna blend\r
+   ubGloAlpha=ubGloColAlpha=255;                       // -> full alpha\r
+   return;                                             // -> and bye\r
+  }\r
+\r
+ ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha;\r
+\r
+ if(!bBlendEnable)\r
+  {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend\r
+\r
+ if(TransSets[GlobalTextABR].srcFac!=obm1 || \r
+    TransSets[GlobalTextABR].dstFac!=obm2)\r
+  {\r
+   //if(glBlendEquationEXTEx==NULL)\r
+    {\r
+     obm1=TransSets[GlobalTextABR].srcFac;\r
+     obm2=TransSets[GlobalTextABR].dstFac;\r
+     glBlendFunc(obm1,obm2);                           // set blend func\r
+    }\r
+   /*else\r
+   if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR)\r
+    {\r
+     if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
+      glBlendEquationEXTEx(FUNC_ADD_EXT);\r
+     obm1=TransSets[GlobalTextABR].srcFac;\r
+     obm2=TransSets[GlobalTextABR].dstFac;\r
+     glBlendFunc(obm1,obm2);                           // set blend func\r
+    }\r
+   else\r
+    {\r
+     glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT);\r
+     obm1=TransSets[GlobalTextABR].srcFac;\r
+     obm2=TransSets[GlobalTextABR].dstFac;\r
+     glBlendFunc(GL_ONE,GL_ONE);                       // set blend func\r
+    }*/\r
+  }\r
+}\r
+\r
+void SetScanTrans(void)                                // blending for scan lines\r
+{\r
+/* if(glBlendEquationEXTEx!=NULL)\r
+  {\r
+   if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
+    glBlendEquationEXTEx(FUNC_ADD_EXT);\r
+  }\r
+*/\r
+ obm1=TransSets[0].srcFac;\r
+ obm2=TransSets[0].dstFac;\r
+ glBlendFunc(obm1,obm2);                               // set blend func\r
+}\r
+\r
+void SetScanTexTrans(void)                             // blending for scan mask texture\r
+{\r
+/* if(glBlendEquationEXTEx!=NULL)\r
+  {\r
+   if(obm2==GL_ONE_MINUS_SRC_COLOR)\r
+    glBlendEquationEXTEx(FUNC_ADD_EXT);\r
+  }\r
+*/\r
+ obm1=TransSets[2].srcFac;\r
+ obm2=TransSets[2].dstFac;\r
+ glBlendFunc(obm1,obm2);                               // set blend func\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// multi pass in old 'Advanced blending' mode... got it from Lewpy :)\r
+////////////////////////////////////////////////////////////////////////                                          \r
+\r
+SemiTransParams MultiTexTransSets[4][2]=\r
+{\r
+ {\r
+ {GL_ONE      ,GL_SRC_ALPHA,          127},\r
+ {GL_SRC_ALPHA,GL_ONE,                127}\r
+ },\r
+ {\r
+ {GL_ONE,      GL_SRC_ALPHA,          255},\r
+ {GL_SRC_ALPHA,GL_ONE,                255}\r
+ },\r
+ {\r
+ {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
+ {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255}\r
+ },\r
+ {\r
+ {GL_SRC_ALPHA,GL_ONE,                127},\r
+ {GL_ONE_MINUS_SRC_ALPHA,GL_ONE,      255}\r
+ }\r
+}; \r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+\r
+SemiTransParams MultiColTransSets[4]=\r
+{\r
+ {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127},\r
+ {GL_ONE,      GL_ONE,                255},\r
+ {GL_ZERO,     GL_ONE_MINUS_SRC_COLOR,255},\r
+ {GL_SRC_ALPHA,GL_ONE,                127}\r
+}; \r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+\r
+void SetSemiTransMulti(int Pass)\r
+{\r
+ static GLenum bm1=GL_ZERO;\r
+ static GLenum bm2=GL_ONE;\r
+\r
+ ubGloAlpha=255;\r
+ ubGloColAlpha=255;\r
\r
+ // are we enabling SemiTransparent mode?\r
+ if(DrawSemiTrans)\r
+  {\r
+   if(bDrawTextured)\r
+    {\r
+     bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac;\r
+     bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac;\r
+     ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha;\r
+    }\r
+   // no texture\r
+   else\r
+    {\r
+     bm1=MultiColTransSets[GlobalTextABR].srcFac;\r
+     bm2=MultiColTransSets[GlobalTextABR].dstFac;\r
+     ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha;\r
+    }\r
+  }\r
+ // no shading\r
+ else\r
+  {\r
+   if(Pass==0)\r
+    {\r
+     // disable blending\r
+     bm1=GL_ONE;bm2=GL_ZERO;\r
+    }\r
+   else\r
+    {\r
+     // disable blending, but add src col a second time\r
+     bm1=GL_ONE;bm2=GL_ONE;\r
+    }\r
+  }\r
+\r
+ if(!bBlendEnable)\r
+  {glEnable(GL_BLEND);bBlendEnable=TRUE;}              // wanna blend\r
+\r
+ if(bm1!=obm1 || bm2!=obm2)\r
+  {\r
+   glBlendFunc(bm1,bm2);                               // set blend func\r
+   obm1=bm1;obm2=bm2;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Set several rendering stuff including blending \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+__inline void SetZMask3O(void)\r
+{\r
+ if(iUseMask && DrawSemiTrans && !iSetMask)\r
+  {\r
+   vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
+   gl_z+=0.00004f;\r
+  }\r
+}\r
+\r
+__inline void SetZMask3(void)\r
+{\r
+ if(iUseMask)\r
+  {\r
+   if(iSetMask || DrawSemiTrans)\r
+    {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}\r
+   else\r
+    {\r
+     vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
+     gl_z+=0.00004f;\r
+    }\r
+  }\r
+}\r
+\r
+__inline void SetZMask3NT(void)\r
+{\r
+ if(iUseMask)\r
+  {\r
+   if(iSetMask)\r
+    {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}\r
+   else\r
+    {\r
+     vertex[0].z=vertex[1].z=vertex[2].z=gl_z;\r
+     gl_z+=0.00004f;\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+__inline void SetZMask4O(void)\r
+{\r
+ if(iUseMask && DrawSemiTrans && !iSetMask)\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
+__inline void SetZMask4(void)\r
+{\r
+ if(iUseMask)\r
+  {\r
+   if(iSetMask || DrawSemiTrans)\r
+    {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
+   else\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
+__inline void SetZMask4NT(void)\r
+{\r
+ if(iUseMask)\r
+  {\r
+   if(iSetMask==1)\r
+    {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
+   else\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
+__inline void SetZMask4SP(void)\r
+{\r
+ if(iUseMask)\r
+  {\r
+   if(iSetMask==1)\r
+    {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
+   else\r
+    {\r
+     if(bCheckMask)\r
+      {\r
+       vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;\r
+       gl_z+=0.00004f;\r
+      }\r
+     else\r
+      {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+__inline void SetRenderState(unsigned long DrawAttributes)\r
+{\r
+ bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE;\r
+ DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;\r
+}                         \r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+\r
+__inline void SetRenderColor(unsigned long DrawAttributes)\r
+{\r
+ if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;}\r
+ else\r
+  {\r
+   g_m1=DrawAttributes&0xff;\r
+   g_m2=(DrawAttributes>>8)&0xff;\r
+   g_m3=(DrawAttributes>>16)&0xff;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+                               \r
+void SetRenderMode(unsigned long DrawAttributes,BOOL bSCol)\r
+{\r
+ if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded))\r
+      {bDrawMultiPass = TRUE; SetSemiTransMulti(0);}\r
+ else {bDrawMultiPass = FALSE;SetSemiTrans();}\r
+\r
+ if(bDrawTextured)                                     // texture ? build it/get it from cache\r
+  {\r
+   GLuint currTex;\r
+   if(bUsingTWin)       currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID);\r
+   else if(bUsingMovie) currTex=LoadTextureMovie();\r
+   else                 currTex=SelectSubTextureS(GlobalTextTP,ulClutID);\r
+\r
+   if(gTexName!=currTex)\r
+    {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);}\r
+\r
+   if(!bTexEnabled)                                    // -> turn texturing on\r
+    {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);}\r
+  }\r
+ else                                                  // no texture ?\r
+ if(bTexEnabled) \r
+  {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);}        // -> turn texturing off\r
+\r
+ if(bSCol)                                             // also set color ?\r
+  {\r
+   if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))\r
+     DrawAttributes|=0x007f7f7f;\r
+\r
+   if(bDrawNonShaded)                                  // -> non shaded?\r
+    {\r
+/*     if(bGLBlend)  vertex[0].c.lcol=0x7f7f7f;          // --> solid color...\r
+     else          */vertex[0].c.lcol=0xffffff;\r
+    }\r
+   else                                                // -> shaded?\r
+    {\r
+//     if(!bUseMultiPass && !bGLBlend)                   // --> given color...\r
+          vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes);\r
+//     else vertex[0].c.lcol=DrawAttributes;\r
+    }\r
+   vertex[0].c.col[3]=ubGloAlpha;                      // -> set color with\r
+   SETCOL(vertex[0]);                                  //    texture alpha\r
+  }\r
\r
+ if(bDrawSmoothShaded!=bOldSmoothShaded)               // shading changed?\r
+  {\r
+   if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH);      // -> set actual shading\r
+   else                  glShadeModel(GL_FLAT);\r
+   bOldSmoothShaded=bDrawSmoothShaded;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Set Opaque multipass color\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void SetOpaqueColor(unsigned long DrawAttributes)\r
+{\r
+ if(bDrawNonShaded) return;                            // no shading? bye\r
+  \r
+ DrawAttributes=DoubleBGR2RGB(DrawAttributes);         // multipass is just half color, so double it on opaque pass\r
+ vertex[0].c.lcol=DrawAttributes|0xff000000;\r
+ SETCOL(vertex[0]);                                    // set color\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////                                          \r
+// Fucking stupid screen coord checking\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL ClipVertexListScreen(void)\r
+{\r
+ if (lx0 >= PSXDisplay.DisplayEnd.x)      goto NEXTSCRTEST;\r
+ if (ly0 >= PSXDisplay.DisplayEnd.y)      goto NEXTSCRTEST;\r
+ if (lx2 <  PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;\r
+ if (ly2 <  PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;\r
+\r
+ return TRUE;\r
+\r
+NEXTSCRTEST:\r
+ if(PSXDisplay.InterlacedTest) return FALSE;\r
+\r
+ if (lx0 >= PreviousPSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if (ly0 >= PreviousPSXDisplay.DisplayEnd.y)      return FALSE;\r
+ if (lx2 <  PreviousPSXDisplay.DisplayPosition.x) return FALSE;\r
+ if (ly2 <  PreviousPSXDisplay.DisplayPosition.y) return FALSE;\r
+\r
+ return TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL bDrawOffscreenFront(void)\r
+{\r
+ if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front\r
+ if(symin < PSXDisplay.DisplayPosition.y) return FALSE;\r
+ if(sxmax > PSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if(symax > PSXDisplay.DisplayEnd.y)      return FALSE;\r
+ return TRUE;\r
+}\r
+\r
+BOOL bOnePointInFront(void)\r
+{\r
+ if(sxmax< PSXDisplay.DisplayPosition.x)\r
+  return FALSE;\r
+\r
+ if(symax< PSXDisplay.DisplayPosition.y)\r
+  return FALSE;\r
+\r
+ if(sxmin>=PSXDisplay.DisplayEnd.x)\r
+  return FALSE;\r
+\r
+ if(symin>=PSXDisplay.DisplayEnd.y)\r
+  return FALSE;\r
+\r
+ return TRUE;\r
+}\r
\r
+\r
+BOOL bOnePointInBack(void)\r
+{\r
+ if(sxmax< PreviousPSXDisplay.DisplayPosition.x)\r
+  return FALSE;\r
+\r
+ if(symax< PreviousPSXDisplay.DisplayPosition.y)\r
+  return FALSE;\r
+\r
+ if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)\r
+  return FALSE;\r
+\r
+ if(symin>=PreviousPSXDisplay.DisplayEnd.y)\r
+  return FALSE;\r
+\r
+ return TRUE;\r
+}\r
\r
+BOOL bDrawOffscreen4(void)\r
+{\r
+ BOOL bFront;short sW,sH;\r
+\r
+ sxmax=max(lx0,max(lx1,max(lx2,lx3)));\r
+ if(sxmax<drawX) return FALSE;\r
+ sxmin=min(lx0,min(lx1,min(lx2,lx3)));\r
+ if(sxmin>drawW) return FALSE;\r
+ symax=max(ly0,max(ly1,max(ly2,ly3)));\r
+ if(symax<drawY) return FALSE;\r
+ symin=min(ly0,min(ly1,min(ly2,ly3)));\r
+ if(symin>drawH) return FALSE;\r
+\r
+ if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
+\r
+ if(iOffscreenDrawing==1) return bFullVRam;\r
+\r
+ if(dwActFixes&1 && iOffscreenDrawing==4)\r
+  {\r
+   if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
+      PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
+      PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
+      PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
+    {\r
+     bRenderFrontBuffer=TRUE;\r
+     return FALSE;\r
+    }\r
+  }\r
+\r
+ sW=drawW-1;sH=drawH-1;\r
\r
+ sxmin=min(sW,max(sxmin,drawX));\r
+ sxmax=max(drawX,min(sxmax,sW));\r
+ symin=min(sH,max(symin,drawY));\r
+ symax=max(drawY,min(symax,sH));\r
+\r
+ if(bOnePointInBack()) return bFullVRam;\r
+\r
+ if(iOffscreenDrawing==2) \r
+      bFront=bDrawOffscreenFront();\r
+ else bFront=bOnePointInFront();\r
+\r
+ if(bFront)\r
+  {\r
+   if(PSXDisplay.InterlacedTest) return bFullVRam;      // -> ok, no need for adjust\r
+                               \r
+   vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+   vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+   vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+   vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+\r
+   if(iOffscreenDrawing==4 && !(dwActFixes&1))         // -> frontbuffer wanted\r
+    {\r
+     bRenderFrontBuffer=TRUE;\r
+     //return TRUE;\r
+    }\r
+   return bFullVRam;                                   // -> but no od\r
+  }\r
+\r
+ return TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
\r
+BOOL bDrawOffscreen3(void)\r
+{\r
+ BOOL bFront;short sW,sH;\r
+\r
+ sxmax=max(lx0,max(lx1,lx2));\r
+ if(sxmax<drawX) return FALSE;\r
+ sxmin=min(lx0,min(lx1,lx2));\r
+ if(sxmin>drawW) return FALSE;\r
+ symax=max(ly0,max(ly1,ly2));\r
+ if(symax<drawY) return FALSE;\r
+ symin=min(ly0,min(ly1,ly2));\r
+ if(symin>drawH) return FALSE;\r
+\r
+ if(PSXDisplay.Disabled) return TRUE;                  // disabled? ever\r
+\r
+ if(iOffscreenDrawing==1) return bFullVRam;\r
+\r
+ sW=drawW-1;sH=drawH-1;\r
+ sxmin=min(sW,max(sxmin,drawX));\r
+ sxmax=max(drawX,min(sxmax,sW));\r
+ symin=min(sH,max(symin,drawY));\r
+ symax=max(drawY,min(symax,sH));\r
+\r
+ if(bOnePointInBack()) return bFullVRam;\r
+\r
+ if(iOffscreenDrawing==2) \r
+      bFront=bDrawOffscreenFront();\r
+ else bFront=bOnePointInFront();\r
+\r
+ if(bFront)\r
+  {\r
+   if(PSXDisplay.InterlacedTest) return bFullVRam;     // -> ok, no need for adjust\r
+\r
+   vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;\r
+   vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+   vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+   vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;\r
+\r
+   if(iOffscreenDrawing==4)                            // -> frontbuffer wanted\r
+    {\r
+     bRenderFrontBuffer=TRUE;\r
+   //  return TRUE;\r
+    }\r
+\r
+   return bFullVRam;                                   // -> but no od\r
+  }\r
+\r
+ return TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
+{\r
+ PSXRect_t xUploadArea;\r
+\r
+ imageX1 += imageX0;\r
+ imageY1 += imageY0;\r
+\r
+ if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
+   xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
+   xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
+ else\r
+   xUploadArea.x0 = imageX0;\r
+\r
+ if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
+   xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
+   xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
+ else\r
+   xUploadArea.x1 = imageX1;\r
+\r
+ if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
+   xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
+   xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
+ else\r
+   xUploadArea.y0 = imageY0;\r
+\r
+ if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
+   xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
+   xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
+ else\r
+   xUploadArea.y1 = imageY1;\r
+\r
+ if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
+      return TRUE;\r
+ else return FALSE;\r
+}\r
+\r
+BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
+{\r
+ imageX1 += imageX0;\r
+ imageY1 += imageY0;\r
+\r
+ if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)\r
+   xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)\r
+   xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;\r
+ else\r
+   xrUploadArea.x0 = imageX0;\r
+\r
+ if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)\r
+   xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)\r
+   xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
+ else\r
+   xrUploadArea.x1 = imageX1;\r
+\r
+ if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)\r
+   xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)\r
+   xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;\r
+ else\r
+   xrUploadArea.y0 = imageY0;\r
+\r
+ if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)\r
+   xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)\r
+   xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
+ else\r
+   xrUploadArea.y1 = imageY1;\r
+\r
+ if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
+      return TRUE;\r
+ else return FALSE;\r
+}\r
+\r
+BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
+{\r
+ PSXRect_t xUploadArea;\r
+\r
+ imageX1 += imageX0;\r
+ imageY1 += imageY0;\r
+\r
+ if (imageX0 < PSXDisplay.DisplayPosition.x)\r
+   xUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX0 > PSXDisplay.DisplayEnd.x)\r
+   xUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
+ else\r
+   xUploadArea.x0 = imageX0;\r
+\r
+ if(imageX1 < PSXDisplay.DisplayPosition.x)\r
+   xUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX1 > PSXDisplay.DisplayEnd.x)\r
+   xUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
+ else\r
+   xUploadArea.x1 = imageX1;\r
+\r
+ if (imageY0 < PSXDisplay.DisplayPosition.y)\r
+   xUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY0 > PSXDisplay.DisplayEnd.y)\r
+   xUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
+ else\r
+   xUploadArea.y0 = imageY0;\r
+\r
+ if (imageY1 < PSXDisplay.DisplayPosition.y)\r
+   xUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY1 > PSXDisplay.DisplayEnd.y)\r
+   xUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
+ else\r
+   xUploadArea.y1 = imageY1;\r
+\r
+ if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))\r
+      return TRUE; \r
+ else return FALSE;\r
+}\r
+\r
+BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)\r
+{\r
+ imageX1 += imageX0;\r
+ imageY1 += imageY0;\r
+\r
+ if (imageX0 < PSXDisplay.DisplayPosition.x)\r
+   xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX0 > PSXDisplay.DisplayEnd.x)\r
+   xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;\r
+ else\r
+   xrUploadArea.x0 = imageX0;\r
+\r
+ if(imageX1 < PSXDisplay.DisplayPosition.x)\r
+   xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;\r
+ else\r
+ if (imageX1 > PSXDisplay.DisplayEnd.x)\r
+   xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
+ else\r
+   xrUploadArea.x1 = imageX1;\r
+\r
+ if (imageY0 < PSXDisplay.DisplayPosition.y)\r
+   xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY0 > PSXDisplay.DisplayEnd.y)\r
+   xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;\r
+ else\r
+   xrUploadArea.y0 = imageY0;\r
+\r
+ if (imageY1 < PSXDisplay.DisplayPosition.y)\r
+   xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;\r
+ else\r
+ if (imageY1 > PSXDisplay.DisplayEnd.y)\r
+   xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
+ else\r
+   xrUploadArea.y1 = imageY1;\r
+\r
+ if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))\r
+      return TRUE; \r
+ else return FALSE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PrepareFullScreenUpload (long Position)\r
+{\r
+ if (Position==-1)                                     // rgb24\r
+  {\r
+   if(PSXDisplay.Interlaced)\r
+    {\r
+     xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
+     xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
+     xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
+     xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
+    }\r
+   else\r
+    {\r
+     xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
+     xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
+     xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
+     xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
+    }\r
+\r
+   if(bNeedRGB24Update)\r
+    {\r
+     if(lClearOnSwap) \r
+      {\r
+//       lClearOnSwap=0;\r
+      }\r
+     else    \r
+     if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)\r
+      {\r
+       PreviousPSXDisplay.RGB24++;\r
+      }\r
+     else\r
+      {\r
+       xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
+       xrUploadArea.y0+=xrUploadAreaRGB24.y0;\r
+      }\r
+    }\r
+  }\r
+ else\r
+ if (Position)\r
+  {\r
+   xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;\r
+   xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;\r
+   xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;\r
+  }\r
+ else\r
+  {\r
+   xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;\r
+   xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;\r
+   xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;\r
+  }\r
+\r
+ if (xrUploadArea.x0 < 0)               xrUploadArea.x0 = 0;\r
+ else\r
+ if (xrUploadArea.x0 > 1023)            xrUploadArea.x0 = 1023;\r
+\r
+ if (xrUploadArea.x1 < 0)               xrUploadArea.x1 = 0;\r
+ else\r
+ if (xrUploadArea.x1 > 1024)            xrUploadArea.x1 = 1024;\r
+\r
+ if (xrUploadArea.y0 < 0)               xrUploadArea.y0 = 0;\r
+ else\r
+ if (xrUploadArea.y0 > iGPUHeightMask)  xrUploadArea.y0 = iGPUHeightMask;\r
+\r
+ if (xrUploadArea.y1 < 0)               xrUploadArea.y1 = 0;\r
+ else\r
+ if (xrUploadArea.y1 > iGPUHeight)      xrUploadArea.y1 = iGPUHeight;\r
+\r
+ if (PSXDisplay.RGB24)\r
+  {\r
+   InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Upload screen (MDEC and such)\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * LoadDirectMovieFast(void);\r
+\r
+void UploadScreenEx(long Position)\r
+{\r
+ short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];\r
+\r
+ if(!PSXDisplay.DisplayMode.x) return;\r
+ if(!PSXDisplay.DisplayMode.y) return;\r
+\r
+ glDisable(GL_SCISSOR_TEST);\r
+ glShadeModel(GL_FLAT);\r
+ bOldSmoothShaded=FALSE;\r
+ glDisable(GL_BLEND);\r
+ bBlendEnable=FALSE;\r
+ glDisable(GL_TEXTURE_2D);\r
+ bTexEnabled=FALSE;\r
+ glDisable(GL_ALPHA_TEST);\r
+\r
+ //glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),\r
+ //            -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));\r
+                                                      \r
+ //----------------------------------------------------//\r
+\r
+ YStep = 256;                                          // max texture size\r
+ XStep = 256;\r
+ UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
+ ya    = xrUploadArea.y0;\r
+ yb    = xrUploadArea.y1;\r
+ xa    = xrUploadArea.x0;\r
+ xb    = xrUploadArea.x1;\r
\r
+ for(y=ya;y<=yb;y+=YStep)                              // loop y\r
+  {\r
+   U = 0;\r
+   for(x=xa;x<=xb;x+=XStep)                            // loop x\r
+    {\r
+     ly0 = ly1 = y;                                    // -> get y coords\r
+     ly2 = y + YStep;\r
+     if (ly2 > yb) ly2 = yb;\r
+     ly3 = ly2;\r
+\r
+     lx0 = lx3 = x;                                    // -> get x coords\r
+     lx1 = x + XStep;\r
+     if (lx1 > xb) lx1 = xb;\r
+\r
+     lx2 = lx1;\r
+\r
+     ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
+     if (ux[0] < 0) ux[0]=ux[3]=0;\r
+     ux[2]=ux[1]=(xb - x);\r
+     if (ux[2] > 256) ux[2]=ux[1]=256;\r
+\r
+     vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
+     if (vy[0] < 0) vy[0]=vy[1]=0;\r
+     vy[2]=vy[3]=(yb - y);\r
+     if (vy[2] > 256) vy[2]=vy[3]=256;\r
+\r
+     if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
+         (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
+                \r
+     xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
+     xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
+     \r
+     offsetScreenUpload(Position);\r
+\r
+     //glRasterPos2f(vertex[0].x,vertex[0].y);\r
+\r
+     //glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,\r
+     //             xrMovieArea.y1-xrMovieArea.y0,\r
+     //             GL_RGBA,GL_UNSIGNED_BYTE,\r
+                  LoadDirectMovieFast();//);\r
+\r
+     U+=UStep;\r
+    }\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+\r
+// glPixelZoom(1.0F,1.0F);\r
+\r
+ glEnable(GL_ALPHA_TEST);\r
+ glEnable(GL_SCISSOR_TEST);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void UploadScreen(long Position)\r
+{\r
+ short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];\r
+ short xa,xb,ya,yb;\r
+\r
+ if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;\r
+ if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;\r
+ if(xrUploadArea.y0>iGPUHeightMask)  xrUploadArea.y0=iGPUHeightMask;\r
+ if(xrUploadArea.y1>iGPUHeight)      xrUploadArea.y1=iGPUHeight;\r
+\r
+ if(xrUploadArea.x0==xrUploadArea.x1) return;\r
+ if(xrUploadArea.y0==xrUploadArea.y1) return;\r
+\r
+ if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;\r
+\r
+ iDrawnSomething   = 2;\r
+ iLastRGB24=PSXDisplay.RGB24+1;\r
+\r
+ if(bSkipNextFrame) return;\r
+\r
+ if(dwActFixes & 2) {UploadScreenEx(Position);return;}\r
+\r
+ bUsingMovie       = TRUE;\r
+ bDrawTextured     = TRUE;                             // just doing textures\r
+ bDrawSmoothShaded = FALSE;\r
+\r
+/* if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f;             // set solid col\r
+ else          */vertex[0].c.lcol=0xffffffff;\r
+ SETCOL(vertex[0]); \r
+\r
+ SetOGLDisplaySettings(0);\r
+\r
+ YStep = 256;                                          // max texture size\r
+ XStep = 256;\r
+\r
+ UStep = (PSXDisplay.RGB24 ? 128 : 0);\r
\r
+ ya=xrUploadArea.y0;\r
+ yb=xrUploadArea.y1;\r
+ xa=xrUploadArea.x0;\r
+ xb=xrUploadArea.x1;\r
+\r
+ for(y=ya;y<=yb;y+=YStep)                              // loop y\r
+  {\r
+   U = 0;\r
+   for(x=xa;x<=xb;x+=XStep)                            // loop x\r
+    {\r
+     ly0 = ly1 = y;                                    // -> get y coords\r
+     ly2 = y + YStep;\r
+     if (ly2 > yb) ly2 = yb;\r
+     ly3 = ly2;\r
+\r
+     lx0 = lx3 = x;                                    // -> get x coords\r
+     lx1 = x + XStep;\r
+     if (lx1 > xb) lx1 = xb;\r
+\r
+     lx2 = lx1;\r
+\r
+     ux[0]=ux[3]=(xa - x);                             // -> set tex x coords\r
+     if (ux[0] < 0) ux[0]=ux[3]=0;\r
+     ux[2]=ux[1]=(xb - x);\r
+     if (ux[2] > 256) ux[2]=ux[1]=256;\r
+\r
+     vy[0]=vy[1]=(ya - y);                             // -> set tex y coords\r
+     if (vy[0] < 0) vy[0]=vy[1]=0;\r
+     vy[2]=vy[3]=(yb - y);\r
+     if (vy[2] > 256) vy[2]=vy[3]=256;\r
+\r
+     if ((ux[0] >= ux[2]) ||                           // -> cheaters never win...\r
+         (vy[0] >= vy[2])) continue;                   //    (but winners always cheat...)\r
+                \r
+     xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;\r
+     xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;\r
+\r
+     s=ux[2] - ux[0]; if(s>255) s=255;\r
+\r
+     gl_ux[2] = gl_ux[1] = s;\r
+     s=vy[2] - vy[0]; if(s>255) s=255;\r
+     gl_vy[2] = gl_vy[3] = s;\r
+     gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;\r
+\r
+     SetRenderState((unsigned long)0x01000000);\r
+     SetRenderMode((unsigned long)0x01000000, FALSE);  // upload texture data\r
+     offsetScreenUpload(Position);\r
+     assignTextureVRAMWrite();\r
+\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+     U+=UStep;\r
+    }\r
+  }\r
+\r
+ bUsingMovie=FALSE;                                    // done...\r
+ bDisplayNotSet = TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Detect next screen\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
+{        \r
+ if (x > PSXDisplay.DisplayPosition.x+1)     return FALSE;\r
+ if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;\r
+ yoff+=y;\r
+ if (y >= PSXDisplay.DisplayPosition.y &&\r
+     y <= PSXDisplay.DisplayEnd.y )\r
+  {\r
+   if ((yoff) >= PSXDisplay.DisplayPosition.y &&\r
+       (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;\r
+  }   \r
+ if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
+ if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
+ return TRUE;\r
+}\r
+\r
+BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)\r
+{\r
+ x+=PSXDisplay.DrawOffset.x;\r
+ if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;\r
+ y+=PSXDisplay.DrawOffset.y;\r
+ if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;\r
+ xoff+=PSXDisplay.DrawOffset.x;\r
+ if (xoff < PSXDisplay.DisplayEnd.x-1)   return FALSE;\r
+ yoff+=PSXDisplay.DrawOffset.y;\r
+ if (yoff < PSXDisplay.DisplayEnd.y-1)   return FALSE;\r
+ return TRUE;\r
+}\r
+\r
+BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)\r
+{                    \r
+ if (x > PSXDisplay.DisplayEnd.x) return FALSE;\r
+ if (y > PSXDisplay.DisplayEnd.y) return FALSE;\r
+ if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;\r
+ if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;\r
+ return TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// mask stuff...\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+//Mask1    Set mask bit while drawing. 1 = on\r
+//Mask2    Do not draw to mask areas. 1= on\r
+\r
+void cmdSTP(u8 * baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+\r
+ STATUSREG&=~0x1800;                                   // clear the necessary bits\r
+ STATUSREG|=((gdata & 0x03) << 11);                    // set the current bits\r
+\r
+ if(!iUseMask) return;\r
+\r
+ if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}\r
+ else        {sSetMask=0;     lSetMask=0;         iSetMask=0;}\r
+\r
+ if(gdata&2) \r
+  {\r
+   if(!(gdata&1)) iSetMask=2;\r
+   bCheckMask=TRUE;\r
+   if(iDepthFunc==0) return;\r
+   iDepthFunc=0;\r
+   glDepthFunc(GL_LESS);\r
+  }\r
+ else\r
+  {\r
+   bCheckMask=FALSE;\r
+   if(iDepthFunc==1) return;\r
+   glDepthFunc(GL_ALWAYS);\r
+   iDepthFunc=1;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: Set texture page infos\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void cmdTexturePage(u8 * baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+ UpdateGlobalTP((unsigned short)gdata);\r
+ GlobalTextREST = (gdata&0x00ffffff)>>9;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: turn on/off texture window\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void cmdTextureWindow(u8 *baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+\r
+ unsigned long YAlign,XAlign;\r
+\r
+ ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;\r
+\r
+ if(gdata & 0x020)\r
+  TWin.Position.y1 = 8;    // xxxx1\r
+ else if (gdata & 0x040)\r
+  TWin.Position.y1 = 16;   // xxx10\r
+ else if (gdata & 0x080)\r
+  TWin.Position.y1 = 32;   // xx100\r
+ else if (gdata & 0x100)\r
+  TWin.Position.y1 = 64;   // x1000\r
+ else if (gdata & 0x200)\r
+  TWin.Position.y1 = 128;  // 10000\r
+ else\r
+  TWin.Position.y1 = 256;  // 00000\r
+\r
+  // Texture window size is determined by the least bit set of the relevant 5 bits\r
+\r
+ if (gdata & 0x001)\r
+  TWin.Position.x1 = 8;    // xxxx1\r
+ else if (gdata & 0x002)\r
+  TWin.Position.x1 = 16;   // xxx10\r
+ else if (gdata & 0x004)\r
+  TWin.Position.x1 = 32;   // xx100\r
+ else if (gdata & 0x008)\r
+  TWin.Position.x1 = 64;   // x1000\r
+ else if (gdata & 0x010)\r
+  TWin.Position.x1 = 128;  // 10000\r
+ else\r
+  TWin.Position.x1 = 256;  // 00000\r
+\r
+ // Re-calculate the bit field, because we can't trust what is passed in the data\r
+\r
+ YAlign = (unsigned long)(32 - (TWin.Position.y1 >> 3));\r
+ XAlign = (unsigned long)(32 - (TWin.Position.x1 >> 3));\r
+\r
+ // Absolute position of the start of the texture window\r
+\r
+ TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);\r
+ TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);\r
+\r
+ if((TWin.Position.x0 == 0 &&                          // tw turned off\r
+     TWin.Position.y0 == 0 &&\r
+     TWin.Position.x1 == 0 &&\r
+     TWin.Position.y1 == 0) ||\r
+     (TWin.Position.x1 == 256 &&\r
+      TWin.Position.y1 == 256))\r
+  {\r
+   bUsingTWin = FALSE;                                 // -> just do it\r
+\r
+#ifdef OWNSCALE\r
+   TWin.UScaleFactor = 1.0f;\r
+   TWin.VScaleFactor = 1.0f;\r
+#else\r
+   TWin.UScaleFactor = \r
+   TWin.VScaleFactor = 1.0f/256.0f;\r
+#endif\r
+  }\r
+ else                                                  // tw turned on\r
+  {\r
+   bUsingTWin = TRUE;\r
+\r
+   TWin.OPosition.y1 = TWin.Position.y1;               // -> get psx sizes\r
+   TWin.OPosition.x1 = TWin.Position.x1;              \r
+\r
+   if(TWin.Position.x1<=2)   TWin.Position.x1=2;       // -> set OGL sizes\r
+   else\r
+   if(TWin.Position.x1<=4)   TWin.Position.x1=4;\r
+   else\r
+   if(TWin.Position.x1<=8)   TWin.Position.x1=8;\r
+   else\r
+   if(TWin.Position.x1<=16)  TWin.Position.x1=16;\r
+   else\r
+   if(TWin.Position.x1<=32)  TWin.Position.x1=32;\r
+   else\r
+   if(TWin.Position.x1<=64)  TWin.Position.x1=64;\r
+   else\r
+   if(TWin.Position.x1<=128) TWin.Position.x1=128;\r
+   else\r
+   if(TWin.Position.x1<=256) TWin.Position.x1=256;\r
+   \r
+   if(TWin.Position.y1<=2)   TWin.Position.y1=2;\r
+   else\r
+   if(TWin.Position.y1<=4)   TWin.Position.y1=4;\r
+   else\r
+   if(TWin.Position.y1<=8)   TWin.Position.y1=8;\r
+   else\r
+   if(TWin.Position.y1<=16)  TWin.Position.y1=16;\r
+   else\r
+   if(TWin.Position.y1<=32)  TWin.Position.y1=32;\r
+   else\r
+   if(TWin.Position.y1<=64)  TWin.Position.y1=64;\r
+   else\r
+   if(TWin.Position.y1<=128) TWin.Position.y1=128;\r
+   else\r
+   if(TWin.Position.y1<=256) TWin.Position.y1=256;\r
+\r
+#ifdef OWNSCALE\r
+   TWin.UScaleFactor = (float)TWin.Position.x1;\r
+   TWin.VScaleFactor = (float)TWin.Position.y1;\r
+#else\r
+   TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor\r
+   TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;\r
+#endif\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// mmm, Lewpy uses that in TileS ... I don't ;)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+/*\r
+void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)\r
+{\r
+ if (*x0 < PSXDisplay.DrawArea.x0)\r
+  {\r
+   *x1 -= (PSXDisplay.DrawArea.x0 - *x0);\r
+   *x0 = PSXDisplay.DrawArea.x0;\r
+  }\r
+ else\r
+ if (*x0 > PSXDisplay.DrawArea.x1)\r
+  {\r
+   *x0 = PSXDisplay.DrawArea.x1;\r
+   *x1 = 0;\r
+  }\r
+\r
+ if (*y0 < PSXDisplay.DrawArea.y0)\r
+  {\r
+   *y1 -= (PSXDisplay.DrawArea.y0 - *y0);\r
+   *y0 = PSXDisplay.DrawArea.y0;\r
+  }\r
+ else\r
+ if (*y0 > PSXDisplay.DrawArea.y1)\r
+  {\r
+   *y0 = PSXDisplay.DrawArea.y1;\r
+   *y1 = 0;\r
+  }\r
+\r
+ if (*x1 < 0) *x1 = 0;\r
+\r
+ if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)\r
+  *x1 = (PSXDisplay.DrawArea.x1 -  *x0 + 1);\r
+\r
+ if (*y1 < 0) *y1 = 0;\r
+\r
+ if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)\r
+  *y1 = (PSXDisplay.DrawArea.y1 -  *y0 + 1);\r
+}\r
+*/\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Check draw area dimensions\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)\r
+{\r
+ if (*x0 < 0)               *x0 = 0;\r
+ else\r
+ if (*x0 > 1023)            *x0 = 1023;\r
+            \r
+ if (*x1 < 0)               *x1 = 0;\r
+ else\r
+ if (*x1 > 1023)            *x1 = 1023;\r
+\r
+ if (*y0 < 0)               *y0 = 0;\r
+ else\r
+ if (*y0 > iGPUHeightMask)  *y0 = iGPUHeightMask;\r
+            \r
+ if (*y1 < 0)               *y1 = 0;\r
+ else\r
+ if (*y1 > iGPUHeightMask)  *y1 = iGPUHeightMask;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Used in Load Image and Blk Fill\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)\r
+{\r
+ if (*x0 < 0)\r
+  { *x1 += *x0;  *x0 = 0; }\r
+ else\r
+ if (*x0 > 1023)\r
+  { *x0 = 1023;  *x1 = 0; }\r
+\r
+ if (*y0 < 0)\r
+  { *y1 += *y0;  *y0 = 0; }\r
+ else\r
+ if (*y0 > iGPUHeightMask)\r
+  { *y0 = iGPUHeightMask;   *y1 = 0; }\r
+\r
+ if (*x1 < 0) *x1 = 0;\r
+\r
+ if ((*x1 + *x0) > 1024) *x1 = (1024 -  *x0);\r
+\r
+ if (*y1 < 0) *y1 = 0;\r
+\r
+ if ((*y1 + *y0) > iGPUHeight)  *y1 = (iGPUHeight -  *y0);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: start of drawing area... primitives will be clipped inside\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void cmdDrawAreaStart(u8 * baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+\r
+ drawX = gdata & 0x3ff;                                // for soft drawing\r
+ if(drawX>=1024) drawX=1023;\r
+\r
+ if(dwGPUVersion==2)\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;\r
+   drawY  = (gdata>>12)&0x3ff;\r
+  }\r
+ else\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;\r
+   drawY  = (gdata>>10)&0x3ff;\r
+  }\r
+\r
+ if(drawY>=iGPUHeight) drawY=iGPUHeightMask;\r
+\r
+ PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;\r
+ PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;\r
+\r
+ PSXDisplay.DrawArea.y0 = (short)drawY;                // for OGL drawing\r
+ PSXDisplay.DrawArea.x0 = (short)drawX;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: end of drawing area... primitives will be clipped inside\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void cmdDrawAreaEnd(u8 * baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+\r
+ drawW = gdata & 0x3ff;                                // for soft drawing\r
+ if(drawW>=1024) drawW=1023;\r
+\r
+ if(dwGPUVersion==2)\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;\r
+   drawH  = (gdata>>12)&0x3ff;\r
+  }\r
+ else\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;\r
+   drawH  = (gdata>>10)&0x3ff;\r
+  }\r
\r
+ if(drawH>=iGPUHeight) drawH=iGPUHeightMask;\r
+\r
+ PSXDisplay.DrawArea.y1 = (short)drawH;                // for OGL drawing\r
+ PSXDisplay.DrawArea.x1 = (short)drawW;\r
+\r
+ ClampToPSXScreen(&PSXDisplay.DrawArea.x0,             // clamp\r
+                  &PSXDisplay.DrawArea.y0,\r
+                  &PSXDisplay.DrawArea.x1,\r
+                  &PSXDisplay.DrawArea.y1);\r
+\r
+ bDisplayNotSet = TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: draw offset... will be added to prim coords\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void cmdDrawOffset(u8 * baseAddr)\r
+{\r
+ unsigned long gdata = ((unsigned long*)baseAddr)[0];\r
+\r
+ PreviousPSXDisplay.DrawOffset.x = \r
+  PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);\r
+\r
+ if(dwGPUVersion==2)\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF;\r
+   PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);\r
+  }\r
+ else\r
+  {\r
+   ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;\r
+   PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);\r
+  }\r
\r
+ PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);\r
+ PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);\r
+\r
+ PSXDisplay.CumulOffset.x =                            // new OGL prim offsets\r
+  PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;\r
+ PSXDisplay.CumulOffset.y = \r
+  PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: load image to vram\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLoadImage(u8 * baseAddr)\r
+{\r
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
+\r
+ VRAMWrite.x      = sgpuData[2]&0x03ff;\r
+ VRAMWrite.y      = sgpuData[3]&iGPUHeightMask;\r
+ VRAMWrite.Width  = sgpuData[4];\r
+ VRAMWrite.Height = sgpuData[5];\r
+\r
+ iDataWriteMode = DR_VRAMTRANSFER;\r
+ VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;\r
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
+ VRAMWrite.ColsRemaining = VRAMWrite.Height;\r
+\r
+ bNeedWriteUpload=TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void PrepareRGB24Upload(void)\r
+{\r
+ VRAMWrite.x=(VRAMWrite.x*2)/3;\r
+ VRAMWrite.Width=(VRAMWrite.Width*2)/3;\r
+\r
+ if(!PSXDisplay.InterlacedTest && // NEW\r
+    CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
+  {\r
+   xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;\r
+   xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;\r
+  }  \r
+ else\r
+ if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))\r
+  {\r
+   xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;\r
+   xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;\r
+   xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;\r
+  }  \r
+ else return;\r
+\r
+ if(bRenderFrontBuffer) \r
+  {\r
+   updateFrontDisplay();\r
+  }\r
+\r
+ if(bNeedRGB24Update==FALSE)\r
+  {\r
+   xrUploadAreaRGB24=xrUploadArea;\r
+   bNeedRGB24Update=TRUE;\r
+  }\r
+ else\r
+  {\r
+   xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);\r
+   xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);\r
+   xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);\r
+   xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CheckWriteUpdate()\r
+{\r
+ int iX=0,iY=0;\r
+\r
+ if(VRAMWrite.Width)   iX=1;\r
+ if(VRAMWrite.Height)  iY=1;\r
+\r
+ InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);\r
+\r
+ if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;\r
+\r
+ if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}\r
+\r
+ if(!PSXDisplay.InterlacedTest &&\r
+    CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
+  {\r
+   if(dwActFixes&0x800) return;\r
+\r
+   if(bRenderFrontBuffer) \r
+    {\r
+     updateFrontDisplay();\r
+    }\r
+\r
+   UploadScreen(FALSE);\r
+\r
+   bNeedUploadTest=TRUE;\r
+  }\r
+ else \r
+ if(iOffscreenDrawing)\r
+  {\r
+   if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) \r
+    {\r
+     if(PSXDisplay.InterlacedTest)\r
+      {\r
+       if(PreviousPSXDisplay.InterlacedNew) \r
+        {\r
+         PreviousPSXDisplay.InterlacedNew=FALSE;\r
+         bNeedInterlaceUpdate=TRUE;\r
+         xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;\r
+         xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;\r
+         xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;\r
+         xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;\r
+         if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;\r
+         if(xrUploadAreaIL.y1>511)  xrUploadAreaIL.y1=511;\r
+        }\r
+\r
+       if(bNeedInterlaceUpdate==FALSE)\r
+        {\r
+         xrUploadAreaIL=xrUploadArea;\r
+         bNeedInterlaceUpdate=TRUE;\r
+        }\r
+       else\r
+        {\r
+         xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);\r
+         xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);\r
+         xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);\r
+         xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);\r
+        }\r
+       return;\r
+      }\r
+\r
+     if(!bNeedUploadAfter)\r
+      {\r
+       bNeedUploadAfter = TRUE;\r
+       xrUploadArea.x0=VRAMWrite.x;\r
+       xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;\r
+       xrUploadArea.y0=VRAMWrite.y;\r
+       xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;\r
+      }\r
+     else\r
+      {\r
+       xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);\r
+       xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);\r
+       xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);\r
+       xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);\r
+      }\r
+\r
+     if(dwActFixes&0x8000)\r
+      {\r
+       if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&\r
+          (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))\r
+        {\r
+         UploadScreen(-1);\r
+         updateFrontDisplay();\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: vram -> psx mem\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primStoreImage(u8 * baseAddr)\r
+{\r
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);\r
+\r
+ VRAMRead.x      = sgpuData[2]&0x03ff;\r
+ VRAMRead.y      = sgpuData[3]&iGPUHeightMask;\r
+ VRAMRead.Width  = sgpuData[4];\r
+ VRAMRead.Height = sgpuData[5];\r
+\r
+ VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;\r
+ VRAMRead.RowsRemaining = VRAMRead.Width;\r
+ VRAMRead.ColsRemaining = VRAMRead.Height;\r
+\r
+ iDataReadMode = DR_VRAMTRANSFER;\r
+\r
+ STATUSREG |= GPUSTATUS_READYFORVRAM;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: blkfill - NO primitive! Doesn't care about draw areas...\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primBlkFill(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ iDrawnSomething=1;\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = sgpuData[4] & 0x3ff;\r
+ sprtH = sgpuData[5] & iGPUHeightMask;\r
+\r
+ sprtW = (sprtW+15) & ~15;\r
+\r
+ // Increase H & W if they are one short of full values, because they never can be full values\r
+ if (sprtH == iGPUHeightMask)  sprtH=iGPUHeight;\r
+ if (sprtW == 1023)            sprtW=1024; \r
+        \r
+ // x and y of start\r
+ ly0 = ly1 = sprtY;\r
+ ly2 = ly3 = (sprtY+sprtH);\r
+ lx0 = lx3 = sprtX;\r
+ lx1 = lx2 = (sprtX+sprtW);\r
+\r
+ offsetBlk();\r
+\r
+ if(ClipVertexListScreen())                           \r
+  {\r
+   PSXDisplay_t * pd;\r
+   if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;\r
+   else                          pd=&PreviousPSXDisplay;\r
+\r
+   if ((lx0 <= pd->DisplayPosition.x+16) &&\r
+       (ly0 <= pd->DisplayPosition.y+16) &&\r
+       (lx2 >= pd->DisplayEnd.x-16) &&\r
+       (ly2 >= pd->DisplayEnd.y-16))\r
+    {\r
+     GLclampf g,b,r;\r
+     g=((GLclampf)GREEN(gpuData[0]))/255.0f;\r
+     b=((GLclampf)BLUE(gpuData[0]))/255.0f;\r
+     r=((GLclampf)RED(gpuData[0]))/255.0f;\r
+     \r
+     glDisable(GL_SCISSOR_TEST);                       \r
+     glClearColor(r,g,b,1.0f);\r
+     glClear(uiBufferBits); \r
+     gl_z=0.0f;\r
+\r
+     if(gpuData[0]!=0x02000000 &&\r
+        (ly0>pd->DisplayPosition.y ||\r
+         ly2<pd->DisplayEnd.y))\r
+      {\r
+       bDrawTextured     = FALSE;\r
+       bDrawSmoothShaded = FALSE;\r
+       SetRenderState((unsigned long)0x01000000);\r
+       SetRenderMode((unsigned long)0x01000000, FALSE);\r
+       vertex[0].c.lcol=0xff000000;\r
+       SETCOL(vertex[0]); \r
+       if(ly0>pd->DisplayPosition.y)\r
+        {\r
+         vertex[0].x=0;vertex[0].y=0;\r
+         vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;\r
+         vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;\r
+         vertex[3].x=0;vertex[3].y=vertex[2].y;\r
+         PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+        }\r
+       if(ly2<pd->DisplayEnd.y)\r
+        {\r
+         vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);\r
+         vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;\r
+         vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;\r
+         vertex[3].x=0;vertex[3].y=vertex[2].y;\r
+         PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+        }\r
+      }\r
+\r
+     glEnable(GL_SCISSOR_TEST);                       \r
+    }\r
+   else\r
+    {\r
+     bDrawTextured     = FALSE;\r
+     bDrawSmoothShaded = FALSE;\r
+     SetRenderState((unsigned long)0x01000000);\r
+     SetRenderMode((unsigned long)0x01000000, FALSE);\r
+     vertex[0].c.lcol=gpuData[0]|0xff000000;\r
+     SETCOL(vertex[0]); \r
+     glDisable(GL_SCISSOR_TEST);                       \r
+     PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+     glEnable(GL_SCISSOR_TEST);                       \r
+    }\r
+  }\r
+\r
+ //mmm... will clean all stuff, also if not all _should_ be cleaned...\r
+ //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
+ // try this:\r
+ if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))\r
+  {\r
+   lClearOnSwapColor = COLOR(gpuData[0]);\r
+   lClearOnSwap = 1;\r
+  }\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);\r
+   if ((sprtW == 0) || (sprtH == 0)) return;\r
+   InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);   \r
+\r
+   sprtW+=sprtX;\r
+   sprtH+=sprtY;\r
+\r
+   FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));\r
+  }*/\r
+}\r
+  \r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: move image vram -> vram\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void MoveImageWrapped(short imageX0,short imageY0,\r
+                      short imageX1,short imageY1,\r
+                      short imageSX,short imageSY)\r
+{\r
+ int i,j,imageXE,imageYE;\r
+\r
+ if(iFrameReadType&2)\r
+  {\r
+   imageXE=imageX0+imageSX;\r
+   imageYE=imageY0+imageSY;\r
+\r
+   if(imageYE>iGPUHeight && imageXE>1024) \r
+    {\r
+     CheckVRamRead(0,0,\r
+                   (imageXE&0x3ff),\r
+                   (imageY0&iGPUHeightMask),\r
+                   FALSE);\r
+    }\r
+\r
+   if(imageXE>1024) \r
+    {\r
+     CheckVRamRead(0,imageY0, \r
+                   (imageXE&0x3ff),\r
+                   (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
+                   FALSE);\r
+    }\r
+\r
+   if(imageYE>iGPUHeight) \r
+    {\r
+     CheckVRamRead(imageX0,0, \r
+                   (imageXE>1024)?1024:imageXE,\r
+                   imageYE&iGPUHeightMask,\r
+                   FALSE);\r
+    }\r
+\r
+   CheckVRamRead(imageX0,imageY0, \r
+                 (imageXE>1024)?1024:imageXE,\r
+                 (imageYE>iGPUHeight)?iGPUHeight:imageYE,\r
+                 FALSE);\r
+  }\r
+\r
+ for(j=0;j<imageSY;j++)\r
+  for(i=0;i<imageSX;i++)\r
+   psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=\r
+    psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];\r
+\r
+ if(!PSXDisplay.RGB24)\r
+  {\r
+   imageXE=imageX1+imageSX;\r
+   imageYE=imageY1+imageSY;\r
+\r
+   if(imageYE>iGPUHeight && imageXE>1024) \r
+    {\r
+     InvalidateTextureArea(0,0,\r
+                           (imageXE&0x3ff)-1,\r
+                           (imageYE&iGPUHeightMask)-1);\r
+    }\r
+\r
+   if(imageXE>1024) \r
+    {\r
+     InvalidateTextureArea(0,imageY1,\r
+                           (imageXE&0x3ff)-1,\r
+                           ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
+    }\r
+\r
+   if(imageYE>iGPUHeight) \r
+    {\r
+     InvalidateTextureArea(imageX1,0,\r
+                           ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
+                           (imageYE&iGPUHeightMask)-1);\r
+    }\r
+\r
+   InvalidateTextureArea(imageX1,imageY1,\r
+                         ((imageXE>1024)?1024:imageXE)-imageX1-1,\r
+                         ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primMoveImage(u8 * baseAddr)\r
+{\r
+ short *sgpuData = ((short *) baseAddr);\r
+ short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;\r
+\r
+ imageX0 = sgpuData[2]&0x03ff;\r
+ imageY0 = sgpuData[3]&iGPUHeightMask;\r
+ imageX1 = sgpuData[4]&0x03ff;\r
+ imageY1 = sgpuData[5]&iGPUHeightMask;\r
+ imageSX = sgpuData[6];\r
+ imageSY = sgpuData[7];\r
+\r
+ if((imageX0 == imageX1) && (imageY0 == imageY1)) return;  \r
+ if(imageSX<=0) return;\r
+ if(imageSY<=0) return;\r
+\r
+ if(iGPUHeight==1024 && sgpuData[7]>1024) return;\r
+\r
+ if((imageY0+imageSY)>iGPUHeight ||\r
+    (imageX0+imageSX)>1024       ||\r
+    (imageY1+imageSY)>iGPUHeight ||\r
+    (imageX1+imageSX)>1024)\r
+  {\r
+   MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);\r
+   if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;\r
+   if((imageX0+imageSX)>1024)       imageSX=1024-imageX0;\r
+   if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;\r
+   if((imageX1+imageSX)>1024)       imageSX=1024-imageX1;\r
+  }\r
+\r
+ if(iFrameReadType&2)\r
+  CheckVRamRead(imageX0,imageY0, \r
+                imageX0+imageSX,\r
+                imageY0+imageSY,\r
+                FALSE);\r
+\r
+ if(imageSX&1)\r
+  {\r
+   unsigned short *SRCPtr, *DSTPtr;\r
+   unsigned short LineOffset;\r
+\r
+   SRCPtr = psxVuw + (1024*imageY0) + imageX0;\r
+   DSTPtr = psxVuw + (1024*imageY1) + imageX1;\r
+\r
+   LineOffset = 1024 - imageSX;\r
+\r
+   for(j=0;j<imageSY;j++)\r
+    {\r
+     for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;\r
+     SRCPtr += LineOffset;\r
+     DSTPtr += LineOffset;\r
+    }\r
+  }\r
+ else\r
+  {\r
+   unsigned long *SRCPtr, *DSTPtr;\r
+   unsigned short LineOffset;\r
+   int dx=imageSX>>1;\r
+\r
+   SRCPtr = (unsigned long *)(psxVuw + (1024*imageY0) + imageX0);\r
+   DSTPtr = (unsigned long *)(psxVuw + (1024*imageY1) + imageX1);\r
+\r
+   LineOffset = 512 - dx;\r
+\r
+   for(j=0;j<imageSY;j++)\r
+    {\r
+     for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;\r
+     SRCPtr += LineOffset;\r
+     DSTPtr += LineOffset;\r
+    }\r
+  }\r
+\r
+ if (!PSXDisplay.RGB24)\r
+  {\r
+   InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);\r
+\r
+   if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY)) \r
+    {\r
+     if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
+        imageX1<PreviousPSXDisplay.DisplayEnd.x &&\r
+        imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
+        imageY1<PreviousPSXDisplay.DisplayEnd.y)\r
+      {\r
+       imageX1 += imageSX;\r
+       imageY1 += imageSY;\r
+\r
+       if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&\r
+          imageX1<=PreviousPSXDisplay.DisplayEnd.x &&\r
+          imageY1>=PreviousPSXDisplay.DisplayPosition.y &&\r
+          imageY1<=PreviousPSXDisplay.DisplayEnd.y)\r
+        {\r
+         if(!(\r
+               imageX0>=PSXDisplay.DisplayPosition.x &&\r
+               imageX0<PSXDisplay.DisplayEnd.x &&\r
+               imageY0>=PSXDisplay.DisplayPosition.y &&\r
+               imageY0<PSXDisplay.DisplayEnd.y \r
+              ))\r
+          {\r
+           if(bRenderFrontBuffer) \r
+            {\r
+             updateFrontDisplay();\r
+            }\r
\r
+           UploadScreen(FALSE);\r
+          }\r
+         else bFakeFrontBuffer=TRUE;\r
+        }\r
+      }\r
+\r
+     bNeedUploadTest=TRUE;\r
+    }\r
+   else\r
+   if(iOffscreenDrawing)\r
+    {\r
+     if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY)) \r
+      {\r
+       if(!PSXDisplay.InterlacedTest &&\r
+//          !bFullVRam &&\r
+          ((\r
+            imageX0>=PreviousPSXDisplay.DisplayPosition.x &&\r
+            imageX0<PreviousPSXDisplay.DisplayEnd.x &&\r
+            imageY0>=PreviousPSXDisplay.DisplayPosition.y &&\r
+            imageY0<PreviousPSXDisplay.DisplayEnd.y\r
+           ) ||\r
+           (\r
+            imageX0>=PSXDisplay.DisplayPosition.x &&\r
+            imageX0<PSXDisplay.DisplayEnd.x &&\r
+            imageY0>=PSXDisplay.DisplayPosition.y &&\r
+            imageY0<PSXDisplay.DisplayEnd.y\r
+           )))\r
+        return;\r
+\r
+       bNeedUploadTest=TRUE;\r
+\r
+       if(!bNeedUploadAfter)\r
+        {\r
+         bNeedUploadAfter = TRUE;\r
+         xrUploadArea.x0=imageX0;\r
+         xrUploadArea.x1=imageX0+imageSX;\r
+         xrUploadArea.y0=imageY0;\r
+         xrUploadArea.y1=imageY0+imageSY;\r
+        }\r
+       else\r
+        {\r
+         xrUploadArea.x0=min(xrUploadArea.x0,imageX0);\r
+         xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);\r
+         xrUploadArea.y0=min(xrUploadArea.y0,imageY0);\r
+         xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: draw free-size Tile \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primTileS(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long*)baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = sgpuData[4] & 0x3ff;\r
+ sprtH = sgpuData[5] & iGPUHeightMask;\r
+\r
+ // x and y of start\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ if((dwActFixes&1) &&                                  // FF7 special game gix (battle cursor)\r
+    sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) \r
+  return;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||\r
+      (ly0==-6 && ly2==10))                            // OH MY GOD... I DIDN'T WANT TO DO IT... BUT I'VE FOUND NO OTHER WAY... HACK FOR GRADIUS SHOOTER :(\r
+    {\r
+     lClearOnSwapColor = COLOR(gpuData[0]);\r
+     lClearOnSwap = 1;\r
+    }\r
+\r
+   offsetPSX4();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games\r
+      {\r
+       InvalidateTextureAreaEx();   \r
+       FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
+                             BGR24to16(gpuData[0]));  \r
+      }\r
+    }\r
+  }*/\r
+\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
\r
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: draw 1 dot Tile (point)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primTile1(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long*)baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = 1;\r
+ sprtH = 1;\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
+                           BGR24to16(gpuData[0]));          \r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
+\r
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: draw 8 dot Tile (small rect)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primTile8(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long*)baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = 8;\r
+ sprtH = 8;\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
+                           BGR24to16(gpuData[0]));    \r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
+\r
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: draw 16 dot Tile (medium rect)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primTile16(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long*)baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = 16;\r
+ sprtH = 16;\r
+ // x and y of start\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,\r
+                           BGR24to16(gpuData[0]));    \r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
+\r
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// helper: filter effect by multipass rendering\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+/*void DrawMultiBlur(void)\r
+{\r
+ long lABR,lDST;float fx,fy;\r
+\r
+ lABR=GlobalTextABR;\r
+ lDST=DrawSemiTrans;\r
+\r
+ fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX); \r
+ fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);\r
+\r
+ vertex[0].x+=fx;vertex[1].x+=fx;\r
+ vertex[2].x+=fx;vertex[3].x+=fx;\r
+\r
+ GlobalTextABR=0;\r
+ DrawSemiTrans=1;\r
+ SetSemiTrans();\r
+\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ vertex[0].y+=fy;vertex[1].y+=fy;\r
+ vertex[2].y+=fy;vertex[3].y+=fy;\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}\r
+\r
+ GlobalTextABR=lABR;\r
+ DrawSemiTrans=lDST;\r
+}\r
+*/\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define   POFF 0.375f\r
+\r
+void DrawMultiFilterSprite(void)\r
+{\r
+ long lABR,lDST;\r
+\r
+ if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw) \r
+  {\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+   return;\r
+  }\r
+\r
+ lABR=GlobalTextABR;\r
+ lDST=DrawSemiTrans;\r
+ vertex[0].c.col[3]=ubGloAlpha/2;                      // -> set color with\r
+ SETCOL(vertex[0]);                                    //    texture alpha\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+ vertex[0].x+=POFF;vertex[1].x+=POFF;\r
+ vertex[2].x+=POFF;vertex[3].x+=POFF;\r
+ vertex[0].y+=POFF;vertex[1].y+=POFF;\r
+ vertex[2].y+=POFF;vertex[3].y+=POFF;\r
+ GlobalTextABR=0;\r
+ DrawSemiTrans=1;\r
+ SetSemiTrans();\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+ GlobalTextABR=lABR;\r
+ DrawSemiTrans=lDST;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: small sprite (textured rect)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primSprt8(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+ short s;\r
+\r
+ iSpriteTex=1;\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = 8;\r
+ sprtH = 8;\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ // do texture stuff\r
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
+\r
+ if(usMirror & 0x1000) \r
+  {\r
+   s=gl_ux[0];\r
+   s-=sprtW-1;\r
+   if(s<0) {s=0;}\r
+   gl_ux[0]=gl_ux[3]=s;\r
+  }\r
+\r
+ sSprite_ux2=s=gl_ux[0]+sprtW; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_ux[1]=gl_ux[2]=s;\r
+ // Y coords\r
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+\r
+ if(usMirror & 0x2000) \r
+  {\r
+   s=gl_vy[0];\r
+   s-=sprtH-1;\r
+   if(s<0) {s=0;}\r
+   gl_vy[0]=gl_vy[1]=s;\r
+  }\r
+\r
+ sSprite_vy2=s=gl_vy[0]+sprtH; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_vy[2]=gl_vy[3]=s;\r
+\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)      \r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     lx0-=PSXDisplay.DrawOffset.x;\r
+     ly0-=PSXDisplay.DrawOffset.y;\r
+\r
+     if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);\r
+     else\r
+     if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,8,8);\r
+     else\r
+     DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+ SetZMask4SP();\r
+\r
+ sSprite_ux2=gl_ux[0]+sprtW;\r
+ sSprite_vy2=gl_vy[0]+sprtH;\r
+\r
+ assignTextureSprite();\r
+\r
+ if(iFilterType>4) \r
+  DrawMultiFilterSprite();\r
+ else\r
+  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+\r
+/*   if(bSmallAlpha && iFilterType<=2)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     SetZMask4O();\r
+    }\r
+*/\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iSpriteTex=0;\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: medium sprite (textured rect)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primSprt16(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+ short s;\r
+\r
+ iSpriteTex=1;\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = 16;\r
+ sprtH = 16;\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ // do texture stuff\r
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
+\r
+ if(usMirror & 0x1000) \r
+  {\r
+   s=gl_ux[0];\r
+   s-=sprtW-1;\r
+   if(s<0) {s=0;}\r
+   gl_ux[0]=gl_ux[3]=s;\r
+  }\r
+\r
+ sSprite_ux2=s=gl_ux[0]+sprtW; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_ux[1]=gl_ux[2]=s; \r
+ // Y coords\r
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+\r
+ if(usMirror & 0x2000) \r
+  {\r
+   s=gl_vy[0];\r
+   s-=sprtH-1;\r
+   if(s<0) {s=0;}\r
+   gl_vy[0]=gl_vy[1]=s;\r
+  }\r
+\r
+ sSprite_vy2=s=gl_vy[0]+sprtH; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_vy[2]=gl_vy[3]=s;\r
+\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)  \r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     lx0-=PSXDisplay.DrawOffset.x;\r
+     ly0-=PSXDisplay.DrawOffset.y;\r
+     if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);\r
+     else\r
+     if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,16,16);\r
+     else\r
+     DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+ SetZMask4SP();\r
+\r
+ sSprite_ux2=gl_ux[0]+sprtW;\r
+ sSprite_vy2=gl_vy[0]+sprtH;\r
+\r
+ assignTextureSprite();\r
+\r
+ if(iFilterType>4) \r
+  DrawMultiFilterSprite();\r
+ else\r
+  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+\r
+/*   if(bSmallAlpha && iFilterType<=2)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     SetZMask4O();\r
+    }\r
+*/\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iSpriteTex=0;\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: free-size sprite (textured rect)\r
+////////////////////////////////////////////////////////////////////////\r
\r
+void primSprtSRest(u8 * baseAddr,unsigned short type)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+ short s;unsigned short sTypeRest=0;\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = sgpuData[6] & 0x3ff;\r
+ sprtH = sgpuData[7] & 0x1ff;\r
+\r
+\r
+ // do texture stuff\r
+ switch(type)\r
+  {\r
+   case 1:\r
+    gl_vy[0]=gl_vy[1]=baseAddr[9];\r
+    s=256-baseAddr[8];\r
+    sprtW-=s;\r
+    sprtX+=s;\r
+    gl_ux[0]=gl_ux[3]=0;\r
+    break;\r
+   case 2:\r
+    gl_ux[0]=gl_ux[3]=baseAddr[8];\r
+    s=256-baseAddr[9];\r
+    sprtH-=s;\r
+    sprtY+=s;\r
+    gl_vy[0]=gl_vy[1]=0;\r
+    break;\r
+   case 3:\r
+    s=256-baseAddr[8];\r
+    sprtW-=s;\r
+    sprtX+=s;\r
+    gl_ux[0]=gl_ux[3]=0;\r
+    s=256-baseAddr[9];\r
+    sprtH-=s;\r
+    sprtY+=s;\r
+    gl_vy[0]=gl_vy[1]=0;\r
+    break;\r
+\r
+   case 4:\r
+    gl_vy[0]=gl_vy[1]=baseAddr[9];\r
+    s=512-baseAddr[8];\r
+    sprtW-=s;\r
+    sprtX+=s;\r
+    gl_ux[0]=gl_ux[3]=0;\r
+    break;\r
+   case 5:\r
+    gl_ux[0]=gl_ux[3]=baseAddr[8];\r
+    s=512-baseAddr[9];\r
+    sprtH-=s;\r
+    sprtY+=s;\r
+    gl_vy[0]=gl_vy[1]=0;\r
+    break;\r
+   case 6:\r
+    s=512-baseAddr[8];\r
+    sprtW-=s;\r
+    sprtX+=s;\r
+    gl_ux[0]=gl_ux[3]=0;\r
+    s=512-baseAddr[9];\r
+    sprtH-=s;\r
+    sprtY+=s;\r
+    gl_vy[0]=gl_vy[1]=0;\r
+    break;\r
+\r
+  }\r
+\r
+ if(usMirror & 0x1000) \r
+  {\r
+   s=gl_ux[0];\r
+   s-=sprtW-1;if(s<0) s=0;\r
+   gl_ux[0]=gl_ux[3]=s;\r
+  }\r
+ if(usMirror & 0x2000) \r
+  {\r
+   s=gl_vy[0];\r
+   s-=sprtH-1;if(s<0) {s=0;}\r
+   gl_vy[0]=gl_vy[1]=s;\r
+  }\r
+\r
+ sSprite_ux2=s=gl_ux[0]+sprtW; \r
+ if(s>255) s=255;\r
+ gl_ux[1]=gl_ux[2]=s;\r
+ sSprite_vy2=s=gl_vy[0]+sprtH; \r
+ if(s>255) s=255;\r
+ gl_vy[2]=gl_vy[3]=s;\r
+\r
+ if(!bUsingTWin)\r
+  {\r
+   if(sSprite_ux2>256) \r
+    {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}\r
+   if(sSprite_vy2>256) \r
+    {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}\r
+  }\r
\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     lx0-=PSXDisplay.DrawOffset.x;\r
+     ly0-=PSXDisplay.DrawOffset.y;\r
+     if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);\r
+     else\r
+     if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);\r
+     else\r
+     DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+ SetZMask4SP();\r
+\r
+ sSprite_ux2=gl_ux[0]+sprtW;\r
+ sSprite_vy2=gl_vy[0]+sprtH;\r
+\r
+ assignTextureSprite();\r
+\r
+ if(iFilterType>4) \r
+  DrawMultiFilterSprite();\r
+ else\r
+  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+\r
+/*   if(bSmallAlpha && iFilterType<=2)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     SetZMask4O();\r
+    }\r
+*/\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ if(sTypeRest && type<4) \r
+  {\r
+   if(sTypeRest&1  && type==1) primSprtSRest(baseAddr,4);\r
+   if(sTypeRest&2  && type==2) primSprtSRest(baseAddr,5);\r
+   if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);\r
+  }\r
+}\r
+\r
+void primSprtS(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ short s;unsigned short sTypeRest=0;\r
+\r
+ sprtX = sgpuData[2];\r
+ sprtY = sgpuData[3];\r
+ sprtW = sgpuData[6] & 0x3ff;\r
+ sprtH = sgpuData[7] & 0x1ff;\r
+\r
+ if(!sprtH) return;\r
+ if(!sprtW) return;\r
+\r
+ iSpriteTex=1;\r
+\r
+ // do texture stuff\r
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+\r
+ if(usMirror & 0x1000) \r
+  {\r
+   s=gl_ux[0];\r
+   s-=sprtW-1;\r
+   if(s<0) {s=0;}\r
+   gl_ux[0]=gl_ux[3]=s;\r
+  }\r
+ if(usMirror & 0x2000) \r
+  {\r
+   s=gl_vy[0];\r
+   s-=sprtH-1;\r
+   if(s<0) {s=0;}\r
+   gl_vy[0]=gl_vy[1]=s;\r
+  }\r
+\r
+ sSprite_ux2=s=gl_ux[0]+sprtW; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_ux[1]=gl_ux[2]=s;\r
+ sSprite_vy2=s=gl_vy[0]+sprtH; \r
+ if(s)     s--;\r
+ if(s>255) s=255;\r
+ gl_vy[2]=gl_vy[3]=s;\r
+\r
+ if(!bUsingTWin)\r
+  {\r
+   if(sSprite_ux2>256) \r
+    {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}\r
+   if(sSprite_vy2>256) \r
+    {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}\r
+  }\r
+\r
+ lx0 = sprtX;\r
+ ly0 = sprtY;\r
+\r
+ offsetST();\r
+\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     lx0-=PSXDisplay.DrawOffset.x;\r
+     ly0-=PSXDisplay.DrawOffset.y;\r
+     if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);\r
+     else\r
+     if(usMirror)   DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);\r
+     else\r
+     DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+ SetZMask4SP();\r
+\r
+ if((dwActFixes&1) && gTexFrameName && gTexName==gTexFrameName) \r
+  {iSpriteTex=0;return;}\r
+\r
+ sSprite_ux2=gl_ux[0]+sprtW;\r
+ sSprite_vy2=gl_vy[0]+sprtH;\r
+\r
+ assignTextureSprite();\r
+\r
+ if(iFilterType>4) \r
+  DrawMultiFilterSprite();\r
+ else\r
+  PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+\r
+/*   if(bSmallAlpha && iFilterType<=2)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     SetZMask4O();\r
+    }\r
+*/\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ if(sTypeRest) \r
+  {\r
+   if(sTypeRest&1)  primSprtSRest(baseAddr,1);\r
+   if(sTypeRest&2)  primSprtSRest(baseAddr,2);\r
+   if(sTypeRest==3) primSprtSRest(baseAddr,3);\r
+  }\r
+\r
+ iSpriteTex=0;\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: flat shaded Poly4\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyF4(u8 *baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[4];\r
+ ly1 = sgpuData[5];\r
+ lx2 = sgpuData[6];\r
+ ly2 = sgpuData[7];\r
+ lx3 = sgpuData[8];\r
+ ly3 = sgpuData[9];\r
+\r
+ if(offset4()) return;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly4F(gpuData[0]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
+\r
+ PRIMdrawTri2(&vertex[0], &vertex[1], &vertex[2],&vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: smooth shaded Poly4\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyG4(u8 * baseAddr);\r
+\r
+BOOL bDrawOffscreenFrontFF9G4(void)\r
+{\r
+ if(lx0< PSXDisplay.DisplayPosition.x) return FALSE;   // must be complete in front\r
+ if(lx0> PSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if(ly0< PSXDisplay.DisplayPosition.y) return FALSE;\r
+ if(ly0> PSXDisplay.DisplayEnd.y)      return FALSE;\r
+ if(lx1< PSXDisplay.DisplayPosition.x) return FALSE;\r
+ if(lx1> PSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if(ly1< PSXDisplay.DisplayPosition.y) return FALSE;\r
+ if(ly1> PSXDisplay.DisplayEnd.y)      return FALSE;\r
+ if(lx2< PSXDisplay.DisplayPosition.x) return FALSE;\r
+ if(lx2> PSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if(ly2< PSXDisplay.DisplayPosition.y) return FALSE;\r
+ if(ly2> PSXDisplay.DisplayEnd.y)      return FALSE;\r
+ if(lx3< PSXDisplay.DisplayPosition.x) return FALSE;\r
+ if(lx3> PSXDisplay.DisplayEnd.x)      return FALSE;\r
+ if(ly3< PSXDisplay.DisplayPosition.y) return FALSE;\r
+ if(ly3> PSXDisplay.DisplayEnd.y)      return FALSE;\r
+ return TRUE;\r
+}\r
+\r
+BOOL bCheckFF9G4(u8 * baseAddr)\r
+{\r
+ static u8 pFF9G4Cache[32];\r
+ static int iFF9Fix=0;\r
+\r
+ if(baseAddr)\r
+  {\r
+   if(iFF9Fix==0)\r
+    {\r
+     if(bDrawOffscreenFrontFF9G4())\r
+      {\r
+       short *sgpuData = ((short *) pFF9G4Cache);\r
+       iFF9Fix=2;\r
+       memcpy(pFF9G4Cache,baseAddr,32);\r
+\r
+       if(sgpuData[2]==142)\r
+        {\r
+         sgpuData[2] +=65;\r
+         sgpuData[10]+=65;\r
+        }\r
+       return TRUE;\r
+      }\r
+     else iFF9Fix=1;\r
+    }\r
+   return FALSE;\r
+  }\r
+\r
+ if(iFF9Fix==2)\r
+  {\r
+   long labr=GlobalTextABR;\r
+   GlobalTextABR=1;\r
+   primPolyG4(pFF9G4Cache);\r
+   GlobalTextABR=labr;\r
+  }\r
+ iFF9Fix=0;\r
+\r
+ return FALSE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyG4(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = (unsigned long *)baseAddr;\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[6];\r
+ ly1 = sgpuData[7];\r
+ lx2 = sgpuData[10];\r
+ ly2 = sgpuData[11];\r
+ lx3 = sgpuData[14];\r
+ ly3 = sgpuData[15];\r
+\r
+ if(offset4()) return;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = TRUE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+\r
+   if((dwActFixes&512) && bCheckFF9G4(baseAddr)) return;\r
+\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly4G(gpuData[0], gpuData[2], gpuData[4], gpuData[6]);\r
+    }     \r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[1].c.lcol=gpuData[2];\r
+ vertex[2].c.lcol=gpuData[4];\r
+ vertex[3].c.lcol=gpuData[6];\r
+\r
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;\r
+\r
+\r
+ PRIMdrawGouraudTri2Color(&vertex[0],&vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: flat shaded Texture3\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL DoLineCheck(unsigned long * gpuData)\r
+{\r
+ BOOL bQuad=FALSE;short dx,dy;\r
+\r
+ if(lx0==lx1)\r
+  {\r
+   dx=lx0-lx2;if(dx<0) dx=-dx;\r
+\r
+   if(ly1==ly2) \r
+    {\r
+     dy=ly1-ly0;if(dy<0) dy=-dy;\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[2]=vertex[0];\r
+       vertex[2].x=vertex[3].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[2].y=vertex[0].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+   else\r
+   if(ly0==ly2) \r
+    {\r
+     dy=ly0-ly1;if(dy<0) dy=-dy;\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[3].x=vertex[2].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[3].y=vertex[1].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+  }\r
+\r
+ if(lx0==lx2)\r
+  {\r
+   dx=lx0-lx1;if(dx<0) dx=-dx;\r
+\r
+   if(ly2==ly1) \r
+    {\r
+     dy=ly2-ly0;if(dy<0) dy=-dy;\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[1]=vertex[0];\r
+       vertex[1].x=vertex[3].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[1].y=vertex[0].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+   else\r
+   if(ly0==ly1)\r
+    {\r
+     dy=ly2-ly0;if(dy<0) dy=-dy;\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[3].x=vertex[1].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[3].y=vertex[2].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+  }\r
+\r
+ if(lx1==lx2)\r
+  {\r
+   dx=lx1-lx0;if(dx<0) dx=-dx;\r
+\r
+   if(ly1==ly0)\r
+    {\r
+     dy=ly1-ly2;if(dy<0) dy=-dy;\r
+\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[2].x=vertex[0].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[2];\r
+       vertex[2]=vertex[0];\r
+       vertex[2].y=vertex[3].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+   else\r
+   if(ly2==ly0)\r
+    {\r
+     dy=ly2-ly1;if(dy<0) dy=-dy;\r
+\r
+     if(dx<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[1].x=vertex[0].x;\r
+      }\r
+     else\r
+     if(dy<=1)\r
+      {\r
+       vertex[3]=vertex[1];\r
+       vertex[1]=vertex[0];\r
+       vertex[1].y=vertex[3].y;\r
+      }\r
+     else return FALSE;\r
+\r
+     bQuad=TRUE;\r
+    }\r
+  }\r
+\r
+ if(!bQuad) return FALSE;\r
+\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+\r
+ return TRUE;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyFT3(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[6];\r
+ ly1 = sgpuData[7];\r
+ lx2 = sgpuData[10];\r
+ ly2 = sgpuData[11];\r
+\r
+ if(offset3()) return;\r
+    \r
+ // do texture UV coordinates stuff\r
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
+ gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+ gl_ux[1]=baseAddr[16];//gpuData[4]&0xff;\r
+ gl_vy[1]=baseAddr[17];//(gpuData[4]>>8)&0xff;\r
+ gl_ux[2]=baseAddr[24];//gpuData[6]&0xff;\r
+ gl_vy[2]=baseAddr[25];//(gpuData[6]>>8)&0xff;\r
+\r
+ UpdateGlobalTP((unsigned short)(gpuData[4]>>16));\r
+ ulClutID=gpuData[2]>>16;\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX3();\r
+   if(bDrawOffscreen3())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     drawPoly3FT(baseAddr);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+ SetZMask3();\r
+\r
+ assignTexture3();\r
+\r
+ if(!(dwActFixes&0x10))\r
+  {\r
+   if(DoLineCheck(gpuData)) return;\r
+  }\r
+\r
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask3O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+   PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: flat shaded Texture4\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define ST_FAC             255.99f\r
+\r
+void RectTexAlign(void)\r
+{\r
+ int UFlipped = FALSE;\r
+ int VFlipped = FALSE;\r
+\r
+ if(gTexName==gTexFrameName) return;\r
+\r
+ if(ly0==ly1)\r
+  {\r
+   if(!((lx1==lx3 && ly3==ly2 && lx2==lx0) ||\r
+        (lx1==lx2 && ly2==ly3 && lx3==lx0)))\r
+    return;\r
+\r
+   if(ly0<ly2) \r
+    {\r
+     if (vertex[0].tow > vertex[2].tow)\r
+      VFlipped = 1;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].tow < vertex[2].tow)\r
+      VFlipped = 2;\r
+    }\r
+  }\r
+ else\r
+ if(ly0==ly2)\r
+  {\r
+   if(!((lx2==lx3 && ly3==ly1 && lx1==lx0) ||\r
+        (lx2==lx1 && ly1==ly3 && lx3==lx0)))\r
+    return;\r
+\r
+   if(ly0<ly1) \r
+    {\r
+     if (vertex[0].tow > vertex[1].tow)\r
+      VFlipped = 3;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].tow < vertex[1].tow)\r
+      VFlipped = 4;\r
+    }\r
+  }\r
+ else\r
+ if(ly0==ly3)\r
+  {\r
+   if(!((lx3==lx2 && ly2==ly1 && lx1==lx0) ||\r
+        (lx3==lx1 && ly1==ly2 && lx2==lx0)))\r
+    return;\r
+\r
+   if(ly0<ly1) \r
+    {\r
+     if (vertex[0].tow > vertex[1].tow)\r
+      VFlipped = 5;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].tow < vertex[1].tow)\r
+      VFlipped = 6;\r
+    }\r
+  }\r
+ else return;\r
+\r
+ if(lx0==lx1)\r
+  {\r
+   if(lx0<lx2) \r
+    {\r
+     if (vertex[0].sow > vertex[2].sow)\r
+      UFlipped = 1;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].sow < vertex[2].sow)\r
+      UFlipped = 2;\r
+    }\r
+  }\r
+ else\r
+ if(lx0==lx2)\r
+  {\r
+   if(lx0<lx1) \r
+    {\r
+     if (vertex[0].sow > vertex[1].sow)\r
+      UFlipped = 3;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].sow < vertex[1].sow)\r
+      UFlipped = 4;\r
+    }\r
+  }\r
+ else\r
+ if(lx0==lx3)\r
+  {\r
+   if(lx0<lx1) \r
+    {\r
+     if (vertex[0].sow > vertex[1].sow)\r
+      UFlipped = 5;\r
+    }\r
+   else\r
+    {\r
+     if (vertex[0].sow < vertex[1].sow)\r
+      UFlipped = 6;\r
+    }\r
+  }\r
+\r
+ if (UFlipped)\r
+  {\r
+#ifdef OWNSCALE\r
+   if(bUsingTWin)\r
+    {\r
+     switch(UFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+       case 2:\r
+        vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[1].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+       case 3:\r
+        vertex[1].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+       case 4:\r
+        vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[2].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+       case 5:\r
+        vertex[1].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[2].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+       case 6:\r
+        vertex[0].sow+=0.95f/TWin.UScaleFactor; \r
+        vertex[3].sow+=0.95f/TWin.UScaleFactor;\r
+        break;\r
+      }\r
+    }\r
+   else\r
+    {\r
+     switch(UFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].sow+=1.0f/ST_FAC; \r
+        vertex[3].sow+=1.0f/ST_FAC;\r
+        break;\r
+       case 2:\r
+        vertex[0].sow+=1.0f/ST_FAC; \r
+        vertex[1].sow+=1.0f/ST_FAC;\r
+        break;\r
+       case 3:\r
+        vertex[1].sow+=1.0f/ST_FAC; \r
+        vertex[3].sow+=1.0f/ST_FAC;\r
+        break;\r
+       case 4:\r
+        vertex[0].sow+=1.0f/ST_FAC; \r
+        vertex[2].sow+=1.0f/ST_FAC;\r
+        break;\r
+       case 5:\r
+        vertex[1].sow+=1.0f/ST_FAC; \r
+        vertex[2].sow+=1.0f/ST_FAC;\r
+        break;\r
+       case 6:\r
+        vertex[0].sow+=1.0f/ST_FAC; \r
+        vertex[3].sow+=1.0f/ST_FAC;\r
+        break;\r
+      }\r
+    }\r
+#else\r
+   if(bUsingTWin)\r
+    {\r
+     switch(UFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+       case 2:\r
+        vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[1].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+       case 3:\r
+        vertex[1].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+       case 4:\r
+        vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[2].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+       case 5:\r
+        vertex[1].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[2].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+       case 6:\r
+        vertex[0].sow+=1.0f/TWin.UScaleFactor; \r
+        vertex[3].sow+=1.0f/TWin.UScaleFactor;\r
+        break;\r
+      }\r
+    }\r
+   else\r
+    {\r
+     switch(UFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].sow+=1.0f; \r
+        vertex[3].sow+=1.0f;\r
+        break;\r
+       case 2:\r
+        vertex[0].sow+=1.0f; \r
+        vertex[1].sow+=1.0f;\r
+        break;\r
+       case 3:\r
+        vertex[1].sow+=1.0f; \r
+        vertex[3].sow+=1.0f;\r
+        break;\r
+       case 4:\r
+        vertex[0].sow+=1.0f; \r
+        vertex[2].sow+=1.0f;\r
+        break;\r
+       case 5:\r
+        vertex[1].sow+=1.0f; \r
+        vertex[2].sow+=1.0f;\r
+        break;\r
+       case 6:\r
+        vertex[0].sow+=1.0f; \r
+        vertex[3].sow+=1.0f;\r
+        break;\r
+      }\r
+    }\r
+#endif\r
+  }\r
+\r
+ if (VFlipped)\r
+  {\r
+#ifdef OWNSCALE\r
+   if(bUsingTWin)\r
+    {\r
+     switch(VFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+       case 2:\r
+        vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[1].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+       case 3:\r
+        vertex[1].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+       case 4:\r
+        vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[2].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+       case 5:\r
+        vertex[1].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[2].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+       case 6:\r
+        vertex[0].tow+=0.95f/TWin.VScaleFactor; \r
+        vertex[3].tow+=0.95f/TWin.VScaleFactor;\r
+        break;\r
+      }\r
+    }\r
+   else\r
+    {\r
+     switch(VFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].tow+=1.0f/ST_FAC; \r
+        vertex[3].tow+=1.0f/ST_FAC;\r
+        break;\r
+       case 2:\r
+        vertex[0].tow+=1.0f/ST_FAC; \r
+        vertex[1].tow+=1.0f/ST_FAC;\r
+        break;\r
+       case 3:\r
+        vertex[1].tow+=1.0f/ST_FAC;\r
+        vertex[3].tow+=1.0f/ST_FAC;\r
+        break;\r
+       case 4:\r
+        vertex[0].tow+=1.0f/ST_FAC; \r
+        vertex[2].tow+=1.0f/ST_FAC;\r
+        break;\r
+       case 5:\r
+        vertex[1].tow+=1.0f/ST_FAC;\r
+        vertex[2].tow+=1.0f/ST_FAC;\r
+        break;\r
+       case 6:\r
+        vertex[0].tow+=1.0f/ST_FAC;\r
+        vertex[3].tow+=1.0f/ST_FAC;\r
+        break;\r
+      }\r
+    }\r
+#else\r
+   if(bUsingTWin)\r
+    {\r
+     switch(VFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+       case 2:\r
+        vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[1].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+       case 3:\r
+        vertex[1].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+       case 4:\r
+        vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[2].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+       case 5:\r
+        vertex[1].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[2].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+       case 6:\r
+        vertex[0].tow+=1.0f/TWin.VScaleFactor; \r
+        vertex[3].tow+=1.0f/TWin.VScaleFactor;\r
+        break;\r
+      }\r
+    }\r
+   else\r
+    {\r
+     switch(VFlipped)\r
+      {\r
+       case 1:\r
+        vertex[2].tow+=1.0f; \r
+        vertex[3].tow+=1.0f;\r
+        break;\r
+       case 2:\r
+        vertex[0].tow+=1.0f; \r
+        vertex[1].tow+=1.0f;\r
+        break;\r
+       case 3:\r
+        vertex[1].tow+=1.0f; \r
+        vertex[3].tow+=1.0f;\r
+        break;\r
+       case 4:\r
+        vertex[0].tow+=1.0f; \r
+        vertex[2].tow+=1.0f;\r
+        break;\r
+       case 5:\r
+        vertex[1].tow+=1.0f; \r
+        vertex[2].tow+=1.0f;\r
+        break;\r
+       case 6:\r
+        vertex[0].tow+=1.0f; \r
+        vertex[3].tow+=1.0f;\r
+        break;\r
+      }\r
+    }\r
+#endif\r
+  }\r
+\r
+}\r
+\r
+void primPolyFT4(u8 * baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[6];\r
+ ly1 = sgpuData[7];\r
+ lx2 = sgpuData[10];\r
+ ly2 = sgpuData[11];\r
+ lx3 = sgpuData[14];\r
+ ly3 = sgpuData[15];\r
+\r
+ if(offset4()) return;\r
+\r
+ gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff);\r
+ gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff);\r
+ gl_vy[2]=baseAddr[25];//((gpuData[6]>>8)&0xff);\r
+ gl_vy[3]=baseAddr[33];//((gpuData[8]>>8)&0xff);\r
\r
+ gl_ux[0]=baseAddr[8];//(gpuData[2]&0xff);\r
+ gl_ux[1]=baseAddr[16];//(gpuData[4]&0xff);\r
+ gl_ux[2]=baseAddr[24];//(gpuData[6]&0xff);\r
+ gl_ux[3]=baseAddr[32];//(gpuData[8]&0xff);\r
+\r
+ UpdateGlobalTP((unsigned short)(gpuData[4]>>16));\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     SetRenderColor(gpuData[0]);\r
+     drawPoly4FT(baseAddr);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], TRUE);\r
+\r
+ SetZMask4();\r
+\r
+ assignTexture4();\r
+\r
+ RectTexAlign();\r
+\r
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) SetOpaqueColor(gpuData[0]);\r
+   DEFOPAQUEON\r
+\r
+/*   if(bSmallAlpha && iFilterType<=2)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+     SetZMask4O();\r
+    }\r
+*/\r
+   \r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: smooth shaded Texture3\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyGT3(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[8];\r
+ ly1 = sgpuData[9];\r
+ lx2 = sgpuData[14];\r
+ ly2 = sgpuData[15];\r
+\r
+ if(offset3()) return;\r
+\r
+ // do texture stuff\r
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;\r
+ gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+ gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;\r
+ gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;\r
+ gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;\r
+ gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;\r
+\r
+ UpdateGlobalTP((unsigned short)(gpuData[5]>>16));\r
+ ulClutID=(gpuData[2]>>16);\r
+           \r
+ bDrawTextured = TRUE;\r
+ bDrawSmoothShaded = TRUE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX3();\r
+   if(bDrawOffscreen3())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly3GT(baseAddr);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask3();\r
+\r
+ assignTexture3();\r
+\r
+ if(bDrawNonShaded)\r
+  {\r
+   //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];\r
+   // eat this...\r
+/*   if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;\r
+   else         */vertex[0].c.lcol=0xffffff;\r
+   vertex[0].c.col[3]=ubGloAlpha;\r
+   SETCOL(vertex[0]); \r
+\r
+   PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);\r
+\r
+   if(ubOpaqueDraw)\r
+    {\r
+     SetZMask3O();\r
+     DEFOPAQUEON\r
+     PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);\r
+     DEFOPAQUEOFF\r
+    }\r
+   return; \r
+  }\r
+\r
+/* if(!bUseMultiPass  && !bGLBlend)\r
+  {\r
+  */ vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); \r
+   vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); \r
+   vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);\r
+  /*}\r
+ else\r
+  {\r
+   vertex[0].c.lcol=gpuData[0];\r
+   vertex[1].c.lcol=gpuData[3];\r
+   vertex[2].c.lcol=gpuData[6];\r
+  }*/\r
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;\r
+\r
+ PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);\r
+\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask3O();\r
+   if(bUseMultiPass) \r
+    {\r
+     vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);\r
+     vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);\r
+     vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);\r
+     vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;\r
+    }\r
+   DEFOPAQUEON\r
+   PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: smooth shaded Poly3\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyG3(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[6];\r
+ ly1 = sgpuData[7];\r
+ lx2 = sgpuData[10];\r
+ ly2 = sgpuData[11];\r
+\r
+ if(offset3()) return;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = TRUE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing) \r
+  {\r
+   offsetPSX3();\r
+   if(bDrawOffscreen3())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly3G(gpuData[0], gpuData[2], gpuData[4]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask3NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[1].c.lcol=gpuData[2];\r
+ vertex[2].c.lcol=gpuData[4];\r
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloColAlpha; \r
+\r
+ PRIMdrawGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: smooth shaded Texture4\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyGT4(u8 *baseAddr)\r
+{ \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[8];\r
+ ly1 = sgpuData[9];\r
+ lx2 = sgpuData[14];\r
+ ly2 = sgpuData[15];\r
+ lx3 = sgpuData[20];\r
+ ly3 = sgpuData[21];\r
+\r
+ if(offset4()) return;\r
+\r
+ // do texture stuff\r
+ gl_ux[0]=baseAddr[8];//gpuData[2]&0xff;\r
+ gl_vy[0]=baseAddr[9];//(gpuData[2]>>8)&0xff;\r
+ gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;\r
+ gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;\r
+ gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;\r
+ gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;\r
+ gl_ux[3]=baseAddr[44];//gpuData[11]&0xff;\r
+ gl_vy[3]=baseAddr[45];//(gpuData[11]>>8)&0xff;\r
+\r
+ UpdateGlobalTP((unsigned short)(gpuData[5]>>16));\r
+ ulClutID=(gpuData[2]>>16);\r
+\r
+ bDrawTextured     = TRUE;\r
+ bDrawSmoothShaded = TRUE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX4();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly4GT(baseAddr);\r
+    }     \r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4();\r
+\r
+ assignTexture4();\r
+\r
+ RectTexAlign();\r
+\r
+ if(bDrawNonShaded)\r
+  {\r
+   //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];\r
+/*   if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;\r
+   else          */vertex[0].c.lcol=0xffffff;\r
+   vertex[0].c.col[3]=ubGloAlpha;\r
+   SETCOL(vertex[0]); \r
+\r
+   PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+  \r
+   if(ubOpaqueDraw)\r
+    {\r
+     SetZMask4O();\r
+     ubGloAlpha=ubGloColAlpha=0xff;   \r
+     DEFOPAQUEON\r
+     PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);\r
+     DEFOPAQUEOFF\r
+    }\r
+   return;\r
+  }\r
+\r
+// if(!bUseMultiPass  && !bGLBlend) \r
+  {\r
+   vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);\r
+   vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);\r
+   vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);\r
+   vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);\r
+  }\r
+ /*else\r
+  {\r
+   vertex[0].c.lcol=gpuData[0];\r
+   vertex[1].c.lcol=gpuData[3];\r
+   vertex[2].c.lcol=gpuData[6];\r
+   vertex[3].c.lcol=gpuData[9];\r
+  }*/\r
+\r
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; \r
+\r
+ PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);\r
\r
+ if(bDrawMultiPass)\r
+  {\r
+   SetSemiTransMulti(1);\r
+   PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);\r
+  }\r
+\r
+ if(ubOpaqueDraw)\r
+  {\r
+   SetZMask4O();\r
+   if(bUseMultiPass) \r
+    {\r
+     vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);\r
+     vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);\r
+     vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);\r
+     vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);\r
+     vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; \r
+    }\r
+   ubGloAlpha=ubGloColAlpha=0xff;   \r
+   DEFOPAQUEON\r
+   PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);\r
+   DEFOPAQUEOFF\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: smooth shaded Poly3\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primPolyF3(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[4];\r
+ ly1 = sgpuData[5];\r
+ lx2 = sgpuData[6];\r
+ ly2 = sgpuData[7];\r
+\r
+ if(offset3()) return;\r
+\r
+ bDrawTextured     = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSX3();\r
+   if(bDrawOffscreen3())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly3F(gpuData[0]);\r
+    }\r
+  }\r
+*/\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask3NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha;\r
+ SETCOL(vertex[0]); \r
+\r
+ PRIMdrawTri(&vertex[0], &vertex[1], &vertex[2]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: skipping shaded polylines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineGSkip(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+ int iMax=255;\r
+ int i=2;\r
+\r
+ lx1 = sgpuData[2];\r
+ ly1 = sgpuData[3];\r
+\r
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))\r
+  {\r
+   i++;\r
+\r
+   ly1 = (short)((gpuData[i]>>16) & 0xffff);\r
+   lx1 = (short)(gpuData[i] & 0xffff);\r
+\r
+   i++;if(i>iMax) break;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: shaded polylines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineGEx(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ int iMax=255;\r
+ short cx0,cx1,cy0,cy1;int i;BOOL bDraw=TRUE;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = TRUE;\r
+ SetRenderState(gpuData[0]);\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; \r
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);\r
+ lx1 = (short)(gpuData[1] & 0xffff);\r
+\r
+ i=2;\r
+\r
+ //while((gpuData[i]>>24)!=0x55)\r
+ //while((gpuData[i]&0x50000000)!=0x50000000) \r
+ // currently best way to check for poly line end:\r
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))\r
+  {\r
+   ly0 = ly1;lx0=lx1;\r
+   vertex[1].c.lcol=vertex[2].c.lcol=vertex[0].c.lcol;\r
+   vertex[0].c.lcol=vertex[3].c.lcol=gpuData[i];\r
+   vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; \r
+\r
+   i++;\r
+\r
+   ly1 = (short)((gpuData[i]>>16) & 0xffff);\r
+   lx1 = (short)(gpuData[i] & 0xffff);\r
+\r
+   if(offsetline()) bDraw=FALSE; else bDraw=TRUE;\r
+  \r
+   if (bDraw && ((lx0 != lx1) || (ly0 != ly1)))\r
+    {\r
+/*     if(iOffscreenDrawing)\r
+      {\r
+       cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;\r
+       offsetPSXLine();\r
+       if(bDrawOffscreen4())\r
+        {\r
+         InvalidateTextureAreaEx();   \r
+         drawPoly4G(gpuData[i-3],gpuData[i-1],gpuData[i-3],gpuData[i-1]);\r
+        }\r
+       lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;\r
+      }*/\r
+\r
+     PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+    }\r
+   i++;  \r
+\r
+   if(i>iMax) break;\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: shaded polyline2\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineG2(u8 *baseAddr)\r
+{    \r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[6];\r
+ ly1 = sgpuData[7];\r
+\r
+ vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];\r
+ vertex[1].c.lcol=vertex[2].c.lcol=gpuData[2];\r
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; \r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = TRUE;\r
+\r
+ if((lx0 == lx1) && (ly0 == ly1)) return;\r
+    \r
+ if(offsetline()) return;\r
+    \r
+ SetRenderState(gpuData[0]);\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSXLine();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly4G(gpuData[0],gpuData[2],gpuData[0],gpuData[2]);\r
+    }\r
+  }\r
+*/\r
+ //if(ClipVertexList4())\r
+ PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: skipping flat polylines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineFSkip(u8 *baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ int i=2,iMax=255;\r
+\r
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);\r
+ lx1 = (short)(gpuData[1] & 0xffff);\r
+\r
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))\r
+  {\r
+   ly1 = (short)((gpuData[i]>>16) & 0xffff);\r
+   lx1 = (short)(gpuData[i] & 0xffff);\r
+   i++;if(i>iMax) break;\r
+  }             \r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: drawing flat polylines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineFEx(u8 *baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ int iMax;\r
+ short cx0,cx1,cy0,cy1;int i;\r
+\r
+ iMax=255;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha; \r
+\r
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);\r
+ lx1 = (short)(gpuData[1] & 0xffff);\r
+\r
+ i=2;\r
+\r
+// while(!(gpuData[i]&0x40000000)) \r
+// while((gpuData[i]>>24)!=0x55)\r
+// while((gpuData[i]&0x50000000)!=0x50000000) \r
+// currently best way to check for poly line end:\r
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))\r
+  {\r
+   ly0 = ly1;lx0=lx1;\r
+   ly1 = (short)((gpuData[i]>>16) & 0xffff);\r
+   lx1 = (short)(gpuData[i] & 0xffff);\r
+\r
+   if(!offsetline())\r
+    {\r
+/*     if(iOffscreenDrawing)\r
+      {\r
+       cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;\r
+       offsetPSXLine();\r
+       if(bDrawOffscreen4())\r
+        {\r
+         InvalidateTextureAreaEx();   \r
+         drawPoly4F(gpuData[0]);\r
+        }\r
+       lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;\r
+      }*/\r
+     PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+    }\r
+                  \r
+   i++;if(i>iMax) break;\r
+  }\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: drawing flat polyline2\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primLineF2(u8 *baseAddr)\r
+{\r
+ unsigned long *gpuData = ((unsigned long *) baseAddr);\r
+ short *sgpuData = ((short *) baseAddr);\r
+\r
+ lx0 = sgpuData[2];\r
+ ly0 = sgpuData[3];\r
+ lx1 = sgpuData[4];\r
+ ly1 = sgpuData[5];\r
+\r
+ if(offsetline()) return;\r
+\r
+ bDrawTextured = FALSE;\r
+ bDrawSmoothShaded = FALSE;\r
+ SetRenderState(gpuData[0]);\r
+ SetRenderMode(gpuData[0], FALSE);\r
+ SetZMask4NT();\r
+\r
+ vertex[0].c.lcol=gpuData[0];\r
+ vertex[0].c.col[3]=ubGloColAlpha; \r
+\r
+/* if(iOffscreenDrawing)\r
+  {\r
+   offsetPSXLine();\r
+   if(bDrawOffscreen4())\r
+    {\r
+     InvalidateTextureAreaEx();   \r
+     drawPoly4F(gpuData[0]);\r
+    }\r
+  }\r
+*/\r
+ //if(ClipVertexList4()) \r
+ PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);\r
+\r
+ iDrawnSomething=1;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd: well, easiest command... not implemented\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void primNI(u8 *bA)\r
+{\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd func ptr table\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void (*primTableJ[256])(u8 *) = \r
+{\r
+    // 00\r
+    primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,\r
+    // 08\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 10\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 18\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 20\r
+    primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,\r
+    // 28\r
+    primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,\r
+    // 30\r
+    primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,\r
+    // 38\r
+    primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,\r
+    // 40\r
+    primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,\r
+    // 48\r
+    primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,\r
+    // 50\r
+    primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,\r
+    // 58\r
+    primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,\r
+    // 60\r
+    primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,\r
+    // 68\r
+    primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,\r
+    // 70\r
+    primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,\r
+    // 78\r
+    primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,\r
+    // 80\r
+    primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 88\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 90\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 98\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // a0\r
+    primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // a8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // b0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // b8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // c0\r
+    primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // c8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // d0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // d8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // e0\r
+    primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,\r
+    // e8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // f0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // f8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI\r
+};\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// cmd func ptr table for skipping\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void (*primTableSkip[256])(u8 *) = \r
+{\r
+    // 00\r
+    primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,\r
+    // 08\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 10\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 18\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 20\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 28\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 30\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 38\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 40\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 48\r
+    primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,\r
+    // 50\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 58\r
+    primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,\r
+    // 60\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 68\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 70\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 78\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 80\r
+    primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 88\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 90\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // 98\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // a0\r
+    primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // a8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // b0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // b8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // c0\r
+    primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // c8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // d0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // d8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // e0\r
+    primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,\r
+    // e8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // f0\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,\r
+    // f8\r
+    primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI\r
+};\r
diff --git a/plugins/gpu-gles/gpuPrim.h b/plugins/gpu-gles/gpuPrim.h
new file mode 100644 (file)
index 0000000..58d3311
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************\r
+                          prim.h  -  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
+#ifndef _PRIMDRAW_H_\r
+#define _PRIMDRAW_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "gpuExternals.h"\r
+#include "gpuStdafx.h"\r
+\r
+#ifndef _WINDOWS\r
+extern EGLSurface surface;\r
+extern EGLDisplay display;\r
+#endif\r
+\r
+void UploadScreen (long Position);\r
+void PrepareFullScreenUpload (long Position);\r
+BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1);\r
+BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1);\r
+BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1);\r
+BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1);\r
+BOOL bCheckFF9G4(u8 * baseAddr);\r
+void SetScanTrans(void);\r
+void SetScanTexTrans(void);\r
+void DrawMultiBlur(void);\r
+void CheckWriteUpdate();\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // _PRIMDRAW_H_\r
diff --git a/plugins/gpu-gles/gpuStdafx.h b/plugins/gpu-gles/gpuStdafx.h
new file mode 100644 (file)
index 0000000..fc7ee3d
--- /dev/null
@@ -0,0 +1,99 @@
+/***************************************************************************\r
+                          stdafx.h  -  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
+#ifndef __GPU_STDAFX__\r
+#define __GPU_STDAFX__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+       \r
+       \r
+       \r
+       // maybe we should remove this? \r
+#ifdef _WINDOWS\r
+\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include <WINDOWS.H>\r
+#include <WINDOWSX.H>\r
+#include <Ts8.H>\r
+#include "resource.h"\r
+\r
+#pragma warning (disable:4244)\r
+\r
+#include <gl/gl.h>\r
+\r
+#else\r
+/*\r
+#define __X11_C_\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <sys/time.h>\r
+#ifdef __NANOGL__\r
+#include <gl/gl.h>\r
+#else\r
+#ifdef SOFT_LINKAGE\r
+#pragma softfp_linkage\r
+#endif\r
+#ifdef MAEMO_CHANGES\r
+       #include <GLES/glplatform.h>\r
+       #include <GLES/gl.h>\r
+       #include <GLES/glext.h>\r
+       #include <EGL/egl.h>\r
+#else\r
+       #include <gles/gl.h> // for opengl es types \r
+       #include <gles/egltypes.h>\r
+#endif\r
+#ifdef SOFT_LINKAGE\r
+#pragma no_softfp_linkage\r
+#endif\r
+#endif\r
+#include <math.h> \r
+\r
+#define __inline inline\r
+\r
+#endif\r
+\r
+#define SHADETEXBIT(x) ((x>>24) & 0x1)\r
+#define SEMITRANSBIT(x) ((x>>25) & 0x1)\r
+\r
+#ifndef _WINDOWS\r
+#ifndef GL_BGRA_EXT\r
+#define GL_BGRA_EXT GL_RGBA\r
+#endif\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/plugins/gpu-gles/gpuTexture.c b/plugins/gpu-gles/gpuTexture.c
new file mode 100644 (file)
index 0000000..d047a62
--- /dev/null
@@ -0,0 +1,4226 @@
+/***************************************************************************\r
+                          texture.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
+////////////////////////////////////////////////////////////////////////////////////\r
+// Texture related functions are here !\r
+//\r
+// The texture handling is heart and soul of this gpu. The plugin was developed\r
+// 1999, by this time no shaders were available. Since the psx gpu is making\r
+// heavy use of CLUT (="color lookup tables", aka palettized textures), it was \r
+// an interesting task to get those emulated at good speed on NV TNT cards \r
+// (which was my major goal when I created the first "gpuPeteTNT"). Later cards \r
+// (Geforce256) supported texture palettes by an OGL extension, but at some point\r
+// this support was dropped again by gfx card vendors.\r
+// Well, at least there is a certain advatage, if no texture palettes extension can\r
+// be used: it is possible to modify the textures in any way, allowing "hi-res" \r
+// textures and other tweaks.\r
+//\r
+// My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures,\r
+// and it places small psx texture parts inside them. The plugin keeps track what \r
+// part (with what palette) it had placed in which texture, so it can re-use this \r
+// part again. The more ogl textures it can use, the better (of course the managing/\r
+// searching will be slower, but everything is faster than uploading textures again\r
+// and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked\r
+// well with many games, but I recommend nowadays 64 MB Vram to get a good speed.\r
+//\r
+// Sadly, there is also a second kind of texture cache needed, for "psx texture windows".\r
+// Those are "repeated" textures, so a psx "texture window" needs to be put in \r
+// a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very\r
+// fast in games which are having an heavy "texture window" usage, like RRT4. As an \r
+// alternative, this plugin can use the OGL "palette" extension on texture windows, \r
+// if available. Nowadays also a fragment shader can easily be used to emulate\r
+// texture wrapping in a texture atlas, so the main cache could hold the texture\r
+// windows as well (that's what I am doing in the OGL2 plugin). But currently the\r
+// OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause\r
+// much texture uploads.\r
+//\r
+// Some final advice: take care if you change things in here. I've removed my ASM\r
+// handlers (they didn't cause much speed gain anyway) for readability/portability,\r
+// but still the functions/data structures used here are easy to mess up. I guess it\r
+// can be a pain in the ass to port the plugin to another byte order :)\r
+//\r
+////////////////////////////////////////////////////////////////////////////////////\r
\r
+#define _IN_TEXTURE\r
+\r
+#ifdef _WINDOWS\r
+#include "stdafx.h"\r
+\r
+#include "externals.h"\r
+#include "texture.h"\r
+#include "gpu.h"\r
+#include "prim.h"\r
+#else\r
+#include "gpuStdafx.h"\r
+#ifdef __NANOGL__\r
+#include <gl/gl.h>\r
+#include <gl/gl.h>\r
+#else\r
+#ifdef SOFT_LINKAGE\r
+#pragma softfp_linkage\r
+#endif\r
+#ifdef MAEMO_CHANGES\r
+       #include <GLES/glplatform.h>\r
+       #include <GLES/gl.h>\r
+       #include <GLES/glext.h>\r
+       #include <EGL/egl.h>\r
+#else\r
+       #include <gles/gl.h> // for opengl es types \r
+       #include <gles/egltypes.h>\r
+#endif\r
+#ifdef SOFT_LINKAGE\r
+#pragma no_softfp_linkage\r
+#endif\r
+#endif\r
+#include "gpuDraw.h"\r
+//#include "plugins.h"\r
+#include "gpuExternals.h"\r
+#include "gpuTexture.h"\r
+#include "gpuPlugin.h"\r
+#include "gpuPrim.h"\r
+#endif\r
+#define CLUTCHK   0x00060000\r
+#define CLUTSHIFT 17\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// texture conversion buffer .. \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLubyte       ubPaletteBuffer[256][4];\r
+GLuint        gTexMovieName=0;\r
+GLuint        gTexBlurName=0;\r
+GLuint        gTexFrameName=0;\r
+int           iTexGarbageCollection=1;\r
+unsigned long dwTexPageComp=0;\r
+int           iVRamSize=0;\r
+#ifdef _WINDOWS\r
+int           iClampType=GL_CLAMP;\r
+#else\r
+int           iClampType=GL_CLAMP_TO_EDGE;\r
+#endif\r
+int iFilter = GL_LINEAR;\r
+void               (*LoadSubTexFn) (int,int,short,short);\r
+unsigned long      (*PalTexturedColourFn)  (unsigned long);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// defines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define PALCOL(x) PalTexturedColourFn (x)\r
+\r
+#define CSUBSIZE  2048\r
+#define CSUBSIZEA 8192\r
+#define CSUBSIZES 4096\r
+\r
+#define OFFA 0\r
+#define OFFB 2048\r
+#define OFFC 4096\r
+#define OFFD 6144\r
+\r
+#define XOFFA 0\r
+#define XOFFB 512\r
+#define XOFFC 1024\r
+#define XOFFD 1536\r
+\r
+#define SOFFA 0\r
+#define SOFFB 1024\r
+#define SOFFC 2048\r
+#define SOFFD 3072\r
+\r
+#define MAXWNDTEXCACHE 128\r
+\r
+#define XCHECK(pos1,pos2) ((pos1.c[0]>=pos2.c[1])&&(pos1.c[1]<=pos2.c[0])&&(pos1.c[2]>=pos2.c[3])&&(pos1.c[3]<=pos2.c[2]))\r
+#define INCHECK(pos2,pos1) ((pos1.c[0]<=pos2.c[0]) && (pos1.c[1]>=pos2.c[1]) && (pos1.c[2]<=pos2.c[2]) && (pos1.c[3]>=pos2.c[3]))\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache);\r
+void            LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+void            LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+void            DefineSubTextureSort(void);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// some globals\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+long  GlobalTexturePage;\r
+GLint XTexS;\r
+GLint YTexS;\r
+GLint DXTexS;\r
+GLint DYTexS;\r
+int   iSortTexCnt=32;\r
+BOOL  bUseFastMdec=FALSE;\r
+BOOL  bUse15bitMdec=FALSE;\r
+int   iFrameTexType=0;\r
+int   iFrameReadType=0;\r
+\r
+unsigned long  (*TCF[2]) (unsigned long);\r
+unsigned short (*PTCF[2]) (unsigned short);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// texture cache implementation\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+#pragma pack(1)\r
+#endif\r
+\r
+// "texture window" cache entry\r
+\r
+typedef struct textureWndCacheEntryTag\r
+{\r
+ unsigned long  ClutID;\r
+ short          pageid;\r
+ short          textureMode;\r
+ short          Opaque;\r
+ short          used;\r
+ EXLong         pos;\r
+ GLuint         texname;\r
+} textureWndCacheEntry;\r
+\r
+// "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them)\r
+\r
+typedef struct textureSubCacheEntryTagS \r
+{\r
+ unsigned long   ClutID;\r
+ EXLong          pos;\r
+ u8   posTX;\r
+ u8   posTY;\r
+ u8   cTexID;\r
+ u8   Opaque;\r
+} textureSubCacheEntryS;\r
+\r
+#ifdef _WINDOWS\r
+#pragma pack()\r
+#endif\r
+\r
+//---------------------------------------------\r
+\r
+#define MAXTPAGES_MAX  64\r
+#define MAXSORTTEX_MAX 196\r
+\r
+//---------------------------------------------\r
+\r
+textureWndCacheEntry     wcWndtexStore[MAXWNDTEXCACHE];\r
+textureSubCacheEntryS *  pscSubtexStore[3][MAXTPAGES_MAX];\r
+EXLong *                 pxSsubtexLeft [MAXSORTTEX_MAX];\r
+GLuint                   uiStexturePage[MAXSORTTEX_MAX];\r
+\r
+unsigned short           usLRUTexPage=0;\r
+\r
+int                      iMaxTexWnds=0;\r
+int                      iTexWndTurn=0;\r
+int                      iTexWndLimit=MAXWNDTEXCACHE/2;\r
+\r
+GLubyte *                texturepart=NULL;\r
+GLubyte *                texturebuffer=NULL;\r
+unsigned long            g_x1,g_y1,g_x2,g_y2;\r
+u8            ubOpaqueDraw=0;\r
+\r
+unsigned short MAXTPAGES     = 32;\r
+unsigned short CLUTMASK      = 0x7fff;\r
+unsigned short CLUTYMASK     = 0x1ff;\r
+unsigned short MAXSORTTEX    = 196;\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Texture color conversions... all my ASM funcs are removed for easier\r
+// porting... and honestly: nowadays the speed gain would be pointless \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+unsigned long XP8RGBA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long CP8RGBA(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xffffff00) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8RGBAEx(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xffffff00) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long XP8RGBA_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRA_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRAEx_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long CP8RGBA_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xfff8f800) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8RGBAEx_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xfff8f800) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8BGRA_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xff00f8f8) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8BGRAEx_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xff00f8f8) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long XP8RGBA_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRA_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRAEx_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long P8RGBA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long P8BGRA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned short XP5RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short XP5RGBA_0 (unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short CP5RGBA_0 (unsigned short BGR)\r
+{\r
+ unsigned short s;\r
+\r
+ if(!BGR) return 0;\r
+\r
+ s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+ if(s==0x07ff) s=1;\r
+ return s;\r
+}\r
+\r
+unsigned short XP5RGBA_1(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ if(!(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short P5RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short XP4RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short XP4RGBA_0 (unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short CP4RGBA_0 (unsigned short BGR)\r
+{\r
+ unsigned short s;\r
+ if(!BGR) return 6;\r
+ s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+ if(s==0x0fff) s=0x000f;\r
+ return s;\r
+}\r
+\r
+unsigned short XP4RGBA_1(unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ if(!(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short P4RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// CHECK TEXTURE MEM (on plugin startup)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+int iFTexA=512;\r
+int iFTexB=512;\r
+\r
+void CheckTextureMemory(void)\r
+{\r
+ GLboolean b;GLboolean * bDetail;\r
+ int i,iCnt,iRam=iVRamSize*1024*1024;\r
+ int iTSize;s8 * p;\r
+\r
+\r
+ if(iVRamSize)\r
+  {\r
+   int ts;\r
+\r
+   iRam-=(iResX*iResY*8);\r
+   iRam-=(iResX*iResY*(iZBufferDepth/8));\r
+\r
+          ts=4;\r
+          iSortTexCnt=iRam/(256*256*ts);\r
+\r
+   if(iSortTexCnt>MAXSORTTEX) \r
+    {\r
+     iSortTexCnt=MAXSORTTEX-min(1,0);\r
+    }\r
+   else\r
+    {\r
+     iSortTexCnt-=3+min(1,0);\r
+     if(iSortTexCnt<8) iSortTexCnt=8;\r
+    }\r
+\r
+   for(i=0;i<MAXSORTTEX;i++)\r
+    uiStexturePage[i]=0;\r
\r
+   return;\r
+  }\r
+\r
+\r
+        iTSize=256;\r
+ p=(s8 *)malloc(iTSize*iTSize*4);\r
+\r
+ iCnt=0;\r
+ glGenTextures(MAXSORTTEX,uiStexturePage);\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iTSize, iTSize, 0,GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+  }\r
+ glBindTexture(GL_TEXTURE_2D,0);\r
+\r
+ free(p);\r
+\r
+ bDetail=(GLboolean*)malloc(MAXSORTTEX*sizeof(GLboolean));\r
+ memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean));\r
+\r
+ glDeleteTextures(MAXSORTTEX,uiStexturePage);\r
+\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   if(bDetail[i]) iCnt++;\r
+   uiStexturePage[i]=0;\r
+  }\r
+\r
+ free(bDetail);\r
+\r
+ if(b) iSortTexCnt=MAXSORTTEX-min(1,0);\r
+ else  iSortTexCnt=iCnt-3+min(1,0);       // place for menu&texwnd\r
+\r
+ if(iSortTexCnt<8) iSortTexCnt=8;\r
+} \r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Main init of textures\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InitializeTextureStore() \r
+{\r
+ int i,j;\r
+\r
+ if(iGPUHeight==1024)\r
+  {\r
+   MAXTPAGES     = 64;\r
+   CLUTMASK      = 0xffff;\r
+   CLUTYMASK     = 0x3ff;\r
+   MAXSORTTEX    = 128;\r
+   iTexGarbageCollection=0;\r
+  }\r
+ else\r
+  {\r
+   MAXTPAGES     = 32;\r
+   CLUTMASK      = 0x7fff;\r
+   CLUTYMASK     = 0x1ff;\r
+   MAXSORTTEX    = 196;\r
+  }\r
+\r
+ memset(vertex,0,4*sizeof(OGLVertex));                 // init vertices\r
+\r
+ gTexName=0;                                           // init main tex name\r
+\r
+ iTexWndLimit=MAXWNDTEXCACHE;\r
+/* if(!iUsePalTextures) */iTexWndLimit/=2;\r
+\r
+ memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)*\r
+                        MAXWNDTEXCACHE);\r
+ texturepart=(GLubyte *)malloc(256*256*4);\r
+ memset(texturepart,0,256*256*4);\r
+        texturebuffer=NULL;\r
+\r
+ for(i=0;i<3;i++)                                    // -> info for 32*3\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   {                                               \r
+    pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS));\r
+    memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS));\r
+   }\r
+ for(i=0;i<MAXSORTTEX;i++)                           // -> info 0..511\r
+  {\r
+   pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong));\r
+   memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong));\r
+   uiStexturePage[i]=0;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Clean up on exit\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CleanupTextureStore() \r
+{\r
+ int i,j;textureWndCacheEntry * tsx;\r
+ //----------------------------------------------------//\r
+ glBindTexture(GL_TEXTURE_2D,0);\r
+ //----------------------------------------------------//\r
+ free(texturepart);                                    // free tex part\r
+ texturepart=0;\r
+ if(texturebuffer)\r
+  {\r
+   free(texturebuffer);\r
+   texturebuffer=0;\r
+  }\r
+ //----------------------------------------------------//\r
+ tsx=wcWndtexStore;                                    // loop tex window cache\r
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
+  {\r
+   if(tsx->texname)                                    // -> some tex?\r
+    glDeleteTextures(1,&tsx->texname);                 // --> delete it\r
+  }\r
+ iMaxTexWnds=0;                                        // no more tex wnds\r
+ //----------------------------------------------------//\r
+ if(gTexMovieName!=0)                                  // some movie tex?\r
+  glDeleteTextures(1, &gTexMovieName);                 // -> delete it\r
+ gTexMovieName=0;                                      // no more movie tex\r
+ //----------------------------------------------------//\r
+ if(gTexFrameName!=0)                                  // some 15bit framebuffer tex?\r
+  glDeleteTextures(1, &gTexFrameName);                 // -> delete it\r
+ gTexFrameName=0;                                      // no more movie tex\r
+ //----------------------------------------------------//\r
+ if(gTexBlurName!=0)                                   // some 15bit framebuffer tex?\r
+  glDeleteTextures(1, &gTexBlurName);                  // -> delete it\r
+ gTexBlurName=0;                                       // no more movie tex\r
+ //----------------------------------------------------//\r
+ for(i=0;i<3;i++)                                    // -> loop\r
+  for(j=0;j<MAXTPAGES;j++)                           // loop tex pages\r
+   {\r
+    free(pscSubtexStore[i][j]);                      // -> clean mem\r
+   }\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   if(uiStexturePage[i])                             // --> tex used ?\r
+    {\r
+     glDeleteTextures(1,&uiStexturePage[i]);\r
+     uiStexturePage[i]=0;                            // --> delete it\r
+    }\r
+   free(pxSsubtexLeft[i]);                           // -> clean mem\r
+  }\r
+ //----------------------------------------------------//\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Reset textures in game...\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ResetTextureArea(BOOL bDelTex)\r
+{\r
+ int i,j;textureSubCacheEntryS * tss;EXLong * lu;\r
+ textureWndCacheEntry * tsx;\r
+ //----------------------------------------------------//\r
+\r
+ dwTexPageComp=0;\r
+\r
+ //----------------------------------------------------//\r
+ if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;}\r
+ //----------------------------------------------------//\r
+ tsx=wcWndtexStore;\r
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
+  {\r
+   tsx->used=0;\r
+   if(bDelTex && tsx->texname)\r
+    {\r
+     glDeleteTextures(1,&tsx->texname);\r
+     tsx->texname=0;\r
+    }\r
+  }\r
+ iMaxTexWnds=0;\r
+ //----------------------------------------------------//\r
+\r
+ for(i=0;i<3;i++)\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   {\r
+    tss=pscSubtexStore[i][j];\r
+    (tss+SOFFA)->pos.l=0;\r
+    (tss+SOFFB)->pos.l=0;\r
+    (tss+SOFFC)->pos.l=0;\r
+    (tss+SOFFD)->pos.l=0;\r
+   }\r
+\r
+ for(i=0;i<iSortTexCnt;i++)\r
+  {\r
+   lu=pxSsubtexLeft[i];\r
+   lu->l=0;\r
+   if(bDelTex && uiStexturePage[i])\r
+    {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;}\r
+  }\r
+}\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Invalidate tex windows\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateWndTextureArea(long X,long Y,long W, long H)\r
+{\r
+ int i,px1,px2,py1,py2,iYM=1;\r
+ textureWndCacheEntry * tsw=wcWndtexStore;\r
+\r
+ W+=X-1;      \r
+ H+=Y-1;\r
+ if(X<0) X=0;if(X>1023) X=1023;\r
+ if(W<0) W=0;if(W>1023) W=1023;\r
+ if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
+ if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
+ W++;H++;\r
+\r
+ if(iGPUHeight==1024) iYM=3;\r
+\r
+ py1=min(iYM,Y>>8);\r
+ py2=min(iYM,H>>8);                                    // y: 0 or 1\r
+\r
+ px1=max(0,(X>>6));\r
+ px2=min(15,(W>>6));\r
+\r
+ if(py1==py2)\r
+  {\r
+   py1=py1<<4;px1+=py1;px2+=py1;                       // change to 0-31\r
+   for(i=0;i<iMaxTexWnds;i++,tsw++)\r
+    {\r
+     if(tsw->used)\r
+      {\r
+       if(tsw->pageid>=px1 && tsw->pageid<=px2)\r
+        {\r
+         tsw->used=0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+ else\r
+  {\r
+   py1=px1+16;py2=px2+16;\r
+   for(i=0;i<iMaxTexWnds;i++,tsw++)\r
+    {\r
+     if(tsw->used)\r
+      {\r
+       if((tsw->pageid>=px1 && tsw->pageid<=px2) ||\r
+          (tsw->pageid>=py1 && tsw->pageid<=py2))\r
+        {\r
+         tsw->used=0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+ // adjust tex window count\r
+ tsw=wcWndtexStore+iMaxTexWnds-1;\r
+ while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;}\r
+}\r
+\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// same for sort textures\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void MarkFree(textureSubCacheEntryS * tsx)\r
+{\r
+ EXLong * ul, * uls;\r
+ int j,iMax;u8 x1,y1,dx,dy;\r
+\r
+ uls=pxSsubtexLeft[tsx->cTexID];\r
+ iMax=uls->l;ul=uls+1;\r
+\r
+ if(!iMax) return;\r
+\r
+ for(j=0;j<iMax;j++,ul++)\r
+  if(ul->l==0xffffffff) break;\r
+\r
+ if(j<CSUBSIZE-2)\r
+  {\r
+   if(j==iMax) uls->l=uls->l+1;\r
+\r
+   x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3];\r
+   if(tsx->posTX) {x1--;dx+=3;}\r
+   y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1];\r
+   if(tsx->posTY) {y1--;dy+=3;}\r
+\r
+   ul->c[3]=x1;\r
+   ul->c[2]=dx;\r
+   ul->c[1]=y1;\r
+   ul->c[0]=dy;\r
+  }\r
+}\r
+\r
+void InvalidateSubSTextureArea(long X,long Y,long W, long H)\r
+{\r
+ int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM=1;\r
+ EXLong npos;textureSubCacheEntryS * tsb;\r
+ long x1,x2,y1,y2,xa,sw;\r
+\r
+ W+=X-1;      \r
+ H+=Y-1;\r
+ if(X<0) X=0;if(X>1023) X=1023;\r
+ if(W<0) W=0;if(W>1023) W=1023;\r
+ if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
+ if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
+ W++;H++;\r
+\r
+ if(iGPUHeight==1024) iYM=3;\r
+\r
+ py1=min(iYM,Y>>8);\r
+ py2=min(iYM,H>>8);                                    // y: 0 or 1\r
+ px1=max(0,(X>>6)-3);                                   \r
+ px2=min(15,(W>>6)+3);                                 // x: 0-15\r
+\r
+ for(py=py1;py<=py2;py++)\r
+  {\r
+   j=(py<<4)+px1;                                      // get page\r
+\r
+   y1=py*256;y2=y1+255;\r
+\r
+   if(H<y1)  continue;\r
+   if(Y>y2)  continue;\r
+\r
+   if(Y>y1)  y1=Y;\r
+   if(H<y2)  y2=H;\r
+   if(y2<y1) {sw=y1;y1=y2;y2=sw;}\r
+   y1=((y1%256)<<8);\r
+   y2=(y2%256);\r
+\r
+   for(px=px1;px<=px2;px++,j++)\r
+    {\r
+     for(k=0;k<3;k++)\r
+      {\r
+       xa=x1=px<<6;\r
+       if(W<x1) continue;\r
+       x2=x1+(64<<k)-1;\r
+       if(X>x2) continue;\r
+\r
+       if(X>x1)  x1=X;\r
+       if(W<x2)  x2=W;\r
+       if(x2<x1) {sw=x1;x1=x2;x2=sw;}\r
+\r
+       if (dwGPUVersion == 2)\r
+        npos.l=0x00ff00ff;\r
+       else\r
+        npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2;\r
+\r
+        {\r
+         tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++;\r
+         for(i=0;i<iMax;i++,tsb++)\r
+          if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+\r
+//         if(npos.l & 0x00800000)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+\r
+//         if(npos.l & 0x00000080)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+\r
+//         if(npos.l & 0x00800080)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Invalidate some parts of cache: main routine\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateTextureAreaEx(void)\r
+{\r
+ short W=sxmax-sxmin;\r
+ short H=symax-symin;\r
+\r
+ if(W==0 && H==0) return;\r
+\r
+ if(iMaxTexWnds) \r
+  InvalidateWndTextureArea(sxmin,symin,W,H);\r
+\r
+ InvalidateSubSTextureArea(sxmin,symin,W,H);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateTextureArea(long X,long Y,long W, long H)\r
+{\r
+ if(W==0 && H==0) return;\r
+\r
+ if(iMaxTexWnds) InvalidateWndTextureArea(X,Y,W,H); \r
+\r
+ InvalidateSubSTextureArea(X,Y,W,H);\r
+}\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: define\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineTextureWnd(void)\r
+{\r
+ if(gTexName==0)\r
+  glGenTextures(1, &gTexName);\r
+\r
+ glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
\r
+{\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+  }\r
+\r
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
+              TWin.Position.x1, \r
+              TWin.Position.y1, \r
+              0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load packed stretch\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned short *wSRCPtr,*wOSRCPtr;\r
+ unsigned long  LineOffset;unsigned short s;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<16;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+          *ta++=s;\r
+\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LPTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*(pa+(*cSRCPtr & 0xF));\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<256;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+\r
+          *ta++=s;\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
+                                \r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      wOSRCPtr=wSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LPTCOL(*wSRCPtr++);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
+      else                 wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load stretched\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned short *wSRCPtr,*wOSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    //------------------- ZN STUFF\r
+\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+          *ta++=s;\r
+\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    //-------------------\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*(pa+(*cSRCPtr & 0xF));\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------//\r
+   // 8bit texture load ..\r
+   case 1:\r
+    //------------ ZN STUFF\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+          *ta++=s;\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+    //------------\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;    \r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      wOSRCPtr=wSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LTCOL(*wSRCPtr++);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
+      else                 wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load packed simple\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<16;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LPTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<256;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LPTCOL(*wSRCPtr++);\r
+      wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load simple\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------//\r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LTCOL(*wSRCPtr++);\r
+      wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void UploadTexWndPal(int mode,short cx,short cy)\r
+{\r
+ unsigned int i,iSize;\r
+ unsigned short * wSrcPtr;\r
+ unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+ wSrcPtr=psxVuw+cx+(cy*1024);\r
+ if(mode==0) i=4; else i=64;\r
+ iSize=i<<2;\r
+ ubOpaqueDraw=0;\r
+\r
+ do\r
+  {\r
+   *ta    =PALCOL(*wSrcPtr);\r
+   *(ta+1)=PALCOL(*(wSrcPtr+1));\r
+   *(ta+2)=PALCOL(*(wSrcPtr+2));\r
+   *(ta+3)=PALCOL(*(wSrcPtr+3));\r
+   ta+=4;wSrcPtr+=4;i--;\r
+  }\r
+ while(i);\r
+\r
+/* (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize,\r
+                    GL_RGBA,GL_UNSIGNED_BYTE,texturepart);\r
+*/}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefinePalTextureWnd(void)\r
+{\r
+ if(gTexName==0)\r
+  glGenTextures(1, &gTexName);\r
+\r
+ glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
\r
+{\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+  }\r
+\r
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
+              TWin.Position.x1, \r
+              TWin.Position.y1, \r
+              0, GL_RGBA, GL_UNSIGNED_BYTE,texturepart);\r
+}\r
+\r
+///////////////////////////////////////////////////////\r
+\r
+void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ u8  *ta;\r
+ u8  *cSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+\r
+ ta=(u8 *)texturepart;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=(*cSRCPtr & 0xF); row++;\r
+        if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=*cSRCPtr++;\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+  }\r
+ UploadTexWndPal(mode,cx,cy);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
+ u8  *ta,s;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ ta=(u8 *)texturepart;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=(*cSRCPtr & 0xF);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=((*cSRCPtr >> 4) & 0xF);\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*cSRCPtr++;\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+  }\r
+ UploadTexWndPal(mode,cx,cy);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: main selecting, cache handler included\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureWnd(long pageid,long TextureMode,unsigned long GivenClutId)\r
+{\r
+ textureWndCacheEntry * ts, * tsx=NULL;\r
+ int i;short cx,cy;\r
+ EXLong npos;\r
+\r
+ npos.c[3]=TWin.Position.x0;\r
+ npos.c[2]=TWin.OPosition.x1;\r
+ npos.c[1]=TWin.Position.y0;\r
+ npos.c[0]=TWin.OPosition.y1;\r
+\r
+ g_x1=TWin.Position.x0;g_x2=g_x1+TWin.Position.x1-1;\r
+ g_y1=TWin.Position.y0;g_y2=g_y1+TWin.Position.y1-1;\r
+\r
+ if(TextureMode==2) {GivenClutId=0;cx=cy=0;}\r
+ else  \r
+  {\r
+   cx=((GivenClutId << 4) & 0x3F0);cy=((GivenClutId >> 6) & CLUTYMASK);\r
+   GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30);\r
+\r
+   // palette check sum\r
+    {\r
+     unsigned long l=0,row;\r
+     unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+     if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+     else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+     l=(l+HIWORD(l))&0x3fffL;\r
+     GivenClutId|=(l<<16);\r
+    }\r
+\r
+  }\r
+\r
+ ts=wcWndtexStore;\r
+\r
+ for(i=0;i<iMaxTexWnds;i++,ts++)\r
+  {\r
+   if(ts->used)\r
+    {\r
+     if(ts->pos.l==npos.l &&\r
+        ts->pageid==pageid &&\r
+        ts->textureMode==TextureMode)\r
+      {\r
+       if(ts->ClutID==GivenClutId)\r
+        {\r
+         ubOpaqueDraw=ts->Opaque;\r
+         return ts->texname;\r
+        }\r
+      }\r
+    }\r
+   else tsx=ts;\r
+  }\r
+\r
+ if(!tsx) \r
+  {\r
+   if(iMaxTexWnds==iTexWndLimit)\r
+    {\r
+     tsx=wcWndtexStore+iTexWndTurn;\r
+     iTexWndTurn++; \r
+     if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0;\r
+    }\r
+   else\r
+    {\r
+     tsx=wcWndtexStore+iMaxTexWnds;\r
+     iMaxTexWnds++;\r
+    }\r
+  }\r
+\r
+ gTexName=tsx->texname;\r
+\r
+ if(TWin.OPosition.y1==TWin.Position.y1 &&\r
+    TWin.OPosition.x1==TWin.Position.x1)\r
+  {\r
+    LoadWndTexturePage(pageid,TextureMode,cx,cy);\r
+  }       \r
+ else\r
+  {\r
+    LoadStretchWndTexturePage(pageid,TextureMode,cx,cy);\r
+  }\r
+\r
+ tsx->Opaque=ubOpaqueDraw;\r
+ tsx->pos.l=npos.l;\r
+ tsx->ClutID=GivenClutId;\r
+ tsx->pageid=pageid;\r
+ tsx->textureMode=TextureMode;\r
+ tsx->texname=gTexName;\r
+ tsx->used=1;\r
+       \r
+ return gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: define\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefinePackedTextureMovie(void)\r
+{\r
+ if(gTexMovieName==0)\r
+  {\r
+   glGenTextures(1, &gTexMovieName);\r
+   gTexName=gTexMovieName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(!bUseFastMdec) \r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+                                 \r
+   glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA, \r
+                GL_RGBA,\r
+                256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
+                 (xrMovieArea.x1-xrMovieArea.x0), \r
+                 (xrMovieArea.y1-xrMovieArea.y0), \r
+                 GL_RGBA,\r
+                 GL_UNSIGNED_SHORT,\r
+                 texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineTextureMovie(void)\r
+{\r
+ if(gTexMovieName==0)\r
+  {\r
+   glGenTextures(1, &gTexMovieName);\r
+   gTexName=gTexMovieName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
\r
+   if(!bUseFastMdec) \r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
+                 (xrMovieArea.x1-xrMovieArea.x0), \r
+                 (xrMovieArea.y1-xrMovieArea.y0), \r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: load\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define MRED(x)   ((x>>3) & 0x1f)\r
+#define MGREEN(x) ((x>>6) & 0x3e0)\r
+#define MBLUE(x)  ((x>>9) & 0x7c00)\r
+\r
+#define XMGREEN(x) ((x>>5)  & 0x07c0)\r
+#define XMRED(x)   ((x<<8)  & 0xf800)\r
+#define XMBLUE(x)  ((x>>18) & 0x003e)\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: load\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * LoadDirectMovieFast(void)\r
+{\r
+ long row,column;\r
+ unsigned int startxy;\r
+\r
+ unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+ if(PSXDisplay.RGB24)\r
+  {\r
+   u8 * pD;\r
+\r
+   startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
+\r
+   for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
+    {\r
+     pD=(u8 *)&psxVuw[startxy];\r
+     for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+      {\r
+       *ta++=*((unsigned long *)pD)|0xff000000;\r
+       pD+=3;\r
+      }\r
+    }\r
+  }\r
+ else\r
+  {\r
+   unsigned long (*LTCOL)(unsigned long);\r
+\r
+   LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+   ubOpaqueDraw=0;\r
+\r
+   for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+    {\r
+     startxy=((1024)*column)+xrMovieArea.x0;\r
+     for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+      *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+    }\r
+  }\r
\r
+ return texturepart;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureMovieFast(void)\r
+{\r
+ long row,column;\r
+ unsigned int start,startxy;\r
+\r
+{\r
+   if(PSXDisplay.RGB24)\r
+    {\r
+     u8 * pD;\r
+     unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+     startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
+\r
+     for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
+      {\r
+       //startxy=((1024)*column)+xrMovieArea.x0;\r
+       pD=(u8 *)&psxVuw[startxy];\r
+       for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+        {\r
+         *ta++=*((unsigned long *)pD)|0xff000000;\r
+         pD+=3;\r
+        }\r
+      }\r
+    }\r
+   else\r
+    {\r
+     unsigned long (*LTCOL)(unsigned long);\r
+     unsigned long *ta;\r
+\r
+     LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+     ubOpaqueDraw=0;\r
+     ta=(unsigned long *)texturepart;\r
+\r
+     for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+      {\r
+       startxy=((1024)*column)+xrMovieArea.x0;\r
+       for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+        *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+      }\r
+    }\r
+   DefineTextureMovie();\r
+  }\r
+ return gTexName;   \r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureMovie(void)\r
+{\r
+ short row,column,dx;\r
+ unsigned int startxy;\r
+ BOOL b_X,b_Y;\r
+\r
+ if(bUseFastMdec) return LoadTextureMovieFast();\r
+\r
+ b_X=FALSE;b_Y=FALSE;\r
+\r
+ if((xrMovieArea.x1-xrMovieArea.x0)<255)  b_X=TRUE;\r
+ if((xrMovieArea.y1-xrMovieArea.y0)<255)  b_Y=TRUE;\r
+\r
+{\r
+   if(PSXDisplay.RGB24)\r
+    {\r
+     u8 * pD;\r
+     unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+     if(b_X)\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         pD=(u8 *)&psxVuw[startxy];\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          {\r
+           *ta++=*((unsigned long *)pD)|0xff000000;\r
+           pD+=3;\r
+          }\r
+         *ta++=*(ta-1);\r
+        }\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+         *ta++=*(ta-1);\r
+        }\r
+      }\r
+     else\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         pD=(u8 *)&psxVuw[startxy];\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          {\r
+           *ta++=*((unsigned long *)pD)|0xff000000;\r
+           pD+=3;\r
+          }\r
+        }\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+        }\r
+      }\r
+    }\r
+   else\r
+    {\r
+     unsigned long (*LTCOL)(unsigned long);\r
+     unsigned long *ta;\r
+\r
+     LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+     ubOpaqueDraw=0;\r
+     ta=(unsigned long *)texturepart;\r
+\r
+     if(b_X)\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+         *ta++=*(ta-1);\r
+        }\r
+\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+         *ta++=*(ta-1);\r
+        }\r
+      }\r
+     else\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+        }\r
+\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+        }\r
+      }\r
+    }\r
+\r
+   xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y;\r
+   DefineTextureMovie();\r
+   xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y;\r
+  }\r
+ return gTexName;   \r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint BlackFake15BitTexture(void)\r
+{\r
+ long pmult;short x1,x2,y1,y2;\r
+\r
+ if(PSXDisplay.InterlacedTest) return 0;\r
\r
+ pmult=GlobalTexturePage/16;\r
+ x1=gl_ux[7];\r
+ x2=gl_ux[6]-gl_ux[7];\r
+ y1=gl_ux[5];\r
+ y2=gl_ux[4]-gl_ux[5];\r
+\r
+ if(iSpriteTex)\r
+  {\r
+   if(x2<255) x2++;\r
+   if(y2<255) y2++;\r
+  }\r
+\r
+ y1+=pmult*256;\r
+ x1+=((GlobalTexturePage-16*pmult)<<6);\r
+\r
+ if(   FastCheckAgainstFrontScreen(x1,y1,x2,y2)\r
+    || FastCheckAgainstScreen(x1,y1,x2,y2))\r
+  {\r
+   if(!gTexFrameName)\r
+    {\r
+     glGenTextures(1, &gTexFrameName);\r
+     gTexName=gTexFrameName;\r
+     glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
\r
+     {\r
+       unsigned long * ta=(unsigned long *)texturepart;\r
+       for(y1=0;y1<=4;y1++)\r
+        for(x1=0;x1<=4;x1++)\r
+         *ta++=0xff000000;\r
+      }\r
+     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+    }\r
+   else\r
+    {\r
+     gTexName=gTexFrameName;\r
+     glBindTexture(GL_TEXTURE_2D, gTexName);\r
+    }\r
+\r
+   ubOpaqueDraw=0;\r
+\r
+   return (GLuint)gTexName;\r
+  }\r
+ return 0;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL bFakeFrontBuffer=FALSE;\r
+BOOL bIgnoreNextTile =FALSE;\r
+\r
+int iFTex=512;\r
+\r
+GLuint Fake15BitTexture(void)\r
+{\r
+ long pmult;short x1,x2,y1,y2;int iYAdjust;\r
+ float ScaleX,ScaleY;RECT rSrc;\r
+\r
+ if(iFrameTexType==1) return BlackFake15BitTexture();\r
+ if(PSXDisplay.InterlacedTest) return 0;\r
\r
+ pmult=GlobalTexturePage/16;\r
+ x1=gl_ux[7];\r
+ x2=gl_ux[6]-gl_ux[7];\r
+ y1=gl_ux[5];\r
+ y2=gl_ux[4]-gl_ux[5];\r
+\r
+ y1+=pmult*256;\r
+ x1+=((GlobalTexturePage-16*pmult)<<6);\r
+\r
+ if(iFrameTexType==3)\r
+  {\r
+   if(iFrameReadType==4) return 0;\r
+\r
+   if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) &&\r
+      !FastCheckAgainstScreen(x1,y1,x2,y2))\r
+    return 0;\r
+\r
+   if(bFakeFrontBuffer) bIgnoreNextTile=TRUE;\r
+   CheckVRamReadEx(x1,y1,x1+x2,y1+y2);\r
+   return 0;\r
+  }\r
+\r
+ /////////////////////////\r
+\r
+ if(FastCheckAgainstFrontScreen(x1,y1,x2,y2))\r
+  {\r
+   x1-=PSXDisplay.DisplayPosition.x;\r
+   y1-=PSXDisplay.DisplayPosition.y;\r
+  }\r
+ else\r
+ if(FastCheckAgainstScreen(x1,y1,x2,y2))\r
+  {\r
+   x1-=PreviousPSXDisplay.DisplayPosition.x;\r
+   y1-=PreviousPSXDisplay.DisplayPosition.y;\r
+  }\r
+ else return 0;\r
+\r
+ bDrawMultiPass = FALSE;\r
+\r
+ if(!gTexFrameName)\r
+  {\r
+   s8 * p;\r
+\r
+   if(iResX>1280 || iResY>1024) iFTex=2048;\r
+   else\r
+   if(iResX>640  || iResY>480)  iFTex=1024;\r
+   else                         iFTex=512; \r
+\r
+   glGenTextures(1, &gTexFrameName);\r
+   gTexName=gTexFrameName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+\r
+   p=(s8 *)malloc(iFTex*iFTex*4);\r
+   memset(p,0,iFTex*iFTex*4);\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iFTex, iFTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+   free(p);\r
+\r
+   glGetError();\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexFrameName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ x1+=PreviousPSXDisplay.Range.x0;\r
+ y1+=PreviousPSXDisplay.Range.y0;\r
+\r
+ if(PSXDisplay.DisplayMode.x)\r
+      ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
+ else ScaleX=1.0f;\r
+ if(PSXDisplay.DisplayMode.y)\r
+      ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
+ else ScaleY=1.0f;\r
+\r
+ rSrc.left  =max(x1*ScaleX,0);\r
+ rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1);\r
+ rSrc.top   =max(y1*ScaleY,0);\r
+ rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1);\r
+\r
+ iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y;\r
+ if(iYAdjust>0)\r
+      iYAdjust=(int)((float)iYAdjust*ScaleY)+1;\r
+ else iYAdjust=0;\r
+          \r
+ gl_vy[0]=255-gl_vy[0];\r
+ gl_vy[1]=255-gl_vy[1];\r
+ gl_vy[2]=255-gl_vy[2];\r
+ gl_vy[3]=255-gl_vy[3];\r
+\r
+ y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3])));\r
+\r
+ gl_vy[0]-=y1;\r
+ gl_vy[1]-=y1;\r
+ gl_vy[2]-=y1;\r
+ gl_vy[3]-=y1;\r
+ gl_ux[0]-=gl_ux[7];\r
+ gl_ux[1]-=gl_ux[7];\r
+ gl_ux[2]-=gl_ux[7];\r
+ gl_ux[3]-=gl_ux[7];\r
+\r
+ ScaleX*=256.0f/((float)(iFTex));\r
+ ScaleY*=256.0f/((float)(iFTex));\r
+\r
+ y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[0]=y1;\r
+ y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[1]=y1;\r
+ y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[2]=y1;\r
+ y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[3]=y1;\r
+\r
+ x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[0]=x1;\r
+ x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[1]=x1;\r
+ x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[2]=x1;\r
+ x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[3]=x1;\r
+\r
+ x1=rSrc.right-rSrc.left;\r
+ if(x1<=0)             x1=1;\r
+ if(x1>iFTex)          x1=iFTex;\r
+\r
+ y1=rSrc.bottom-rSrc.top;\r
+ if(y1<=0)             y1=1;\r
+ if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust;\r
+\r
+\r
+ glCopyTexSubImage2D( GL_TEXTURE_2D, 0, \r
+                      0,\r
+                      iYAdjust,\r
+                      rSrc.left+rRatioRect.left,\r
+                      iResY-rSrc.bottom-rRatioRect.top,\r
+                      x1,y1);\r
+\r
+ if(glGetError()) \r
+  {\r
+   s8 * p=(s8 *)malloc(iFTex*iFTex*4);\r
+   memset(p,0,iFTex*iFTex*4);\r
+   glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex,\r
+                   GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+   free(p);\r
+  }\r
+\r
\r
+ ubOpaqueDraw=0;\r
+\r
+ if(iSpriteTex)\r
+  {\r
+   sprtW=gl_ux[1]-gl_ux[0];    \r
+   sprtH=-(gl_vy[0]-gl_vy[2]);\r
+  }\r
+\r
+ return (GLuint)gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// load texture part (unpacked)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long  start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ unsigned long  x2a,xalign=0;\r
+ unsigned long  x1=gl_ux[7];\r
+ unsigned long  x2=gl_ux[6];\r
+ unsigned long  y1=gl_ux[5];\r
+ unsigned long  y2=gl_ux[4];\r
+ unsigned long  dx=x2-x1+1;\r
+ unsigned long  dy=y2-y1+1;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
+ unsigned int a,r,g,b,cnt,h;\r
+ unsigned long scol[8];\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy<<10);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
+ if(XTexS) {ta+=1;xalign=2;}\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+\r
+    row=4;do\r
+     {\r
+      *px    =LTCOL(*wSRCPtr);\r
+      *(px+1)=LTCOL(*(wSRCPtr+1));\r
+      *(px+2)=LTCOL(*(wSRCPtr+2));\r
+      *(px+3)=LTCOL(*(wSRCPtr+3));\r
+      row--;px+=4;wSRCPtr+=4;\r
+     }\r
+    while (row);\r
+\r
+    x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
+    sxm=x1&1;sxh=x1>>1;\r
+    j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
+    for(column=y1;column<=y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (column<<11) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+\r
+      for(row=j;row<x2a;row+=2)\r
+       {\r
+        *ta    =*(pa+(*cSRCPtr & 0xF)); \r
+        *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;ta+=2;\r
+       }\r
+\r
+      if(row<=x2) \r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+       }\r
+\r
+      ta+=xalign;\r
+     }\r
+\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (y1<<11) + x1;\r
+    LineOffset = 2048 - dx; \r
+\r
+    if(dy*dx>384)\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
+        ta+=xalign;\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    else\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
+        ta+=xalign;\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)<<6)+262144*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
+    LineOffset = 1024 - dx; \r
+\r
+    column=dy;do \r
+     {\r
+      row=dx;\r
+      do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row);\r
+      ta+=xalign;\r
+      wSRCPtr+=LineOffset;column--;\r
+     }\r
+    while(column);\r
+\r
+    break;\r
+   //--------------------------------------------------//\r
+   // others are not possible !\r
+  }\r
+\r
+ x2a=dx+xalign;\r
+\r
+ if(YTexS)\r
+  {\r
+   ta=(unsigned long *)texturepart;\r
+   pa=(unsigned long *)texturepart+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);        \r
+   pa=(unsigned long *)texturepart+dy*x2a;\r
+   ta=pa+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+   YTexS--;\r
+   dy+=2;\r
+  }\r
+\r
+ if(XTexS)\r
+  {\r
+   ta=(unsigned long *)texturepart;\r
+   pa=ta+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+   pa=(unsigned long *)texturepart+dx;\r
+   ta=pa+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+   XTexS--;\r
+   dx+=2;\r
+  }\r
+\r
+ DXTexS=dx;DYTexS=dy;\r
+\r
+ if(!iFilterType) {DefineSubTextureSort();return;}\r
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
+  {DefineSubTextureSort();return;}\r
+\r
+ ta=(unsigned long *)texturepart;\r
+ x1=dx-1;\r
+ y1=dy-1;\r
+\r
+ if(bOpaquePass)\r
+  {\r
+{\r
+     for(column=0;column<dy;column++)\r
+      {\r
+       for(row=0;row<dx;row++)\r
+        {\r
+         if(*ta==0x50000000)\r
+          {\r
+           cnt=0;\r
+\r
+           if(           column     && *(ta-dx)  !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx);\r
+           if(row                   && *(ta-1)   !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1);\r
+           if(row!=x1               && *(ta+1)   !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1);\r
+           if(           column!=y1 && *(ta+dx)  !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx);\r
+\r
+           if(row     && column     && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1);\r
+           if(row!=x1 && column     && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1);\r
+           if(row     && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1);\r
+           if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1);\r
+\r
+           if(cnt)\r
+            {\r
+             r=g=b=a=0;\r
+             for(h=0;h<cnt;h++)\r
+              {\r
+               a+=(scol[h]>>24);\r
+               r+=(scol[h]>>16)&0xff;\r
+               g+=(scol[h]>>8)&0xff;\r
+               b+=scol[h]&0xff;\r
+              }\r
+             r/=cnt;b/=cnt;g/=cnt;\r
+\r
+             *ta=(r<<16)|(g<<8)|b;\r
+             if(a) *ta|=0x50000000;\r
+             else  *ta|=0x01000000;\r
+            }\r
+          }\r
+         ta++;\r
+        }\r
+      }\r
+    }\r
+  }\r
+ else\r
+ for(column=0;column<dy;column++)\r
+  {\r
+   for(row=0;row<dx;row++)\r
+    {\r
+     if(*ta==0x00000000)\r
+      {\r
+       cnt=0;\r
+\r
+       if(row!=x1               && *(ta+1)   !=0x00000000) scol[cnt++]=*(ta+1);\r
+       if(           column!=y1 && *(ta+dx)  !=0x00000000) scol[cnt++]=*(ta+dx);\r
+\r
+       if(cnt)\r
+        {\r
+         r=g=b=0;\r
+         for(h=0;h<cnt;h++)\r
+          {\r
+           r+=(scol[h]>>16)&0xff;\r
+           g+=(scol[h]>>8)&0xff;\r
+           b+=scol[h]&0xff;\r
+          }\r
+         r/=cnt;b/=cnt;g/=cnt;\r
+         *ta=(r<<16)|(g<<8)|b;\r
+        }\r
+      }\r
+     ta++;\r
+    }\r
+  }\r
+\r
+ DefineSubTextureSort();\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// load texture part (packed)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long  start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ unsigned long  x2a,xalign=0;\r
+ unsigned long  x1=gl_ux[7];\r
+ unsigned long  x2=gl_ux[6];\r
+ unsigned long  y1=gl_ux[5];\r
+ unsigned long  y2=gl_ux[4];\r
+ unsigned long  dx=x2-x1+1;\r
+ unsigned long  dy=y2-y1+1;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+ unsigned int a,r,g,b,cnt,h;\r
+ unsigned short scol[8];\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy<<10);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
+ if(XTexS) {ta+=1;xalign=2;}\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      row=4;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    row=4;do\r
+     {\r
+      *px    =LPTCOL(*wSRCPtr);\r
+      *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+      *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+      *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+      row--;px+=4;wSRCPtr+=4;\r
+     }\r
+    while (row);\r
+\r
+    x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
+    sxm=x1&1;sxh=x1>>1;\r
+    j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
+\r
+    for(column=y1;column<=y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (column<<11) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
\r
+      for(row=j;row<x2a;row+=2)\r
+       {\r
+        *ta    =*(pa+(*cSRCPtr & 0xF));\r
+        *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;ta+=2;\r
+       }\r
+\r
+      if(row<=x2)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF));row++;\r
+        if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+       }\r
+\r
+      ta+=xalign;\r
+     }\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (y1<<11) + x1;\r
+    LineOffset = 2048 - dx;\r
+\r
+    if(dy*dx>384)                                      // more pix? use lut\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
+\r
+        ta+=xalign;\r
+\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    else                                               // small area? no lut\r
+     {                                            \r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
+\r
+        ta+=xalign;\r
+\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)<<6)+262144*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
+    LineOffset = 1024 - dx; \r
+\r
+    column=dy;do \r
+     {\r
+      row=dx;\r
+      do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row);\r
+\r
+      ta+=xalign;\r
+\r
+      wSRCPtr+=LineOffset;column--;\r
+     }\r
+    while(column);\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+\r
+ ////////////////////////////////////////////////////////\r
+\r
+ x2a=dx+xalign;\r
+\r
+ if(YTexS)\r
+  {\r
+   ta=(unsigned short *)texturepart;\r
+   pa=(unsigned short *)texturepart+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+\r
+   pa=(unsigned short *)texturepart+dy*x2a;\r
+   ta=pa+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+\r
+   YTexS--;\r
+   dy+=2;\r
+  }\r
+\r
+ if(XTexS)\r
+  {\r
+   ta=(unsigned short *)texturepart;\r
+   pa=ta+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+\r
+   pa=(unsigned short *)texturepart+dx;\r
+   ta=pa+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+\r
+   XTexS--;\r
+   dx+=2;\r
+  }\r
+\r
+ DXTexS=dx;DYTexS=dy;\r
+\r
+ if(!iFilterType) {DefineSubTextureSort();return;}\r
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
+  {DefineSubTextureSort();return;}\r
+\r
+ ta=(unsigned short *)texturepart;\r
+ x1=dx-1;\r
+ y1=dy-1;      \r
+\r
+{\r
+   for(column=0;column<dy;column++)\r
+    {\r
+     for(row=0;row<dx;row++)\r
+      {\r
+       if(*ta==0)\r
+        {\r
+         cnt=0;\r
+\r
+         if(           column     && *(ta-dx)  &1) scol[cnt++]=*(ta-dx);\r
+         if(row                   && *(ta-1)   &1) scol[cnt++]=*(ta-1);\r
+         if(row!=x1               && *(ta+1)   &1) scol[cnt++]=*(ta+1);\r
+         if(           column!=y1 && *(ta+dx)  &1) scol[cnt++]=*(ta+dx);\r
+\r
+         if(row     && column     && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1);\r
+         if(row!=x1 && column     && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1);\r
+         if(row     && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1);\r
+         if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1);\r
+\r
+         if(cnt)\r
+          {\r
+           r=g=b=0;\r
+           for(h=0;h<cnt;h++)\r
+            {\r
+             r+=scol[h]>>11;\r
+             g+=(scol[h]>>6)&0x1f;\r
+             b+=(scol[h]>>1)&0x1f;\r
+            }\r
+           r/=cnt;b/=cnt;g/=cnt;\r
+           *ta=(r<<11)|(g<<6)|(b<<1);\r
+          }\r
+        }\r
+       ta++;\r
+      }\r
+    }\r
+  }\r
+\r
+ DefineSubTextureSort();\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// hires texture funcs\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define colorMask8     0x00FEFEFE\r
+#define lowPixelMask8  0x00010101\r
+#define qcolorMask8    0x00FCFCFC\r
+#define qlowpixelMask8 0x00030303\r
+\r
+\r
+#define INTERPOLATE8_02(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))\r
+\r
+#define Q_INTERPOLATE8_02(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((C&0xFF000000)==0x03000000)?0x03000000:(((D&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))\r
+\r
+#define INTERPOLATE8(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))\r
+\r
+#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((C&0xFF000000)==0x50000000)?0x50000000:(((D&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))\r
+\r
+void Super2xSaI_ex8_Ex(u8 *srcPtr, DWORD srcPitch,\r
+                   u8  *dstBitmap, int width, int height)\r
+{\r
+ DWORD dstPitch = srcPitch * 2;\r
+ DWORD line;\r
+ DWORD *dP;\r
+ DWORD *bP;\r
+ int   width2 = width*2;\r
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
+ DWORD color4, color5, color6;\r
+ DWORD color1, color2, color3;\r
+ DWORD colorA0, colorA1, colorA2, colorA3,\r
+       colorB0, colorB1, colorB2, colorB3,\r
+       colorS1, colorS2;\r
+ DWORD product1a, product1b,\r
+       product2a, product2b;\r
+\r
+ line = 0;\r
+\r
+  {\r
+   for (; height; height-=1)\r
+       {\r
+     bP = (DWORD *)srcPtr;\r
+        dP = (DWORD *)(dstBitmap + line*dstPitch);\r
+     for (finish = width; finish; finish -= 1 )\r
+      {\r
+//---------------------------------------    B1 B2\r
+//                                         4  5  6 S2\r
+//                                         1  2  3 S1\r
+//                                           A1 A2\r
+       if(finish==width) iXA=0;\r
+       else              iXA=1;\r
+       if(finish>4) {iXB=1;iXC=2;}\r
+       else\r
+       if(finish>3) {iXB=1;iXC=1;}\r
+       else         {iXB=0;iXC=0;}\r
+       if(line==0) iYA=0;\r
+       else        iYA=width;\r
+       if(height>4) {iYB=width;iYC=width2;}\r
+       else\r
+       if(height>3) {iYB=width;iYC=width;}\r
+       else         {iYB=0;iYC=0;}\r
+\r
+\r
+       colorB0 = *(bP- iYA - iXA);\r
+       colorB1 = *(bP- iYA);\r
+       colorB2 = *(bP- iYA + iXB);\r
+       colorB3 = *(bP- iYA + iXC);\r
+\r
+       color4 = *(bP  - iXA);\r
+       color5 = *(bP);\r
+       color6 = *(bP  + iXB);\r
+       colorS2 = *(bP + iXC);\r
+\r
+       color1 = *(bP  + iYB  - iXA);\r
+       color2 = *(bP  + iYB);\r
+       color3 = *(bP  + iYB  + iXB);\r
+       colorS1= *(bP  + iYB  + iXC);\r
+\r
+       colorA0 = *(bP + iYC - iXA);\r
+       colorA1 = *(bP + iYC);\r
+       colorA2 = *(bP + iYC + iXB);\r
+       colorA3 = *(bP + iYC + iXC);\r
+\r
+//--------------------------------------\r
+       if (color2 == color6 && color5 != color3)\r
+        {\r
+         product2b = product1b = color2;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 != color6)\r
+        {\r
+         product2b = product1b = color5;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 == color6)\r
+        {\r
+         register int r = 0;\r
+\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
+\r
+         if (r > 0)\r
+          product2b = product1b = color6;\r
+         else\r
+         if (r < 0)\r
+          product2b = product1b = color5;\r
+         else\r
+          {\r
+           product2b = product1b = INTERPOLATE8_02(color5, color6);\r
+          }\r
+        }\r
+       else\r
+        {\r
+         if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
+             product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2);\r
+         else\r
+         if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
+             product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3);\r
+         else\r
+             product2b = INTERPOLATE8_02 (color2, color3);\r
+\r
+         if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
+             product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5);\r
+         else\r
+         if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
+             product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5);\r
+         else\r
+             product1b = INTERPOLATE8_02 (color5, color6);\r
+        }\r
+\r
+       if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
+        product2a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+       if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
+        product2a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+        product2a = color2;\r
+\r
+       if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
+        product1a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+       if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
+        product1a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+        product1a = color5;\r
+\r
+       *dP=product1a;\r
+       *(dP+1)=product1b;\r
+       *(dP+(width2))=product2a;\r
+       *(dP+1+(width2))=product2b;\r
+\r
+       bP += 1;\r
+       dP += 2;\r
+      }//end of for ( finish= width etc..)\r
+\r
+     line += 2;\r
+     srcPtr += srcPitch;\r
+       }; //endof: for (; height; height--)\r
+  }\r
+}\r
+\r
+\r
+void Super2xSaI_ex8(u8 *srcPtr, DWORD srcPitch,\r
+                   u8  *dstBitmap, int width, int height)\r
+{\r
+ DWORD dstPitch = srcPitch * 2;\r
+ DWORD line;\r
+ DWORD *dP;\r
+ DWORD *bP;\r
+ int   width2 = width*2;\r
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
+ DWORD color4, color5, color6;\r
+ DWORD color1, color2, color3;\r
+ DWORD colorA0, colorA1, colorA2, colorA3,\r
+       colorB0, colorB1, colorB2, colorB3,\r
+       colorS1, colorS2;\r
+ DWORD product1a, product1b,\r
+       product2a, product2b;\r
+\r
+ line = 0;\r
+\r
+  {\r
+   for (; height; height-=1)\r
+       {\r
+     bP = (DWORD *)srcPtr;\r
+        dP = (DWORD *)(dstBitmap + line*dstPitch);\r
+     for (finish = width; finish; finish -= 1 )\r
+      {\r
+//---------------------------------------    B1 B2\r
+//                                         4  5  6 S2\r
+//                                         1  2  3 S1\r
+//                                           A1 A2\r
+       if(finish==width) iXA=0;\r
+       else              iXA=1;\r
+       if(finish>4) {iXB=1;iXC=2;}\r
+       else\r
+       if(finish>3) {iXB=1;iXC=1;}\r
+       else         {iXB=0;iXC=0;}\r
+       if(line==0) iYA=0;\r
+       else        iYA=width;\r
+       if(height>4) {iYB=width;iYC=width2;}\r
+       else\r
+       if(height>3) {iYB=width;iYC=width;}\r
+       else         {iYB=0;iYC=0;}\r
+\r
+\r
+       colorB0 = *(bP- iYA - iXA);\r
+       colorB1 = *(bP- iYA);\r
+       colorB2 = *(bP- iYA + iXB);\r
+       colorB3 = *(bP- iYA + iXC);\r
+\r
+       color4 = *(bP  - iXA);\r
+       color5 = *(bP);\r
+       color6 = *(bP  + iXB);\r
+       colorS2 = *(bP + iXC);\r
+\r
+       color1 = *(bP  + iYB  - iXA);\r
+       color2 = *(bP  + iYB);\r
+       color3 = *(bP  + iYB  + iXB);\r
+       colorS1= *(bP  + iYB  + iXC);\r
+\r
+       colorA0 = *(bP + iYC - iXA);\r
+       colorA1 = *(bP + iYC);\r
+       colorA2 = *(bP + iYC + iXB);\r
+       colorA3 = *(bP + iYC + iXC);\r
+\r
+//--------------------------------------\r
+       if (color2 == color6 && color5 != color3)\r
+        {\r
+         product2b = product1b = color2;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 != color6)\r
+        {\r
+         product2b = product1b = color5;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 == color6)\r
+        {\r
+         register int r = 0;\r
+\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
+\r
+         if (r > 0)\r
+          product2b = product1b = color6;\r
+         else\r
+         if (r < 0)\r
+          product2b = product1b = color5;\r
+         else\r
+          {\r
+           product2b = product1b = INTERPOLATE8(color5, color6);\r
+          }\r
+        }\r
+       else\r
+        {\r
+         if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
+             product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);\r
+         else\r
+         if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
+             product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);\r
+         else\r
+             product2b = INTERPOLATE8 (color2, color3);\r
+\r
+         if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
+             product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);\r
+         else\r
+         if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
+             product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);\r
+         else\r
+             product1b = INTERPOLATE8 (color5, color6);\r
+        }\r
+\r
+       if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
+        product2a = INTERPOLATE8(color2, color5);\r
+       else\r
+       if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
+        product2a = INTERPOLATE8(color2, color5);\r
+       else\r
+        product2a = color2;\r
+\r
+       if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
+        product1a = INTERPOLATE8(color2, color5);\r
+       else\r
+       if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
+        product1a = INTERPOLATE8(color2, color5);\r
+       else\r
+        product1a = color5;\r
+\r
+       *dP=product1a;\r
+       *(dP+1)=product1b;\r
+       *(dP+(width2))=product2a;\r
+       *(dP+1+(width2))=product2b;\r
+\r
+       bP += 1;\r
+       dP += 2;\r
+      }//end of for ( finish= width etc..)\r
+\r
+     line += 2;\r
+     srcPtr += srcPitch;\r
+       }; //endof: for (; height; height--)\r
+  }\r
+}\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define colorMask4     0x0000EEE0\r
+#define lowPixelMask4  0x00001110\r
+#define qcolorMask4    0x0000CCC0\r
+#define qlowpixelMask4 0x00003330\r
+\r
+#define INTERPOLATE4(A, B) ((((A & colorMask4) >> 1) + ((B & colorMask4) >> 1) + (A & B & lowPixelMask4))|((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))\r
+\r
+#define Q_INTERPOLATE4(A, B, C, D) ((((A & qcolorMask4) >> 2) + ((B & qcolorMask4) >> 2) + ((C & qcolorMask4) >> 2) + ((D & qcolorMask4) >> 2) + ((((A & qlowpixelMask4) + (B & qlowpixelMask4) + (C & qlowpixelMask4) + (D & qlowpixelMask4)) >> 2) & qlowpixelMask4))| ((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((C&0x0000000F)==0x00000006)?0x00000006:(((D&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:(((C&0x0000000F)==0x00000000)?0x00000000:(((D&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))))))\r
+\r
+\r
+#define colorMask5     0x0000F7BC\r
+#define lowPixelMask5  0x00000842\r
+#define qcolorMask5    0x0000E738\r
+#define qlowpixelMask5 0x000018C6\r
+\r
+#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001))))\r
+\r
+#define Q_INTERPOLATE5(A, B, C, D) ((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))| ((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:(((C&0x00000001)==0x00000000)?0x00000000:(((D&0x00000001)==0x00000000)?0x00000000:0x00000001))))))\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// ogl texture defines\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineSubTextureSortHiRes(void)\r
+{\r
+ int x,y,dx2;\r
+\r
+ if(!gTexName)             \r
+  {\r
+   glGenTextures(1, &gTexName);\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(iFilterType)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {            \r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }   \r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
+  }\r
+ else glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1,\r
+                 DXTexS<<1, DYTexS<<1,\r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineSubTextureSort(void)\r
+{\r
+\r
+ if(!gTexName)\r
+  {\r
+   glGenTextures(1, &gTexName);\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(iFilterType)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS,\r
+                 DXTexS, DYTexS,\r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// texture cache garbage collection\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DoTexGarbageCollection(void)\r
+{\r
+ static unsigned short LRUCleaned=0;\r
+ unsigned short iC,iC1,iC2;\r
+ int i,j,iMax;textureSubCacheEntryS * tsb;\r
+\r
+ iC=4;//=iSortTexCnt/2,\r
+ LRUCleaned+=iC;                                       // we clean different textures each time\r
+ if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0;        // wrap? wrap!\r
+ iC1=LRUCleaned;                                       // range of textures to clean\r
+ iC2=LRUCleaned+iC;\r
+\r
+ for(iC=iC1;iC<iC2;iC++)                               // make some textures available\r
+  {\r
+   pxSsubtexLeft[iC]->l=0;\r
+  }\r
+\r
+ for(i=0;i<3;i++)                                      // remove all references to that textures\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   for(iC=0;iC<4;iC++)                                 // loop all texture rect info areas\r
+    {\r
+     tsb=pscSubtexStore[i][j]+(iC*SOFFB);\r
+     iMax=tsb->pos.l;\r
+     if(iMax)\r
+      do\r
+       {\r
+        tsb++;\r
+        if(tsb->cTexID>=iC1 && tsb->cTexID<iC2)        // info uses the cleaned textures? remove info\r
+         tsb->ClutID=0;\r
+       } \r
+      while(--iMax);\r
+     }\r
+\r
+ usLRUTexPage=LRUCleaned;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// search cache for existing (already used) parts\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache)\r
+{\r
+ textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL;\r
+ int i,iMax;EXLong npos;\r
+ u8 cx,cy;\r
+ int iC,j,k;unsigned long rx,ry,mx,my;\r
+ EXLong * ul=0, * uls;\r
+ EXLong rfree;\r
+ u8 cXAdj,cYAdj;\r
+\r
+ npos.l=*((unsigned long *)&gl_ux[4]);\r
+\r
+ //--------------------------------------------------------------//\r
+ // find matching texturepart first... speed up...\r
+ //--------------------------------------------------------------//\r
+\r
+ tsg=pscSubtexStore[TextureMode][GlobalTexturePage];\r
+ tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB;\r
+\r
+ iMax=tsg->pos.l;\r
+ if(iMax)\r
+  {\r
+   i=iMax;\r
+   tsb=tsg+1;                 \r
+   do\r
+    {\r
+     if(GivenClutId==tsb->ClutID &&\r
+        (INCHECK(tsb->pos,npos)))\r
+      {\r
+        {\r
+         cx=tsb->pos.c[3]-tsb->posTX;\r
+         cy=tsb->pos.c[1]-tsb->posTY;\r
+\r
+         gl_ux[0]-=cx;\r
+         gl_ux[1]-=cx;\r
+         gl_ux[2]-=cx;\r
+         gl_ux[3]-=cx;\r
+         gl_vy[0]-=cy;\r
+         gl_vy[1]-=cy;\r
+         gl_vy[2]-=cy;\r
+         gl_vy[3]-=cy;\r
+\r
+         ubOpaqueDraw=tsb->Opaque;\r
+         *pCache=tsb->cTexID;\r
+         return NULL;\r
+        }\r
+      } \r
+     tsb++;\r
+    }\r
+   while(--i);\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+\r
+ cXAdj=1;cYAdj=1;\r
+\r
+ rx=(int)gl_ux[6]-(int)gl_ux[7];\r
+ ry=(int)gl_ux[4]-(int)gl_ux[5];\r
+\r
+ tsx=NULL;tsb=tsg+1;\r
+ for(i=0;i<iMax;i++,tsb++)\r
+  {\r
+   if(!tsb->ClutID) {tsx=tsb;break;}\r
+  }\r
+\r
+ if(!tsx) \r
+  {\r
+   iMax++;\r
+   if(iMax>=SOFFB-2) \r
+    {\r
+     if(iTexGarbageCollection)                         // gc mode?\r
+      {\r
+       if(*pCache==0) \r
+        {\r
+         dwTexPageComp|=(1<<GlobalTexturePage);\r
+         *pCache=0xffff;\r
+         return 0;\r
+        }\r
+\r
+       iMax--;\r
+       tsb=tsg+1;\r
+\r
+       for(i=0;i<iMax;i++,tsb++)                       // 1. search other slots with same cluts, and unite the area\r
+        if(GivenClutId==tsb->ClutID)\r
+         {\r
+          if(!tsx) {tsx=tsb;rfree.l=npos.l;}           // \r
+          else      tsb->ClutID=0;\r
+          rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]);\r
+          rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]);\r
+          rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]);\r
+          rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]);\r
+          MarkFree(tsb);\r
+         }\r
+\r
+       if(tsx)                                         // 3. if one or more found, create a new rect with bigger size\r
+        {\r
+         *((unsigned long *)&gl_ux[4])=npos.l=rfree.l;\r
+         rx=(int)rfree.c[2]-(int)rfree.c[3];\r
+         ry=(int)rfree.c[0]-(int)rfree.c[1];\r
+         DoTexGarbageCollection();\r
+       \r
+         goto ENDLOOP3;\r
+        }\r
+      }\r
+\r
+     iMax=1;\r
+    }\r
+   tsx=tsg+iMax;\r
+   tsg->pos.l=iMax;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // now get a free texture space\r
+ //----------------------------------------------------//\r
+\r
+ if(iTexGarbageCollection) usLRUTexPage=0;\r
+\r
+ENDLOOP3:\r
+\r
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
+\r
+ iC=usLRUTexPage;\r
+\r
+ for(k=0;k<iSortTexCnt;k++)\r
+  {\r
+   uls=pxSsubtexLeft[iC];\r
+   iMax=uls->l;ul=uls+1;\r
+\r
+   //--------------------------------------------------//\r
+   // first time\r
+\r
+   if(!iMax) \r
+    {\r
+     rfree.l=0;\r
+\r
+     if(rx>252 && ry>252)\r
+      {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;}\r
+\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1; \r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+     ul=0;\r
+     goto ENDLOOP;\r
+    }\r
+                                                       \r
+   //--------------------------------------------------//\r
+   for(i=0;i<iMax;i++,ul++)\r
+    {\r
+     if(ul->l!=0xffffffff && \r
+        ry<=ul->c[0]      && \r
+        rx<=ul->c[2])\r
+      {\r
+       rfree=*ul;\r
+       mx=ul->c[2]-2;\r
+       my=ul->c[0]-2;\r
+       if(rx<mx && ry<my)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+         ul->c[0]=ry;\r
+\r
+         for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
+          if(ul->l==0xffffffff) break;\r
\r
+         if(j<CSUBSIZE-2)\r
+          {\r
+           if(j==iMax) uls->l=uls->l+1;\r
+\r
+           ul->c[3]=rfree.c[3];\r
+           ul->c[2]=rfree.c[2];\r
+           ul->c[1]=rfree.c[1]+ry;\r
+           ul->c[0]=rfree.c[0]-ry;\r
+          }\r
+        }\r
+       else if(rx<mx)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+        }\r
+       else if(ry<my)\r
+        {\r
+         ul->c[1]+=ry;\r
+         ul->c[0]-=ry;\r
+        }\r
+       else\r
+        {\r
+         ul->l=0xffffffff;\r
+        }\r
+       ul=0;\r
+       goto ENDLOOP;\r
+      }\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+\r
+   iC++; if(iC>=iSortTexCnt) iC=0;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // check, if free space got\r
+ //----------------------------------------------------//\r
+\r
+ENDLOOP:\r
+ if(ul)\r
+  {\r
+   //////////////////////////////////////////////////////\r
+\r
+    {\r
+     dwTexPageComp=0;\r
+\r
+     for(i=0;i<3;i++)                                    // cleaning up\r
+      for(j=0;j<MAXTPAGES;j++)\r
+       {\r
+        tsb=pscSubtexStore[i][j];\r
+        (tsb+SOFFA)->pos.l=0;\r
+        (tsb+SOFFB)->pos.l=0;\r
+        (tsb+SOFFC)->pos.l=0;\r
+        (tsb+SOFFD)->pos.l=0;\r
+       }\r
+     for(i=0;i<iSortTexCnt;i++)\r
+      {ul=pxSsubtexLeft[i];ul->l=0;}\r
+     usLRUTexPage=0;\r
+    }\r
+\r
+   //////////////////////////////////////////////////////\r
+   iC=usLRUTexPage;\r
+   uls=pxSsubtexLeft[usLRUTexPage];\r
+   uls->l=0;ul=uls+1;\r
+   rfree.l=0;\r
+\r
+   if(rx>252 && ry>252)\r
+    {uls->l=1;ul->l=0xffffffff;}\r
+   else\r
+    {\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1; \r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+    }\r
+   tsg->pos.l=1;tsx=tsg+1;\r
+  }\r
+\r
+ rfree.c[3]+=cXAdj;\r
+ rfree.c[1]+=cYAdj;\r
+\r
+ tsx->cTexID   =*pCache=iC;\r
+ tsx->pos      = npos;\r
+ tsx->ClutID   = GivenClutId;\r
+ tsx->posTX    = rfree.c[3];\r
+ tsx->posTY    = rfree.c[1];\r
+\r
+ cx=gl_ux[7]-rfree.c[3];\r
+ cy=gl_ux[5]-rfree.c[1];\r
+\r
+ gl_ux[0]-=cx;\r
+ gl_ux[1]-=cx;\r
+ gl_ux[2]-=cx;\r
+ gl_ux[3]-=cx;\r
+ gl_vy[0]-=cy;\r
+ gl_vy[1]-=cy;\r
+ gl_vy[2]-=cy;\r
+ gl_vy[3]-=cy;\r
+\r
+ XTexS=rfree.c[3];\r
+ YTexS=rfree.c[1];\r
+\r
+ return &tsx->Opaque;\r
+}\r
+                   \r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// search cache for free place (on compress)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx)\r
+{\r
+ int i,j,k,iMax,iC;unsigned long rx,ry,mx,my;\r
+ EXLong * ul=0, * uls, rfree;\r
+ u8 cXAdj=1,cYAdj=1;\r
+\r
+ rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3];\r
+ ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1];\r
+\r
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
+\r
+ iC=usLRUTexPage;\r
+\r
+ for(k=0;k<iSortTexCnt;k++)\r
+  {\r
+   uls=pxSsubtexLeft[iC];\r
+   iMax=uls->l;ul=uls+1;\r
+\r
+   //--------------------------------------------------//\r
+   // first time\r
+\r
+   if(!iMax)\r
+    {\r
+     rfree.l=0;\r
+\r
+     if(rx>252 && ry>252)\r
+      {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;}\r
+\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+     ul=0;\r
+     goto TENDLOOP;\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+   for(i=0;i<iMax;i++,ul++)\r
+    {\r
+     if(ul->l!=0xffffffff &&\r
+        ry<=ul->c[0]      &&\r
+        rx<=ul->c[2])\r
+      {\r
+       rfree=*ul;\r
+       mx=ul->c[2]-2;\r
+       my=ul->c[0]-2;\r
+\r
+       if(rx<mx && ry<my)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+         ul->c[0]=ry;\r
+\r
+         for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
+          if(ul->l==0xffffffff) break;\r
+\r
+         if(j<CSUBSIZE-2)\r
+          {\r
+           if(j==iMax) uls->l=uls->l+1;\r
+\r
+           ul->c[3]=rfree.c[3];\r
+           ul->c[2]=rfree.c[2];\r
+           ul->c[1]=rfree.c[1]+ry;\r
+           ul->c[0]=rfree.c[0]-ry;\r
+          }\r
+        }\r
+       else if(rx<mx)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+        }\r
+       else if(ry<my)\r
+        {\r
+         ul->c[1]+=ry;\r
+         ul->c[0]-=ry;\r
+        }\r
+       else\r
+        {\r
+         ul->l=0xffffffff;\r
+        }\r
+       ul=0;\r
+       goto TENDLOOP;\r
+      }\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+\r
+   iC++; if(iC>=iSortTexCnt) iC=0;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // check, if free space got\r
+ //----------------------------------------------------//\r
+\r
+TENDLOOP:\r
+ if(ul) return FALSE;\r
+\r
+ rfree.c[3]+=cXAdj;\r
+ rfree.c[1]+=cYAdj;\r
+\r
+ tsx->cTexID   = iC;\r
+ tsx->posTX    = rfree.c[3];\r
+ tsx->posTY    = rfree.c[1];\r
+\r
+ XTexS=rfree.c[3];\r
+ YTexS=rfree.c[1];\r
+\r
+ return TRUE;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// compress texture cache (to make place for new texture part, if needed)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void CompressTextureSpace(void)\r
+{\r
+ textureSubCacheEntryS * tsx, * tsg, * tsb;\r
+ int i,j,k,m,n,iMax;EXLong * ul, r,opos;\r
+ short sOldDST=DrawSemiTrans,cx,cy;\r
+ long  lOGTP=GlobalTexturePage;\r
+ unsigned long l,row;\r
+ unsigned long * lSRCPtr;\r
+\r
+ opos.l=*((unsigned long *)&gl_ux[4]);\r
+\r
+ // 1. mark all textures as free\r
+ for(i=0;i<iSortTexCnt;i++)\r
+  {ul=pxSsubtexLeft[i];ul->l=0;}\r
+ usLRUTexPage=0;\r
+\r
+ // 2. compress\r
+ for(j=0;j<3;j++)\r
+  {\r
+   for(k=0;k<MAXTPAGES;k++)\r
+    {\r
+     tsg=pscSubtexStore[j][k];\r
+\r
+     if((!(dwTexPageComp&(1<<k))))\r
+      {\r
+       (tsg+SOFFA)->pos.l=0;\r
+       (tsg+SOFFB)->pos.l=0;\r
+       (tsg+SOFFC)->pos.l=0;\r
+       (tsg+SOFFD)->pos.l=0;\r
+       continue;\r
+      }\r
+\r
+     for(m=0;m<4;m++,tsg+=SOFFB)\r
+      {\r
+       iMax=tsg->pos.l;\r
+\r
+       tsx=tsg+1;\r
+       for(i=0;i<iMax;i++,tsx++)\r
+        {\r
+         if(tsx->ClutID)\r
+          {\r
+           r.l=tsx->pos.l;\r
+           for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++)\r
+            {\r
+             if(tsx->ClutID==tsb->ClutID)\r
+              {\r
+               r.c[3]=min(r.c[3],tsb->pos.c[3]);\r
+               r.c[2]=max(r.c[2],tsb->pos.c[2]);\r
+               r.c[1]=min(r.c[1],tsb->pos.c[1]);\r
+               r.c[0]=max(r.c[0],tsb->pos.c[0]);\r
+               tsb->ClutID=0;\r
+              }\r
+            }\r
+\r
+//           if(r.l!=tsx->pos.l)\r
+            {\r
+             cx=((tsx->ClutID << 4) & 0x3F0);          \r
+             cy=((tsx->ClutID >> 6) & CLUTYMASK);\r
+\r
+             if(j!=2)\r
+              {\r
+               // palette check sum\r
+               l=0;lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+               if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+               else     for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+               l=((l+HIWORD(l))&0x3fffL)<<16;\r
+               if(l!=(tsx->ClutID&(0x00003fff<<16)))\r
+                {\r
+                 tsx->ClutID=0;continue;\r
+                }\r
+              }\r
+\r
+             tsx->pos.l=r.l;\r
+             if(!GetCompressTexturePlace(tsx))         // no place?\r
+              {\r
+               for(i=0;i<3;i++)                        // -> clean up everything\r
+                for(j=0;j<MAXTPAGES;j++)\r
+                 {\r
+                  tsb=pscSubtexStore[i][j];\r
+                  (tsb+SOFFA)->pos.l=0;\r
+                  (tsb+SOFFB)->pos.l=0;\r
+                  (tsb+SOFFC)->pos.l=0;\r
+                  (tsb+SOFFD)->pos.l=0;\r
+                 }\r
+               for(i=0;i<iSortTexCnt;i++)\r
+                {ul=pxSsubtexLeft[i];ul->l=0;}\r
+               usLRUTexPage=0;\r
+               DrawSemiTrans=sOldDST;\r
+               GlobalTexturePage=lOGTP;\r
+               *((unsigned long *)&gl_ux[4])=opos.l;\r
+               dwTexPageComp=0;\r
+\r
+               return;\r
+              }\r
+\r
+             if(tsx->ClutID&(1<<30)) DrawSemiTrans=1;\r
+             else                    DrawSemiTrans=0;\r
+             *((unsigned long *)&gl_ux[4])=r.l;\r
+   \r
+             gTexName=uiStexturePage[tsx->cTexID];\r
+             LoadSubTexFn(k,j,cx,cy);\r
+             uiStexturePage[tsx->cTexID]=gTexName;\r
+             tsx->Opaque=ubOpaqueDraw;\r
+            }\r
+          }\r
+        }\r
+\r
+       if(iMax)  \r
+        {\r
+         tsx=tsg+iMax;\r
+         while(!tsx->ClutID && iMax) {tsx--;iMax--;}\r
+         tsg->pos.l=iMax;\r
+        }\r
+\r
+      }                      \r
+    }\r
+  }\r
+\r
+ if(dwTexPageComp==0xffffffff) dwTexPageComp=0;\r
+\r
+ *((unsigned long *)&gl_ux[4])=opos.l;\r
+ GlobalTexturePage=lOGTP;\r
+ DrawSemiTrans=sOldDST;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// main entry for searching/creating textures, called from prim.c\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint SelectSubTextureS(long TextureMode, unsigned long GivenClutId) \r
+{\r
+ u8 * OPtr;unsigned short iCache;short cx,cy;\r
+\r
+ // sort sow/tow infos for fast access\r
+\r
+ u8 ma1,ma2,mi1,mi2;\r
+ if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];}\r
+ else                  {mi1=gl_ux[0];ma1=gl_ux[1];}\r
+ if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];}\r
+ else                  {mi2=gl_ux[2];ma2=gl_ux[3];}\r
+ if(mi1>mi2) gl_ux[7]=mi2; \r
+ else        gl_ux[7]=mi1;\r
+ if(ma1>ma2) gl_ux[6]=ma1; \r
+ else        gl_ux[6]=ma2;\r
+\r
+ if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];}\r
+ else                  {mi1=gl_vy[0];ma1=gl_vy[1];}\r
+ if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];}\r
+ else                  {mi2=gl_vy[2];ma2=gl_vy[3];}\r
+ if(mi1>mi2) gl_ux[5]=mi2; \r
+ else        gl_ux[5]=mi1;\r
+ if(ma1>ma2) gl_ux[4]=ma1; \r
+ else        gl_ux[4]=ma2;\r
+\r
+ // get clut infos in one 32 bit val\r
+\r
+ if(TextureMode==2)                                    // no clut here\r
+  {\r
+   GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0;\r
\r
+   if(iFrameTexType && Fake15BitTexture()) \r
+    return (GLuint)gTexName;\r
+  }           \r
+ else \r
+  {\r
+   cx=((GivenClutId << 4) & 0x3F0);                    // but here\r
+   cy=((GivenClutId >> 6) & CLUTYMASK);\r
+   GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED;\r
+\r
+   // palette check sum.. removed MMX asm, this easy func works as well\r
+    {\r
+     unsigned long l=0,row;\r
+\r
+     unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+     if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+     else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+     l=(l+HIWORD(l))&0x3fffL;\r
+     GivenClutId|=(l<<16);\r
+    }\r
+\r
+  }\r
+\r
+ // search cache\r
+ iCache=0;\r
+ OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
+\r
+ // cache full? compress and try again\r
+ if(iCache==0xffff)\r
+  {\r
+   CompressTextureSpace();\r
+   OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
+  }\r
+\r
+ // found? fine\r
+ usLRUTexPage=iCache;\r
+ if(!OPtr) return uiStexturePage[iCache];\r
+\r
+ // not found? upload texture and store infos in cache\r
+ gTexName=uiStexturePage[iCache];\r
+ LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy);\r
+ uiStexturePage[iCache]=gTexName;\r
+ *OPtr=ubOpaqueDraw;\r
+ return (GLuint) gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
diff --git a/plugins/gpu-gles/gpuTexture.h b/plugins/gpu-gles/gpuTexture.h
new file mode 100644 (file)
index 0000000..680208c
--- /dev/null
@@ -0,0 +1,87 @@
+/***************************************************************************\r
+                          texture.h  -  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
+#ifndef _GPU_TEXTURE_H_\r
+#define _GPU_TEXTURE_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+#define TEXTUREPAGESIZE 256*256\r
+\r
+void           InitializeTextureStore();\r
+void           CleanupTextureStore();\r
+GLuint         LoadTextureWnd(long pageid,long TextureMode,unsigned long GivenClutId);\r
+GLuint         LoadTextureMovie(void);\r
+void           InvalidateTextureArea(long imageX0,long imageY0,long imageX1,long imageY1);\r
+void           InvalidateTextureAreaEx(void);\r
+void           LoadTexturePage(int pageid, int mode, short cx, short cy);\r
+void           ResetTextureArea(BOOL bDelTex);\r
+GLuint         SelectSubTextureS(long TextureMode, unsigned long GivenClutId);\r
+void           CheckTextureMemory(void);\r
+\r
+\r
+void           LoadSubTexturePage(int pageid, int mode, short cx, short cy);\r
+void           LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+void           LoadPackedSubTexturePage(int pageid, int mode, short cx, short cy);\r
+void           LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+unsigned long  XP8RGBA(unsigned long BGR);\r
+unsigned long  XP8RGBAEx(unsigned long BGR);\r
+unsigned long  XP8RGBA_0(unsigned long BGR);\r
+unsigned long  XP8RGBAEx_0(unsigned long BGR);\r
+unsigned long  XP8BGRA_0(unsigned long BGR);\r
+unsigned long  XP8BGRAEx_0(unsigned long BGR);\r
+unsigned long  XP8RGBA_1(unsigned long BGR);\r
+unsigned long  XP8RGBAEx_1(unsigned long BGR);\r
+unsigned long  XP8BGRA_1(unsigned long BGR);\r
+unsigned long  XP8BGRAEx_1(unsigned long BGR);\r
+unsigned long  P8RGBA(unsigned long BGR);\r
+unsigned long  P8BGRA(unsigned long BGR);\r
+unsigned long  CP8RGBA_0(unsigned long BGR);\r
+unsigned long  CP8RGBAEx_0(unsigned long BGR);\r
+unsigned long  CP8BGRA_0(unsigned long BGR);\r
+unsigned long  CP8BGRAEx_0(unsigned long BGR);\r
+unsigned long  CP8RGBA(unsigned long BGR);\r
+unsigned long  CP8RGBAEx(unsigned long BGR);\r
+unsigned short XP5RGBA (unsigned short BGR);\r
+unsigned short XP5RGBA_0 (unsigned short BGR);\r
+unsigned short XP5RGBA_1 (unsigned short BGR);\r
+unsigned short P5RGBA (unsigned short BGR);\r
+unsigned short CP5RGBA_0 (unsigned short BGR);\r
+unsigned short XP4RGBA (unsigned short BGR);\r
+unsigned short XP4RGBA_0 (unsigned short BGR);\r
+unsigned short XP4RGBA_1 (unsigned short BGR);\r
+unsigned short P4RGBA (unsigned short BGR);\r
+unsigned short CP4RGBA_0 (unsigned short BGR);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif // _TEXTURE_H_\r