gpu-gles from psx4m
[pcsx_rearmed.git] / plugins / gpu-gles / gpuTexture.c
diff --git a/plugins/gpu-gles/gpuTexture.c b/plugins/gpu-gles/gpuTexture.c
new file mode 100644 (file)
index 0000000..d047a62
--- /dev/null
@@ -0,0 +1,4226 @@
+/***************************************************************************\r
+                          texture.c  -  description\r
+                             -------------------\r
+    begin                : Sun Mar 08 2009\r
+    copyright            : (C) 1999-2009 by Pete Bernert\r
+    web                  : www.pbernert.com   \r
+ ***************************************************************************/\r
+\r
+/***************************************************************************\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version. See also the license.txt file for *\r
+ *   additional informations.                                              *\r
+ *                                                                         *\r
+ ***************************************************************************/\r
+\r
+//*************************************************************************// \r
+// History of changes:\r
+//\r
+// 2009/03/08 - Pete  \r
+// - generic cleanup for the Peops release\r
+//\r
+//*************************************************************************// \r
+\r
+\r
+////////////////////////////////////////////////////////////////////////////////////\r
+// Texture related functions are here !\r
+//\r
+// The texture handling is heart and soul of this gpu. The plugin was developed\r
+// 1999, by this time no shaders were available. Since the psx gpu is making\r
+// heavy use of CLUT (="color lookup tables", aka palettized textures), it was \r
+// an interesting task to get those emulated at good speed on NV TNT cards \r
+// (which was my major goal when I created the first "gpuPeteTNT"). Later cards \r
+// (Geforce256) supported texture palettes by an OGL extension, but at some point\r
+// this support was dropped again by gfx card vendors.\r
+// Well, at least there is a certain advatage, if no texture palettes extension can\r
+// be used: it is possible to modify the textures in any way, allowing "hi-res" \r
+// textures and other tweaks.\r
+//\r
+// My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures,\r
+// and it places small psx texture parts inside them. The plugin keeps track what \r
+// part (with what palette) it had placed in which texture, so it can re-use this \r
+// part again. The more ogl textures it can use, the better (of course the managing/\r
+// searching will be slower, but everything is faster than uploading textures again\r
+// and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked\r
+// well with many games, but I recommend nowadays 64 MB Vram to get a good speed.\r
+//\r
+// Sadly, there is also a second kind of texture cache needed, for "psx texture windows".\r
+// Those are "repeated" textures, so a psx "texture window" needs to be put in \r
+// a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very\r
+// fast in games which are having an heavy "texture window" usage, like RRT4. As an \r
+// alternative, this plugin can use the OGL "palette" extension on texture windows, \r
+// if available. Nowadays also a fragment shader can easily be used to emulate\r
+// texture wrapping in a texture atlas, so the main cache could hold the texture\r
+// windows as well (that's what I am doing in the OGL2 plugin). But currently the\r
+// OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause\r
+// much texture uploads.\r
+//\r
+// Some final advice: take care if you change things in here. I've removed my ASM\r
+// handlers (they didn't cause much speed gain anyway) for readability/portability,\r
+// but still the functions/data structures used here are easy to mess up. I guess it\r
+// can be a pain in the ass to port the plugin to another byte order :)\r
+//\r
+////////////////////////////////////////////////////////////////////////////////////\r
\r
+#define _IN_TEXTURE\r
+\r
+#ifdef _WINDOWS\r
+#include "stdafx.h"\r
+\r
+#include "externals.h"\r
+#include "texture.h"\r
+#include "gpu.h"\r
+#include "prim.h"\r
+#else\r
+#include "gpuStdafx.h"\r
+#ifdef __NANOGL__\r
+#include <gl/gl.h>\r
+#include <gl/gl.h>\r
+#else\r
+#ifdef SOFT_LINKAGE\r
+#pragma softfp_linkage\r
+#endif\r
+#ifdef MAEMO_CHANGES\r
+       #include <GLES/glplatform.h>\r
+       #include <GLES/gl.h>\r
+       #include <GLES/glext.h>\r
+       #include <EGL/egl.h>\r
+#else\r
+       #include <gles/gl.h> // for opengl es types \r
+       #include <gles/egltypes.h>\r
+#endif\r
+#ifdef SOFT_LINKAGE\r
+#pragma no_softfp_linkage\r
+#endif\r
+#endif\r
+#include "gpuDraw.h"\r
+//#include "plugins.h"\r
+#include "gpuExternals.h"\r
+#include "gpuTexture.h"\r
+#include "gpuPlugin.h"\r
+#include "gpuPrim.h"\r
+#endif\r
+#define CLUTCHK   0x00060000\r
+#define CLUTSHIFT 17\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// texture conversion buffer .. \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLubyte       ubPaletteBuffer[256][4];\r
+GLuint        gTexMovieName=0;\r
+GLuint        gTexBlurName=0;\r
+GLuint        gTexFrameName=0;\r
+int           iTexGarbageCollection=1;\r
+unsigned long dwTexPageComp=0;\r
+int           iVRamSize=0;\r
+#ifdef _WINDOWS\r
+int           iClampType=GL_CLAMP;\r
+#else\r
+int           iClampType=GL_CLAMP_TO_EDGE;\r
+#endif\r
+int iFilter = GL_LINEAR;\r
+void               (*LoadSubTexFn) (int,int,short,short);\r
+unsigned long      (*PalTexturedColourFn)  (unsigned long);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// defines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define PALCOL(x) PalTexturedColourFn (x)\r
+\r
+#define CSUBSIZE  2048\r
+#define CSUBSIZEA 8192\r
+#define CSUBSIZES 4096\r
+\r
+#define OFFA 0\r
+#define OFFB 2048\r
+#define OFFC 4096\r
+#define OFFD 6144\r
+\r
+#define XOFFA 0\r
+#define XOFFB 512\r
+#define XOFFC 1024\r
+#define XOFFD 1536\r
+\r
+#define SOFFA 0\r
+#define SOFFB 1024\r
+#define SOFFC 2048\r
+#define SOFFD 3072\r
+\r
+#define MAXWNDTEXCACHE 128\r
+\r
+#define XCHECK(pos1,pos2) ((pos1.c[0]>=pos2.c[1])&&(pos1.c[1]<=pos2.c[0])&&(pos1.c[2]>=pos2.c[3])&&(pos1.c[3]<=pos2.c[2]))\r
+#define INCHECK(pos2,pos1) ((pos1.c[0]<=pos2.c[0]) && (pos1.c[1]>=pos2.c[1]) && (pos1.c[2]<=pos2.c[2]) && (pos1.c[3]>=pos2.c[3]))\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache);\r
+void            LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+void            LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
+void            DefineSubTextureSort(void);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// some globals\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+long  GlobalTexturePage;\r
+GLint XTexS;\r
+GLint YTexS;\r
+GLint DXTexS;\r
+GLint DYTexS;\r
+int   iSortTexCnt=32;\r
+BOOL  bUseFastMdec=FALSE;\r
+BOOL  bUse15bitMdec=FALSE;\r
+int   iFrameTexType=0;\r
+int   iFrameReadType=0;\r
+\r
+unsigned long  (*TCF[2]) (unsigned long);\r
+unsigned short (*PTCF[2]) (unsigned short);\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// texture cache implementation\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WINDOWS\r
+#pragma pack(1)\r
+#endif\r
+\r
+// "texture window" cache entry\r
+\r
+typedef struct textureWndCacheEntryTag\r
+{\r
+ unsigned long  ClutID;\r
+ short          pageid;\r
+ short          textureMode;\r
+ short          Opaque;\r
+ short          used;\r
+ EXLong         pos;\r
+ GLuint         texname;\r
+} textureWndCacheEntry;\r
+\r
+// "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them)\r
+\r
+typedef struct textureSubCacheEntryTagS \r
+{\r
+ unsigned long   ClutID;\r
+ EXLong          pos;\r
+ u8   posTX;\r
+ u8   posTY;\r
+ u8   cTexID;\r
+ u8   Opaque;\r
+} textureSubCacheEntryS;\r
+\r
+#ifdef _WINDOWS\r
+#pragma pack()\r
+#endif\r
+\r
+//---------------------------------------------\r
+\r
+#define MAXTPAGES_MAX  64\r
+#define MAXSORTTEX_MAX 196\r
+\r
+//---------------------------------------------\r
+\r
+textureWndCacheEntry     wcWndtexStore[MAXWNDTEXCACHE];\r
+textureSubCacheEntryS *  pscSubtexStore[3][MAXTPAGES_MAX];\r
+EXLong *                 pxSsubtexLeft [MAXSORTTEX_MAX];\r
+GLuint                   uiStexturePage[MAXSORTTEX_MAX];\r
+\r
+unsigned short           usLRUTexPage=0;\r
+\r
+int                      iMaxTexWnds=0;\r
+int                      iTexWndTurn=0;\r
+int                      iTexWndLimit=MAXWNDTEXCACHE/2;\r
+\r
+GLubyte *                texturepart=NULL;\r
+GLubyte *                texturebuffer=NULL;\r
+unsigned long            g_x1,g_y1,g_x2,g_y2;\r
+u8            ubOpaqueDraw=0;\r
+\r
+unsigned short MAXTPAGES     = 32;\r
+unsigned short CLUTMASK      = 0x7fff;\r
+unsigned short CLUTYMASK     = 0x1ff;\r
+unsigned short MAXSORTTEX    = 196;\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Texture color conversions... all my ASM funcs are removed for easier\r
+// porting... and honestly: nowadays the speed gain would be pointless \r
+////////////////////////////////////////////////////////////////////////\r
+\r
+unsigned long XP8RGBA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long CP8RGBA(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xffffff00) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8RGBAEx(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xffffff00) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long XP8RGBA_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRA_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRAEx_0(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long CP8RGBA_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xfff8f800) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8RGBAEx_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xfff8f800) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8BGRA_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xff00f8f8) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long CP8BGRAEx_0(unsigned long BGR)\r
+{\r
+ unsigned long l;\r
+\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+ if(l==0xff00f8f8) l=0xff000000;\r
+ return l;\r
+}\r
+\r
+unsigned long XP8RGBA_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8RGBAEx_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRA_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x50000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long XP8BGRAEx_1(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0x03000000;\r
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long P8RGBA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0;\r
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned long P8BGRA(unsigned long BGR)\r
+{\r
+ if(!(BGR&0xffff)) return 0;\r
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
+}\r
+\r
+unsigned short XP5RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short XP5RGBA_0 (unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short CP5RGBA_0 (unsigned short BGR)\r
+{\r
+ unsigned short s;\r
+\r
+ if(!BGR) return 0;\r
+\r
+ s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+ if(s==0x07ff) s=1;\r
+ return s;\r
+}\r
+\r
+unsigned short XP5RGBA_1(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ if(!(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short P5RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
+}\r
+\r
+unsigned short XP4RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ if(DrawSemiTrans && !(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short XP4RGBA_0 (unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short CP4RGBA_0 (unsigned short BGR)\r
+{\r
+ unsigned short s;\r
+ if(!BGR) return 6;\r
+ s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+ if(s==0x0fff) s=0x000f;\r
+ return s;\r
+}\r
+\r
+unsigned short XP4RGBA_1(unsigned short BGR)\r
+{\r
+ if(!BGR) return 6;\r
+ if(!(BGR&0x8000)) \r
+  {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+unsigned short P4RGBA(unsigned short BGR)\r
+{\r
+ if(!BGR) return 0;\r
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// CHECK TEXTURE MEM (on plugin startup)\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+int iFTexA=512;\r
+int iFTexB=512;\r
+\r
+void CheckTextureMemory(void)\r
+{\r
+ GLboolean b;GLboolean * bDetail;\r
+ int i,iCnt,iRam=iVRamSize*1024*1024;\r
+ int iTSize;s8 * p;\r
+\r
+\r
+ if(iVRamSize)\r
+  {\r
+   int ts;\r
+\r
+   iRam-=(iResX*iResY*8);\r
+   iRam-=(iResX*iResY*(iZBufferDepth/8));\r
+\r
+          ts=4;\r
+          iSortTexCnt=iRam/(256*256*ts);\r
+\r
+   if(iSortTexCnt>MAXSORTTEX) \r
+    {\r
+     iSortTexCnt=MAXSORTTEX-min(1,0);\r
+    }\r
+   else\r
+    {\r
+     iSortTexCnt-=3+min(1,0);\r
+     if(iSortTexCnt<8) iSortTexCnt=8;\r
+    }\r
+\r
+   for(i=0;i<MAXSORTTEX;i++)\r
+    uiStexturePage[i]=0;\r
\r
+   return;\r
+  }\r
+\r
+\r
+        iTSize=256;\r
+ p=(s8 *)malloc(iTSize*iTSize*4);\r
+\r
+ iCnt=0;\r
+ glGenTextures(MAXSORTTEX,uiStexturePage);\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iTSize, iTSize, 0,GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+  }\r
+ glBindTexture(GL_TEXTURE_2D,0);\r
+\r
+ free(p);\r
+\r
+ bDetail=(GLboolean*)malloc(MAXSORTTEX*sizeof(GLboolean));\r
+ memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean));\r
+\r
+ glDeleteTextures(MAXSORTTEX,uiStexturePage);\r
+\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   if(bDetail[i]) iCnt++;\r
+   uiStexturePage[i]=0;\r
+  }\r
+\r
+ free(bDetail);\r
+\r
+ if(b) iSortTexCnt=MAXSORTTEX-min(1,0);\r
+ else  iSortTexCnt=iCnt-3+min(1,0);       // place for menu&texwnd\r
+\r
+ if(iSortTexCnt<8) iSortTexCnt=8;\r
+} \r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Main init of textures\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InitializeTextureStore() \r
+{\r
+ int i,j;\r
+\r
+ if(iGPUHeight==1024)\r
+  {\r
+   MAXTPAGES     = 64;\r
+   CLUTMASK      = 0xffff;\r
+   CLUTYMASK     = 0x3ff;\r
+   MAXSORTTEX    = 128;\r
+   iTexGarbageCollection=0;\r
+  }\r
+ else\r
+  {\r
+   MAXTPAGES     = 32;\r
+   CLUTMASK      = 0x7fff;\r
+   CLUTYMASK     = 0x1ff;\r
+   MAXSORTTEX    = 196;\r
+  }\r
+\r
+ memset(vertex,0,4*sizeof(OGLVertex));                 // init vertices\r
+\r
+ gTexName=0;                                           // init main tex name\r
+\r
+ iTexWndLimit=MAXWNDTEXCACHE;\r
+/* if(!iUsePalTextures) */iTexWndLimit/=2;\r
+\r
+ memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)*\r
+                        MAXWNDTEXCACHE);\r
+ texturepart=(GLubyte *)malloc(256*256*4);\r
+ memset(texturepart,0,256*256*4);\r
+        texturebuffer=NULL;\r
+\r
+ for(i=0;i<3;i++)                                    // -> info for 32*3\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   {                                               \r
+    pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS));\r
+    memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS));\r
+   }\r
+ for(i=0;i<MAXSORTTEX;i++)                           // -> info 0..511\r
+  {\r
+   pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong));\r
+   memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong));\r
+   uiStexturePage[i]=0;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Clean up on exit\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void CleanupTextureStore() \r
+{\r
+ int i,j;textureWndCacheEntry * tsx;\r
+ //----------------------------------------------------//\r
+ glBindTexture(GL_TEXTURE_2D,0);\r
+ //----------------------------------------------------//\r
+ free(texturepart);                                    // free tex part\r
+ texturepart=0;\r
+ if(texturebuffer)\r
+  {\r
+   free(texturebuffer);\r
+   texturebuffer=0;\r
+  }\r
+ //----------------------------------------------------//\r
+ tsx=wcWndtexStore;                                    // loop tex window cache\r
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
+  {\r
+   if(tsx->texname)                                    // -> some tex?\r
+    glDeleteTextures(1,&tsx->texname);                 // --> delete it\r
+  }\r
+ iMaxTexWnds=0;                                        // no more tex wnds\r
+ //----------------------------------------------------//\r
+ if(gTexMovieName!=0)                                  // some movie tex?\r
+  glDeleteTextures(1, &gTexMovieName);                 // -> delete it\r
+ gTexMovieName=0;                                      // no more movie tex\r
+ //----------------------------------------------------//\r
+ if(gTexFrameName!=0)                                  // some 15bit framebuffer tex?\r
+  glDeleteTextures(1, &gTexFrameName);                 // -> delete it\r
+ gTexFrameName=0;                                      // no more movie tex\r
+ //----------------------------------------------------//\r
+ if(gTexBlurName!=0)                                   // some 15bit framebuffer tex?\r
+  glDeleteTextures(1, &gTexBlurName);                  // -> delete it\r
+ gTexBlurName=0;                                       // no more movie tex\r
+ //----------------------------------------------------//\r
+ for(i=0;i<3;i++)                                    // -> loop\r
+  for(j=0;j<MAXTPAGES;j++)                           // loop tex pages\r
+   {\r
+    free(pscSubtexStore[i][j]);                      // -> clean mem\r
+   }\r
+ for(i=0;i<MAXSORTTEX;i++)\r
+  {\r
+   if(uiStexturePage[i])                             // --> tex used ?\r
+    {\r
+     glDeleteTextures(1,&uiStexturePage[i]);\r
+     uiStexturePage[i]=0;                            // --> delete it\r
+    }\r
+   free(pxSsubtexLeft[i]);                           // -> clean mem\r
+  }\r
+ //----------------------------------------------------//\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Reset textures in game...\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void ResetTextureArea(BOOL bDelTex)\r
+{\r
+ int i,j;textureSubCacheEntryS * tss;EXLong * lu;\r
+ textureWndCacheEntry * tsx;\r
+ //----------------------------------------------------//\r
+\r
+ dwTexPageComp=0;\r
+\r
+ //----------------------------------------------------//\r
+ if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;}\r
+ //----------------------------------------------------//\r
+ tsx=wcWndtexStore;\r
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
+  {\r
+   tsx->used=0;\r
+   if(bDelTex && tsx->texname)\r
+    {\r
+     glDeleteTextures(1,&tsx->texname);\r
+     tsx->texname=0;\r
+    }\r
+  }\r
+ iMaxTexWnds=0;\r
+ //----------------------------------------------------//\r
+\r
+ for(i=0;i<3;i++)\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   {\r
+    tss=pscSubtexStore[i][j];\r
+    (tss+SOFFA)->pos.l=0;\r
+    (tss+SOFFB)->pos.l=0;\r
+    (tss+SOFFC)->pos.l=0;\r
+    (tss+SOFFD)->pos.l=0;\r
+   }\r
+\r
+ for(i=0;i<iSortTexCnt;i++)\r
+  {\r
+   lu=pxSsubtexLeft[i];\r
+   lu->l=0;\r
+   if(bDelTex && uiStexturePage[i])\r
+    {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;}\r
+  }\r
+}\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Invalidate tex windows\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateWndTextureArea(long X,long Y,long W, long H)\r
+{\r
+ int i,px1,px2,py1,py2,iYM=1;\r
+ textureWndCacheEntry * tsw=wcWndtexStore;\r
+\r
+ W+=X-1;      \r
+ H+=Y-1;\r
+ if(X<0) X=0;if(X>1023) X=1023;\r
+ if(W<0) W=0;if(W>1023) W=1023;\r
+ if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
+ if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
+ W++;H++;\r
+\r
+ if(iGPUHeight==1024) iYM=3;\r
+\r
+ py1=min(iYM,Y>>8);\r
+ py2=min(iYM,H>>8);                                    // y: 0 or 1\r
+\r
+ px1=max(0,(X>>6));\r
+ px2=min(15,(W>>6));\r
+\r
+ if(py1==py2)\r
+  {\r
+   py1=py1<<4;px1+=py1;px2+=py1;                       // change to 0-31\r
+   for(i=0;i<iMaxTexWnds;i++,tsw++)\r
+    {\r
+     if(tsw->used)\r
+      {\r
+       if(tsw->pageid>=px1 && tsw->pageid<=px2)\r
+        {\r
+         tsw->used=0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+ else\r
+  {\r
+   py1=px1+16;py2=px2+16;\r
+   for(i=0;i<iMaxTexWnds;i++,tsw++)\r
+    {\r
+     if(tsw->used)\r
+      {\r
+       if((tsw->pageid>=px1 && tsw->pageid<=px2) ||\r
+          (tsw->pageid>=py1 && tsw->pageid<=py2))\r
+        {\r
+         tsw->used=0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+ // adjust tex window count\r
+ tsw=wcWndtexStore+iMaxTexWnds-1;\r
+ while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;}\r
+}\r
+\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// same for sort textures\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void MarkFree(textureSubCacheEntryS * tsx)\r
+{\r
+ EXLong * ul, * uls;\r
+ int j,iMax;u8 x1,y1,dx,dy;\r
+\r
+ uls=pxSsubtexLeft[tsx->cTexID];\r
+ iMax=uls->l;ul=uls+1;\r
+\r
+ if(!iMax) return;\r
+\r
+ for(j=0;j<iMax;j++,ul++)\r
+  if(ul->l==0xffffffff) break;\r
+\r
+ if(j<CSUBSIZE-2)\r
+  {\r
+   if(j==iMax) uls->l=uls->l+1;\r
+\r
+   x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3];\r
+   if(tsx->posTX) {x1--;dx+=3;}\r
+   y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1];\r
+   if(tsx->posTY) {y1--;dy+=3;}\r
+\r
+   ul->c[3]=x1;\r
+   ul->c[2]=dx;\r
+   ul->c[1]=y1;\r
+   ul->c[0]=dy;\r
+  }\r
+}\r
+\r
+void InvalidateSubSTextureArea(long X,long Y,long W, long H)\r
+{\r
+ int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM=1;\r
+ EXLong npos;textureSubCacheEntryS * tsb;\r
+ long x1,x2,y1,y2,xa,sw;\r
+\r
+ W+=X-1;      \r
+ H+=Y-1;\r
+ if(X<0) X=0;if(X>1023) X=1023;\r
+ if(W<0) W=0;if(W>1023) W=1023;\r
+ if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
+ if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
+ W++;H++;\r
+\r
+ if(iGPUHeight==1024) iYM=3;\r
+\r
+ py1=min(iYM,Y>>8);\r
+ py2=min(iYM,H>>8);                                    // y: 0 or 1\r
+ px1=max(0,(X>>6)-3);                                   \r
+ px2=min(15,(W>>6)+3);                                 // x: 0-15\r
+\r
+ for(py=py1;py<=py2;py++)\r
+  {\r
+   j=(py<<4)+px1;                                      // get page\r
+\r
+   y1=py*256;y2=y1+255;\r
+\r
+   if(H<y1)  continue;\r
+   if(Y>y2)  continue;\r
+\r
+   if(Y>y1)  y1=Y;\r
+   if(H<y2)  y2=H;\r
+   if(y2<y1) {sw=y1;y1=y2;y2=sw;}\r
+   y1=((y1%256)<<8);\r
+   y2=(y2%256);\r
+\r
+   for(px=px1;px<=px2;px++,j++)\r
+    {\r
+     for(k=0;k<3;k++)\r
+      {\r
+       xa=x1=px<<6;\r
+       if(W<x1) continue;\r
+       x2=x1+(64<<k)-1;\r
+       if(X>x2) continue;\r
+\r
+       if(X>x1)  x1=X;\r
+       if(W<x2)  x2=W;\r
+       if(x2<x1) {sw=x1;x1=x2;x2=sw;}\r
+\r
+       if (dwGPUVersion == 2)\r
+        npos.l=0x00ff00ff;\r
+       else\r
+        npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2;\r
+\r
+        {\r
+         tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++;\r
+         for(i=0;i<iMax;i++,tsb++)\r
+          if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+\r
+//         if(npos.l & 0x00800000)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+\r
+//         if(npos.l & 0x00000080)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+\r
+//         if(npos.l & 0x00800080)\r
+          {\r
+           tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++;\r
+           for(i=0;i<iMax;i++,tsb++)\r
+            if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Invalidate some parts of cache: main routine\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateTextureAreaEx(void)\r
+{\r
+ short W=sxmax-sxmin;\r
+ short H=symax-symin;\r
+\r
+ if(W==0 && H==0) return;\r
+\r
+ if(iMaxTexWnds) \r
+  InvalidateWndTextureArea(sxmin,symin,W,H);\r
+\r
+ InvalidateSubSTextureArea(sxmin,symin,W,H);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void InvalidateTextureArea(long X,long Y,long W, long H)\r
+{\r
+ if(W==0 && H==0) return;\r
+\r
+ if(iMaxTexWnds) InvalidateWndTextureArea(X,Y,W,H); \r
+\r
+ InvalidateSubSTextureArea(X,Y,W,H);\r
+}\r
+\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: define\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineTextureWnd(void)\r
+{\r
+ if(gTexName==0)\r
+  glGenTextures(1, &gTexName);\r
+\r
+ glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
\r
+{\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+  }\r
+\r
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
+              TWin.Position.x1, \r
+              TWin.Position.y1, \r
+              0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load packed stretch\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned short *wSRCPtr,*wOSRCPtr;\r
+ unsigned long  LineOffset;unsigned short s;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<16;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+          *ta++=s;\r
+\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LPTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*(pa+(*cSRCPtr & 0xF));\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<256;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+\r
+          *ta++=s;\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
+                                \r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      wOSRCPtr=wSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LPTCOL(*wSRCPtr++);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
+      else                 wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load stretched\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned short *wSRCPtr,*wOSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    //------------------- ZN STUFF\r
+\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+          *ta++=s;\r
+\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    //-------------------\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*(pa+(*cSRCPtr & 0xF));\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------//\r
+   // 8bit texture load ..\r
+   case 1:\r
+    //------------ ZN STUFF\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=g_y2-ldy;\r
+      for(TXV=g_y1;TXV<=column;TXV++)\r
+       {\r
+        ldx=ldxo;\r
+        for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+          *ta++=s;\r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+\r
+        if(ldy) \r
+         {ldy--;\r
+          for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+           *ta++=*(ta-(g_x2-g_x1));\r
+         }\r
+\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+    //------------\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;    \r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      wOSRCPtr=wSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=LTCOL(*wSRCPtr++);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
+      else                 wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load packed simple\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<16;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LPTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      for(row=0;row<256;row++)\r
+       *px++=LPTCOL(*wSRCPtr++);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LPTCOL(*wSRCPtr++);\r
+      wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: load simple\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy*1024);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    for(row=0;row<16;row++)\r
+     *px++=LTCOL(*wSRCPtr++);\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------//\r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=g_y1;TXV<=g_y2;TXV++)\r
+       {\r
+        for(TXU=g_x1;TXU<=g_x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+       }\r
+\r
+      DefineTextureWnd();\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)*64)+256*1024*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
+    LineOffset = 1024 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=LTCOL(*wSRCPtr++);\r
+      wSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefineTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void UploadTexWndPal(int mode,short cx,short cy)\r
+{\r
+ unsigned int i,iSize;\r
+ unsigned short * wSrcPtr;\r
+ unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+ wSrcPtr=psxVuw+cx+(cy*1024);\r
+ if(mode==0) i=4; else i=64;\r
+ iSize=i<<2;\r
+ ubOpaqueDraw=0;\r
+\r
+ do\r
+  {\r
+   *ta    =PALCOL(*wSrcPtr);\r
+   *(ta+1)=PALCOL(*(wSrcPtr+1));\r
+   *(ta+2)=PALCOL(*(wSrcPtr+2));\r
+   *(ta+3)=PALCOL(*(wSrcPtr+3));\r
+   ta+=4;wSrcPtr+=4;i--;\r
+  }\r
+ while(i);\r
+\r
+/* (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize,\r
+                    GL_RGBA,GL_UNSIGNED_BYTE,texturepart);\r
+*/}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefinePalTextureWnd(void)\r
+{\r
+ if(gTexName==0)\r
+  glGenTextures(1, &gTexName);\r
+\r
+ glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
\r
+{\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+  }\r
+\r
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
+              TWin.Position.x1, \r
+              TWin.Position.y1, \r
+              0, GL_RGBA, GL_UNSIGNED_BYTE,texturepart);\r
+}\r
+\r
+///////////////////////////////////////////////////////\r
+\r
+void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm;\r
+ u8  *ta;\r
+ u8  *cSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+\r
+ ta=(u8 *)texturepart;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (2048*column) + sxh;\r
+    \r
+      if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
+      \r
+      for(row=j;row<=g_x2;row++)\r
+       {\r
+        *ta++=(*cSRCPtr & 0xF); row++;\r
+        if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF); \r
+        cSRCPtr++;\r
+       }\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    // not using a lookup table here... speeds up smaller texture areas\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1); \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      for(row=g_x1;row<=g_x2;row++)\r
+       *ta++=*cSRCPtr++;\r
+      cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+  }\r
+ UploadTexWndPal(mode,cx,cy);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
+ u8  *ta,s;\r
+ u8  *cSRCPtr,*cOSRCPtr;\r
+ unsigned long  LineOffset;\r
+ int pmult=pageid/16;\r
+\r
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
+ ldy =TWin.Position.y1-TWin.OPosition.y1;\r
+\r
+ ta=(u8 *)texturepart;\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    sxm=g_x1&1;sxh=g_x1>>1;\r
+    if(sxm) j=g_x1+1; else j=g_x1;\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
+      \r
+      for(row=j;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=(*cSRCPtr & 0xF);\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+        row++;\r
+        if(row<=g_x2-ldxo) \r
+         {\r
+          s=((*cSRCPtr >> 4) & 0xF);\r
+          *ta++=s; \r
+          if(ldx) {*ta++=s;ldx--;}\r
+         }\r
+        cSRCPtr++;\r
+       }\r
+      if(ldy && column&1) \r
+           {ldy--;cSRCPtr = cOSRCPtr;}\r
+      else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    start=((pageid-16*pmult)*128)+256*2048*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
+    LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
+\r
+    for(column=g_y1;column<=g_y2;column++)\r
+     {\r
+      cOSRCPtr=cSRCPtr;ldx=ldxo;\r
+      for(row=g_x1;row<=g_x2-ldxo;row++)\r
+       {\r
+        s=*cSRCPtr++;\r
+        *ta++=s;\r
+        if(ldx) {*ta++=s;ldx--;}\r
+       }\r
+      if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
+      else                cSRCPtr+=LineOffset;\r
+     }\r
+\r
+    DefinePalTextureWnd();\r
+    break;\r
+  }\r
+ UploadTexWndPal(mode,cx,cy);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// tex window: main selecting, cache handler included\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureWnd(long pageid,long TextureMode,unsigned long GivenClutId)\r
+{\r
+ textureWndCacheEntry * ts, * tsx=NULL;\r
+ int i;short cx,cy;\r
+ EXLong npos;\r
+\r
+ npos.c[3]=TWin.Position.x0;\r
+ npos.c[2]=TWin.OPosition.x1;\r
+ npos.c[1]=TWin.Position.y0;\r
+ npos.c[0]=TWin.OPosition.y1;\r
+\r
+ g_x1=TWin.Position.x0;g_x2=g_x1+TWin.Position.x1-1;\r
+ g_y1=TWin.Position.y0;g_y2=g_y1+TWin.Position.y1-1;\r
+\r
+ if(TextureMode==2) {GivenClutId=0;cx=cy=0;}\r
+ else  \r
+  {\r
+   cx=((GivenClutId << 4) & 0x3F0);cy=((GivenClutId >> 6) & CLUTYMASK);\r
+   GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30);\r
+\r
+   // palette check sum\r
+    {\r
+     unsigned long l=0,row;\r
+     unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+     if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+     else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+     l=(l+HIWORD(l))&0x3fffL;\r
+     GivenClutId|=(l<<16);\r
+    }\r
+\r
+  }\r
+\r
+ ts=wcWndtexStore;\r
+\r
+ for(i=0;i<iMaxTexWnds;i++,ts++)\r
+  {\r
+   if(ts->used)\r
+    {\r
+     if(ts->pos.l==npos.l &&\r
+        ts->pageid==pageid &&\r
+        ts->textureMode==TextureMode)\r
+      {\r
+       if(ts->ClutID==GivenClutId)\r
+        {\r
+         ubOpaqueDraw=ts->Opaque;\r
+         return ts->texname;\r
+        }\r
+      }\r
+    }\r
+   else tsx=ts;\r
+  }\r
+\r
+ if(!tsx) \r
+  {\r
+   if(iMaxTexWnds==iTexWndLimit)\r
+    {\r
+     tsx=wcWndtexStore+iTexWndTurn;\r
+     iTexWndTurn++; \r
+     if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0;\r
+    }\r
+   else\r
+    {\r
+     tsx=wcWndtexStore+iMaxTexWnds;\r
+     iMaxTexWnds++;\r
+    }\r
+  }\r
+\r
+ gTexName=tsx->texname;\r
+\r
+ if(TWin.OPosition.y1==TWin.Position.y1 &&\r
+    TWin.OPosition.x1==TWin.Position.x1)\r
+  {\r
+    LoadWndTexturePage(pageid,TextureMode,cx,cy);\r
+  }       \r
+ else\r
+  {\r
+    LoadStretchWndTexturePage(pageid,TextureMode,cx,cy);\r
+  }\r
+\r
+ tsx->Opaque=ubOpaqueDraw;\r
+ tsx->pos.l=npos.l;\r
+ tsx->ClutID=GivenClutId;\r
+ tsx->pageid=pageid;\r
+ tsx->textureMode=TextureMode;\r
+ tsx->texname=gTexName;\r
+ tsx->used=1;\r
+       \r
+ return gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: define\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefinePackedTextureMovie(void)\r
+{\r
+ if(gTexMovieName==0)\r
+  {\r
+   glGenTextures(1, &gTexMovieName);\r
+   gTexName=gTexMovieName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(!bUseFastMdec) \r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+                                 \r
+   glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA, \r
+                GL_RGBA,\r
+                256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
+                 (xrMovieArea.x1-xrMovieArea.x0), \r
+                 (xrMovieArea.y1-xrMovieArea.y0), \r
+                 GL_RGBA,\r
+                 GL_UNSIGNED_SHORT,\r
+                 texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineTextureMovie(void)\r
+{\r
+ if(gTexMovieName==0)\r
+  {\r
+   glGenTextures(1, &gTexMovieName);\r
+   gTexName=gTexMovieName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
\r
+   if(!bUseFastMdec) \r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
+                 (xrMovieArea.x1-xrMovieArea.x0), \r
+                 (xrMovieArea.y1-xrMovieArea.y0), \r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: load\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define MRED(x)   ((x>>3) & 0x1f)\r
+#define MGREEN(x) ((x>>6) & 0x3e0)\r
+#define MBLUE(x)  ((x>>9) & 0x7c00)\r
+\r
+#define XMGREEN(x) ((x>>5)  & 0x07c0)\r
+#define XMRED(x)   ((x<<8)  & 0xf800)\r
+#define XMBLUE(x)  ((x>>18) & 0x003e)\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// movie texture: load\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * LoadDirectMovieFast(void)\r
+{\r
+ long row,column;\r
+ unsigned int startxy;\r
+\r
+ unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+ if(PSXDisplay.RGB24)\r
+  {\r
+   u8 * pD;\r
+\r
+   startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
+\r
+   for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
+    {\r
+     pD=(u8 *)&psxVuw[startxy];\r
+     for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+      {\r
+       *ta++=*((unsigned long *)pD)|0xff000000;\r
+       pD+=3;\r
+      }\r
+    }\r
+  }\r
+ else\r
+  {\r
+   unsigned long (*LTCOL)(unsigned long);\r
+\r
+   LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+   ubOpaqueDraw=0;\r
+\r
+   for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+    {\r
+     startxy=((1024)*column)+xrMovieArea.x0;\r
+     for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+      *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+    }\r
+  }\r
\r
+ return texturepart;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureMovieFast(void)\r
+{\r
+ long row,column;\r
+ unsigned int start,startxy;\r
+\r
+{\r
+   if(PSXDisplay.RGB24)\r
+    {\r
+     u8 * pD;\r
+     unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+     startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
+\r
+     for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
+      {\r
+       //startxy=((1024)*column)+xrMovieArea.x0;\r
+       pD=(u8 *)&psxVuw[startxy];\r
+       for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+        {\r
+         *ta++=*((unsigned long *)pD)|0xff000000;\r
+         pD+=3;\r
+        }\r
+      }\r
+    }\r
+   else\r
+    {\r
+     unsigned long (*LTCOL)(unsigned long);\r
+     unsigned long *ta;\r
+\r
+     LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+     ubOpaqueDraw=0;\r
+     ta=(unsigned long *)texturepart;\r
+\r
+     for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+      {\r
+       startxy=((1024)*column)+xrMovieArea.x0;\r
+       for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+        *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+      }\r
+    }\r
+   DefineTextureMovie();\r
+  }\r
+ return gTexName;   \r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint LoadTextureMovie(void)\r
+{\r
+ short row,column,dx;\r
+ unsigned int startxy;\r
+ BOOL b_X,b_Y;\r
+\r
+ if(bUseFastMdec) return LoadTextureMovieFast();\r
+\r
+ b_X=FALSE;b_Y=FALSE;\r
+\r
+ if((xrMovieArea.x1-xrMovieArea.x0)<255)  b_X=TRUE;\r
+ if((xrMovieArea.y1-xrMovieArea.y0)<255)  b_Y=TRUE;\r
+\r
+{\r
+   if(PSXDisplay.RGB24)\r
+    {\r
+     u8 * pD;\r
+     unsigned long * ta=(unsigned long *)texturepart;\r
+\r
+     if(b_X)\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         pD=(u8 *)&psxVuw[startxy];\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          {\r
+           *ta++=*((unsigned long *)pD)|0xff000000;\r
+           pD+=3;\r
+          }\r
+         *ta++=*(ta-1);\r
+        }\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+         *ta++=*(ta-1);\r
+        }\r
+      }\r
+     else\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         pD=(u8 *)&psxVuw[startxy];\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          {\r
+           *ta++=*((unsigned long *)pD)|0xff000000;\r
+           pD+=3;\r
+          }\r
+        }\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+        }\r
+      }\r
+    }\r
+   else\r
+    {\r
+     unsigned long (*LTCOL)(unsigned long);\r
+     unsigned long *ta;\r
+\r
+     LTCOL=XP8RGBA_0;//TCF[0];\r
+\r
+     ubOpaqueDraw=0;\r
+     ta=(unsigned long *)texturepart;\r
+\r
+     if(b_X)\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+         *ta++=*(ta-1);\r
+        }\r
+\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+         *ta++=*(ta-1);\r
+        }\r
+      }\r
+     else\r
+      {\r
+       for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
+        {\r
+         startxy=((1024)*column)+xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
+        }\r
+\r
+       if(b_Y)\r
+        {\r
+         dx=xrMovieArea.x1-xrMovieArea.x0;\r
+         for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
+          *ta++=*(ta-dx);\r
+        }\r
+      }\r
+    }\r
+\r
+   xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y;\r
+   DefineTextureMovie();\r
+   xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y;\r
+  }\r
+ return gTexName;   \r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint BlackFake15BitTexture(void)\r
+{\r
+ long pmult;short x1,x2,y1,y2;\r
+\r
+ if(PSXDisplay.InterlacedTest) return 0;\r
\r
+ pmult=GlobalTexturePage/16;\r
+ x1=gl_ux[7];\r
+ x2=gl_ux[6]-gl_ux[7];\r
+ y1=gl_ux[5];\r
+ y2=gl_ux[4]-gl_ux[5];\r
+\r
+ if(iSpriteTex)\r
+  {\r
+   if(x2<255) x2++;\r
+   if(y2<255) y2++;\r
+  }\r
+\r
+ y1+=pmult*256;\r
+ x1+=((GlobalTexturePage-16*pmult)<<6);\r
+\r
+ if(   FastCheckAgainstFrontScreen(x1,y1,x2,y2)\r
+    || FastCheckAgainstScreen(x1,y1,x2,y2))\r
+  {\r
+   if(!gTexFrameName)\r
+    {\r
+     glGenTextures(1, &gTexFrameName);\r
+     gTexName=gTexFrameName;\r
+     glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
\r
+     {\r
+       unsigned long * ta=(unsigned long *)texturepart;\r
+       for(y1=0;y1<=4;y1++)\r
+        for(x1=0;x1<=4;x1++)\r
+         *ta++=0xff000000;\r
+      }\r
+     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+    }\r
+   else\r
+    {\r
+     gTexName=gTexFrameName;\r
+     glBindTexture(GL_TEXTURE_2D, gTexName);\r
+    }\r
+\r
+   ubOpaqueDraw=0;\r
+\r
+   return (GLuint)gTexName;\r
+  }\r
+ return 0;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL bFakeFrontBuffer=FALSE;\r
+BOOL bIgnoreNextTile =FALSE;\r
+\r
+int iFTex=512;\r
+\r
+GLuint Fake15BitTexture(void)\r
+{\r
+ long pmult;short x1,x2,y1,y2;int iYAdjust;\r
+ float ScaleX,ScaleY;RECT rSrc;\r
+\r
+ if(iFrameTexType==1) return BlackFake15BitTexture();\r
+ if(PSXDisplay.InterlacedTest) return 0;\r
\r
+ pmult=GlobalTexturePage/16;\r
+ x1=gl_ux[7];\r
+ x2=gl_ux[6]-gl_ux[7];\r
+ y1=gl_ux[5];\r
+ y2=gl_ux[4]-gl_ux[5];\r
+\r
+ y1+=pmult*256;\r
+ x1+=((GlobalTexturePage-16*pmult)<<6);\r
+\r
+ if(iFrameTexType==3)\r
+  {\r
+   if(iFrameReadType==4) return 0;\r
+\r
+   if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) &&\r
+      !FastCheckAgainstScreen(x1,y1,x2,y2))\r
+    return 0;\r
+\r
+   if(bFakeFrontBuffer) bIgnoreNextTile=TRUE;\r
+   CheckVRamReadEx(x1,y1,x1+x2,y1+y2);\r
+   return 0;\r
+  }\r
+\r
+ /////////////////////////\r
+\r
+ if(FastCheckAgainstFrontScreen(x1,y1,x2,y2))\r
+  {\r
+   x1-=PSXDisplay.DisplayPosition.x;\r
+   y1-=PSXDisplay.DisplayPosition.y;\r
+  }\r
+ else\r
+ if(FastCheckAgainstScreen(x1,y1,x2,y2))\r
+  {\r
+   x1-=PreviousPSXDisplay.DisplayPosition.x;\r
+   y1-=PreviousPSXDisplay.DisplayPosition.y;\r
+  }\r
+ else return 0;\r
+\r
+ bDrawMultiPass = FALSE;\r
+\r
+ if(!gTexFrameName)\r
+  {\r
+   s8 * p;\r
+\r
+   if(iResX>1280 || iResY>1024) iFTex=2048;\r
+   else\r
+   if(iResX>640  || iResY>480)  iFTex=1024;\r
+   else                         iFTex=512; \r
+\r
+   glGenTextures(1, &gTexFrameName);\r
+   gTexName=gTexFrameName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+\r
+   p=(s8 *)malloc(iFTex*iFTex*4);\r
+   memset(p,0,iFTex*iFTex*4);\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iFTex, iFTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+   free(p);\r
+\r
+   glGetError();\r
+  }\r
+ else \r
+  {\r
+   gTexName=gTexFrameName;\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+  }\r
+\r
+ x1+=PreviousPSXDisplay.Range.x0;\r
+ y1+=PreviousPSXDisplay.Range.y0;\r
+\r
+ if(PSXDisplay.DisplayMode.x)\r
+      ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
+ else ScaleX=1.0f;\r
+ if(PSXDisplay.DisplayMode.y)\r
+      ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
+ else ScaleY=1.0f;\r
+\r
+ rSrc.left  =max(x1*ScaleX,0);\r
+ rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1);\r
+ rSrc.top   =max(y1*ScaleY,0);\r
+ rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1);\r
+\r
+ iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y;\r
+ if(iYAdjust>0)\r
+      iYAdjust=(int)((float)iYAdjust*ScaleY)+1;\r
+ else iYAdjust=0;\r
+          \r
+ gl_vy[0]=255-gl_vy[0];\r
+ gl_vy[1]=255-gl_vy[1];\r
+ gl_vy[2]=255-gl_vy[2];\r
+ gl_vy[3]=255-gl_vy[3];\r
+\r
+ y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3])));\r
+\r
+ gl_vy[0]-=y1;\r
+ gl_vy[1]-=y1;\r
+ gl_vy[2]-=y1;\r
+ gl_vy[3]-=y1;\r
+ gl_ux[0]-=gl_ux[7];\r
+ gl_ux[1]-=gl_ux[7];\r
+ gl_ux[2]-=gl_ux[7];\r
+ gl_ux[3]-=gl_ux[7];\r
+\r
+ ScaleX*=256.0f/((float)(iFTex));\r
+ ScaleY*=256.0f/((float)(iFTex));\r
+\r
+ y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[0]=y1;\r
+ y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[1]=y1;\r
+ y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[2]=y1;\r
+ y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255;\r
+ gl_vy[3]=y1;\r
+\r
+ x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[0]=x1;\r
+ x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[1]=x1;\r
+ x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[2]=x1;\r
+ x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255;\r
+ gl_ux[3]=x1;\r
+\r
+ x1=rSrc.right-rSrc.left;\r
+ if(x1<=0)             x1=1;\r
+ if(x1>iFTex)          x1=iFTex;\r
+\r
+ y1=rSrc.bottom-rSrc.top;\r
+ if(y1<=0)             y1=1;\r
+ if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust;\r
+\r
+\r
+ glCopyTexSubImage2D( GL_TEXTURE_2D, 0, \r
+                      0,\r
+                      iYAdjust,\r
+                      rSrc.left+rRatioRect.left,\r
+                      iResY-rSrc.bottom-rRatioRect.top,\r
+                      x1,y1);\r
+\r
+ if(glGetError()) \r
+  {\r
+   s8 * p=(s8 *)malloc(iFTex*iFTex*4);\r
+   memset(p,0,iFTex*iFTex*4);\r
+   glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex,\r
+                   GL_RGBA, GL_UNSIGNED_BYTE, p);\r
+   free(p);\r
+  }\r
+\r
\r
+ ubOpaqueDraw=0;\r
+\r
+ if(iSpriteTex)\r
+  {\r
+   sprtW=gl_ux[1]-gl_ux[0];    \r
+   sprtH=-(gl_vy[0]-gl_vy[2]);\r
+  }\r
+\r
+ return (GLuint)gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// load texture part (unpacked)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long  start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned long  *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ unsigned long  x2a,xalign=0;\r
+ unsigned long  x1=gl_ux[7];\r
+ unsigned long  x2=gl_ux[6];\r
+ unsigned long  y1=gl_ux[5];\r
+ unsigned long  y2=gl_ux[4];\r
+ unsigned long  dx=x2-x1+1;\r
+ unsigned long  dy=y2-y1+1;\r
+ int pmult=pageid/16;\r
+ unsigned long (*LTCOL)(unsigned long);\r
+ unsigned int a,r,g,b,cnt,h;\r
+ unsigned long scol[8];\r
\r
+ LTCOL=TCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned long *)ubPaletteBuffer;\r
+ ta=(unsigned long *)texturepart;\r
+ palstart=cx+(cy<<10);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
+ if(XTexS) {ta+=1;xalign=2;}\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=4;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+    // convert CLUT to 32bits .. and then use THAT as a lookup table\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+\r
+    row=4;do\r
+     {\r
+      *px    =LTCOL(*wSRCPtr);\r
+      *(px+1)=LTCOL(*(wSRCPtr+1));\r
+      *(px+2)=LTCOL(*(wSRCPtr+2));\r
+      *(px+3)=LTCOL(*(wSRCPtr+3));\r
+      row--;px+=4;wSRCPtr+=4;\r
+     }\r
+    while (row);\r
+\r
+    x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
+    sxm=x1&1;sxh=x1>>1;\r
+    j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
+    for(column=y1;column<=y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (column<<11) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
+\r
+      for(row=j;row<x2a;row+=2)\r
+       {\r
+        *ta    =*(pa+(*cSRCPtr & 0xF)); \r
+        *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;ta+=2;\r
+       }\r
+\r
+      if(row<=x2) \r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
+        if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+       }\r
+\r
+      ta+=xalign;\r
+     }\r
+\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (y1<<11) + x1;\r
+    LineOffset = 2048 - dx; \r
+\r
+    if(dy*dx>384)\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LTCOL(*wSRCPtr);\r
+        *(px+1)=LTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
+        ta+=xalign;\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    else\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
+        ta+=xalign;\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)<<6)+262144*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
+    LineOffset = 1024 - dx; \r
+\r
+    column=dy;do \r
+     {\r
+      row=dx;\r
+      do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row);\r
+      ta+=xalign;\r
+      wSRCPtr+=LineOffset;column--;\r
+     }\r
+    while(column);\r
+\r
+    break;\r
+   //--------------------------------------------------//\r
+   // others are not possible !\r
+  }\r
+\r
+ x2a=dx+xalign;\r
+\r
+ if(YTexS)\r
+  {\r
+   ta=(unsigned long *)texturepart;\r
+   pa=(unsigned long *)texturepart+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);        \r
+   pa=(unsigned long *)texturepart+dy*x2a;\r
+   ta=pa+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+   YTexS--;\r
+   dy+=2;\r
+  }\r
+\r
+ if(XTexS)\r
+  {\r
+   ta=(unsigned long *)texturepart;\r
+   pa=ta+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+   pa=(unsigned long *)texturepart+dx;\r
+   ta=pa+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+   XTexS--;\r
+   dx+=2;\r
+  }\r
+\r
+ DXTexS=dx;DYTexS=dy;\r
+\r
+ if(!iFilterType) {DefineSubTextureSort();return;}\r
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
+  {DefineSubTextureSort();return;}\r
+\r
+ ta=(unsigned long *)texturepart;\r
+ x1=dx-1;\r
+ y1=dy-1;\r
+\r
+ if(bOpaquePass)\r
+  {\r
+{\r
+     for(column=0;column<dy;column++)\r
+      {\r
+       for(row=0;row<dx;row++)\r
+        {\r
+         if(*ta==0x50000000)\r
+          {\r
+           cnt=0;\r
+\r
+           if(           column     && *(ta-dx)  !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx);\r
+           if(row                   && *(ta-1)   !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1);\r
+           if(row!=x1               && *(ta+1)   !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1);\r
+           if(           column!=y1 && *(ta+dx)  !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx);\r
+\r
+           if(row     && column     && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1);\r
+           if(row!=x1 && column     && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1);\r
+           if(row     && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1);\r
+           if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1);\r
+\r
+           if(cnt)\r
+            {\r
+             r=g=b=a=0;\r
+             for(h=0;h<cnt;h++)\r
+              {\r
+               a+=(scol[h]>>24);\r
+               r+=(scol[h]>>16)&0xff;\r
+               g+=(scol[h]>>8)&0xff;\r
+               b+=scol[h]&0xff;\r
+              }\r
+             r/=cnt;b/=cnt;g/=cnt;\r
+\r
+             *ta=(r<<16)|(g<<8)|b;\r
+             if(a) *ta|=0x50000000;\r
+             else  *ta|=0x01000000;\r
+            }\r
+          }\r
+         ta++;\r
+        }\r
+      }\r
+    }\r
+  }\r
+ else\r
+ for(column=0;column<dy;column++)\r
+  {\r
+   for(row=0;row<dx;row++)\r
+    {\r
+     if(*ta==0x00000000)\r
+      {\r
+       cnt=0;\r
+\r
+       if(row!=x1               && *(ta+1)   !=0x00000000) scol[cnt++]=*(ta+1);\r
+       if(           column!=y1 && *(ta+dx)  !=0x00000000) scol[cnt++]=*(ta+dx);\r
+\r
+       if(cnt)\r
+        {\r
+         r=g=b=0;\r
+         for(h=0;h<cnt;h++)\r
+          {\r
+           r+=(scol[h]>>16)&0xff;\r
+           g+=(scol[h]>>8)&0xff;\r
+           b+=scol[h]&0xff;\r
+          }\r
+         r/=cnt;b/=cnt;g/=cnt;\r
+         *ta=(r<<16)|(g<<8)|b;\r
+        }\r
+      }\r
+     ta++;\r
+    }\r
+  }\r
+\r
+ DefineSubTextureSort();\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// load texture part (packed)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
+{\r
+ unsigned long  start,row,column,j,sxh,sxm;\r
+ unsigned int   palstart;\r
+ unsigned short *px,*pa,*ta;\r
+ u8  *cSRCPtr;\r
+ unsigned short *wSRCPtr;\r
+ unsigned long  LineOffset;\r
+ unsigned long  x2a,xalign=0;\r
+ unsigned long  x1=gl_ux[7];\r
+ unsigned long  x2=gl_ux[6];\r
+ unsigned long  y1=gl_ux[5];\r
+ unsigned long  y2=gl_ux[4];\r
+ unsigned long  dx=x2-x1+1;\r
+ unsigned long  dy=y2-y1+1;\r
+ int pmult=pageid/16;\r
+ unsigned short (*LPTCOL)(unsigned short);\r
+ unsigned int a,r,g,b,cnt,h;\r
+ unsigned short scol[8];\r
+\r
+ LPTCOL=PTCF[DrawSemiTrans];\r
+\r
+ pa=px=(unsigned short *)ubPaletteBuffer;\r
+ ta=(unsigned short *)texturepart;\r
+ palstart=cx+(cy<<10);\r
+\r
+ ubOpaqueDraw=0;\r
+\r
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
+ if(XTexS) {ta+=1;xalign=2;}\r
+\r
+ switch(mode)\r
+  {\r
+   //--------------------------------------------------// \r
+   // 4bit texture load ..\r
+   case 0:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+      row=4;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
+                 n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    wSRCPtr=psxVuw+palstart;\r
+    row=4;do\r
+     {\r
+      *px    =LPTCOL(*wSRCPtr);\r
+      *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+      *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+      *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+      row--;px+=4;wSRCPtr+=4;\r
+     }\r
+    while (row);\r
+\r
+    x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
+    sxm=x1&1;sxh=x1>>1;\r
+    j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
+\r
+    for(column=y1;column<=y2;column++)\r
+     {\r
+      cSRCPtr = psxVub + start + (column<<11) + sxh;\r
+    \r
+      if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
\r
+      for(row=j;row<x2a;row+=2)\r
+       {\r
+        *ta    =*(pa+(*cSRCPtr & 0xF));\r
+        *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
+        cSRCPtr++;ta+=2;\r
+       }\r
+\r
+      if(row<=x2)\r
+       {\r
+        *ta++=*(pa+(*cSRCPtr & 0xF));row++;\r
+        if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
+       }\r
+\r
+      ta+=xalign;\r
+     }\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 8bit texture load ..\r
+   case 1:\r
+    if(GlobalTextIL)\r
+     {\r
+      unsigned int TXV,TXU,n_xi,n_yi;\r
+\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      for(TXV=y1;TXV<=y2;TXV++)\r
+       {\r
+        for(TXU=x1;TXU<=x2;TXU++)\r
+         {\r
+                 n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
+                 n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
+\r
+          *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
+         }\r
+        ta+=xalign;\r
+       }\r
+\r
+      break;\r
+     }\r
+\r
+    start=((pageid-16*pmult)<<7)+524288*pmult;\r
+\r
+    cSRCPtr = psxVub + start + (y1<<11) + x1;\r
+    LineOffset = 2048 - dx;\r
+\r
+    if(dy*dx>384)                                      // more pix? use lut\r
+     {\r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      row=64;do\r
+       {\r
+        *px    =LPTCOL(*wSRCPtr);\r
+        *(px+1)=LPTCOL(*(wSRCPtr+1));\r
+        *(px+2)=LPTCOL(*(wSRCPtr+2));\r
+        *(px+3)=LPTCOL(*(wSRCPtr+3));\r
+        row--;px+=4;wSRCPtr+=4;\r
+       }\r
+      while (row);\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
+\r
+        ta+=xalign;\r
+\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    else                                               // small area? no lut\r
+     {                                            \r
+      wSRCPtr=psxVuw+palstart;\r
+\r
+      column=dy;do \r
+       {\r
+        row=dx;\r
+        do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
+\r
+        ta+=xalign;\r
+\r
+        cSRCPtr+=LineOffset;column--;\r
+       }\r
+      while(column);\r
+     }\r
+    break;\r
+   //--------------------------------------------------// \r
+   // 16bit texture load ..\r
+   case 2:\r
+    start=((pageid-16*pmult)<<6)+262144*pmult;\r
+\r
+    wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
+    LineOffset = 1024 - dx; \r
+\r
+    column=dy;do \r
+     {\r
+      row=dx;\r
+      do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row);\r
+\r
+      ta+=xalign;\r
+\r
+      wSRCPtr+=LineOffset;column--;\r
+     }\r
+    while(column);\r
+    break;\r
+   //--------------------------------------------------// \r
+   // others are not possible !\r
+  }\r
+\r
+ ////////////////////////////////////////////////////////\r
+\r
+ x2a=dx+xalign;\r
+\r
+ if(YTexS)\r
+  {\r
+   ta=(unsigned short *)texturepart;\r
+   pa=(unsigned short *)texturepart+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+\r
+   pa=(unsigned short *)texturepart+dy*x2a;\r
+   ta=pa+x2a;\r
+   row=x2a;do {*ta++=*pa++;row--;} while(row);\r
+\r
+   YTexS--;\r
+   dy+=2;\r
+  }\r
+\r
+ if(XTexS)\r
+  {\r
+   ta=(unsigned short *)texturepart;\r
+   pa=ta+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+\r
+   pa=(unsigned short *)texturepart+dx;\r
+   ta=pa+1;\r
+   row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
+\r
+   XTexS--;\r
+   dx+=2;\r
+  }\r
+\r
+ DXTexS=dx;DYTexS=dy;\r
+\r
+ if(!iFilterType) {DefineSubTextureSort();return;}\r
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
+  {DefineSubTextureSort();return;}\r
+\r
+ ta=(unsigned short *)texturepart;\r
+ x1=dx-1;\r
+ y1=dy-1;      \r
+\r
+{\r
+   for(column=0;column<dy;column++)\r
+    {\r
+     for(row=0;row<dx;row++)\r
+      {\r
+       if(*ta==0)\r
+        {\r
+         cnt=0;\r
+\r
+         if(           column     && *(ta-dx)  &1) scol[cnt++]=*(ta-dx);\r
+         if(row                   && *(ta-1)   &1) scol[cnt++]=*(ta-1);\r
+         if(row!=x1               && *(ta+1)   &1) scol[cnt++]=*(ta+1);\r
+         if(           column!=y1 && *(ta+dx)  &1) scol[cnt++]=*(ta+dx);\r
+\r
+         if(row     && column     && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1);\r
+         if(row!=x1 && column     && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1);\r
+         if(row     && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1);\r
+         if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1);\r
+\r
+         if(cnt)\r
+          {\r
+           r=g=b=0;\r
+           for(h=0;h<cnt;h++)\r
+            {\r
+             r+=scol[h]>>11;\r
+             g+=(scol[h]>>6)&0x1f;\r
+             b+=(scol[h]>>1)&0x1f;\r
+            }\r
+           r/=cnt;b/=cnt;g/=cnt;\r
+           *ta=(r<<11)|(g<<6)|(b<<1);\r
+          }\r
+        }\r
+       ta++;\r
+      }\r
+    }\r
+  }\r
+\r
+ DefineSubTextureSort();\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// hires texture funcs\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define colorMask8     0x00FEFEFE\r
+#define lowPixelMask8  0x00010101\r
+#define qcolorMask8    0x00FCFCFC\r
+#define qlowpixelMask8 0x00030303\r
+\r
+\r
+#define INTERPOLATE8_02(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))\r
+\r
+#define Q_INTERPOLATE8_02(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((C&0xFF000000)==0x03000000)?0x03000000:(((D&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))\r
+\r
+#define INTERPOLATE8(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))\r
+\r
+#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((C&0xFF000000)==0x50000000)?0x50000000:(((D&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))\r
+\r
+void Super2xSaI_ex8_Ex(u8 *srcPtr, DWORD srcPitch,\r
+                   u8  *dstBitmap, int width, int height)\r
+{\r
+ DWORD dstPitch = srcPitch * 2;\r
+ DWORD line;\r
+ DWORD *dP;\r
+ DWORD *bP;\r
+ int   width2 = width*2;\r
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
+ DWORD color4, color5, color6;\r
+ DWORD color1, color2, color3;\r
+ DWORD colorA0, colorA1, colorA2, colorA3,\r
+       colorB0, colorB1, colorB2, colorB3,\r
+       colorS1, colorS2;\r
+ DWORD product1a, product1b,\r
+       product2a, product2b;\r
+\r
+ line = 0;\r
+\r
+  {\r
+   for (; height; height-=1)\r
+       {\r
+     bP = (DWORD *)srcPtr;\r
+        dP = (DWORD *)(dstBitmap + line*dstPitch);\r
+     for (finish = width; finish; finish -= 1 )\r
+      {\r
+//---------------------------------------    B1 B2\r
+//                                         4  5  6 S2\r
+//                                         1  2  3 S1\r
+//                                           A1 A2\r
+       if(finish==width) iXA=0;\r
+       else              iXA=1;\r
+       if(finish>4) {iXB=1;iXC=2;}\r
+       else\r
+       if(finish>3) {iXB=1;iXC=1;}\r
+       else         {iXB=0;iXC=0;}\r
+       if(line==0) iYA=0;\r
+       else        iYA=width;\r
+       if(height>4) {iYB=width;iYC=width2;}\r
+       else\r
+       if(height>3) {iYB=width;iYC=width;}\r
+       else         {iYB=0;iYC=0;}\r
+\r
+\r
+       colorB0 = *(bP- iYA - iXA);\r
+       colorB1 = *(bP- iYA);\r
+       colorB2 = *(bP- iYA + iXB);\r
+       colorB3 = *(bP- iYA + iXC);\r
+\r
+       color4 = *(bP  - iXA);\r
+       color5 = *(bP);\r
+       color6 = *(bP  + iXB);\r
+       colorS2 = *(bP + iXC);\r
+\r
+       color1 = *(bP  + iYB  - iXA);\r
+       color2 = *(bP  + iYB);\r
+       color3 = *(bP  + iYB  + iXB);\r
+       colorS1= *(bP  + iYB  + iXC);\r
+\r
+       colorA0 = *(bP + iYC - iXA);\r
+       colorA1 = *(bP + iYC);\r
+       colorA2 = *(bP + iYC + iXB);\r
+       colorA3 = *(bP + iYC + iXC);\r
+\r
+//--------------------------------------\r
+       if (color2 == color6 && color5 != color3)\r
+        {\r
+         product2b = product1b = color2;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 != color6)\r
+        {\r
+         product2b = product1b = color5;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 == color6)\r
+        {\r
+         register int r = 0;\r
+\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
+\r
+         if (r > 0)\r
+          product2b = product1b = color6;\r
+         else\r
+         if (r < 0)\r
+          product2b = product1b = color5;\r
+         else\r
+          {\r
+           product2b = product1b = INTERPOLATE8_02(color5, color6);\r
+          }\r
+        }\r
+       else\r
+        {\r
+         if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
+             product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2);\r
+         else\r
+         if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
+             product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3);\r
+         else\r
+             product2b = INTERPOLATE8_02 (color2, color3);\r
+\r
+         if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
+             product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5);\r
+         else\r
+         if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
+             product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5);\r
+         else\r
+             product1b = INTERPOLATE8_02 (color5, color6);\r
+        }\r
+\r
+       if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
+        product2a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+       if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
+        product2a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+        product2a = color2;\r
+\r
+       if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
+        product1a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+       if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
+        product1a = INTERPOLATE8_02(color2, color5);\r
+       else\r
+        product1a = color5;\r
+\r
+       *dP=product1a;\r
+       *(dP+1)=product1b;\r
+       *(dP+(width2))=product2a;\r
+       *(dP+1+(width2))=product2b;\r
+\r
+       bP += 1;\r
+       dP += 2;\r
+      }//end of for ( finish= width etc..)\r
+\r
+     line += 2;\r
+     srcPtr += srcPitch;\r
+       }; //endof: for (; height; height--)\r
+  }\r
+}\r
+\r
+\r
+void Super2xSaI_ex8(u8 *srcPtr, DWORD srcPitch,\r
+                   u8  *dstBitmap, int width, int height)\r
+{\r
+ DWORD dstPitch = srcPitch * 2;\r
+ DWORD line;\r
+ DWORD *dP;\r
+ DWORD *bP;\r
+ int   width2 = width*2;\r
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
+ DWORD color4, color5, color6;\r
+ DWORD color1, color2, color3;\r
+ DWORD colorA0, colorA1, colorA2, colorA3,\r
+       colorB0, colorB1, colorB2, colorB3,\r
+       colorS1, colorS2;\r
+ DWORD product1a, product1b,\r
+       product2a, product2b;\r
+\r
+ line = 0;\r
+\r
+  {\r
+   for (; height; height-=1)\r
+       {\r
+     bP = (DWORD *)srcPtr;\r
+        dP = (DWORD *)(dstBitmap + line*dstPitch);\r
+     for (finish = width; finish; finish -= 1 )\r
+      {\r
+//---------------------------------------    B1 B2\r
+//                                         4  5  6 S2\r
+//                                         1  2  3 S1\r
+//                                           A1 A2\r
+       if(finish==width) iXA=0;\r
+       else              iXA=1;\r
+       if(finish>4) {iXB=1;iXC=2;}\r
+       else\r
+       if(finish>3) {iXB=1;iXC=1;}\r
+       else         {iXB=0;iXC=0;}\r
+       if(line==0) iYA=0;\r
+       else        iYA=width;\r
+       if(height>4) {iYB=width;iYC=width2;}\r
+       else\r
+       if(height>3) {iYB=width;iYC=width;}\r
+       else         {iYB=0;iYC=0;}\r
+\r
+\r
+       colorB0 = *(bP- iYA - iXA);\r
+       colorB1 = *(bP- iYA);\r
+       colorB2 = *(bP- iYA + iXB);\r
+       colorB3 = *(bP- iYA + iXC);\r
+\r
+       color4 = *(bP  - iXA);\r
+       color5 = *(bP);\r
+       color6 = *(bP  + iXB);\r
+       colorS2 = *(bP + iXC);\r
+\r
+       color1 = *(bP  + iYB  - iXA);\r
+       color2 = *(bP  + iYB);\r
+       color3 = *(bP  + iYB  + iXB);\r
+       colorS1= *(bP  + iYB  + iXC);\r
+\r
+       colorA0 = *(bP + iYC - iXA);\r
+       colorA1 = *(bP + iYC);\r
+       colorA2 = *(bP + iYC + iXB);\r
+       colorA3 = *(bP + iYC + iXC);\r
+\r
+//--------------------------------------\r
+       if (color2 == color6 && color5 != color3)\r
+        {\r
+         product2b = product1b = color2;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 != color6)\r
+        {\r
+         product2b = product1b = color5;\r
+        }\r
+       else\r
+       if (color5 == color3 && color2 == color6)\r
+        {\r
+         register int r = 0;\r
+\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
+         r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
+\r
+         if (r > 0)\r
+          product2b = product1b = color6;\r
+         else\r
+         if (r < 0)\r
+          product2b = product1b = color5;\r
+         else\r
+          {\r
+           product2b = product1b = INTERPOLATE8(color5, color6);\r
+          }\r
+        }\r
+       else\r
+        {\r
+         if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
+             product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);\r
+         else\r
+         if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
+             product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);\r
+         else\r
+             product2b = INTERPOLATE8 (color2, color3);\r
+\r
+         if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
+             product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);\r
+         else\r
+         if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
+             product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);\r
+         else\r
+             product1b = INTERPOLATE8 (color5, color6);\r
+        }\r
+\r
+       if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
+        product2a = INTERPOLATE8(color2, color5);\r
+       else\r
+       if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
+        product2a = INTERPOLATE8(color2, color5);\r
+       else\r
+        product2a = color2;\r
+\r
+       if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
+        product1a = INTERPOLATE8(color2, color5);\r
+       else\r
+       if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
+        product1a = INTERPOLATE8(color2, color5);\r
+       else\r
+        product1a = color5;\r
+\r
+       *dP=product1a;\r
+       *(dP+1)=product1b;\r
+       *(dP+(width2))=product2a;\r
+       *(dP+1+(width2))=product2b;\r
+\r
+       bP += 1;\r
+       dP += 2;\r
+      }//end of for ( finish= width etc..)\r
+\r
+     line += 2;\r
+     srcPtr += srcPitch;\r
+       }; //endof: for (; height; height--)\r
+  }\r
+}\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#define colorMask4     0x0000EEE0\r
+#define lowPixelMask4  0x00001110\r
+#define qcolorMask4    0x0000CCC0\r
+#define qlowpixelMask4 0x00003330\r
+\r
+#define INTERPOLATE4(A, B) ((((A & colorMask4) >> 1) + ((B & colorMask4) >> 1) + (A & B & lowPixelMask4))|((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))\r
+\r
+#define Q_INTERPOLATE4(A, B, C, D) ((((A & qcolorMask4) >> 2) + ((B & qcolorMask4) >> 2) + ((C & qcolorMask4) >> 2) + ((D & qcolorMask4) >> 2) + ((((A & qlowpixelMask4) + (B & qlowpixelMask4) + (C & qlowpixelMask4) + (D & qlowpixelMask4)) >> 2) & qlowpixelMask4))| ((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((C&0x0000000F)==0x00000006)?0x00000006:(((D&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:(((C&0x0000000F)==0x00000000)?0x00000000:(((D&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))))))\r
+\r
+\r
+#define colorMask5     0x0000F7BC\r
+#define lowPixelMask5  0x00000842\r
+#define qcolorMask5    0x0000E738\r
+#define qlowpixelMask5 0x000018C6\r
+\r
+#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001))))\r
+\r
+#define Q_INTERPOLATE5(A, B, C, D) ((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))| ((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:(((C&0x00000001)==0x00000000)?0x00000000:(((D&0x00000001)==0x00000000)?0x00000000:0x00000001))))))\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// ogl texture defines\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineSubTextureSortHiRes(void)\r
+{\r
+ int x,y,dx2;\r
+\r
+ if(!gTexName)             \r
+  {\r
+   glGenTextures(1, &gTexName);\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(iFilterType)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {            \r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }   \r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
+  }\r
+ else glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1,\r
+                 DXTexS<<1, DYTexS<<1,\r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DefineSubTextureSort(void)\r
+{\r
+\r
+ if(!gTexName)\r
+  {\r
+   glGenTextures(1, &gTexName);\r
+   glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
+\r
+   if(iFilterType)\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+    }\r
+   else\r
+    {\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
+    }\r
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+  }\r
+ else glBindTexture(GL_TEXTURE_2D, gTexName);\r
+\r
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS,\r
+                 DXTexS, DYTexS,\r
+                 GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// texture cache garbage collection\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void DoTexGarbageCollection(void)\r
+{\r
+ static unsigned short LRUCleaned=0;\r
+ unsigned short iC,iC1,iC2;\r
+ int i,j,iMax;textureSubCacheEntryS * tsb;\r
+\r
+ iC=4;//=iSortTexCnt/2,\r
+ LRUCleaned+=iC;                                       // we clean different textures each time\r
+ if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0;        // wrap? wrap!\r
+ iC1=LRUCleaned;                                       // range of textures to clean\r
+ iC2=LRUCleaned+iC;\r
+\r
+ for(iC=iC1;iC<iC2;iC++)                               // make some textures available\r
+  {\r
+   pxSsubtexLeft[iC]->l=0;\r
+  }\r
+\r
+ for(i=0;i<3;i++)                                      // remove all references to that textures\r
+  for(j=0;j<MAXTPAGES;j++)\r
+   for(iC=0;iC<4;iC++)                                 // loop all texture rect info areas\r
+    {\r
+     tsb=pscSubtexStore[i][j]+(iC*SOFFB);\r
+     iMax=tsb->pos.l;\r
+     if(iMax)\r
+      do\r
+       {\r
+        tsb++;\r
+        if(tsb->cTexID>=iC1 && tsb->cTexID<iC2)        // info uses the cleaned textures? remove info\r
+         tsb->ClutID=0;\r
+       } \r
+      while(--iMax);\r
+     }\r
+\r
+ usLRUTexPage=LRUCleaned;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// search cache for existing (already used) parts\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+u8 * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache)\r
+{\r
+ textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL;\r
+ int i,iMax;EXLong npos;\r
+ u8 cx,cy;\r
+ int iC,j,k;unsigned long rx,ry,mx,my;\r
+ EXLong * ul=0, * uls;\r
+ EXLong rfree;\r
+ u8 cXAdj,cYAdj;\r
+\r
+ npos.l=*((unsigned long *)&gl_ux[4]);\r
+\r
+ //--------------------------------------------------------------//\r
+ // find matching texturepart first... speed up...\r
+ //--------------------------------------------------------------//\r
+\r
+ tsg=pscSubtexStore[TextureMode][GlobalTexturePage];\r
+ tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB;\r
+\r
+ iMax=tsg->pos.l;\r
+ if(iMax)\r
+  {\r
+   i=iMax;\r
+   tsb=tsg+1;                 \r
+   do\r
+    {\r
+     if(GivenClutId==tsb->ClutID &&\r
+        (INCHECK(tsb->pos,npos)))\r
+      {\r
+        {\r
+         cx=tsb->pos.c[3]-tsb->posTX;\r
+         cy=tsb->pos.c[1]-tsb->posTY;\r
+\r
+         gl_ux[0]-=cx;\r
+         gl_ux[1]-=cx;\r
+         gl_ux[2]-=cx;\r
+         gl_ux[3]-=cx;\r
+         gl_vy[0]-=cy;\r
+         gl_vy[1]-=cy;\r
+         gl_vy[2]-=cy;\r
+         gl_vy[3]-=cy;\r
+\r
+         ubOpaqueDraw=tsb->Opaque;\r
+         *pCache=tsb->cTexID;\r
+         return NULL;\r
+        }\r
+      } \r
+     tsb++;\r
+    }\r
+   while(--i);\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+\r
+ cXAdj=1;cYAdj=1;\r
+\r
+ rx=(int)gl_ux[6]-(int)gl_ux[7];\r
+ ry=(int)gl_ux[4]-(int)gl_ux[5];\r
+\r
+ tsx=NULL;tsb=tsg+1;\r
+ for(i=0;i<iMax;i++,tsb++)\r
+  {\r
+   if(!tsb->ClutID) {tsx=tsb;break;}\r
+  }\r
+\r
+ if(!tsx) \r
+  {\r
+   iMax++;\r
+   if(iMax>=SOFFB-2) \r
+    {\r
+     if(iTexGarbageCollection)                         // gc mode?\r
+      {\r
+       if(*pCache==0) \r
+        {\r
+         dwTexPageComp|=(1<<GlobalTexturePage);\r
+         *pCache=0xffff;\r
+         return 0;\r
+        }\r
+\r
+       iMax--;\r
+       tsb=tsg+1;\r
+\r
+       for(i=0;i<iMax;i++,tsb++)                       // 1. search other slots with same cluts, and unite the area\r
+        if(GivenClutId==tsb->ClutID)\r
+         {\r
+          if(!tsx) {tsx=tsb;rfree.l=npos.l;}           // \r
+          else      tsb->ClutID=0;\r
+          rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]);\r
+          rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]);\r
+          rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]);\r
+          rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]);\r
+          MarkFree(tsb);\r
+         }\r
+\r
+       if(tsx)                                         // 3. if one or more found, create a new rect with bigger size\r
+        {\r
+         *((unsigned long *)&gl_ux[4])=npos.l=rfree.l;\r
+         rx=(int)rfree.c[2]-(int)rfree.c[3];\r
+         ry=(int)rfree.c[0]-(int)rfree.c[1];\r
+         DoTexGarbageCollection();\r
+       \r
+         goto ENDLOOP3;\r
+        }\r
+      }\r
+\r
+     iMax=1;\r
+    }\r
+   tsx=tsg+iMax;\r
+   tsg->pos.l=iMax;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // now get a free texture space\r
+ //----------------------------------------------------//\r
+\r
+ if(iTexGarbageCollection) usLRUTexPage=0;\r
+\r
+ENDLOOP3:\r
+\r
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
+\r
+ iC=usLRUTexPage;\r
+\r
+ for(k=0;k<iSortTexCnt;k++)\r
+  {\r
+   uls=pxSsubtexLeft[iC];\r
+   iMax=uls->l;ul=uls+1;\r
+\r
+   //--------------------------------------------------//\r
+   // first time\r
+\r
+   if(!iMax) \r
+    {\r
+     rfree.l=0;\r
+\r
+     if(rx>252 && ry>252)\r
+      {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;}\r
+\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1; \r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+     ul=0;\r
+     goto ENDLOOP;\r
+    }\r
+                                                       \r
+   //--------------------------------------------------//\r
+   for(i=0;i<iMax;i++,ul++)\r
+    {\r
+     if(ul->l!=0xffffffff && \r
+        ry<=ul->c[0]      && \r
+        rx<=ul->c[2])\r
+      {\r
+       rfree=*ul;\r
+       mx=ul->c[2]-2;\r
+       my=ul->c[0]-2;\r
+       if(rx<mx && ry<my)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+         ul->c[0]=ry;\r
+\r
+         for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
+          if(ul->l==0xffffffff) break;\r
\r
+         if(j<CSUBSIZE-2)\r
+          {\r
+           if(j==iMax) uls->l=uls->l+1;\r
+\r
+           ul->c[3]=rfree.c[3];\r
+           ul->c[2]=rfree.c[2];\r
+           ul->c[1]=rfree.c[1]+ry;\r
+           ul->c[0]=rfree.c[0]-ry;\r
+          }\r
+        }\r
+       else if(rx<mx)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+        }\r
+       else if(ry<my)\r
+        {\r
+         ul->c[1]+=ry;\r
+         ul->c[0]-=ry;\r
+        }\r
+       else\r
+        {\r
+         ul->l=0xffffffff;\r
+        }\r
+       ul=0;\r
+       goto ENDLOOP;\r
+      }\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+\r
+   iC++; if(iC>=iSortTexCnt) iC=0;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // check, if free space got\r
+ //----------------------------------------------------//\r
+\r
+ENDLOOP:\r
+ if(ul)\r
+  {\r
+   //////////////////////////////////////////////////////\r
+\r
+    {\r
+     dwTexPageComp=0;\r
+\r
+     for(i=0;i<3;i++)                                    // cleaning up\r
+      for(j=0;j<MAXTPAGES;j++)\r
+       {\r
+        tsb=pscSubtexStore[i][j];\r
+        (tsb+SOFFA)->pos.l=0;\r
+        (tsb+SOFFB)->pos.l=0;\r
+        (tsb+SOFFC)->pos.l=0;\r
+        (tsb+SOFFD)->pos.l=0;\r
+       }\r
+     for(i=0;i<iSortTexCnt;i++)\r
+      {ul=pxSsubtexLeft[i];ul->l=0;}\r
+     usLRUTexPage=0;\r
+    }\r
+\r
+   //////////////////////////////////////////////////////\r
+   iC=usLRUTexPage;\r
+   uls=pxSsubtexLeft[usLRUTexPage];\r
+   uls->l=0;ul=uls+1;\r
+   rfree.l=0;\r
+\r
+   if(rx>252 && ry>252)\r
+    {uls->l=1;ul->l=0xffffffff;}\r
+   else\r
+    {\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1; \r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+    }\r
+   tsg->pos.l=1;tsx=tsg+1;\r
+  }\r
+\r
+ rfree.c[3]+=cXAdj;\r
+ rfree.c[1]+=cYAdj;\r
+\r
+ tsx->cTexID   =*pCache=iC;\r
+ tsx->pos      = npos;\r
+ tsx->ClutID   = GivenClutId;\r
+ tsx->posTX    = rfree.c[3];\r
+ tsx->posTY    = rfree.c[1];\r
+\r
+ cx=gl_ux[7]-rfree.c[3];\r
+ cy=gl_ux[5]-rfree.c[1];\r
+\r
+ gl_ux[0]-=cx;\r
+ gl_ux[1]-=cx;\r
+ gl_ux[2]-=cx;\r
+ gl_ux[3]-=cx;\r
+ gl_vy[0]-=cy;\r
+ gl_vy[1]-=cy;\r
+ gl_vy[2]-=cy;\r
+ gl_vy[3]-=cy;\r
+\r
+ XTexS=rfree.c[3];\r
+ YTexS=rfree.c[1];\r
+\r
+ return &tsx->Opaque;\r
+}\r
+                   \r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// search cache for free place (on compress)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx)\r
+{\r
+ int i,j,k,iMax,iC;unsigned long rx,ry,mx,my;\r
+ EXLong * ul=0, * uls, rfree;\r
+ u8 cXAdj=1,cYAdj=1;\r
+\r
+ rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3];\r
+ ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1];\r
+\r
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
+\r
+ iC=usLRUTexPage;\r
+\r
+ for(k=0;k<iSortTexCnt;k++)\r
+  {\r
+   uls=pxSsubtexLeft[iC];\r
+   iMax=uls->l;ul=uls+1;\r
+\r
+   //--------------------------------------------------//\r
+   // first time\r
+\r
+   if(!iMax)\r
+    {\r
+     rfree.l=0;\r
+\r
+     if(rx>252 && ry>252)\r
+      {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;}\r
+\r
+     if(rx<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=rx;\r
+       ul->c[2]=255-rx;\r
+       ul->c[1]=0;\r
+       ul->c[0]=ry;\r
+       ul++;\r
+      }\r
+\r
+     if(ry<253)\r
+      {\r
+       uls->l=uls->l+1;\r
+       ul->c[3]=0;\r
+       ul->c[2]=255;\r
+       ul->c[1]=ry;\r
+       ul->c[0]=255-ry;\r
+      }\r
+     ul=0;\r
+     goto TENDLOOP;\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+   for(i=0;i<iMax;i++,ul++)\r
+    {\r
+     if(ul->l!=0xffffffff &&\r
+        ry<=ul->c[0]      &&\r
+        rx<=ul->c[2])\r
+      {\r
+       rfree=*ul;\r
+       mx=ul->c[2]-2;\r
+       my=ul->c[0]-2;\r
+\r
+       if(rx<mx && ry<my)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+         ul->c[0]=ry;\r
+\r
+         for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
+          if(ul->l==0xffffffff) break;\r
+\r
+         if(j<CSUBSIZE-2)\r
+          {\r
+           if(j==iMax) uls->l=uls->l+1;\r
+\r
+           ul->c[3]=rfree.c[3];\r
+           ul->c[2]=rfree.c[2];\r
+           ul->c[1]=rfree.c[1]+ry;\r
+           ul->c[0]=rfree.c[0]-ry;\r
+          }\r
+        }\r
+       else if(rx<mx)\r
+        {\r
+         ul->c[3]+=rx;\r
+         ul->c[2]-=rx;\r
+        }\r
+       else if(ry<my)\r
+        {\r
+         ul->c[1]+=ry;\r
+         ul->c[0]-=ry;\r
+        }\r
+       else\r
+        {\r
+         ul->l=0xffffffff;\r
+        }\r
+       ul=0;\r
+       goto TENDLOOP;\r
+      }\r
+    }\r
+\r
+   //--------------------------------------------------//\r
+\r
+   iC++; if(iC>=iSortTexCnt) iC=0;\r
+  }\r
+\r
+ //----------------------------------------------------//\r
+ // check, if free space got\r
+ //----------------------------------------------------//\r
+\r
+TENDLOOP:\r
+ if(ul) return FALSE;\r
+\r
+ rfree.c[3]+=cXAdj;\r
+ rfree.c[1]+=cYAdj;\r
+\r
+ tsx->cTexID   = iC;\r
+ tsx->posTX    = rfree.c[3];\r
+ tsx->posTY    = rfree.c[1];\r
+\r
+ XTexS=rfree.c[3];\r
+ YTexS=rfree.c[1];\r
+\r
+ return TRUE;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// compress texture cache (to make place for new texture part, if needed)\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+void CompressTextureSpace(void)\r
+{\r
+ textureSubCacheEntryS * tsx, * tsg, * tsb;\r
+ int i,j,k,m,n,iMax;EXLong * ul, r,opos;\r
+ short sOldDST=DrawSemiTrans,cx,cy;\r
+ long  lOGTP=GlobalTexturePage;\r
+ unsigned long l,row;\r
+ unsigned long * lSRCPtr;\r
+\r
+ opos.l=*((unsigned long *)&gl_ux[4]);\r
+\r
+ // 1. mark all textures as free\r
+ for(i=0;i<iSortTexCnt;i++)\r
+  {ul=pxSsubtexLeft[i];ul->l=0;}\r
+ usLRUTexPage=0;\r
+\r
+ // 2. compress\r
+ for(j=0;j<3;j++)\r
+  {\r
+   for(k=0;k<MAXTPAGES;k++)\r
+    {\r
+     tsg=pscSubtexStore[j][k];\r
+\r
+     if((!(dwTexPageComp&(1<<k))))\r
+      {\r
+       (tsg+SOFFA)->pos.l=0;\r
+       (tsg+SOFFB)->pos.l=0;\r
+       (tsg+SOFFC)->pos.l=0;\r
+       (tsg+SOFFD)->pos.l=0;\r
+       continue;\r
+      }\r
+\r
+     for(m=0;m<4;m++,tsg+=SOFFB)\r
+      {\r
+       iMax=tsg->pos.l;\r
+\r
+       tsx=tsg+1;\r
+       for(i=0;i<iMax;i++,tsx++)\r
+        {\r
+         if(tsx->ClutID)\r
+          {\r
+           r.l=tsx->pos.l;\r
+           for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++)\r
+            {\r
+             if(tsx->ClutID==tsb->ClutID)\r
+              {\r
+               r.c[3]=min(r.c[3],tsb->pos.c[3]);\r
+               r.c[2]=max(r.c[2],tsb->pos.c[2]);\r
+               r.c[1]=min(r.c[1],tsb->pos.c[1]);\r
+               r.c[0]=max(r.c[0],tsb->pos.c[0]);\r
+               tsb->ClutID=0;\r
+              }\r
+            }\r
+\r
+//           if(r.l!=tsx->pos.l)\r
+            {\r
+             cx=((tsx->ClutID << 4) & 0x3F0);          \r
+             cy=((tsx->ClutID >> 6) & CLUTYMASK);\r
+\r
+             if(j!=2)\r
+              {\r
+               // palette check sum\r
+               l=0;lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+               if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+               else     for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+               l=((l+HIWORD(l))&0x3fffL)<<16;\r
+               if(l!=(tsx->ClutID&(0x00003fff<<16)))\r
+                {\r
+                 tsx->ClutID=0;continue;\r
+                }\r
+              }\r
+\r
+             tsx->pos.l=r.l;\r
+             if(!GetCompressTexturePlace(tsx))         // no place?\r
+              {\r
+               for(i=0;i<3;i++)                        // -> clean up everything\r
+                for(j=0;j<MAXTPAGES;j++)\r
+                 {\r
+                  tsb=pscSubtexStore[i][j];\r
+                  (tsb+SOFFA)->pos.l=0;\r
+                  (tsb+SOFFB)->pos.l=0;\r
+                  (tsb+SOFFC)->pos.l=0;\r
+                  (tsb+SOFFD)->pos.l=0;\r
+                 }\r
+               for(i=0;i<iSortTexCnt;i++)\r
+                {ul=pxSsubtexLeft[i];ul->l=0;}\r
+               usLRUTexPage=0;\r
+               DrawSemiTrans=sOldDST;\r
+               GlobalTexturePage=lOGTP;\r
+               *((unsigned long *)&gl_ux[4])=opos.l;\r
+               dwTexPageComp=0;\r
+\r
+               return;\r
+              }\r
+\r
+             if(tsx->ClutID&(1<<30)) DrawSemiTrans=1;\r
+             else                    DrawSemiTrans=0;\r
+             *((unsigned long *)&gl_ux[4])=r.l;\r
+   \r
+             gTexName=uiStexturePage[tsx->cTexID];\r
+             LoadSubTexFn(k,j,cx,cy);\r
+             uiStexturePage[tsx->cTexID]=gTexName;\r
+             tsx->Opaque=ubOpaqueDraw;\r
+            }\r
+          }\r
+        }\r
+\r
+       if(iMax)  \r
+        {\r
+         tsx=tsg+iMax;\r
+         while(!tsx->ClutID && iMax) {tsx--;iMax--;}\r
+         tsg->pos.l=iMax;\r
+        }\r
+\r
+      }                      \r
+    }\r
+  }\r
+\r
+ if(dwTexPageComp==0xffffffff) dwTexPageComp=0;\r
+\r
+ *((unsigned long *)&gl_ux[4])=opos.l;\r
+ GlobalTexturePage=lOGTP;\r
+ DrawSemiTrans=sOldDST;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// main entry for searching/creating textures, called from prim.c\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+GLuint SelectSubTextureS(long TextureMode, unsigned long GivenClutId) \r
+{\r
+ u8 * OPtr;unsigned short iCache;short cx,cy;\r
+\r
+ // sort sow/tow infos for fast access\r
+\r
+ u8 ma1,ma2,mi1,mi2;\r
+ if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];}\r
+ else                  {mi1=gl_ux[0];ma1=gl_ux[1];}\r
+ if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];}\r
+ else                  {mi2=gl_ux[2];ma2=gl_ux[3];}\r
+ if(mi1>mi2) gl_ux[7]=mi2; \r
+ else        gl_ux[7]=mi1;\r
+ if(ma1>ma2) gl_ux[6]=ma1; \r
+ else        gl_ux[6]=ma2;\r
+\r
+ if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];}\r
+ else                  {mi1=gl_vy[0];ma1=gl_vy[1];}\r
+ if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];}\r
+ else                  {mi2=gl_vy[2];ma2=gl_vy[3];}\r
+ if(mi1>mi2) gl_ux[5]=mi2; \r
+ else        gl_ux[5]=mi1;\r
+ if(ma1>ma2) gl_ux[4]=ma1; \r
+ else        gl_ux[4]=ma2;\r
+\r
+ // get clut infos in one 32 bit val\r
+\r
+ if(TextureMode==2)                                    // no clut here\r
+  {\r
+   GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0;\r
\r
+   if(iFrameTexType && Fake15BitTexture()) \r
+    return (GLuint)gTexName;\r
+  }           \r
+ else \r
+  {\r
+   cx=((GivenClutId << 4) & 0x3F0);                    // but here\r
+   cy=((GivenClutId >> 6) & CLUTYMASK);\r
+   GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED;\r
+\r
+   // palette check sum.. removed MMX asm, this easy func works as well\r
+    {\r
+     unsigned long l=0,row;\r
+\r
+     unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
+     if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
+     else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
+     l=(l+HIWORD(l))&0x3fffL;\r
+     GivenClutId|=(l<<16);\r
+    }\r
+\r
+  }\r
+\r
+ // search cache\r
+ iCache=0;\r
+ OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
+\r
+ // cache full? compress and try again\r
+ if(iCache==0xffff)\r
+  {\r
+   CompressTextureSpace();\r
+   OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
+  }\r
+\r
+ // found? fine\r
+ usLRUTexPage=iCache;\r
+ if(!OPtr) return uiStexturePage[iCache];\r
+\r
+ // not found? upload texture and store infos in cache\r
+ gTexName=uiStexturePage[iCache];\r
+ LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy);\r
+ uiStexturePage[iCache]=gTexName;\r
+ *OPtr=ubOpaqueDraw;\r
+ return (GLuint) gTexName;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r
+/////////////////////////////////////////////////////////////////////////////\r