gpu-gles from psx4m
[pcsx_rearmed.git] / plugins / gpu-gles / gpuPrim.c
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