gpu-gles: schtruck/fpse merge: remove windows code
[pcsx_rearmed.git] / plugins / gpu-gles / gpuTexture.c
1 /***************************************************************************\r
2                           texture.c  -  description\r
3                              -------------------\r
4     begin                : Sun Mar 08 2009\r
5     copyright            : (C) 1999-2009 by Pete Bernert\r
6     web                  : www.pbernert.com   \r
7  ***************************************************************************/\r
8 \r
9 /***************************************************************************\r
10  *                                                                         *\r
11  *   This program is free software; you can redistribute it and/or modify  *\r
12  *   it under the terms of the GNU General Public License as published by  *\r
13  *   the Free Software Foundation; either version 2 of the License, or     *\r
14  *   (at your option) any later version. See also the license.txt file for *\r
15  *   additional informations.                                              *\r
16  *                                                                         *\r
17  ***************************************************************************/\r
18 \r
19 //*************************************************************************// \r
20 // History of changes:\r
21 //\r
22 // 2009/03/08 - Pete  \r
23 // - generic cleanup for the Peops release\r
24 //\r
25 //*************************************************************************// \r
26 \r
27 \r
28 ////////////////////////////////////////////////////////////////////////////////////\r
29 // Texture related functions are here !\r
30 //\r
31 // The texture handling is heart and soul of this gpu. The plugin was developed\r
32 // 1999, by this time no shaders were available. Since the psx gpu is making\r
33 // heavy use of CLUT (="color lookup tables", aka palettized textures), it was \r
34 // an interesting task to get those emulated at good speed on NV TNT cards \r
35 // (which was my major goal when I created the first "gpuPeteTNT"). Later cards \r
36 // (Geforce256) supported texture palettes by an OGL extension, but at some point\r
37 // this support was dropped again by gfx card vendors.\r
38 // Well, at least there is a certain advatage, if no texture palettes extension can\r
39 // be used: it is possible to modify the textures in any way, allowing "hi-res" \r
40 // textures and other tweaks.\r
41 //\r
42 // My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures,\r
43 // and it places small psx texture parts inside them. The plugin keeps track what \r
44 // part (with what palette) it had placed in which texture, so it can re-use this \r
45 // part again. The more ogl textures it can use, the better (of course the managing/\r
46 // searching will be slower, but everything is faster than uploading textures again\r
47 // and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked\r
48 // well with many games, but I recommend nowadays 64 MB Vram to get a good speed.\r
49 //\r
50 // Sadly, there is also a second kind of texture cache needed, for "psx texture windows".\r
51 // Those are "repeated" textures, so a psx "texture window" needs to be put in \r
52 // a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very\r
53 // fast in games which are having an heavy "texture window" usage, like RRT4. As an \r
54 // alternative, this plugin can use the OGL "palette" extension on texture windows, \r
55 // if available. Nowadays also a fragment shader can easily be used to emulate\r
56 // texture wrapping in a texture atlas, so the main cache could hold the texture\r
57 // windows as well (that's what I am doing in the OGL2 plugin). But currently the\r
58 // OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause\r
59 // much texture uploads.\r
60 //\r
61 // Some final advice: take care if you change things in here. I've removed my ASM\r
62 // handlers (they didn't cause much speed gain anyway) for readability/portability,\r
63 // but still the functions/data structures used here are easy to mess up. I guess it\r
64 // can be a pain in the ass to port the plugin to another byte order :)\r
65 //\r
66 ////////////////////////////////////////////////////////////////////////////////////\r
67  \r
68 #define _IN_TEXTURE\r
69 \r
70 #include "gpuStdafx.h"\r
71 \r
72 #include "gpuDraw.h"\r
73 //#include "plugins.h"\r
74 #include "gpuExternals.h"\r
75 #include "gpuTexture.h"\r
76 #include "gpuPlugin.h"\r
77 #include "gpuPrim.h"\r
78 \r
79 #define CLUTCHK   0x00060000\r
80 #define CLUTSHIFT 17\r
81 \r
82 ////////////////////////////////////////////////////////////////////////\r
83 // texture conversion buffer .. \r
84 ////////////////////////////////////////////////////////////////////////\r
85 \r
86 GLubyte       ubPaletteBuffer[256][4];\r
87 GLuint        gTexMovieName=0;\r
88 GLuint        gTexBlurName=0;\r
89 GLuint        gTexFrameName=0;\r
90 int           iTexGarbageCollection=1;\r
91 unsigned long dwTexPageComp=0;\r
92 int           iVRamSize=0;\r
93 int           iClampType=GL_CLAMP_TO_EDGE;\r
94 int iFilter = GL_LINEAR;\r
95 void               (*LoadSubTexFn) (int,int,short,short);\r
96 unsigned long      (*PalTexturedColourFn)  (unsigned long);\r
97 \r
98 ////////////////////////////////////////////////////////////////////////\r
99 // defines\r
100 ////////////////////////////////////////////////////////////////////////\r
101 \r
102 #define PALCOL(x) PalTexturedColourFn (x)\r
103 \r
104 #define CSUBSIZE  2048\r
105 #define CSUBSIZEA 8192\r
106 #define CSUBSIZES 4096\r
107 \r
108 #define OFFA 0\r
109 #define OFFB 2048\r
110 #define OFFC 4096\r
111 #define OFFD 6144\r
112 \r
113 #define XOFFA 0\r
114 #define XOFFB 512\r
115 #define XOFFC 1024\r
116 #define XOFFD 1536\r
117 \r
118 #define SOFFA 0\r
119 #define SOFFB 1024\r
120 #define SOFFC 2048\r
121 #define SOFFD 3072\r
122 \r
123 #define MAXWNDTEXCACHE 128\r
124 \r
125 #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
126 #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
127 \r
128 ////////////////////////////////////////////////////////////////////////\r
129 \r
130 unsigned char * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache);\r
131 void            LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
132 void            LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);\r
133 void            DefineSubTextureSort(void);\r
134 \r
135 ////////////////////////////////////////////////////////////////////////\r
136 // some globals\r
137 ////////////////////////////////////////////////////////////////////////\r
138 \r
139 long  GlobalTexturePage;\r
140 GLint XTexS;\r
141 GLint YTexS;\r
142 GLint DXTexS;\r
143 GLint DYTexS;\r
144 int   iSortTexCnt=32;\r
145 BOOL  bUseFastMdec=FALSE;\r
146 BOOL  bUse15bitMdec=FALSE;\r
147 int   iFrameTexType=0;\r
148 int   iFrameReadType=0;\r
149 \r
150 unsigned long  (*TCF[2]) (unsigned long);\r
151 unsigned short (*PTCF[2]) (unsigned short);\r
152 \r
153 ////////////////////////////////////////////////////////////////////////\r
154 // texture cache implementation\r
155 ////////////////////////////////////////////////////////////////////////\r
156 \r
157 // "texture window" cache entry\r
158 \r
159 typedef struct textureWndCacheEntryTag\r
160 {\r
161  unsigned long  ClutID;\r
162  short          pageid;\r
163  short          textureMode;\r
164  short          Opaque;\r
165  short          used;\r
166  EXLong         pos;\r
167  GLuint         texname;\r
168 } textureWndCacheEntry;\r
169 \r
170 // "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them)\r
171 \r
172 typedef struct textureSubCacheEntryTagS \r
173 {\r
174  unsigned long   ClutID;\r
175  EXLong          pos;\r
176  unsigned char   posTX;\r
177  unsigned char   posTY;\r
178  unsigned char   cTexID;\r
179  unsigned char   Opaque;\r
180 } textureSubCacheEntryS;\r
181 \r
182 \r
183 //---------------------------------------------\r
184 \r
185 #define MAXTPAGES_MAX  64\r
186 #define MAXSORTTEX_MAX 196\r
187 \r
188 //---------------------------------------------\r
189 \r
190 textureWndCacheEntry     wcWndtexStore[MAXWNDTEXCACHE];\r
191 textureSubCacheEntryS *  pscSubtexStore[3][MAXTPAGES_MAX];\r
192 EXLong *                 pxSsubtexLeft [MAXSORTTEX_MAX];\r
193 GLuint                   uiStexturePage[MAXSORTTEX_MAX];\r
194 \r
195 unsigned short           usLRUTexPage=0;\r
196 \r
197 int                      iMaxTexWnds=0;\r
198 int                      iTexWndTurn=0;\r
199 int                      iTexWndLimit=MAXWNDTEXCACHE/2;\r
200 \r
201 GLubyte *                texturepart=NULL;\r
202 GLubyte *                texturebuffer=NULL;\r
203 unsigned long            g_x1,g_y1,g_x2,g_y2;\r
204 unsigned char            ubOpaqueDraw=0;\r
205 \r
206 unsigned short MAXTPAGES     = 32;\r
207 unsigned short CLUTMASK      = 0x7fff;\r
208 unsigned short CLUTYMASK     = 0x1ff;\r
209 unsigned short MAXSORTTEX    = 196;\r
210 \r
211 ////////////////////////////////////////////////////////////////////////\r
212 // Texture color conversions... all my ASM funcs are removed for easier\r
213 // porting... and honestly: nowadays the speed gain would be pointless \r
214 ////////////////////////////////////////////////////////////////////////\r
215 \r
216 unsigned long XP8RGBA(unsigned long BGR)\r
217 {\r
218  if(!(BGR&0xffff)) return 0x50000000;\r
219  if(DrawSemiTrans && !(BGR&0x8000)) \r
220   {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
221  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
222 }\r
223 \r
224 unsigned long XP8RGBAEx(unsigned long BGR)\r
225 {\r
226  if(!(BGR&0xffff)) return 0x03000000;\r
227  if(DrawSemiTrans && !(BGR&0x8000)) \r
228   {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
229  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
230 }\r
231 \r
232 unsigned long CP8RGBA(unsigned long BGR)\r
233 {\r
234  unsigned long l;\r
235  if(!(BGR&0xffff)) return 0x50000000;\r
236  if(DrawSemiTrans && !(BGR&0x8000)) \r
237   {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
238  l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
239  if(l==0xffffff00) l=0xff000000;\r
240  return l;\r
241 }\r
242 \r
243 unsigned long CP8RGBAEx(unsigned long BGR)\r
244 {\r
245  unsigned long l;\r
246  if(!(BGR&0xffff)) return 0x03000000;\r
247  if(DrawSemiTrans && !(BGR&0x8000)) \r
248   {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
249  l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
250  if(l==0xffffff00) l=0xff000000;\r
251  return l;\r
252 }\r
253 \r
254 unsigned long XP8RGBA_0(unsigned long BGR)\r
255 {\r
256  if(!(BGR&0xffff)) return 0x50000000;\r
257  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
258 }\r
259 \r
260 unsigned long XP8RGBAEx_0(unsigned long BGR)\r
261 {\r
262  if(!(BGR&0xffff)) return 0x03000000;\r
263  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
264 }\r
265 \r
266 unsigned long XP8BGRA_0(unsigned long BGR)\r
267 {\r
268  if(!(BGR&0xffff)) return 0x50000000;\r
269  return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
270 }\r
271 \r
272 unsigned long XP8BGRAEx_0(unsigned long BGR)\r
273 {\r
274  if(!(BGR&0xffff)) return 0x03000000;\r
275  return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
276 }\r
277 \r
278 unsigned long CP8RGBA_0(unsigned long BGR)\r
279 {\r
280  unsigned long l;\r
281 \r
282  if(!(BGR&0xffff)) return 0x50000000;\r
283  l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
284  if(l==0xfff8f800) l=0xff000000;\r
285  return l;\r
286 }\r
287 \r
288 unsigned long CP8RGBAEx_0(unsigned long BGR)\r
289 {\r
290  unsigned long l;\r
291 \r
292  if(!(BGR&0xffff)) return 0x03000000;\r
293  l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
294  if(l==0xfff8f800) l=0xff000000;\r
295  return l;\r
296 }\r
297 \r
298 unsigned long CP8BGRA_0(unsigned long BGR)\r
299 {\r
300  unsigned long l;\r
301 \r
302  if(!(BGR&0xffff)) return 0x50000000;\r
303  l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
304  if(l==0xff00f8f8) l=0xff000000;\r
305  return l;\r
306 }\r
307 \r
308 unsigned long CP8BGRAEx_0(unsigned long BGR)\r
309 {\r
310  unsigned long l;\r
311 \r
312  if(!(BGR&0xffff)) return 0x03000000;\r
313  l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
314  if(l==0xff00f8f8) l=0xff000000;\r
315  return l;\r
316 }\r
317 \r
318 unsigned long XP8RGBA_1(unsigned long BGR)\r
319 {\r
320  if(!(BGR&0xffff)) return 0x50000000;\r
321  if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
322  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
323 }\r
324 \r
325 unsigned long XP8RGBAEx_1(unsigned long BGR)\r
326 {\r
327  if(!(BGR&0xffff)) return 0x03000000;\r
328  if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}\r
329  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
330 }\r
331 \r
332 unsigned long XP8BGRA_1(unsigned long BGR)\r
333 {\r
334  if(!(BGR&0xffff)) return 0x50000000;\r
335  if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
336  return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
337 }\r
338 \r
339 unsigned long XP8BGRAEx_1(unsigned long BGR)\r
340 {\r
341  if(!(BGR&0xffff)) return 0x03000000;\r
342  if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}\r
343  return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
344 }\r
345 \r
346 unsigned long P8RGBA(unsigned long BGR)\r
347 {\r
348  if(!(BGR&0xffff)) return 0;\r
349  return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;\r
350 }\r
351 \r
352 unsigned long P8BGRA(unsigned long BGR)\r
353 {\r
354  if(!(BGR&0xffff)) return 0;\r
355  return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;\r
356 }\r
357 \r
358 unsigned short XP5RGBA(unsigned short BGR)\r
359 {\r
360  if(!BGR) return 0;\r
361  if(DrawSemiTrans && !(BGR&0x8000)) \r
362   {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
363  return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
364 }\r
365 \r
366 unsigned short XP5RGBA_0 (unsigned short BGR)\r
367 {\r
368  if(!BGR) return 0;\r
369 \r
370  return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
371 }\r
372 \r
373 unsigned short CP5RGBA_0 (unsigned short BGR)\r
374 {\r
375  unsigned short s;\r
376 \r
377  if(!BGR) return 0;\r
378 \r
379  s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
380  if(s==0x07ff) s=1;\r
381  return s;\r
382 }\r
383 \r
384 unsigned short XP5RGBA_1(unsigned short BGR)\r
385 {\r
386  if(!BGR) return 0;\r
387  if(!(BGR&0x8000)) \r
388   {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
389  return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
390 }\r
391 \r
392 unsigned short P5RGBA(unsigned short BGR)\r
393 {\r
394  if(!BGR) return 0;\r
395  return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;\r
396 }\r
397 \r
398 unsigned short XP4RGBA(unsigned short BGR)\r
399 {\r
400  if(!BGR) return 6;\r
401  if(DrawSemiTrans && !(BGR&0x8000)) \r
402   {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
403  return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
404 }\r
405 \r
406 unsigned short XP4RGBA_0 (unsigned short BGR)\r
407 {\r
408  if(!BGR) return 6;\r
409  return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
410 }\r
411 \r
412 unsigned short CP4RGBA_0 (unsigned short BGR)\r
413 {\r
414  unsigned short s;\r
415  if(!BGR) return 6;\r
416  s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
417  if(s==0x0fff) s=0x000f;\r
418  return s;\r
419 }\r
420 \r
421 unsigned short XP4RGBA_1(unsigned short BGR)\r
422 {\r
423  if(!BGR) return 6;\r
424  if(!(BGR&0x8000)) \r
425   {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}\r
426  return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
427 }\r
428 \r
429 unsigned short P4RGBA(unsigned short BGR)\r
430 {\r
431  if(!BGR) return 0;\r
432  return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;\r
433 }\r
434 \r
435 ////////////////////////////////////////////////////////////////////////\r
436 // CHECK TEXTURE MEM (on plugin startup)\r
437 ////////////////////////////////////////////////////////////////////////\r
438 \r
439 int iFTexA=512;\r
440 int iFTexB=512;\r
441 \r
442 void CheckTextureMemory(void)\r
443 {\r
444  GLboolean b;GLboolean * bDetail;\r
445  int i,iCnt,iRam=iVRamSize*1024*1024;\r
446  int iTSize;char * p;\r
447 \r
448 \r
449  if(iVRamSize)\r
450   {\r
451    int ts;\r
452 \r
453    iRam-=(iResX*iResY*8);\r
454    iRam-=(iResX*iResY*(iZBufferDepth/8));\r
455 \r
456            ts=4;\r
457            iSortTexCnt=iRam/(256*256*ts);\r
458 \r
459    if(iSortTexCnt>MAXSORTTEX) \r
460     {\r
461      iSortTexCnt=MAXSORTTEX-min(1,0);\r
462     }\r
463    else\r
464     {\r
465      iSortTexCnt-=3+min(1,0);\r
466      if(iSortTexCnt<8) iSortTexCnt=8;\r
467     }\r
468 \r
469    for(i=0;i<MAXSORTTEX;i++)\r
470     uiStexturePage[i]=0;\r
471  \r
472    return;\r
473   }\r
474 \r
475 \r
476          iTSize=256;\r
477  p=(char *)malloc(iTSize*iTSize*4);\r
478 \r
479  iCnt=0;\r
480  glGenTextures(MAXSORTTEX,uiStexturePage);\r
481  for(i=0;i<MAXSORTTEX;i++)\r
482   {\r
483    glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]);\r
484    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
485    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
486    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
487    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
488    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iTSize, iTSize, 0,GL_RGBA, GL_UNSIGNED_BYTE, p);\r
489   }\r
490  glBindTexture(GL_TEXTURE_2D,0);\r
491 \r
492  free(p);\r
493 \r
494  bDetail=(GLboolean*)malloc(MAXSORTTEX*sizeof(GLboolean));\r
495  memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean));\r
496 \r
497  glDeleteTextures(MAXSORTTEX,uiStexturePage);\r
498 \r
499  for(i=0;i<MAXSORTTEX;i++)\r
500   {\r
501    if(bDetail[i]) iCnt++;\r
502    uiStexturePage[i]=0;\r
503   }\r
504 \r
505  free(bDetail);\r
506 \r
507  if(b) iSortTexCnt=MAXSORTTEX-min(1,0);\r
508  else  iSortTexCnt=iCnt-3+min(1,0);       // place for menu&texwnd\r
509 \r
510  if(iSortTexCnt<8) iSortTexCnt=8;\r
511\r
512 \r
513 ////////////////////////////////////////////////////////////////////////\r
514 // Main init of textures\r
515 ////////////////////////////////////////////////////////////////////////\r
516 \r
517 void InitializeTextureStore() \r
518 {\r
519  int i,j;\r
520 \r
521  if(iGPUHeight==1024)\r
522   {\r
523    MAXTPAGES     = 64;\r
524    CLUTMASK      = 0xffff;\r
525    CLUTYMASK     = 0x3ff;\r
526    MAXSORTTEX    = 128;\r
527    iTexGarbageCollection=0;\r
528   }\r
529  else\r
530   {\r
531    MAXTPAGES     = 32;\r
532    CLUTMASK      = 0x7fff;\r
533    CLUTYMASK     = 0x1ff;\r
534    MAXSORTTEX    = 196;\r
535   }\r
536 \r
537  memset(vertex,0,4*sizeof(OGLVertex));                 // init vertices\r
538 \r
539  gTexName=0;                                           // init main tex name\r
540 \r
541  iTexWndLimit=MAXWNDTEXCACHE;\r
542 /* if(!iUsePalTextures) */iTexWndLimit/=2;\r
543 \r
544  memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)*\r
545                         MAXWNDTEXCACHE);\r
546  texturepart=(GLubyte *)malloc(256*256*4);\r
547  memset(texturepart,0,256*256*4);\r
548          texturebuffer=NULL;\r
549 \r
550  for(i=0;i<3;i++)                                    // -> info for 32*3\r
551   for(j=0;j<MAXTPAGES;j++)\r
552    {                                               \r
553     pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS));\r
554     memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS));\r
555    }\r
556  for(i=0;i<MAXSORTTEX;i++)                           // -> info 0..511\r
557   {\r
558    pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong));\r
559    memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong));\r
560    uiStexturePage[i]=0;\r
561   }\r
562 }\r
563 \r
564 ////////////////////////////////////////////////////////////////////////\r
565 // Clean up on exit\r
566 ////////////////////////////////////////////////////////////////////////\r
567 \r
568 void CleanupTextureStore() \r
569 {\r
570  int i,j;textureWndCacheEntry * tsx;\r
571  //----------------------------------------------------//\r
572  glBindTexture(GL_TEXTURE_2D,0);\r
573  //----------------------------------------------------//\r
574  free(texturepart);                                    // free tex part\r
575  texturepart=0;\r
576  if(texturebuffer)\r
577   {\r
578    free(texturebuffer);\r
579    texturebuffer=0;\r
580   }\r
581  //----------------------------------------------------//\r
582  tsx=wcWndtexStore;                                    // loop tex window cache\r
583  for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
584   {\r
585    if(tsx->texname)                                    // -> some tex?\r
586     glDeleteTextures(1,&tsx->texname);                 // --> delete it\r
587   }\r
588  iMaxTexWnds=0;                                        // no more tex wnds\r
589  //----------------------------------------------------//\r
590  if(gTexMovieName!=0)                                  // some movie tex?\r
591   glDeleteTextures(1, &gTexMovieName);                 // -> delete it\r
592  gTexMovieName=0;                                      // no more movie tex\r
593  //----------------------------------------------------//\r
594  if(gTexFrameName!=0)                                  // some 15bit framebuffer tex?\r
595   glDeleteTextures(1, &gTexFrameName);                 // -> delete it\r
596  gTexFrameName=0;                                      // no more movie tex\r
597  //----------------------------------------------------//\r
598  if(gTexBlurName!=0)                                   // some 15bit framebuffer tex?\r
599   glDeleteTextures(1, &gTexBlurName);                  // -> delete it\r
600  gTexBlurName=0;                                       // no more movie tex\r
601  //----------------------------------------------------//\r
602  for(i=0;i<3;i++)                                    // -> loop\r
603   for(j=0;j<MAXTPAGES;j++)                           // loop tex pages\r
604    {\r
605     free(pscSubtexStore[i][j]);                      // -> clean mem\r
606    }\r
607  for(i=0;i<MAXSORTTEX;i++)\r
608   {\r
609    if(uiStexturePage[i])                             // --> tex used ?\r
610     {\r
611      glDeleteTextures(1,&uiStexturePage[i]);\r
612      uiStexturePage[i]=0;                            // --> delete it\r
613     }\r
614    free(pxSsubtexLeft[i]);                           // -> clean mem\r
615   }\r
616  //----------------------------------------------------//\r
617 }\r
618 \r
619 ////////////////////////////////////////////////////////////////////////\r
620 // Reset textures in game...\r
621 ////////////////////////////////////////////////////////////////////////\r
622 \r
623 void ResetTextureArea(BOOL bDelTex)\r
624 {\r
625  int i,j;textureSubCacheEntryS * tss;EXLong * lu;\r
626  textureWndCacheEntry * tsx;\r
627  //----------------------------------------------------//\r
628 \r
629  dwTexPageComp=0;\r
630 \r
631  //----------------------------------------------------//\r
632  if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;}\r
633  //----------------------------------------------------//\r
634  tsx=wcWndtexStore;\r
635  for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)\r
636   {\r
637    tsx->used=0;\r
638    if(bDelTex && tsx->texname)\r
639     {\r
640      glDeleteTextures(1,&tsx->texname);\r
641      tsx->texname=0;\r
642     }\r
643   }\r
644  iMaxTexWnds=0;\r
645  //----------------------------------------------------//\r
646 \r
647  for(i=0;i<3;i++)\r
648   for(j=0;j<MAXTPAGES;j++)\r
649    {\r
650     tss=pscSubtexStore[i][j];\r
651     (tss+SOFFA)->pos.l=0;\r
652     (tss+SOFFB)->pos.l=0;\r
653     (tss+SOFFC)->pos.l=0;\r
654     (tss+SOFFD)->pos.l=0;\r
655    }\r
656 \r
657  for(i=0;i<iSortTexCnt;i++)\r
658   {\r
659    lu=pxSsubtexLeft[i];\r
660    lu->l=0;\r
661    if(bDelTex && uiStexturePage[i])\r
662     {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;}\r
663   }\r
664 }\r
665 \r
666 \r
667 ////////////////////////////////////////////////////////////////////////\r
668 // Invalidate tex windows\r
669 ////////////////////////////////////////////////////////////////////////\r
670 \r
671 void InvalidateWndTextureArea(long X,long Y,long W, long H)\r
672 {\r
673  int i,px1,px2,py1,py2,iYM=1;\r
674  textureWndCacheEntry * tsw=wcWndtexStore;\r
675 \r
676  W+=X-1;      \r
677  H+=Y-1;\r
678  if(X<0) X=0;if(X>1023) X=1023;\r
679  if(W<0) W=0;if(W>1023) W=1023;\r
680  if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
681  if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
682  W++;H++;\r
683 \r
684  if(iGPUHeight==1024) iYM=3;\r
685 \r
686  py1=min(iYM,Y>>8);\r
687  py2=min(iYM,H>>8);                                    // y: 0 or 1\r
688 \r
689  px1=max(0,(X>>6));\r
690  px2=min(15,(W>>6));\r
691 \r
692  if(py1==py2)\r
693   {\r
694    py1=py1<<4;px1+=py1;px2+=py1;                       // change to 0-31\r
695    for(i=0;i<iMaxTexWnds;i++,tsw++)\r
696     {\r
697      if(tsw->used)\r
698       {\r
699        if(tsw->pageid>=px1 && tsw->pageid<=px2)\r
700         {\r
701          tsw->used=0;\r
702         }\r
703       }\r
704     }\r
705   }\r
706  else\r
707   {\r
708    py1=px1+16;py2=px2+16;\r
709    for(i=0;i<iMaxTexWnds;i++,tsw++)\r
710     {\r
711      if(tsw->used)\r
712       {\r
713        if((tsw->pageid>=px1 && tsw->pageid<=px2) ||\r
714           (tsw->pageid>=py1 && tsw->pageid<=py2))\r
715         {\r
716          tsw->used=0;\r
717         }\r
718       }\r
719     }\r
720   }\r
721 \r
722  // adjust tex window count\r
723  tsw=wcWndtexStore+iMaxTexWnds-1;\r
724  while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;}\r
725 }\r
726 \r
727 \r
728 \r
729 ////////////////////////////////////////////////////////////////////////\r
730 // same for sort textures\r
731 ////////////////////////////////////////////////////////////////////////\r
732 \r
733 void MarkFree(textureSubCacheEntryS * tsx)\r
734 {\r
735  EXLong * ul, * uls;\r
736  int j,iMax;unsigned char x1,y1,dx,dy;\r
737 \r
738  uls=pxSsubtexLeft[tsx->cTexID];\r
739  iMax=uls->l;ul=uls+1;\r
740 \r
741  if(!iMax) return;\r
742 \r
743  for(j=0;j<iMax;j++,ul++)\r
744   if(ul->l==0xffffffff) break;\r
745 \r
746  if(j<CSUBSIZE-2)\r
747   {\r
748    if(j==iMax) uls->l=uls->l+1;\r
749 \r
750    x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3];\r
751    if(tsx->posTX) {x1--;dx+=3;}\r
752    y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1];\r
753    if(tsx->posTY) {y1--;dy+=3;}\r
754 \r
755    ul->c[3]=x1;\r
756    ul->c[2]=dx;\r
757    ul->c[1]=y1;\r
758    ul->c[0]=dy;\r
759   }\r
760 }\r
761 \r
762 void InvalidateSubSTextureArea(long X,long Y,long W, long H)\r
763 {\r
764  int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM=1;\r
765  EXLong npos;textureSubCacheEntryS * tsb;\r
766  long x1,x2,y1,y2,xa,sw;\r
767 \r
768  W+=X-1;      \r
769  H+=Y-1;\r
770  if(X<0) X=0;if(X>1023) X=1023;\r
771  if(W<0) W=0;if(W>1023) W=1023;\r
772  if(Y<0) Y=0;if(Y>iGPUHeightMask)  Y=iGPUHeightMask;\r
773  if(H<0) H=0;if(H>iGPUHeightMask)  H=iGPUHeightMask;\r
774  W++;H++;\r
775 \r
776  if(iGPUHeight==1024) iYM=3;\r
777 \r
778  py1=min(iYM,Y>>8);\r
779  py2=min(iYM,H>>8);                                    // y: 0 or 1\r
780  px1=max(0,(X>>6)-3);                                   \r
781  px2=min(15,(W>>6)+3);                                 // x: 0-15\r
782 \r
783  for(py=py1;py<=py2;py++)\r
784   {\r
785    j=(py<<4)+px1;                                      // get page\r
786 \r
787    y1=py*256;y2=y1+255;\r
788 \r
789    if(H<y1)  continue;\r
790    if(Y>y2)  continue;\r
791 \r
792    if(Y>y1)  y1=Y;\r
793    if(H<y2)  y2=H;\r
794    if(y2<y1) {sw=y1;y1=y2;y2=sw;}\r
795    y1=((y1%256)<<8);\r
796    y2=(y2%256);\r
797 \r
798    for(px=px1;px<=px2;px++,j++)\r
799     {\r
800      for(k=0;k<3;k++)\r
801       {\r
802        xa=x1=px<<6;\r
803        if(W<x1) continue;\r
804        x2=x1+(64<<k)-1;\r
805        if(X>x2) continue;\r
806 \r
807        if(X>x1)  x1=X;\r
808        if(W<x2)  x2=W;\r
809        if(x2<x1) {sw=x1;x1=x2;x2=sw;}\r
810 \r
811        if (dwGPUVersion == 2)\r
812         npos.l=0x00ff00ff;\r
813        else\r
814         npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2;\r
815 \r
816         {\r
817          tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++;\r
818          for(i=0;i<iMax;i++,tsb++)\r
819           if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
820 \r
821 //         if(npos.l & 0x00800000)\r
822           {\r
823            tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++;\r
824            for(i=0;i<iMax;i++,tsb++)\r
825             if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
826           }\r
827 \r
828 //         if(npos.l & 0x00000080)\r
829           {\r
830            tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++;\r
831            for(i=0;i<iMax;i++,tsb++)\r
832             if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
833           }\r
834 \r
835 //         if(npos.l & 0x00800080)\r
836           {\r
837            tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++;\r
838            for(i=0;i<iMax;i++,tsb++)\r
839             if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}\r
840           }\r
841         }\r
842       }\r
843     }\r
844   }\r
845 }\r
846 \r
847 ////////////////////////////////////////////////////////////////////////\r
848 // Invalidate some parts of cache: main routine\r
849 ////////////////////////////////////////////////////////////////////////\r
850 \r
851 void InvalidateTextureAreaEx(void)\r
852 {\r
853  short W=sxmax-sxmin;\r
854  short H=symax-symin;\r
855 \r
856  if(W==0 && H==0) return;\r
857 \r
858  if(iMaxTexWnds) \r
859   InvalidateWndTextureArea(sxmin,symin,W,H);\r
860 \r
861  InvalidateSubSTextureArea(sxmin,symin,W,H);\r
862 }\r
863 \r
864 ////////////////////////////////////////////////////////////////////////\r
865 \r
866 void InvalidateTextureArea(long X,long Y,long W, long H)\r
867 {\r
868  if(W==0 && H==0) return;\r
869 \r
870  if(iMaxTexWnds) InvalidateWndTextureArea(X,Y,W,H); \r
871 \r
872  InvalidateSubSTextureArea(X,Y,W,H);\r
873 }\r
874 \r
875 \r
876 ////////////////////////////////////////////////////////////////////////\r
877 // tex window: define\r
878 ////////////////////////////////////////////////////////////////////////\r
879 \r
880 void DefineTextureWnd(void)\r
881 {\r
882  if(gTexName==0)\r
883   glGenTextures(1, &gTexName);\r
884 \r
885  glBindTexture(GL_TEXTURE_2D, gTexName);\r
886 \r
887  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
888  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
889  \r
890 {\r
891    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
892    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
893   }\r
894 \r
895  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
896               TWin.Position.x1, \r
897               TWin.Position.y1, \r
898               0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
899 }\r
900 \r
901 ////////////////////////////////////////////////////////////////////////\r
902 // tex window: load packed stretch\r
903 ////////////////////////////////////////////////////////////////////////\r
904 \r
905 void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
906 {\r
907  unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
908  unsigned int   palstart;\r
909  unsigned short *px,*pa,*ta;\r
910  unsigned char  *cSRCPtr,*cOSRCPtr;\r
911  unsigned short *wSRCPtr,*wOSRCPtr;\r
912  unsigned long  LineOffset;unsigned short s;\r
913  int pmult=pageid/16;\r
914  unsigned short (*LPTCOL)(unsigned short);\r
915 \r
916  LPTCOL=PTCF[DrawSemiTrans];\r
917 \r
918  ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
919  ldy =TWin.Position.y1-TWin.OPosition.y1;\r
920 \r
921  pa=px=(unsigned short *)ubPaletteBuffer;\r
922  ta=(unsigned short *)texturepart;\r
923  palstart=cx+(cy*1024);\r
924 \r
925  ubOpaqueDraw=0;\r
926 \r
927  switch(mode)\r
928   {\r
929    //--------------------------------------------------// \r
930    // 4bit texture load ..\r
931    case 0:\r
932     if(GlobalTextIL)\r
933      {\r
934       unsigned int TXV,TXU,n_xi,n_yi;\r
935 \r
936       wSRCPtr=psxVuw+palstart;\r
937       for(row=0;row<16;row++)\r
938        *px++=LPTCOL(*wSRCPtr++);\r
939 \r
940       column=g_y2-ldy;\r
941       for(TXV=g_y1;TXV<=column;TXV++)\r
942        {\r
943         ldx=ldxo;\r
944         for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
945          {\r
946                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
947                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
948 \r
949           s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
950           *ta++=s;\r
951 \r
952           if(ldx) {*ta++=s;ldx--;}\r
953          }\r
954 \r
955         if(ldy) \r
956          {ldy--;\r
957           for(TXU=g_x1;TXU<=g_x2;TXU++)\r
958            *ta++=*(ta-(g_x2-g_x1));\r
959          }\r
960        }\r
961 \r
962       DefineTextureWnd();\r
963 \r
964       break;\r
965      }\r
966 \r
967 \r
968     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
969 \r
970     // convert CLUT to 32bits .. and then use THAT as a lookup table\r
971 \r
972     wSRCPtr=psxVuw+palstart;\r
973     for(row=0;row<16;row++)\r
974      *px++=LPTCOL(*wSRCPtr++);\r
975 \r
976     sxm=g_x1&1;sxh=g_x1>>1;\r
977     if(sxm) j=g_x1+1; else j=g_x1;\r
978     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
979     for(column=g_y1;column<=g_y2;column++)\r
980      {\r
981       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
982       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
983       \r
984       for(row=j;row<=g_x2-ldxo;row++)\r
985        {\r
986         s=*(pa+(*cSRCPtr & 0xF));\r
987         *ta++=s;\r
988         if(ldx) {*ta++=s;ldx--;}\r
989         row++;\r
990         if(row<=g_x2-ldxo) \r
991          {\r
992           s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
993           *ta++=s; \r
994           if(ldx) {*ta++=s;ldx--;}\r
995          }\r
996         cSRCPtr++;\r
997        }\r
998 \r
999       if(ldy && column&1) \r
1000            {ldy--;cSRCPtr = cOSRCPtr;}\r
1001       else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
1002      }\r
1003 \r
1004     DefineTextureWnd();\r
1005     break;\r
1006    //--------------------------------------------------// \r
1007    // 8bit texture load ..\r
1008    case 1:\r
1009     if(GlobalTextIL)\r
1010      {\r
1011       unsigned int TXV,TXU,n_xi,n_yi;\r
1012 \r
1013       wSRCPtr=psxVuw+palstart;\r
1014       for(row=0;row<256;row++)\r
1015        *px++=LPTCOL(*wSRCPtr++);\r
1016 \r
1017       column=g_y2-ldy;\r
1018       for(TXV=g_y1;TXV<=column;TXV++)\r
1019        {\r
1020         ldx=ldxo;\r
1021         for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
1022          {\r
1023                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
1024                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
1025 \r
1026           s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
1027 \r
1028           *ta++=s;\r
1029           if(ldx) {*ta++=s;ldx--;}\r
1030          }\r
1031 \r
1032         if(ldy) \r
1033          {ldy--;\r
1034           for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1035            *ta++=*(ta-(g_x2-g_x1));\r
1036          }\r
1037 \r
1038        }\r
1039 \r
1040       DefineTextureWnd();\r
1041 \r
1042       break;\r
1043      }\r
1044 \r
1045     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1046 \r
1047     // not using a lookup table here... speeds up smaller texture areas\r
1048     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1049     LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
1050 \r
1051     for(column=g_y1;column<=g_y2;column++)\r
1052      {\r
1053       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
1054       for(row=g_x1;row<=g_x2-ldxo;row++)\r
1055        {\r
1056         s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
1057         *ta++=s;\r
1058         if(ldx) {*ta++=s;ldx--;}\r
1059        }\r
1060       if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
1061       else                cSRCPtr+=LineOffset;\r
1062      }\r
1063 \r
1064     DefineTextureWnd();\r
1065     break;\r
1066    //--------------------------------------------------// \r
1067    // 16bit texture load ..\r
1068    case 2:\r
1069     start=((pageid-16*pmult)*64)+256*1024*pmult;\r
1070     wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
1071     LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
1072                                 \r
1073     for(column=g_y1;column<=g_y2;column++)\r
1074      {\r
1075       wOSRCPtr=wSRCPtr;ldx=ldxo;\r
1076       for(row=g_x1;row<=g_x2-ldxo;row++)\r
1077        {\r
1078         s=LPTCOL(*wSRCPtr++);\r
1079         *ta++=s;\r
1080         if(ldx) {*ta++=s;ldx--;}\r
1081        }\r
1082       if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
1083       else                 wSRCPtr+=LineOffset;\r
1084      }\r
1085 \r
1086     DefineTextureWnd();\r
1087     break;\r
1088    //--------------------------------------------------// \r
1089    // others are not possible !\r
1090   }\r
1091 }\r
1092 \r
1093 ////////////////////////////////////////////////////////////////////////\r
1094 // tex window: load stretched\r
1095 ////////////////////////////////////////////////////////////////////////\r
1096 \r
1097 void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy)\r
1098 {\r
1099  unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s;\r
1100  unsigned int   palstart;\r
1101  unsigned long  *px,*pa,*ta;\r
1102  unsigned char  *cSRCPtr,*cOSRCPtr;\r
1103  unsigned short *wSRCPtr,*wOSRCPtr;\r
1104  unsigned long  LineOffset;\r
1105  int pmult=pageid/16;\r
1106  unsigned long (*LTCOL)(unsigned long);\r
1107  \r
1108  LTCOL=TCF[DrawSemiTrans];\r
1109 \r
1110  ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
1111  ldy =TWin.Position.y1-TWin.OPosition.y1;\r
1112 \r
1113  pa=px=(unsigned long *)ubPaletteBuffer;\r
1114  ta=(unsigned long *)texturepart;\r
1115  palstart=cx+(cy*1024);\r
1116 \r
1117  ubOpaqueDraw=0;\r
1118 \r
1119  switch(mode)\r
1120   {\r
1121    //--------------------------------------------------// \r
1122    // 4bit texture load ..\r
1123    case 0:\r
1124     //------------------- ZN STUFF\r
1125 \r
1126     if(GlobalTextIL)\r
1127      {\r
1128       unsigned int TXV,TXU,n_xi,n_yi;\r
1129 \r
1130       wSRCPtr=psxVuw+palstart;\r
1131 \r
1132       row=4;do\r
1133        {\r
1134         *px    =LTCOL(*wSRCPtr);\r
1135         *(px+1)=LTCOL(*(wSRCPtr+1));\r
1136         *(px+2)=LTCOL(*(wSRCPtr+2));\r
1137         *(px+3)=LTCOL(*(wSRCPtr+3));\r
1138         row--;px+=4;wSRCPtr+=4;\r
1139        }\r
1140       while (row);\r
1141 \r
1142       column=g_y2-ldy;\r
1143       for(TXV=g_y1;TXV<=column;TXV++)\r
1144        {\r
1145         ldx=ldxo;\r
1146         for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
1147          {\r
1148                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
1149                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
1150 \r
1151           s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
1152           *ta++=s;\r
1153 \r
1154           if(ldx) {*ta++=s;ldx--;}\r
1155          }\r
1156 \r
1157         if(ldy) \r
1158          {ldy--;\r
1159           for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1160            *ta++=*(ta-(g_x2-g_x1));\r
1161          }\r
1162        }\r
1163 \r
1164       DefineTextureWnd();\r
1165 \r
1166       break;\r
1167      }\r
1168 \r
1169     //-------------------\r
1170 \r
1171     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1172     // convert CLUT to 32bits .. and then use THAT as a lookup table\r
1173 \r
1174     wSRCPtr=psxVuw+palstart;\r
1175     for(row=0;row<16;row++)\r
1176      *px++=LTCOL(*wSRCPtr++);\r
1177 \r
1178     sxm=g_x1&1;sxh=g_x1>>1;\r
1179     if(sxm) j=g_x1+1; else j=g_x1;\r
1180     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
1181     for(column=g_y1;column<=g_y2;column++)\r
1182      {\r
1183       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
1184       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
1185       \r
1186       for(row=j;row<=g_x2-ldxo;row++)\r
1187        {\r
1188         s=*(pa+(*cSRCPtr & 0xF));\r
1189         *ta++=s;\r
1190         if(ldx) {*ta++=s;ldx--;}\r
1191         row++;\r
1192         if(row<=g_x2-ldxo) \r
1193          {\r
1194           s=*(pa+((*cSRCPtr >> 4) & 0xF));\r
1195           *ta++=s; \r
1196           if(ldx) {*ta++=s;ldx--;}\r
1197          }\r
1198         cSRCPtr++;\r
1199        }\r
1200       if(ldy && column&1) \r
1201            {ldy--;cSRCPtr = cOSRCPtr;}\r
1202       else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
1203      }\r
1204 \r
1205     DefineTextureWnd();\r
1206     break;\r
1207    //--------------------------------------------------//\r
1208    // 8bit texture load ..\r
1209    case 1:\r
1210     //------------ ZN STUFF\r
1211     if(GlobalTextIL)\r
1212      {\r
1213       unsigned int TXV,TXU,n_xi,n_yi;\r
1214 \r
1215       wSRCPtr=psxVuw+palstart;\r
1216 \r
1217       row=64;do\r
1218        {\r
1219         *px    =LTCOL(*wSRCPtr);\r
1220         *(px+1)=LTCOL(*(wSRCPtr+1));\r
1221         *(px+2)=LTCOL(*(wSRCPtr+2));\r
1222         *(px+3)=LTCOL(*(wSRCPtr+3));\r
1223         row--;px+=4;wSRCPtr+=4;\r
1224        }\r
1225       while (row);\r
1226 \r
1227       column=g_y2-ldy;\r
1228       for(TXV=g_y1;TXV<=column;TXV++)\r
1229        {\r
1230         ldx=ldxo;\r
1231         for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)\r
1232          {\r
1233                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
1234                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
1235 \r
1236           s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
1237           *ta++=s;\r
1238           if(ldx) {*ta++=s;ldx--;}\r
1239          }\r
1240 \r
1241         if(ldy) \r
1242          {ldy--;\r
1243           for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1244            *ta++=*(ta-(g_x2-g_x1));\r
1245          }\r
1246 \r
1247        }\r
1248 \r
1249       DefineTextureWnd();\r
1250 \r
1251       break;\r
1252      }\r
1253     //------------\r
1254 \r
1255     start=((pageid-16*pmult)*128)+256*2048*pmult;    \r
1256 \r
1257     // not using a lookup table here... speeds up smaller texture areas\r
1258     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1259     LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
1260 \r
1261     for(column=g_y1;column<=g_y2;column++)\r
1262      {\r
1263       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
1264       for(row=g_x1;row<=g_x2-ldxo;row++)\r
1265        {\r
1266         s=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
1267         *ta++=s;\r
1268         if(ldx) {*ta++=s;ldx--;}\r
1269        }\r
1270       if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
1271       else                cSRCPtr+=LineOffset;\r
1272      }\r
1273 \r
1274     DefineTextureWnd();\r
1275     break;\r
1276    //--------------------------------------------------// \r
1277    // 16bit texture load ..\r
1278    case 2:\r
1279     start=((pageid-16*pmult)*64)+256*1024*pmult;\r
1280 \r
1281     wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
1282     LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; \r
1283 \r
1284     for(column=g_y1;column<=g_y2;column++)\r
1285      {\r
1286       wOSRCPtr=wSRCPtr;ldx=ldxo;\r
1287       for(row=g_x1;row<=g_x2-ldxo;row++)\r
1288        {\r
1289         s=LTCOL(*wSRCPtr++);\r
1290         *ta++=s;\r
1291         if(ldx) {*ta++=s;ldx--;}\r
1292        }\r
1293       if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}\r
1294       else                 wSRCPtr+=LineOffset;\r
1295      }\r
1296 \r
1297     DefineTextureWnd();\r
1298     break;\r
1299    //--------------------------------------------------// \r
1300    // others are not possible !\r
1301   }\r
1302 }\r
1303 \r
1304 ////////////////////////////////////////////////////////////////////////\r
1305 // tex window: load packed simple\r
1306 ////////////////////////////////////////////////////////////////////////\r
1307 \r
1308 void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy)\r
1309 {\r
1310  unsigned long start,row,column,j,sxh,sxm;\r
1311  unsigned int   palstart;\r
1312  unsigned short *px,*pa,*ta;\r
1313  unsigned char  *cSRCPtr;\r
1314  unsigned short *wSRCPtr;\r
1315  unsigned long  LineOffset;\r
1316  int pmult=pageid/16;\r
1317  unsigned short (*LPTCOL)(unsigned short);\r
1318 \r
1319  LPTCOL=PTCF[DrawSemiTrans];\r
1320 \r
1321  pa=px=(unsigned short *)ubPaletteBuffer;\r
1322  ta=(unsigned short *)texturepart;\r
1323  palstart=cx+(cy*1024);\r
1324 \r
1325  ubOpaqueDraw=0;\r
1326 \r
1327  switch(mode)\r
1328   {\r
1329    //--------------------------------------------------// \r
1330    // 4bit texture load ..\r
1331    case 0:\r
1332     if(GlobalTextIL)\r
1333      {\r
1334       unsigned int TXV,TXU,n_xi,n_yi;\r
1335 \r
1336       wSRCPtr=psxVuw+palstart;\r
1337       for(row=0;row<16;row++)\r
1338        *px++=LPTCOL(*wSRCPtr++);\r
1339 \r
1340       for(TXV=g_y1;TXV<=g_y2;TXV++)\r
1341        {\r
1342         for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1343          {\r
1344                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
1345                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
1346 \r
1347           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
1348          }\r
1349        }\r
1350 \r
1351       DefineTextureWnd();\r
1352 \r
1353       break;\r
1354      }\r
1355 \r
1356     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1357 \r
1358     // convert CLUT to 32bits .. and then use THAT as a lookup table\r
1359 \r
1360     wSRCPtr=psxVuw+palstart;\r
1361     for(row=0;row<16;row++)\r
1362      *px++=LPTCOL(*wSRCPtr++);\r
1363 \r
1364     sxm=g_x1&1;sxh=g_x1>>1;\r
1365     if(sxm) j=g_x1+1; else j=g_x1;\r
1366     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
1367     for(column=g_y1;column<=g_y2;column++)\r
1368      {\r
1369       cSRCPtr = psxVub + start + (2048*column) + sxh;\r
1370     \r
1371       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
1372       \r
1373       for(row=j;row<=g_x2;row++)\r
1374        {\r
1375         *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
1376         if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
1377         cSRCPtr++;\r
1378        }\r
1379      }\r
1380 \r
1381     DefineTextureWnd();\r
1382     break;\r
1383    //--------------------------------------------------// \r
1384    // 8bit texture load ..\r
1385    case 1:\r
1386     if(GlobalTextIL)\r
1387      {\r
1388       unsigned int TXV,TXU,n_xi,n_yi;\r
1389 \r
1390       wSRCPtr=psxVuw+palstart;\r
1391       for(row=0;row<256;row++)\r
1392        *px++=LPTCOL(*wSRCPtr++);\r
1393 \r
1394       for(TXV=g_y1;TXV<=g_y2;TXV++)\r
1395        {\r
1396         for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1397          {\r
1398                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
1399                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
1400 \r
1401           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
1402          }\r
1403        }\r
1404 \r
1405       DefineTextureWnd();\r
1406 \r
1407       break;\r
1408      }\r
1409 \r
1410     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1411 \r
1412     // not using a lookup table here... speeds up smaller texture areas\r
1413     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1414     LineOffset = 2048 - (g_x2-g_x1+1); \r
1415 \r
1416     for(column=g_y1;column<=g_y2;column++)\r
1417      {\r
1418       for(row=g_x1;row<=g_x2;row++)\r
1419        *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
1420       cSRCPtr+=LineOffset;\r
1421      }\r
1422 \r
1423     DefineTextureWnd();\r
1424     break;\r
1425    //--------------------------------------------------// \r
1426    // 16bit texture load ..\r
1427    case 2:\r
1428     start=((pageid-16*pmult)*64)+256*1024*pmult;\r
1429     wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
1430     LineOffset = 1024 - (g_x2-g_x1+1); \r
1431 \r
1432     for(column=g_y1;column<=g_y2;column++)\r
1433      {\r
1434       for(row=g_x1;row<=g_x2;row++)\r
1435        *ta++=LPTCOL(*wSRCPtr++);\r
1436       wSRCPtr+=LineOffset;\r
1437      }\r
1438 \r
1439     DefineTextureWnd();\r
1440     break;\r
1441    //--------------------------------------------------// \r
1442    // others are not possible !\r
1443   }\r
1444 }\r
1445 \r
1446 ////////////////////////////////////////////////////////////////////////\r
1447 // tex window: load simple\r
1448 ////////////////////////////////////////////////////////////////////////\r
1449 \r
1450 void LoadWndTexturePage(int pageid, int mode, short cx, short cy)\r
1451 {\r
1452  unsigned long start,row,column,j,sxh,sxm;\r
1453  unsigned int   palstart;\r
1454  unsigned long  *px,*pa,*ta;\r
1455  unsigned char  *cSRCPtr;\r
1456  unsigned short *wSRCPtr;\r
1457  unsigned long  LineOffset;\r
1458  int pmult=pageid/16;\r
1459  unsigned long (*LTCOL)(unsigned long);\r
1460  \r
1461  LTCOL=TCF[DrawSemiTrans];\r
1462 \r
1463  pa=px=(unsigned long *)ubPaletteBuffer;\r
1464  ta=(unsigned long *)texturepart;\r
1465  palstart=cx+(cy*1024);\r
1466 \r
1467  ubOpaqueDraw=0;\r
1468 \r
1469  switch(mode)\r
1470   {\r
1471    //--------------------------------------------------// \r
1472    // 4bit texture load ..\r
1473    case 0:\r
1474     if(GlobalTextIL)\r
1475      {\r
1476       unsigned int TXV,TXU,n_xi,n_yi;\r
1477 \r
1478       wSRCPtr=psxVuw+palstart;\r
1479 \r
1480       row=4;do\r
1481        {\r
1482         *px    =LTCOL(*wSRCPtr);\r
1483         *(px+1)=LTCOL(*(wSRCPtr+1));\r
1484         *(px+2)=LTCOL(*(wSRCPtr+2));\r
1485         *(px+3)=LTCOL(*(wSRCPtr+3));\r
1486         row--;px+=4;wSRCPtr+=4;\r
1487        }\r
1488       while (row);\r
1489 \r
1490       for(TXV=g_y1;TXV<=g_y2;TXV++)\r
1491        {\r
1492         for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1493          {\r
1494                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
1495                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
1496 \r
1497           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
1498          }\r
1499        }\r
1500 \r
1501       DefineTextureWnd();\r
1502 \r
1503       break;\r
1504      }\r
1505 \r
1506     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1507 \r
1508     // convert CLUT to 32bits .. and then use THAT as a lookup table\r
1509 \r
1510     wSRCPtr=psxVuw+palstart;\r
1511     for(row=0;row<16;row++)\r
1512      *px++=LTCOL(*wSRCPtr++);\r
1513 \r
1514     sxm=g_x1&1;sxh=g_x1>>1;\r
1515     if(sxm) j=g_x1+1; else j=g_x1;\r
1516     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
1517     for(column=g_y1;column<=g_y2;column++)\r
1518      {\r
1519       cSRCPtr = psxVub + start + (2048*column) + sxh;\r
1520     \r
1521       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
1522       \r
1523       for(row=j;row<=g_x2;row++)\r
1524        {\r
1525         *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
1526         if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
1527         cSRCPtr++;\r
1528        }\r
1529      }\r
1530 \r
1531     DefineTextureWnd();\r
1532     break;\r
1533    //--------------------------------------------------//\r
1534    // 8bit texture load ..\r
1535    case 1:\r
1536     if(GlobalTextIL)\r
1537      {\r
1538       unsigned int TXV,TXU,n_xi,n_yi;\r
1539 \r
1540       wSRCPtr=psxVuw+palstart;\r
1541 \r
1542       row=64;do\r
1543        {\r
1544         *px    =LTCOL(*wSRCPtr);\r
1545         *(px+1)=LTCOL(*(wSRCPtr+1));\r
1546         *(px+2)=LTCOL(*(wSRCPtr+2));\r
1547         *(px+3)=LTCOL(*(wSRCPtr+3));\r
1548         row--;px+=4;wSRCPtr+=4;\r
1549        }\r
1550       while (row);\r
1551 \r
1552       for(TXV=g_y1;TXV<=g_y2;TXV++)\r
1553        {\r
1554         for(TXU=g_x1;TXU<=g_x2;TXU++)\r
1555          {\r
1556                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
1557                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
1558 \r
1559           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
1560          }\r
1561        }\r
1562 \r
1563       DefineTextureWnd();\r
1564 \r
1565       break;\r
1566      }\r
1567 \r
1568     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1569 \r
1570     // not using a lookup table here... speeds up smaller texture areas\r
1571     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1572     LineOffset = 2048 - (g_x2-g_x1+1); \r
1573 \r
1574     for(column=g_y1;column<=g_y2;column++)\r
1575      {\r
1576       for(row=g_x1;row<=g_x2;row++)\r
1577        *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]);\r
1578       cSRCPtr+=LineOffset;\r
1579      }\r
1580 \r
1581     DefineTextureWnd();\r
1582     break;\r
1583    //--------------------------------------------------// \r
1584    // 16bit texture load ..\r
1585    case 2:\r
1586     start=((pageid-16*pmult)*64)+256*1024*pmult;\r
1587 \r
1588     wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;\r
1589     LineOffset = 1024 - (g_x2-g_x1+1); \r
1590 \r
1591     for(column=g_y1;column<=g_y2;column++)\r
1592      {\r
1593       for(row=g_x1;row<=g_x2;row++)\r
1594        *ta++=LTCOL(*wSRCPtr++);\r
1595       wSRCPtr+=LineOffset;\r
1596      }\r
1597 \r
1598     DefineTextureWnd();\r
1599     break;\r
1600    //--------------------------------------------------// \r
1601    // others are not possible !\r
1602   }\r
1603 }\r
1604 \r
1605 ////////////////////////////////////////////////////////////////////////\r
1606 ////////////////////////////////////////////////////////////////////////\r
1607 ////////////////////////////////////////////////////////////////////////\r
1608 ////////////////////////////////////////////////////////////////////////\r
1609 \r
1610 void UploadTexWndPal(int mode,short cx,short cy)\r
1611 {\r
1612  unsigned int i,iSize;\r
1613  unsigned short * wSrcPtr;\r
1614  unsigned long * ta=(unsigned long *)texturepart;\r
1615 \r
1616  wSrcPtr=psxVuw+cx+(cy*1024);\r
1617  if(mode==0) i=4; else i=64;\r
1618  iSize=i<<2;\r
1619  ubOpaqueDraw=0;\r
1620 \r
1621  do\r
1622   {\r
1623    *ta    =PALCOL(*wSrcPtr);\r
1624    *(ta+1)=PALCOL(*(wSrcPtr+1));\r
1625    *(ta+2)=PALCOL(*(wSrcPtr+2));\r
1626    *(ta+3)=PALCOL(*(wSrcPtr+3));\r
1627    ta+=4;wSrcPtr+=4;i--;\r
1628   }\r
1629  while(i);\r
1630 \r
1631 /* (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize,\r
1632                     GL_RGBA,GL_UNSIGNED_BYTE,texturepart);\r
1633 */}\r
1634 \r
1635 ////////////////////////////////////////////////////////////////////////\r
1636 \r
1637 void DefinePalTextureWnd(void)\r
1638 {\r
1639  if(gTexName==0)\r
1640   glGenTextures(1, &gTexName);\r
1641 \r
1642  glBindTexture(GL_TEXTURE_2D, gTexName);\r
1643 \r
1644  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
1645  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
1646  \r
1647 {\r
1648    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
1649    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
1650   }\r
1651 \r
1652  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, \r
1653               TWin.Position.x1, \r
1654               TWin.Position.y1, \r
1655               0, GL_RGBA, GL_UNSIGNED_BYTE,texturepart);\r
1656 }\r
1657 \r
1658 ///////////////////////////////////////////////////////\r
1659 \r
1660 void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
1661 {\r
1662  unsigned long start,row,column,j,sxh,sxm;\r
1663  unsigned char  *ta;\r
1664  unsigned char  *cSRCPtr;\r
1665  unsigned long  LineOffset;\r
1666  int pmult=pageid/16;\r
1667 \r
1668  ta=(unsigned char *)texturepart;\r
1669 \r
1670  switch(mode)\r
1671   {\r
1672    //--------------------------------------------------// \r
1673    // 4bit texture load ..\r
1674    case 0:\r
1675     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1676 \r
1677     sxm=g_x1&1;sxh=g_x1>>1;\r
1678     if(sxm) j=g_x1+1; else j=g_x1;\r
1679     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
1680     for(column=g_y1;column<=g_y2;column++)\r
1681      {\r
1682       cSRCPtr = psxVub + start + (2048*column) + sxh;\r
1683     \r
1684       if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
1685       \r
1686       for(row=j;row<=g_x2;row++)\r
1687        {\r
1688         *ta++=(*cSRCPtr & 0xF); row++;\r
1689         if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF); \r
1690         cSRCPtr++;\r
1691        }\r
1692      }\r
1693 \r
1694     DefinePalTextureWnd();\r
1695     break;\r
1696    //--------------------------------------------------// \r
1697    // 8bit texture load ..\r
1698    case 1:\r
1699     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1700 \r
1701     // not using a lookup table here... speeds up smaller texture areas\r
1702     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1703     LineOffset = 2048 - (g_x2-g_x1+1); \r
1704 \r
1705     for(column=g_y1;column<=g_y2;column++)\r
1706      {\r
1707       for(row=g_x1;row<=g_x2;row++)\r
1708        *ta++=*cSRCPtr++;\r
1709       cSRCPtr+=LineOffset;\r
1710      }\r
1711 \r
1712     DefinePalTextureWnd();\r
1713     break;\r
1714   }\r
1715  UploadTexWndPal(mode,cx,cy);\r
1716 }\r
1717 \r
1718 ////////////////////////////////////////////////////////////////////////\r
1719 \r
1720 void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy)\r
1721 {\r
1722  unsigned long start,row,column,j,sxh,sxm,ldx,ldy,ldxo;\r
1723  unsigned char  *ta,s;\r
1724  unsigned char  *cSRCPtr,*cOSRCPtr;\r
1725  unsigned long  LineOffset;\r
1726  int pmult=pageid/16;\r
1727 \r
1728  ldxo=TWin.Position.x1-TWin.OPosition.x1;\r
1729  ldy =TWin.Position.y1-TWin.OPosition.y1;\r
1730 \r
1731  ta=(unsigned char *)texturepart;\r
1732 \r
1733  switch(mode)\r
1734   {\r
1735    //--------------------------------------------------// \r
1736    // 4bit texture load ..\r
1737    case 0:\r
1738     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1739 \r
1740     sxm=g_x1&1;sxh=g_x1>>1;\r
1741     if(sxm) j=g_x1+1; else j=g_x1;\r
1742     cSRCPtr = psxVub + start + (2048*g_y1) + sxh;\r
1743     for(column=g_y1;column<=g_y2;column++)\r
1744      {\r
1745       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
1746       if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);\r
1747       \r
1748       for(row=j;row<=g_x2-ldxo;row++)\r
1749        {\r
1750         s=(*cSRCPtr & 0xF);\r
1751         *ta++=s;\r
1752         if(ldx) {*ta++=s;ldx--;}\r
1753         row++;\r
1754         if(row<=g_x2-ldxo) \r
1755          {\r
1756           s=((*cSRCPtr >> 4) & 0xF);\r
1757           *ta++=s; \r
1758           if(ldx) {*ta++=s;ldx--;}\r
1759          }\r
1760         cSRCPtr++;\r
1761        }\r
1762       if(ldy && column&1) \r
1763            {ldy--;cSRCPtr = cOSRCPtr;}\r
1764       else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;\r
1765      }\r
1766 \r
1767     DefinePalTextureWnd();\r
1768     break;\r
1769    //--------------------------------------------------// \r
1770    // 8bit texture load ..\r
1771    case 1:\r
1772     start=((pageid-16*pmult)*128)+256*2048*pmult;\r
1773 \r
1774     cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;\r
1775     LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; \r
1776 \r
1777     for(column=g_y1;column<=g_y2;column++)\r
1778      {\r
1779       cOSRCPtr=cSRCPtr;ldx=ldxo;\r
1780       for(row=g_x1;row<=g_x2-ldxo;row++)\r
1781        {\r
1782         s=*cSRCPtr++;\r
1783         *ta++=s;\r
1784         if(ldx) {*ta++=s;ldx--;}\r
1785        }\r
1786       if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}\r
1787       else                cSRCPtr+=LineOffset;\r
1788      }\r
1789 \r
1790     DefinePalTextureWnd();\r
1791     break;\r
1792   }\r
1793  UploadTexWndPal(mode,cx,cy);\r
1794 }\r
1795 \r
1796 ////////////////////////////////////////////////////////////////////////\r
1797 // tex window: main selecting, cache handler included\r
1798 ////////////////////////////////////////////////////////////////////////\r
1799 \r
1800 GLuint LoadTextureWnd(long pageid,long TextureMode,unsigned long GivenClutId)\r
1801 {\r
1802  textureWndCacheEntry * ts, * tsx=NULL;\r
1803  int i;short cx,cy;\r
1804  EXLong npos;\r
1805 \r
1806  npos.c[3]=TWin.Position.x0;\r
1807  npos.c[2]=TWin.OPosition.x1;\r
1808  npos.c[1]=TWin.Position.y0;\r
1809  npos.c[0]=TWin.OPosition.y1;\r
1810 \r
1811  g_x1=TWin.Position.x0;g_x2=g_x1+TWin.Position.x1-1;\r
1812  g_y1=TWin.Position.y0;g_y2=g_y1+TWin.Position.y1-1;\r
1813 \r
1814  if(TextureMode==2) {GivenClutId=0;cx=cy=0;}\r
1815  else  \r
1816   {\r
1817    cx=((GivenClutId << 4) & 0x3F0);cy=((GivenClutId >> 6) & CLUTYMASK);\r
1818    GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30);\r
1819 \r
1820    // palette check sum\r
1821     {\r
1822      unsigned long l=0,row;\r
1823      unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
1824      if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
1825      else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
1826      l=(l+HIWORD(l))&0x3fffL;\r
1827      GivenClutId|=(l<<16);\r
1828     }\r
1829 \r
1830   }\r
1831 \r
1832  ts=wcWndtexStore;\r
1833 \r
1834  for(i=0;i<iMaxTexWnds;i++,ts++)\r
1835   {\r
1836    if(ts->used)\r
1837     {\r
1838      if(ts->pos.l==npos.l &&\r
1839         ts->pageid==pageid &&\r
1840         ts->textureMode==TextureMode)\r
1841       {\r
1842        if(ts->ClutID==GivenClutId)\r
1843         {\r
1844          ubOpaqueDraw=ts->Opaque;\r
1845          return ts->texname;\r
1846         }\r
1847       }\r
1848     }\r
1849    else tsx=ts;\r
1850   }\r
1851 \r
1852  if(!tsx) \r
1853   {\r
1854    if(iMaxTexWnds==iTexWndLimit)\r
1855     {\r
1856      tsx=wcWndtexStore+iTexWndTurn;\r
1857      iTexWndTurn++; \r
1858      if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0;\r
1859     }\r
1860    else\r
1861     {\r
1862      tsx=wcWndtexStore+iMaxTexWnds;\r
1863      iMaxTexWnds++;\r
1864     }\r
1865   }\r
1866 \r
1867  gTexName=tsx->texname;\r
1868 \r
1869  if(TWin.OPosition.y1==TWin.Position.y1 &&\r
1870     TWin.OPosition.x1==TWin.Position.x1)\r
1871   {\r
1872     LoadWndTexturePage(pageid,TextureMode,cx,cy);\r
1873   }       \r
1874  else\r
1875   {\r
1876     LoadStretchWndTexturePage(pageid,TextureMode,cx,cy);\r
1877   }\r
1878 \r
1879  tsx->Opaque=ubOpaqueDraw;\r
1880  tsx->pos.l=npos.l;\r
1881  tsx->ClutID=GivenClutId;\r
1882  tsx->pageid=pageid;\r
1883  tsx->textureMode=TextureMode;\r
1884  tsx->texname=gTexName;\r
1885  tsx->used=1;\r
1886        \r
1887  return gTexName;\r
1888 }\r
1889 \r
1890 /////////////////////////////////////////////////////////////////////////////\r
1891 /////////////////////////////////////////////////////////////////////////////\r
1892 /////////////////////////////////////////////////////////////////////////////\r
1893 \r
1894 ////////////////////////////////////////////////////////////////////////\r
1895 // movie texture: define\r
1896 ////////////////////////////////////////////////////////////////////////\r
1897 \r
1898 void DefinePackedTextureMovie(void)\r
1899 {\r
1900  if(gTexMovieName==0)\r
1901   {\r
1902    glGenTextures(1, &gTexMovieName);\r
1903    gTexName=gTexMovieName;\r
1904    glBindTexture(GL_TEXTURE_2D, gTexName);\r
1905 \r
1906    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
1907    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
1908 \r
1909    if(!bUseFastMdec) \r
1910     {\r
1911      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1912      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1913     }\r
1914    else\r
1915     {\r
1916      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
1917      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
1918     }\r
1919                                  \r
1920    glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA, \r
1921                 GL_RGBA,\r
1922                 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
1923   }\r
1924  else \r
1925   {\r
1926    gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
1927   }\r
1928 \r
1929  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
1930                  (xrMovieArea.x1-xrMovieArea.x0), \r
1931                  (xrMovieArea.y1-xrMovieArea.y0), \r
1932                  GL_RGBA,\r
1933                  GL_UNSIGNED_SHORT,\r
1934                  texturepart);\r
1935 }\r
1936 \r
1937 ////////////////////////////////////////////////////////////////////////\r
1938 \r
1939 void DefineTextureMovie(void)\r
1940 {\r
1941  if(gTexMovieName==0)\r
1942   {\r
1943    glGenTextures(1, &gTexMovieName);\r
1944    gTexName=gTexMovieName;\r
1945    glBindTexture(GL_TEXTURE_2D, gTexName);\r
1946 \r
1947    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
1948    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
1949  \r
1950    if(!bUseFastMdec) \r
1951     {\r
1952      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
1953      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
1954     }\r
1955    else\r
1956     {\r
1957      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
1958      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
1959     }\r
1960 \r
1961    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
1962   }\r
1963  else \r
1964   {\r
1965    gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);\r
1966   }\r
1967 \r
1968  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,\r
1969                  (xrMovieArea.x1-xrMovieArea.x0), \r
1970                  (xrMovieArea.y1-xrMovieArea.y0), \r
1971                  GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
1972 }\r
1973 \r
1974 ////////////////////////////////////////////////////////////////////////\r
1975 // movie texture: load\r
1976 ////////////////////////////////////////////////////////////////////////\r
1977 \r
1978 #define MRED(x)   ((x>>3) & 0x1f)\r
1979 #define MGREEN(x) ((x>>6) & 0x3e0)\r
1980 #define MBLUE(x)  ((x>>9) & 0x7c00)\r
1981 \r
1982 #define XMGREEN(x) ((x>>5)  & 0x07c0)\r
1983 #define XMRED(x)   ((x<<8)  & 0xf800)\r
1984 #define XMBLUE(x)  ((x>>18) & 0x003e)\r
1985 \r
1986 ////////////////////////////////////////////////////////////////////////\r
1987 // movie texture: load\r
1988 ////////////////////////////////////////////////////////////////////////\r
1989 \r
1990 unsigned char * LoadDirectMovieFast(void)\r
1991 {\r
1992  long row,column;\r
1993  unsigned int startxy;\r
1994 \r
1995  unsigned long * ta=(unsigned long *)texturepart;\r
1996 \r
1997  if(PSXDisplay.RGB24)\r
1998   {\r
1999    unsigned char * pD;\r
2000 \r
2001    startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
2002 \r
2003    for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
2004     {\r
2005      pD=(unsigned char *)&psxVuw[startxy];\r
2006      for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2007       {\r
2008        *ta++=*((unsigned long *)pD)|0xff000000;\r
2009        pD+=3;\r
2010       }\r
2011     }\r
2012   }\r
2013  else\r
2014   {\r
2015    unsigned long (*LTCOL)(unsigned long);\r
2016 \r
2017    LTCOL=XP8RGBA_0;//TCF[0];\r
2018 \r
2019    ubOpaqueDraw=0;\r
2020 \r
2021    for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2022     {\r
2023      startxy=((1024)*column)+xrMovieArea.x0;\r
2024      for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2025       *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
2026     }\r
2027   }\r
2028  \r
2029  return texturepart;\r
2030 }\r
2031 \r
2032 ////////////////////////////////////////////////////////////////////////\r
2033 \r
2034 GLuint LoadTextureMovieFast(void)\r
2035 {\r
2036  long row,column;\r
2037  unsigned int start,startxy;\r
2038 \r
2039 {\r
2040    if(PSXDisplay.RGB24)\r
2041     {\r
2042      unsigned char * pD;\r
2043      unsigned long * ta=(unsigned long *)texturepart;\r
2044 \r
2045      startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;\r
2046 \r
2047      for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)\r
2048       {\r
2049        //startxy=((1024)*column)+xrMovieArea.x0;\r
2050        pD=(unsigned char *)&psxVuw[startxy];\r
2051        for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2052         {\r
2053          *ta++=*((unsigned long *)pD)|0xff000000;\r
2054          pD+=3;\r
2055         }\r
2056       }\r
2057     }\r
2058    else\r
2059     {\r
2060      unsigned long (*LTCOL)(unsigned long);\r
2061      unsigned long *ta;\r
2062 \r
2063      LTCOL=XP8RGBA_0;//TCF[0];\r
2064 \r
2065      ubOpaqueDraw=0;\r
2066      ta=(unsigned long *)texturepart;\r
2067 \r
2068      for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2069       {\r
2070        startxy=((1024)*column)+xrMovieArea.x0;\r
2071        for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2072         *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
2073       }\r
2074     }\r
2075    DefineTextureMovie();\r
2076   }\r
2077  return gTexName;   \r
2078 }\r
2079 \r
2080 ////////////////////////////////////////////////////////////////////////\r
2081 \r
2082 GLuint LoadTextureMovie(void)\r
2083 {\r
2084  short row,column,dx;\r
2085  unsigned int startxy;\r
2086  BOOL b_X,b_Y;\r
2087 \r
2088  if(bUseFastMdec) return LoadTextureMovieFast();\r
2089 \r
2090  b_X=FALSE;b_Y=FALSE;\r
2091 \r
2092  if((xrMovieArea.x1-xrMovieArea.x0)<255)  b_X=TRUE;\r
2093  if((xrMovieArea.y1-xrMovieArea.y0)<255)  b_Y=TRUE;\r
2094 \r
2095 {\r
2096    if(PSXDisplay.RGB24)\r
2097     {\r
2098      unsigned char * pD;\r
2099      unsigned long * ta=(unsigned long *)texturepart;\r
2100 \r
2101      if(b_X)\r
2102       {\r
2103        for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2104         {\r
2105          startxy=((1024)*column)+xrMovieArea.x0;\r
2106          pD=(unsigned char *)&psxVuw[startxy];\r
2107          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2108           {\r
2109            *ta++=*((unsigned long *)pD)|0xff000000;\r
2110            pD+=3;\r
2111           }\r
2112          *ta++=*(ta-1);\r
2113         }\r
2114        if(b_Y)\r
2115         {\r
2116          dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
2117          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2118           *ta++=*(ta-dx);\r
2119          *ta++=*(ta-1);\r
2120         }\r
2121       }\r
2122      else\r
2123       {\r
2124        for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2125         {\r
2126          startxy=((1024)*column)+xrMovieArea.x0;\r
2127          pD=(unsigned char *)&psxVuw[startxy];\r
2128          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2129           {\r
2130            *ta++=*((unsigned long *)pD)|0xff000000;\r
2131            pD+=3;\r
2132           }\r
2133         }\r
2134        if(b_Y)\r
2135         {\r
2136          dx=xrMovieArea.x1-xrMovieArea.x0;\r
2137          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2138           *ta++=*(ta-dx);\r
2139         }\r
2140       }\r
2141     }\r
2142    else\r
2143     {\r
2144      unsigned long (*LTCOL)(unsigned long);\r
2145      unsigned long *ta;\r
2146 \r
2147      LTCOL=XP8RGBA_0;//TCF[0];\r
2148 \r
2149      ubOpaqueDraw=0;\r
2150      ta=(unsigned long *)texturepart;\r
2151 \r
2152      if(b_X)\r
2153       {\r
2154        for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2155         {\r
2156          startxy=((1024)*column)+xrMovieArea.x0;\r
2157          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2158           *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
2159          *ta++=*(ta-1);\r
2160         }\r
2161 \r
2162        if(b_Y)\r
2163         {\r
2164          dx=xrMovieArea.x1-xrMovieArea.x0+1;\r
2165          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2166           *ta++=*(ta-dx);\r
2167          *ta++=*(ta-1);\r
2168         }\r
2169       }\r
2170      else\r
2171       {\r
2172        for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)\r
2173         {\r
2174          startxy=((1024)*column)+xrMovieArea.x0;\r
2175          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2176           *ta++=LTCOL(psxVuw[startxy++]|0x8000);\r
2177         }\r
2178 \r
2179        if(b_Y)\r
2180         {\r
2181          dx=xrMovieArea.x1-xrMovieArea.x0;\r
2182          for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)\r
2183           *ta++=*(ta-dx);\r
2184         }\r
2185       }\r
2186     }\r
2187 \r
2188    xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y;\r
2189    DefineTextureMovie();\r
2190    xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y;\r
2191   }\r
2192  return gTexName;   \r
2193 }\r
2194 \r
2195 /////////////////////////////////////////////////////////////////////////////\r
2196 /////////////////////////////////////////////////////////////////////////////\r
2197 /////////////////////////////////////////////////////////////////////////////\r
2198 \r
2199 GLuint BlackFake15BitTexture(void)\r
2200 {\r
2201  long pmult;short x1,x2,y1,y2;\r
2202 \r
2203  if(PSXDisplay.InterlacedTest) return 0;\r
2204  \r
2205  pmult=GlobalTexturePage/16;\r
2206  x1=gl_ux[7];\r
2207  x2=gl_ux[6]-gl_ux[7];\r
2208  y1=gl_ux[5];\r
2209  y2=gl_ux[4]-gl_ux[5];\r
2210 \r
2211  if(iSpriteTex)\r
2212   {\r
2213    if(x2<255) x2++;\r
2214    if(y2<255) y2++;\r
2215   }\r
2216 \r
2217  y1+=pmult*256;\r
2218  x1+=((GlobalTexturePage-16*pmult)<<6);\r
2219 \r
2220  if(   FastCheckAgainstFrontScreen(x1,y1,x2,y2)\r
2221     || FastCheckAgainstScreen(x1,y1,x2,y2))\r
2222   {\r
2223    if(!gTexFrameName)\r
2224     {\r
2225      glGenTextures(1, &gTexFrameName);\r
2226      gTexName=gTexFrameName;\r
2227      glBindTexture(GL_TEXTURE_2D, gTexName);\r
2228 \r
2229      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
2230      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
2231      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
2232      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
2233  \r
2234      {\r
2235        unsigned long * ta=(unsigned long *)texturepart;\r
2236        for(y1=0;y1<=4;y1++)\r
2237         for(x1=0;x1<=4;x1++)\r
2238          *ta++=0xff000000;\r
2239       }\r
2240      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
2241     }\r
2242    else\r
2243     {\r
2244      gTexName=gTexFrameName;\r
2245      glBindTexture(GL_TEXTURE_2D, gTexName);\r
2246     }\r
2247 \r
2248    ubOpaqueDraw=0;\r
2249 \r
2250    return (GLuint)gTexName;\r
2251   }\r
2252  return 0;\r
2253 }\r
2254 \r
2255 /////////////////////////////////////////////////////////////////////////////\r
2256 \r
2257 BOOL bFakeFrontBuffer=FALSE;\r
2258 BOOL bIgnoreNextTile =FALSE;\r
2259 \r
2260 int iFTex=512;\r
2261 \r
2262 GLuint Fake15BitTexture(void)\r
2263 {\r
2264  long pmult;short x1,x2,y1,y2;int iYAdjust;\r
2265  float ScaleX,ScaleY;RECT rSrc;\r
2266 \r
2267  if(iFrameTexType==1) return BlackFake15BitTexture();\r
2268  if(PSXDisplay.InterlacedTest) return 0;\r
2269  \r
2270  pmult=GlobalTexturePage/16;\r
2271  x1=gl_ux[7];\r
2272  x2=gl_ux[6]-gl_ux[7];\r
2273  y1=gl_ux[5];\r
2274  y2=gl_ux[4]-gl_ux[5];\r
2275 \r
2276  y1+=pmult*256;\r
2277  x1+=((GlobalTexturePage-16*pmult)<<6);\r
2278 \r
2279  if(iFrameTexType==3)\r
2280   {\r
2281    if(iFrameReadType==4) return 0;\r
2282 \r
2283    if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) &&\r
2284       !FastCheckAgainstScreen(x1,y1,x2,y2))\r
2285     return 0;\r
2286 \r
2287    if(bFakeFrontBuffer) bIgnoreNextTile=TRUE;\r
2288    CheckVRamReadEx(x1,y1,x1+x2,y1+y2);\r
2289    return 0;\r
2290   }\r
2291 \r
2292  /////////////////////////\r
2293 \r
2294  if(FastCheckAgainstFrontScreen(x1,y1,x2,y2))\r
2295   {\r
2296    x1-=PSXDisplay.DisplayPosition.x;\r
2297    y1-=PSXDisplay.DisplayPosition.y;\r
2298   }\r
2299  else\r
2300  if(FastCheckAgainstScreen(x1,y1,x2,y2))\r
2301   {\r
2302    x1-=PreviousPSXDisplay.DisplayPosition.x;\r
2303    y1-=PreviousPSXDisplay.DisplayPosition.y;\r
2304   }\r
2305  else return 0;\r
2306 \r
2307  bDrawMultiPass = FALSE;\r
2308 \r
2309  if(!gTexFrameName)\r
2310   {\r
2311    char * p;\r
2312 \r
2313    if(iResX>1280 || iResY>1024) iFTex=2048;\r
2314    else\r
2315    if(iResX>640  || iResY>480)  iFTex=1024;\r
2316    else                         iFTex=512; \r
2317 \r
2318    glGenTextures(1, &gTexFrameName);\r
2319    gTexName=gTexFrameName;\r
2320    glBindTexture(GL_TEXTURE_2D, gTexName);\r
2321 \r
2322    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
2323    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
2324    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
2325    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
2326 \r
2327    p=(char *)malloc(iFTex*iFTex*4);\r
2328    memset(p,0,iFTex*iFTex*4);\r
2329    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iFTex, iFTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, p);\r
2330    free(p);\r
2331 \r
2332    glGetError();\r
2333   }\r
2334  else \r
2335   {\r
2336    gTexName=gTexFrameName;\r
2337    glBindTexture(GL_TEXTURE_2D, gTexName);\r
2338   }\r
2339 \r
2340  x1+=PreviousPSXDisplay.Range.x0;\r
2341  y1+=PreviousPSXDisplay.Range.y0;\r
2342 \r
2343  if(PSXDisplay.DisplayMode.x)\r
2344       ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;\r
2345  else ScaleX=1.0f;\r
2346  if(PSXDisplay.DisplayMode.y)\r
2347       ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;\r
2348  else ScaleY=1.0f;\r
2349 \r
2350  rSrc.left  =max(x1*ScaleX,0);\r
2351  rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1);\r
2352  rSrc.top   =max(y1*ScaleY,0);\r
2353  rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1);\r
2354 \r
2355  iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y;\r
2356  if(iYAdjust>0)\r
2357       iYAdjust=(int)((float)iYAdjust*ScaleY)+1;\r
2358  else iYAdjust=0;\r
2359           \r
2360  gl_vy[0]=255-gl_vy[0];\r
2361  gl_vy[1]=255-gl_vy[1];\r
2362  gl_vy[2]=255-gl_vy[2];\r
2363  gl_vy[3]=255-gl_vy[3];\r
2364 \r
2365  y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3])));\r
2366 \r
2367  gl_vy[0]-=y1;\r
2368  gl_vy[1]-=y1;\r
2369  gl_vy[2]-=y1;\r
2370  gl_vy[3]-=y1;\r
2371  gl_ux[0]-=gl_ux[7];\r
2372  gl_ux[1]-=gl_ux[7];\r
2373  gl_ux[2]-=gl_ux[7];\r
2374  gl_ux[3]-=gl_ux[7];\r
2375 \r
2376  ScaleX*=256.0f/((float)(iFTex));\r
2377  ScaleY*=256.0f/((float)(iFTex));\r
2378 \r
2379  y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255;\r
2380  gl_vy[0]=y1;\r
2381  y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255;\r
2382  gl_vy[1]=y1;\r
2383  y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255;\r
2384  gl_vy[2]=y1;\r
2385  y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255;\r
2386  gl_vy[3]=y1;\r
2387 \r
2388  x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255;\r
2389  gl_ux[0]=x1;\r
2390  x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255;\r
2391  gl_ux[1]=x1;\r
2392  x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255;\r
2393  gl_ux[2]=x1;\r
2394  x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255;\r
2395  gl_ux[3]=x1;\r
2396 \r
2397  x1=rSrc.right-rSrc.left;\r
2398  if(x1<=0)             x1=1;\r
2399  if(x1>iFTex)          x1=iFTex;\r
2400 \r
2401  y1=rSrc.bottom-rSrc.top;\r
2402  if(y1<=0)             y1=1;\r
2403  if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust;\r
2404 \r
2405 \r
2406  glCopyTexSubImage2D( GL_TEXTURE_2D, 0, \r
2407                       0,\r
2408                       iYAdjust,\r
2409                       rSrc.left+rRatioRect.left,\r
2410                       iResY-rSrc.bottom-rRatioRect.top,\r
2411                       x1,y1);\r
2412 \r
2413  if(glGetError()) \r
2414   {\r
2415    char * p=(char *)malloc(iFTex*iFTex*4);\r
2416    memset(p,0,iFTex*iFTex*4);\r
2417    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex,\r
2418                    GL_RGBA, GL_UNSIGNED_BYTE, p);\r
2419    free(p);\r
2420   }\r
2421 \r
2422  \r
2423  ubOpaqueDraw=0;\r
2424 \r
2425  if(iSpriteTex)\r
2426   {\r
2427    sprtW=gl_ux[1]-gl_ux[0];    \r
2428    sprtH=-(gl_vy[0]-gl_vy[2]);\r
2429   }\r
2430 \r
2431  return (GLuint)gTexName;\r
2432 }\r
2433 \r
2434 /////////////////////////////////////////////////////////////////////////////\r
2435 /////////////////////////////////////////////////////////////////////////////\r
2436 /////////////////////////////////////////////////////////////////////////////\r
2437 //\r
2438 // load texture part (unpacked)\r
2439 //\r
2440 /////////////////////////////////////////////////////////////////////////////\r
2441 /////////////////////////////////////////////////////////////////////////////\r
2442 /////////////////////////////////////////////////////////////////////////////\r
2443 \r
2444 void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
2445 {\r
2446  unsigned long  start,row,column,j,sxh,sxm;\r
2447  unsigned int   palstart;\r
2448  unsigned long  *px,*pa,*ta;\r
2449  unsigned char  *cSRCPtr;\r
2450  unsigned short *wSRCPtr;\r
2451  unsigned long  LineOffset;\r
2452  unsigned long  x2a,xalign=0;\r
2453  unsigned long  x1=gl_ux[7];\r
2454  unsigned long  x2=gl_ux[6];\r
2455  unsigned long  y1=gl_ux[5];\r
2456  unsigned long  y2=gl_ux[4];\r
2457  unsigned long  dx=x2-x1+1;\r
2458  unsigned long  dy=y2-y1+1;\r
2459  int pmult=pageid/16;\r
2460  unsigned long (*LTCOL)(unsigned long);\r
2461  unsigned int a,r,g,b,cnt,h;\r
2462  unsigned long scol[8];\r
2463  \r
2464  LTCOL=TCF[DrawSemiTrans];\r
2465 \r
2466  pa=px=(unsigned long *)ubPaletteBuffer;\r
2467  ta=(unsigned long *)texturepart;\r
2468  palstart=cx+(cy<<10);\r
2469 \r
2470  ubOpaqueDraw=0;\r
2471 \r
2472  if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
2473  if(XTexS) {ta+=1;xalign=2;}\r
2474 \r
2475  switch(mode)\r
2476   {\r
2477    //--------------------------------------------------// \r
2478    // 4bit texture load ..\r
2479    case 0:\r
2480     if(GlobalTextIL)\r
2481      {\r
2482       unsigned int TXV,TXU,n_xi,n_yi;\r
2483 \r
2484       wSRCPtr=psxVuw+palstart;\r
2485 \r
2486       row=4;do\r
2487        {\r
2488         *px    =LTCOL(*wSRCPtr);\r
2489         *(px+1)=LTCOL(*(wSRCPtr+1));\r
2490         *(px+2)=LTCOL(*(wSRCPtr+2));\r
2491         *(px+3)=LTCOL(*(wSRCPtr+3));\r
2492         row--;px+=4;wSRCPtr+=4;\r
2493        }\r
2494       while (row);\r
2495 \r
2496       for(TXV=y1;TXV<=y2;TXV++)\r
2497        {\r
2498         for(TXU=x1;TXU<=x2;TXU++)\r
2499          {\r
2500                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
2501                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
2502 \r
2503           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
2504          }\r
2505         ta+=xalign;\r
2506        }\r
2507       break;\r
2508      }\r
2509 \r
2510     start=((pageid-16*pmult)<<7)+524288*pmult;\r
2511     // convert CLUT to 32bits .. and then use THAT as a lookup table\r
2512 \r
2513     wSRCPtr=psxVuw+palstart;\r
2514 \r
2515     row=4;do\r
2516      {\r
2517       *px    =LTCOL(*wSRCPtr);\r
2518       *(px+1)=LTCOL(*(wSRCPtr+1));\r
2519       *(px+2)=LTCOL(*(wSRCPtr+2));\r
2520       *(px+3)=LTCOL(*(wSRCPtr+3));\r
2521       row--;px+=4;wSRCPtr+=4;\r
2522      }\r
2523     while (row);\r
2524 \r
2525     x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
2526     sxm=x1&1;sxh=x1>>1;\r
2527     j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
2528     for(column=y1;column<=y2;column++)\r
2529      {\r
2530       cSRCPtr = psxVub + start + (column<<11) + sxh;\r
2531     \r
2532       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
2533 \r
2534       for(row=j;row<x2a;row+=2)\r
2535        {\r
2536         *ta    =*(pa+(*cSRCPtr & 0xF)); \r
2537         *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
2538         cSRCPtr++;ta+=2;\r
2539        }\r
2540 \r
2541       if(row<=x2) \r
2542        {\r
2543         *ta++=*(pa+(*cSRCPtr & 0xF)); row++;\r
2544         if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
2545        }\r
2546 \r
2547       ta+=xalign;\r
2548      }\r
2549 \r
2550     break;\r
2551    //--------------------------------------------------// \r
2552    // 8bit texture load ..\r
2553    case 1:\r
2554     if(GlobalTextIL)\r
2555      {\r
2556       unsigned int TXV,TXU,n_xi,n_yi;\r
2557 \r
2558       wSRCPtr=psxVuw+palstart;\r
2559 \r
2560       row=64;do\r
2561        {\r
2562         *px    =LTCOL(*wSRCPtr);\r
2563         *(px+1)=LTCOL(*(wSRCPtr+1));\r
2564         *(px+2)=LTCOL(*(wSRCPtr+2));\r
2565         *(px+3)=LTCOL(*(wSRCPtr+3));\r
2566         row--;px+=4;wSRCPtr+=4;\r
2567        }\r
2568       while (row);\r
2569 \r
2570       for(TXV=y1;TXV<=y2;TXV++)\r
2571        {\r
2572         for(TXU=x1;TXU<=x2;TXU++)\r
2573          {\r
2574                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
2575                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
2576 \r
2577           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
2578          }\r
2579         ta+=xalign;\r
2580        }\r
2581 \r
2582       break;\r
2583      }\r
2584 \r
2585     start=((pageid-16*pmult)<<7)+524288*pmult;\r
2586 \r
2587     cSRCPtr = psxVub + start + (y1<<11) + x1;\r
2588     LineOffset = 2048 - dx; \r
2589 \r
2590     if(dy*dx>384)\r
2591      {\r
2592       wSRCPtr=psxVuw+palstart;\r
2593 \r
2594       row=64;do\r
2595        {\r
2596         *px    =LTCOL(*wSRCPtr);\r
2597         *(px+1)=LTCOL(*(wSRCPtr+1));\r
2598         *(px+2)=LTCOL(*(wSRCPtr+2));\r
2599         *(px+3)=LTCOL(*(wSRCPtr+3));\r
2600         row--;px+=4;wSRCPtr+=4;\r
2601        }\r
2602       while (row);\r
2603 \r
2604       column=dy;do \r
2605        {\r
2606         row=dx;\r
2607         do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
2608         ta+=xalign;\r
2609         cSRCPtr+=LineOffset;column--;\r
2610        }\r
2611       while(column);\r
2612      }\r
2613     else\r
2614      {\r
2615       wSRCPtr=psxVuw+palstart;\r
2616 \r
2617       column=dy;do \r
2618        {\r
2619         row=dx;\r
2620         do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
2621         ta+=xalign;\r
2622         cSRCPtr+=LineOffset;column--;\r
2623        }\r
2624       while(column);\r
2625      }\r
2626 \r
2627     break;\r
2628    //--------------------------------------------------// \r
2629    // 16bit texture load ..\r
2630    case 2:\r
2631     start=((pageid-16*pmult)<<6)+262144*pmult;\r
2632 \r
2633     wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
2634     LineOffset = 1024 - dx; \r
2635 \r
2636     column=dy;do \r
2637      {\r
2638       row=dx;\r
2639       do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row);\r
2640       ta+=xalign;\r
2641       wSRCPtr+=LineOffset;column--;\r
2642      }\r
2643     while(column);\r
2644 \r
2645     break;\r
2646    //--------------------------------------------------//\r
2647    // others are not possible !\r
2648   }\r
2649 \r
2650  x2a=dx+xalign;\r
2651 \r
2652  if(YTexS)\r
2653   {\r
2654    ta=(unsigned long *)texturepart;\r
2655    pa=(unsigned long *)texturepart+x2a;\r
2656    row=x2a;do {*ta++=*pa++;row--;} while(row);        \r
2657    pa=(unsigned long *)texturepart+dy*x2a;\r
2658    ta=pa+x2a;\r
2659    row=x2a;do {*ta++=*pa++;row--;} while(row);\r
2660    YTexS--;\r
2661    dy+=2;\r
2662   }\r
2663 \r
2664  if(XTexS)\r
2665   {\r
2666    ta=(unsigned long *)texturepart;\r
2667    pa=ta+1;\r
2668    row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
2669    pa=(unsigned long *)texturepart+dx;\r
2670    ta=pa+1;\r
2671    row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
2672    XTexS--;\r
2673    dx+=2;\r
2674   }\r
2675 \r
2676  DXTexS=dx;DYTexS=dy;\r
2677 \r
2678  if(!iFilterType) {DefineSubTextureSort();return;}\r
2679  if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
2680  if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
2681   {DefineSubTextureSort();return;}\r
2682 \r
2683  ta=(unsigned long *)texturepart;\r
2684  x1=dx-1;\r
2685  y1=dy-1;\r
2686 \r
2687  if(bOpaquePass)\r
2688   {\r
2689 {\r
2690      for(column=0;column<dy;column++)\r
2691       {\r
2692        for(row=0;row<dx;row++)\r
2693         {\r
2694          if(*ta==0x50000000)\r
2695           {\r
2696            cnt=0;\r
2697 \r
2698            if(           column     && *(ta-dx)  !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx);\r
2699            if(row                   && *(ta-1)   !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1);\r
2700            if(row!=x1               && *(ta+1)   !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1);\r
2701            if(           column!=y1 && *(ta+dx)  !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx);\r
2702 \r
2703            if(row     && column     && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1);\r
2704            if(row!=x1 && column     && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1);\r
2705            if(row     && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1);\r
2706            if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1);\r
2707 \r
2708            if(cnt)\r
2709             {\r
2710              r=g=b=a=0;\r
2711              for(h=0;h<cnt;h++)\r
2712               {\r
2713                a+=(scol[h]>>24);\r
2714                r+=(scol[h]>>16)&0xff;\r
2715                g+=(scol[h]>>8)&0xff;\r
2716                b+=scol[h]&0xff;\r
2717               }\r
2718              r/=cnt;b/=cnt;g/=cnt;\r
2719 \r
2720              *ta=(r<<16)|(g<<8)|b;\r
2721              if(a) *ta|=0x50000000;\r
2722              else  *ta|=0x01000000;\r
2723             }\r
2724           }\r
2725          ta++;\r
2726         }\r
2727       }\r
2728     }\r
2729   }\r
2730  else\r
2731  for(column=0;column<dy;column++)\r
2732   {\r
2733    for(row=0;row<dx;row++)\r
2734     {\r
2735      if(*ta==0x00000000)\r
2736       {\r
2737        cnt=0;\r
2738 \r
2739        if(row!=x1               && *(ta+1)   !=0x00000000) scol[cnt++]=*(ta+1);\r
2740        if(           column!=y1 && *(ta+dx)  !=0x00000000) scol[cnt++]=*(ta+dx);\r
2741 \r
2742        if(cnt)\r
2743         {\r
2744          r=g=b=0;\r
2745          for(h=0;h<cnt;h++)\r
2746           {\r
2747            r+=(scol[h]>>16)&0xff;\r
2748            g+=(scol[h]>>8)&0xff;\r
2749            b+=scol[h]&0xff;\r
2750           }\r
2751          r/=cnt;b/=cnt;g/=cnt;\r
2752          *ta=(r<<16)|(g<<8)|b;\r
2753         }\r
2754       }\r
2755      ta++;\r
2756     }\r
2757   }\r
2758 \r
2759  DefineSubTextureSort();\r
2760 }\r
2761 \r
2762 /////////////////////////////////////////////////////////////////////////////\r
2763 /////////////////////////////////////////////////////////////////////////////\r
2764 /////////////////////////////////////////////////////////////////////////////\r
2765 //\r
2766 // load texture part (packed)\r
2767 //\r
2768 /////////////////////////////////////////////////////////////////////////////\r
2769 /////////////////////////////////////////////////////////////////////////////\r
2770 /////////////////////////////////////////////////////////////////////////////\r
2771 \r
2772 void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy)\r
2773 {\r
2774  unsigned long  start,row,column,j,sxh,sxm;\r
2775  unsigned int   palstart;\r
2776  unsigned short *px,*pa,*ta;\r
2777  unsigned char  *cSRCPtr;\r
2778  unsigned short *wSRCPtr;\r
2779  unsigned long  LineOffset;\r
2780  unsigned long  x2a,xalign=0;\r
2781  unsigned long  x1=gl_ux[7];\r
2782  unsigned long  x2=gl_ux[6];\r
2783  unsigned long  y1=gl_ux[5];\r
2784  unsigned long  y2=gl_ux[4];\r
2785  unsigned long  dx=x2-x1+1;\r
2786  unsigned long  dy=y2-y1+1;\r
2787  int pmult=pageid/16;\r
2788  unsigned short (*LPTCOL)(unsigned short);\r
2789  unsigned int a,r,g,b,cnt,h;\r
2790  unsigned short scol[8];\r
2791 \r
2792  LPTCOL=PTCF[DrawSemiTrans];\r
2793 \r
2794  pa=px=(unsigned short *)ubPaletteBuffer;\r
2795  ta=(unsigned short *)texturepart;\r
2796  palstart=cx+(cy<<10);\r
2797 \r
2798  ubOpaqueDraw=0;\r
2799 \r
2800  if(YTexS) {ta+=dx;if(XTexS) ta+=2;}\r
2801  if(XTexS) {ta+=1;xalign=2;}\r
2802 \r
2803  switch(mode)\r
2804   {\r
2805    //--------------------------------------------------// \r
2806    // 4bit texture load ..\r
2807    case 0:\r
2808     if(GlobalTextIL)\r
2809      {\r
2810       unsigned int TXV,TXU,n_xi,n_yi;\r
2811 \r
2812       wSRCPtr=psxVuw+palstart;\r
2813       row=4;do\r
2814        {\r
2815         *px    =LPTCOL(*wSRCPtr);\r
2816         *(px+1)=LPTCOL(*(wSRCPtr+1));\r
2817         *(px+2)=LPTCOL(*(wSRCPtr+2));\r
2818         *(px+3)=LPTCOL(*(wSRCPtr+3));\r
2819         row--;px+=4;wSRCPtr+=4;\r
2820        }\r
2821       while (row);\r
2822 \r
2823       for(TXV=y1;TXV<=y2;TXV++)\r
2824        {\r
2825         for(TXU=x1;TXU<=x2;TXU++)\r
2826          {\r
2827                   n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );\r
2828                   n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );\r
2829 \r
2830           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));\r
2831          }\r
2832         ta+=xalign;\r
2833        }\r
2834       break;\r
2835      }\r
2836 \r
2837     start=((pageid-16*pmult)<<7)+524288*pmult;\r
2838 \r
2839     wSRCPtr=psxVuw+palstart;\r
2840     row=4;do\r
2841      {\r
2842       *px    =LPTCOL(*wSRCPtr);\r
2843       *(px+1)=LPTCOL(*(wSRCPtr+1));\r
2844       *(px+2)=LPTCOL(*(wSRCPtr+2));\r
2845       *(px+3)=LPTCOL(*(wSRCPtr+3));\r
2846       row--;px+=4;wSRCPtr+=4;\r
2847      }\r
2848     while (row);\r
2849 \r
2850     x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;\r
2851     sxm=x1&1;sxh=x1>>1;\r
2852     j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;\r
2853 \r
2854     for(column=y1;column<=y2;column++)\r
2855      {\r
2856       cSRCPtr = psxVub + start + (column<<11) + sxh;\r
2857     \r
2858       if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));\r
2859  \r
2860       for(row=j;row<x2a;row+=2)\r
2861        {\r
2862         *ta    =*(pa+(*cSRCPtr & 0xF));\r
2863         *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); \r
2864         cSRCPtr++;ta+=2;\r
2865        }\r
2866 \r
2867       if(row<=x2)\r
2868        {\r
2869         *ta++=*(pa+(*cSRCPtr & 0xF));row++;\r
2870         if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));\r
2871        }\r
2872 \r
2873       ta+=xalign;\r
2874      }\r
2875     break;\r
2876    //--------------------------------------------------// \r
2877    // 8bit texture load ..\r
2878    case 1:\r
2879     if(GlobalTextIL)\r
2880      {\r
2881       unsigned int TXV,TXU,n_xi,n_yi;\r
2882 \r
2883       wSRCPtr=psxVuw+palstart;\r
2884 \r
2885       row=64;do\r
2886        {\r
2887         *px    =LPTCOL(*wSRCPtr);\r
2888         *(px+1)=LPTCOL(*(wSRCPtr+1));\r
2889         *(px+2)=LPTCOL(*(wSRCPtr+2));\r
2890         *(px+3)=LPTCOL(*(wSRCPtr+3));\r
2891         row--;px+=4;wSRCPtr+=4;\r
2892        }\r
2893       while (row);\r
2894 \r
2895       for(TXV=y1;TXV<=y2;TXV++)\r
2896        {\r
2897         for(TXU=x1;TXU<=x2;TXU++)\r
2898          {\r
2899                   n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );\r
2900                   n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );\r
2901 \r
2902           *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));\r
2903          }\r
2904         ta+=xalign;\r
2905        }\r
2906 \r
2907       break;\r
2908      }\r
2909 \r
2910     start=((pageid-16*pmult)<<7)+524288*pmult;\r
2911 \r
2912     cSRCPtr = psxVub + start + (y1<<11) + x1;\r
2913     LineOffset = 2048 - dx;\r
2914 \r
2915     if(dy*dx>384)                                      // more pix? use lut\r
2916      {\r
2917       wSRCPtr=psxVuw+palstart;\r
2918 \r
2919       row=64;do\r
2920        {\r
2921         *px    =LPTCOL(*wSRCPtr);\r
2922         *(px+1)=LPTCOL(*(wSRCPtr+1));\r
2923         *(px+2)=LPTCOL(*(wSRCPtr+2));\r
2924         *(px+3)=LPTCOL(*(wSRCPtr+3));\r
2925         row--;px+=4;wSRCPtr+=4;\r
2926        }\r
2927       while (row);\r
2928 \r
2929       column=dy;do \r
2930        {\r
2931         row=dx;\r
2932         do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);\r
2933 \r
2934         ta+=xalign;\r
2935 \r
2936         cSRCPtr+=LineOffset;column--;\r
2937        }\r
2938       while(column);\r
2939      }\r
2940     else                                               // small area? no lut\r
2941      {                                            \r
2942       wSRCPtr=psxVuw+palstart;\r
2943 \r
2944       column=dy;do \r
2945        {\r
2946         row=dx;\r
2947         do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);\r
2948 \r
2949         ta+=xalign;\r
2950 \r
2951         cSRCPtr+=LineOffset;column--;\r
2952        }\r
2953       while(column);\r
2954      }\r
2955     break;\r
2956    //--------------------------------------------------// \r
2957    // 16bit texture load ..\r
2958    case 2:\r
2959     start=((pageid-16*pmult)<<6)+262144*pmult;\r
2960 \r
2961     wSRCPtr = psxVuw + start + (y1<<10) + x1;\r
2962     LineOffset = 1024 - dx; \r
2963 \r
2964     column=dy;do \r
2965      {\r
2966       row=dx;\r
2967       do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row);\r
2968 \r
2969       ta+=xalign;\r
2970 \r
2971       wSRCPtr+=LineOffset;column--;\r
2972      }\r
2973     while(column);\r
2974     break;\r
2975    //--------------------------------------------------// \r
2976    // others are not possible !\r
2977   }\r
2978 \r
2979  ////////////////////////////////////////////////////////\r
2980 \r
2981  x2a=dx+xalign;\r
2982 \r
2983  if(YTexS)\r
2984   {\r
2985    ta=(unsigned short *)texturepart;\r
2986    pa=(unsigned short *)texturepart+x2a;\r
2987    row=x2a;do {*ta++=*pa++;row--;} while(row);\r
2988 \r
2989    pa=(unsigned short *)texturepart+dy*x2a;\r
2990    ta=pa+x2a;\r
2991    row=x2a;do {*ta++=*pa++;row--;} while(row);\r
2992 \r
2993    YTexS--;\r
2994    dy+=2;\r
2995   }\r
2996 \r
2997  if(XTexS)\r
2998   {\r
2999    ta=(unsigned short *)texturepart;\r
3000    pa=ta+1;\r
3001    row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
3002 \r
3003    pa=(unsigned short *)texturepart+dx;\r
3004    ta=pa+1;\r
3005    row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);\r
3006 \r
3007    XTexS--;\r
3008    dx+=2;\r
3009   }\r
3010 \r
3011  DXTexS=dx;DYTexS=dy;\r
3012 \r
3013  if(!iFilterType) {DefineSubTextureSort();return;}\r
3014  if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}\r
3015  if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)\r
3016   {DefineSubTextureSort();return;}\r
3017 \r
3018  ta=(unsigned short *)texturepart;\r
3019  x1=dx-1;\r
3020  y1=dy-1;      \r
3021 \r
3022 {\r
3023    for(column=0;column<dy;column++)\r
3024     {\r
3025      for(row=0;row<dx;row++)\r
3026       {\r
3027        if(*ta==0)\r
3028         {\r
3029          cnt=0;\r
3030 \r
3031          if(           column     && *(ta-dx)  &1) scol[cnt++]=*(ta-dx);\r
3032          if(row                   && *(ta-1)   &1) scol[cnt++]=*(ta-1);\r
3033          if(row!=x1               && *(ta+1)   &1) scol[cnt++]=*(ta+1);\r
3034          if(           column!=y1 && *(ta+dx)  &1) scol[cnt++]=*(ta+dx);\r
3035 \r
3036          if(row     && column     && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1);\r
3037          if(row!=x1 && column     && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1);\r
3038          if(row     && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1);\r
3039          if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1);\r
3040 \r
3041          if(cnt)\r
3042           {\r
3043            r=g=b=0;\r
3044            for(h=0;h<cnt;h++)\r
3045             {\r
3046              r+=scol[h]>>11;\r
3047              g+=(scol[h]>>6)&0x1f;\r
3048              b+=(scol[h]>>1)&0x1f;\r
3049             }\r
3050            r/=cnt;b/=cnt;g/=cnt;\r
3051            *ta=(r<<11)|(g<<6)|(b<<1);\r
3052           }\r
3053         }\r
3054        ta++;\r
3055       }\r
3056     }\r
3057   }\r
3058 \r
3059  DefineSubTextureSort();\r
3060 }\r
3061 \r
3062 /////////////////////////////////////////////////////////////////////////////\r
3063 \r
3064 /////////////////////////////////////////////////////////////////////////////\r
3065 /////////////////////////////////////////////////////////////////////////////\r
3066 /////////////////////////////////////////////////////////////////////////////\r
3067 //\r
3068 // hires texture funcs\r
3069 //\r
3070 /////////////////////////////////////////////////////////////////////////////\r
3071 /////////////////////////////////////////////////////////////////////////////\r
3072 /////////////////////////////////////////////////////////////////////////////\r
3073 \r
3074 \r
3075 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))\r
3076 \r
3077 ////////////////////////////////////////////////////////////////////////\r
3078 \r
3079 #define colorMask8     0x00FEFEFE\r
3080 #define lowPixelMask8  0x00010101\r
3081 #define qcolorMask8    0x00FCFCFC\r
3082 #define qlowpixelMask8 0x00030303\r
3083 \r
3084 \r
3085 #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
3086 \r
3087 #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
3088 \r
3089 #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
3090 \r
3091 #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
3092 \r
3093 void Super2xSaI_ex8_Ex(unsigned char *srcPtr, DWORD srcPitch,\r
3094                     unsigned char  *dstBitmap, int width, int height)\r
3095 {\r
3096  DWORD dstPitch = srcPitch * 2;\r
3097  DWORD line;\r
3098  DWORD *dP;\r
3099  DWORD *bP;\r
3100  int   width2 = width*2;\r
3101  int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
3102  DWORD color4, color5, color6;\r
3103  DWORD color1, color2, color3;\r
3104  DWORD colorA0, colorA1, colorA2, colorA3,\r
3105        colorB0, colorB1, colorB2, colorB3,\r
3106        colorS1, colorS2;\r
3107  DWORD product1a, product1b,\r
3108        product2a, product2b;\r
3109 \r
3110  line = 0;\r
3111 \r
3112   {\r
3113    for (; height; height-=1)\r
3114         {\r
3115      bP = (DWORD *)srcPtr;\r
3116          dP = (DWORD *)(dstBitmap + line*dstPitch);\r
3117      for (finish = width; finish; finish -= 1 )\r
3118       {\r
3119 //---------------------------------------    B1 B2\r
3120 //                                         4  5  6 S2\r
3121 //                                         1  2  3 S1\r
3122 //                                           A1 A2\r
3123        if(finish==width) iXA=0;\r
3124        else              iXA=1;\r
3125        if(finish>4) {iXB=1;iXC=2;}\r
3126        else\r
3127        if(finish>3) {iXB=1;iXC=1;}\r
3128        else         {iXB=0;iXC=0;}\r
3129        if(line==0) iYA=0;\r
3130        else        iYA=width;\r
3131        if(height>4) {iYB=width;iYC=width2;}\r
3132        else\r
3133        if(height>3) {iYB=width;iYC=width;}\r
3134        else         {iYB=0;iYC=0;}\r
3135 \r
3136 \r
3137        colorB0 = *(bP- iYA - iXA);\r
3138        colorB1 = *(bP- iYA);\r
3139        colorB2 = *(bP- iYA + iXB);\r
3140        colorB3 = *(bP- iYA + iXC);\r
3141 \r
3142        color4 = *(bP  - iXA);\r
3143        color5 = *(bP);\r
3144        color6 = *(bP  + iXB);\r
3145        colorS2 = *(bP + iXC);\r
3146 \r
3147        color1 = *(bP  + iYB  - iXA);\r
3148        color2 = *(bP  + iYB);\r
3149        color3 = *(bP  + iYB  + iXB);\r
3150        colorS1= *(bP  + iYB  + iXC);\r
3151 \r
3152        colorA0 = *(bP + iYC - iXA);\r
3153        colorA1 = *(bP + iYC);\r
3154        colorA2 = *(bP + iYC + iXB);\r
3155        colorA3 = *(bP + iYC + iXC);\r
3156 \r
3157 //--------------------------------------\r
3158        if (color2 == color6 && color5 != color3)\r
3159         {\r
3160          product2b = product1b = color2;\r
3161         }\r
3162        else\r
3163        if (color5 == color3 && color2 != color6)\r
3164         {\r
3165          product2b = product1b = color5;\r
3166         }\r
3167        else\r
3168        if (color5 == color3 && color2 == color6)\r
3169         {\r
3170          register int r = 0;\r
3171 \r
3172          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
3173          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
3174          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
3175          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
3176 \r
3177          if (r > 0)\r
3178           product2b = product1b = color6;\r
3179          else\r
3180          if (r < 0)\r
3181           product2b = product1b = color5;\r
3182          else\r
3183           {\r
3184            product2b = product1b = INTERPOLATE8_02(color5, color6);\r
3185           }\r
3186         }\r
3187        else\r
3188         {\r
3189          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
3190              product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2);\r
3191          else\r
3192          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
3193              product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3);\r
3194          else\r
3195              product2b = INTERPOLATE8_02 (color2, color3);\r
3196 \r
3197          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
3198              product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5);\r
3199          else\r
3200          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
3201              product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5);\r
3202          else\r
3203              product1b = INTERPOLATE8_02 (color5, color6);\r
3204         }\r
3205 \r
3206        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
3207         product2a = INTERPOLATE8_02(color2, color5);\r
3208        else\r
3209        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
3210         product2a = INTERPOLATE8_02(color2, color5);\r
3211        else\r
3212         product2a = color2;\r
3213 \r
3214        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
3215         product1a = INTERPOLATE8_02(color2, color5);\r
3216        else\r
3217        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
3218         product1a = INTERPOLATE8_02(color2, color5);\r
3219        else\r
3220         product1a = color5;\r
3221 \r
3222        *dP=product1a;\r
3223        *(dP+1)=product1b;\r
3224        *(dP+(width2))=product2a;\r
3225        *(dP+1+(width2))=product2b;\r
3226 \r
3227        bP += 1;\r
3228        dP += 2;\r
3229       }//end of for ( finish= width etc..)\r
3230 \r
3231      line += 2;\r
3232      srcPtr += srcPitch;\r
3233         }; //endof: for (; height; height--)\r
3234   }\r
3235 }\r
3236 \r
3237 \r
3238 void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,\r
3239                     unsigned char  *dstBitmap, int width, int height)\r
3240 {\r
3241  DWORD dstPitch = srcPitch * 2;\r
3242  DWORD line;\r
3243  DWORD *dP;\r
3244  DWORD *bP;\r
3245  int   width2 = width*2;\r
3246  int iXA,iXB,iXC,iYA,iYB,iYC,finish;\r
3247  DWORD color4, color5, color6;\r
3248  DWORD color1, color2, color3;\r
3249  DWORD colorA0, colorA1, colorA2, colorA3,\r
3250        colorB0, colorB1, colorB2, colorB3,\r
3251        colorS1, colorS2;\r
3252  DWORD product1a, product1b,\r
3253        product2a, product2b;\r
3254 \r
3255  line = 0;\r
3256 \r
3257   {\r
3258    for (; height; height-=1)\r
3259         {\r
3260      bP = (DWORD *)srcPtr;\r
3261          dP = (DWORD *)(dstBitmap + line*dstPitch);\r
3262      for (finish = width; finish; finish -= 1 )\r
3263       {\r
3264 //---------------------------------------    B1 B2\r
3265 //                                         4  5  6 S2\r
3266 //                                         1  2  3 S1\r
3267 //                                           A1 A2\r
3268        if(finish==width) iXA=0;\r
3269        else              iXA=1;\r
3270        if(finish>4) {iXB=1;iXC=2;}\r
3271        else\r
3272        if(finish>3) {iXB=1;iXC=1;}\r
3273        else         {iXB=0;iXC=0;}\r
3274        if(line==0) iYA=0;\r
3275        else        iYA=width;\r
3276        if(height>4) {iYB=width;iYC=width2;}\r
3277        else\r
3278        if(height>3) {iYB=width;iYC=width;}\r
3279        else         {iYB=0;iYC=0;}\r
3280 \r
3281 \r
3282        colorB0 = *(bP- iYA - iXA);\r
3283        colorB1 = *(bP- iYA);\r
3284        colorB2 = *(bP- iYA + iXB);\r
3285        colorB3 = *(bP- iYA + iXC);\r
3286 \r
3287        color4 = *(bP  - iXA);\r
3288        color5 = *(bP);\r
3289        color6 = *(bP  + iXB);\r
3290        colorS2 = *(bP + iXC);\r
3291 \r
3292        color1 = *(bP  + iYB  - iXA);\r
3293        color2 = *(bP  + iYB);\r
3294        color3 = *(bP  + iYB  + iXB);\r
3295        colorS1= *(bP  + iYB  + iXC);\r
3296 \r
3297        colorA0 = *(bP + iYC - iXA);\r
3298        colorA1 = *(bP + iYC);\r
3299        colorA2 = *(bP + iYC + iXB);\r
3300        colorA3 = *(bP + iYC + iXC);\r
3301 \r
3302 //--------------------------------------\r
3303        if (color2 == color6 && color5 != color3)\r
3304         {\r
3305          product2b = product1b = color2;\r
3306         }\r
3307        else\r
3308        if (color5 == color3 && color2 != color6)\r
3309         {\r
3310          product2b = product1b = color5;\r
3311         }\r
3312        else\r
3313        if (color5 == color3 && color2 == color6)\r
3314         {\r
3315          register int r = 0;\r
3316 \r
3317          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));\r
3318          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));\r
3319          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));\r
3320          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));\r
3321 \r
3322          if (r > 0)\r
3323           product2b = product1b = color6;\r
3324          else\r
3325          if (r < 0)\r
3326           product2b = product1b = color5;\r
3327          else\r
3328           {\r
3329            product2b = product1b = INTERPOLATE8(color5, color6);\r
3330           }\r
3331         }\r
3332        else\r
3333         {\r
3334          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)\r
3335              product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);\r
3336          else\r
3337          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)\r
3338              product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);\r
3339          else\r
3340              product2b = INTERPOLATE8 (color2, color3);\r
3341 \r
3342          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)\r
3343              product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);\r
3344          else\r
3345          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)\r
3346              product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);\r
3347          else\r
3348              product1b = INTERPOLATE8 (color5, color6);\r
3349         }\r
3350 \r
3351        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)\r
3352         product2a = INTERPOLATE8(color2, color5);\r
3353        else\r
3354        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)\r
3355         product2a = INTERPOLATE8(color2, color5);\r
3356        else\r
3357         product2a = color2;\r
3358 \r
3359        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)\r
3360         product1a = INTERPOLATE8(color2, color5);\r
3361        else\r
3362        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)\r
3363         product1a = INTERPOLATE8(color2, color5);\r
3364        else\r
3365         product1a = color5;\r
3366 \r
3367        *dP=product1a;\r
3368        *(dP+1)=product1b;\r
3369        *(dP+(width2))=product2a;\r
3370        *(dP+1+(width2))=product2b;\r
3371 \r
3372        bP += 1;\r
3373        dP += 2;\r
3374       }//end of for ( finish= width etc..)\r
3375 \r
3376      line += 2;\r
3377      srcPtr += srcPitch;\r
3378         }; //endof: for (; height; height--)\r
3379   }\r
3380 }\r
3381 /////////////////////////////////////////////////////////////////////////////\r
3382 \r
3383 #define colorMask4     0x0000EEE0\r
3384 #define lowPixelMask4  0x00001110\r
3385 #define qcolorMask4    0x0000CCC0\r
3386 #define qlowpixelMask4 0x00003330\r
3387 \r
3388 #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
3389 \r
3390 #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
3391 \r
3392 \r
3393 #define colorMask5     0x0000F7BC\r
3394 #define lowPixelMask5  0x00000842\r
3395 #define qcolorMask5    0x0000E738\r
3396 #define qlowpixelMask5 0x000018C6\r
3397 \r
3398 #define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001))))\r
3399 \r
3400 #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
3401 /////////////////////////////////////////////////////////////////////////////\r
3402 /////////////////////////////////////////////////////////////////////////////\r
3403 /////////////////////////////////////////////////////////////////////////////\r
3404 //\r
3405 // ogl texture defines\r
3406 //\r
3407 /////////////////////////////////////////////////////////////////////////////\r
3408 /////////////////////////////////////////////////////////////////////////////\r
3409 /////////////////////////////////////////////////////////////////////////////\r
3410 \r
3411 void DefineSubTextureSortHiRes(void)\r
3412 {\r
3413  int x,y,dx2;\r
3414 \r
3415  if(!gTexName)             \r
3416   {\r
3417    glGenTextures(1, &gTexName);\r
3418    glBindTexture(GL_TEXTURE_2D, gTexName);\r
3419 \r
3420    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
3421    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
3422 \r
3423    if(iFilterType)\r
3424     {\r
3425      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3426      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3427     }\r
3428    else\r
3429     {            \r
3430      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
3431      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
3432     }   \r
3433    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
3434   }\r
3435  else glBindTexture(GL_TEXTURE_2D, gTexName);\r
3436 \r
3437  glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1,\r
3438                  DXTexS<<1, DYTexS<<1,\r
3439                  GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer);\r
3440 }\r
3441 \r
3442 /////////////////////////////////////////////////////////////////////////////\r
3443 \r
3444 void DefineSubTextureSort(void)\r
3445 {\r
3446 \r
3447  if(!gTexName)\r
3448   {\r
3449    glGenTextures(1, &gTexName);\r
3450    glBindTexture(GL_TEXTURE_2D, gTexName);\r
3451 \r
3452    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);\r
3453    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);\r
3454 \r
3455    if(iFilterType)\r
3456     {\r
3457      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
3458      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
3459     }\r
3460    else\r
3461     {\r
3462      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iFilter);\r
3463      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iFilter);\r
3464     }\r
3465    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
3466   }\r
3467  else glBindTexture(GL_TEXTURE_2D, gTexName);\r
3468 \r
3469  glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS,\r
3470                  DXTexS, DYTexS,\r
3471                  GL_RGBA, GL_UNSIGNED_BYTE, texturepart);\r
3472 }\r
3473 \r
3474 /////////////////////////////////////////////////////////////////////////////\r
3475 \r
3476 /////////////////////////////////////////////////////////////////////////////\r
3477 /////////////////////////////////////////////////////////////////////////////\r
3478 /////////////////////////////////////////////////////////////////////////////\r
3479 //\r
3480 // texture cache garbage collection\r
3481 //\r
3482 /////////////////////////////////////////////////////////////////////////////\r
3483 /////////////////////////////////////////////////////////////////////////////\r
3484 /////////////////////////////////////////////////////////////////////////////\r
3485 \r
3486 void DoTexGarbageCollection(void)\r
3487 {\r
3488  static unsigned short LRUCleaned=0;\r
3489  unsigned short iC,iC1,iC2;\r
3490  int i,j,iMax;textureSubCacheEntryS * tsb;\r
3491 \r
3492  iC=4;//=iSortTexCnt/2,\r
3493  LRUCleaned+=iC;                                       // we clean different textures each time\r
3494  if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0;        // wrap? wrap!\r
3495  iC1=LRUCleaned;                                       // range of textures to clean\r
3496  iC2=LRUCleaned+iC;\r
3497 \r
3498  for(iC=iC1;iC<iC2;iC++)                               // make some textures available\r
3499   {\r
3500    pxSsubtexLeft[iC]->l=0;\r
3501   }\r
3502 \r
3503  for(i=0;i<3;i++)                                      // remove all references to that textures\r
3504   for(j=0;j<MAXTPAGES;j++)\r
3505    for(iC=0;iC<4;iC++)                                 // loop all texture rect info areas\r
3506     {\r
3507      tsb=pscSubtexStore[i][j]+(iC*SOFFB);\r
3508      iMax=tsb->pos.l;\r
3509      if(iMax)\r
3510       do\r
3511        {\r
3512         tsb++;\r
3513         if(tsb->cTexID>=iC1 && tsb->cTexID<iC2)        // info uses the cleaned textures? remove info\r
3514          tsb->ClutID=0;\r
3515        } \r
3516       while(--iMax);\r
3517      }\r
3518 \r
3519  usLRUTexPage=LRUCleaned;\r
3520 }\r
3521 \r
3522 /////////////////////////////////////////////////////////////////////////////\r
3523 /////////////////////////////////////////////////////////////////////////////\r
3524 /////////////////////////////////////////////////////////////////////////////\r
3525 //\r
3526 // search cache for existing (already used) parts\r
3527 //\r
3528 /////////////////////////////////////////////////////////////////////////////\r
3529 /////////////////////////////////////////////////////////////////////////////\r
3530 /////////////////////////////////////////////////////////////////////////////\r
3531 \r
3532 unsigned char * CheckTextureInSubSCache(long TextureMode,unsigned long GivenClutId,unsigned short * pCache)\r
3533 {\r
3534  textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL;\r
3535  int i,iMax;EXLong npos;\r
3536  unsigned char cx,cy;\r
3537  int iC,j,k;unsigned long rx,ry,mx,my;\r
3538  EXLong * ul=0, * uls;\r
3539  EXLong rfree;\r
3540  unsigned char cXAdj,cYAdj;\r
3541 \r
3542  npos.l=*((unsigned long *)&gl_ux[4]);\r
3543 \r
3544  //--------------------------------------------------------------//\r
3545  // find matching texturepart first... speed up...\r
3546  //--------------------------------------------------------------//\r
3547 \r
3548  tsg=pscSubtexStore[TextureMode][GlobalTexturePage];\r
3549  tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB;\r
3550 \r
3551  iMax=tsg->pos.l;\r
3552  if(iMax)\r
3553   {\r
3554    i=iMax;\r
3555    tsb=tsg+1;                 \r
3556    do\r
3557     {\r
3558      if(GivenClutId==tsb->ClutID &&\r
3559         (INCHECK(tsb->pos,npos)))\r
3560       {\r
3561         {\r
3562          cx=tsb->pos.c[3]-tsb->posTX;\r
3563          cy=tsb->pos.c[1]-tsb->posTY;\r
3564 \r
3565          gl_ux[0]-=cx;\r
3566          gl_ux[1]-=cx;\r
3567          gl_ux[2]-=cx;\r
3568          gl_ux[3]-=cx;\r
3569          gl_vy[0]-=cy;\r
3570          gl_vy[1]-=cy;\r
3571          gl_vy[2]-=cy;\r
3572          gl_vy[3]-=cy;\r
3573 \r
3574          ubOpaqueDraw=tsb->Opaque;\r
3575          *pCache=tsb->cTexID;\r
3576          return NULL;\r
3577         }\r
3578       } \r
3579      tsb++;\r
3580     }\r
3581    while(--i);\r
3582   }\r
3583 \r
3584  //----------------------------------------------------//\r
3585 \r
3586  cXAdj=1;cYAdj=1;\r
3587 \r
3588  rx=(int)gl_ux[6]-(int)gl_ux[7];\r
3589  ry=(int)gl_ux[4]-(int)gl_ux[5];\r
3590 \r
3591  tsx=NULL;tsb=tsg+1;\r
3592  for(i=0;i<iMax;i++,tsb++)\r
3593   {\r
3594    if(!tsb->ClutID) {tsx=tsb;break;}\r
3595   }\r
3596 \r
3597  if(!tsx) \r
3598   {\r
3599    iMax++;\r
3600    if(iMax>=SOFFB-2) \r
3601     {\r
3602      if(iTexGarbageCollection)                         // gc mode?\r
3603       {\r
3604        if(*pCache==0) \r
3605         {\r
3606          dwTexPageComp|=(1<<GlobalTexturePage);\r
3607          *pCache=0xffff;\r
3608          return 0;\r
3609         }\r
3610 \r
3611        iMax--;\r
3612        tsb=tsg+1;\r
3613 \r
3614        for(i=0;i<iMax;i++,tsb++)                       // 1. search other slots with same cluts, and unite the area\r
3615         if(GivenClutId==tsb->ClutID)\r
3616          {\r
3617           if(!tsx) {tsx=tsb;rfree.l=npos.l;}           // \r
3618           else      tsb->ClutID=0;\r
3619           rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]);\r
3620           rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]);\r
3621           rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]);\r
3622           rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]);\r
3623           MarkFree(tsb);\r
3624          }\r
3625 \r
3626        if(tsx)                                         // 3. if one or more found, create a new rect with bigger size\r
3627         {\r
3628          *((unsigned long *)&gl_ux[4])=npos.l=rfree.l;\r
3629          rx=(int)rfree.c[2]-(int)rfree.c[3];\r
3630          ry=(int)rfree.c[0]-(int)rfree.c[1];\r
3631          DoTexGarbageCollection();\r
3632        \r
3633          goto ENDLOOP3;\r
3634         }\r
3635       }\r
3636 \r
3637      iMax=1;\r
3638     }\r
3639    tsx=tsg+iMax;\r
3640    tsg->pos.l=iMax;\r
3641   }\r
3642 \r
3643  //----------------------------------------------------//\r
3644  // now get a free texture space\r
3645  //----------------------------------------------------//\r
3646 \r
3647  if(iTexGarbageCollection) usLRUTexPage=0;\r
3648 \r
3649 ENDLOOP3:\r
3650 \r
3651  rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
3652  ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
3653 \r
3654  iC=usLRUTexPage;\r
3655 \r
3656  for(k=0;k<iSortTexCnt;k++)\r
3657   {\r
3658    uls=pxSsubtexLeft[iC];\r
3659    iMax=uls->l;ul=uls+1;\r
3660 \r
3661    //--------------------------------------------------//\r
3662    // first time\r
3663 \r
3664    if(!iMax) \r
3665     {\r
3666      rfree.l=0;\r
3667 \r
3668      if(rx>252 && ry>252)\r
3669       {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;}\r
3670 \r
3671      if(rx<253)\r
3672       {\r
3673        uls->l=uls->l+1;\r
3674        ul->c[3]=rx;\r
3675        ul->c[2]=255-rx;\r
3676        ul->c[1]=0;\r
3677        ul->c[0]=ry;\r
3678        ul++;\r
3679       }\r
3680 \r
3681      if(ry<253)\r
3682       {\r
3683        uls->l=uls->l+1; \r
3684        ul->c[3]=0;\r
3685        ul->c[2]=255;\r
3686        ul->c[1]=ry;\r
3687        ul->c[0]=255-ry;\r
3688       }\r
3689      ul=0;\r
3690      goto ENDLOOP;\r
3691     }\r
3692                                                        \r
3693    //--------------------------------------------------//\r
3694    for(i=0;i<iMax;i++,ul++)\r
3695     {\r
3696      if(ul->l!=0xffffffff && \r
3697         ry<=ul->c[0]      && \r
3698         rx<=ul->c[2])\r
3699       {\r
3700        rfree=*ul;\r
3701        mx=ul->c[2]-2;\r
3702        my=ul->c[0]-2;\r
3703        if(rx<mx && ry<my)\r
3704         {\r
3705          ul->c[3]+=rx;\r
3706          ul->c[2]-=rx;\r
3707          ul->c[0]=ry;\r
3708 \r
3709          for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
3710           if(ul->l==0xffffffff) break;\r
3711  \r
3712          if(j<CSUBSIZE-2)\r
3713           {\r
3714            if(j==iMax) uls->l=uls->l+1;\r
3715 \r
3716            ul->c[3]=rfree.c[3];\r
3717            ul->c[2]=rfree.c[2];\r
3718            ul->c[1]=rfree.c[1]+ry;\r
3719            ul->c[0]=rfree.c[0]-ry;\r
3720           }\r
3721         }\r
3722        else if(rx<mx)\r
3723         {\r
3724          ul->c[3]+=rx;\r
3725          ul->c[2]-=rx;\r
3726         }\r
3727        else if(ry<my)\r
3728         {\r
3729          ul->c[1]+=ry;\r
3730          ul->c[0]-=ry;\r
3731         }\r
3732        else\r
3733         {\r
3734          ul->l=0xffffffff;\r
3735         }\r
3736        ul=0;\r
3737        goto ENDLOOP;\r
3738       }\r
3739     }\r
3740 \r
3741    //--------------------------------------------------//\r
3742 \r
3743    iC++; if(iC>=iSortTexCnt) iC=0;\r
3744   }\r
3745 \r
3746  //----------------------------------------------------//\r
3747  // check, if free space got\r
3748  //----------------------------------------------------//\r
3749 \r
3750 ENDLOOP:\r
3751  if(ul)\r
3752   {\r
3753    //////////////////////////////////////////////////////\r
3754 \r
3755     {\r
3756      dwTexPageComp=0;\r
3757 \r
3758      for(i=0;i<3;i++)                                    // cleaning up\r
3759       for(j=0;j<MAXTPAGES;j++)\r
3760        {\r
3761         tsb=pscSubtexStore[i][j];\r
3762         (tsb+SOFFA)->pos.l=0;\r
3763         (tsb+SOFFB)->pos.l=0;\r
3764         (tsb+SOFFC)->pos.l=0;\r
3765         (tsb+SOFFD)->pos.l=0;\r
3766        }\r
3767      for(i=0;i<iSortTexCnt;i++)\r
3768       {ul=pxSsubtexLeft[i];ul->l=0;}\r
3769      usLRUTexPage=0;\r
3770     }\r
3771 \r
3772    //////////////////////////////////////////////////////\r
3773    iC=usLRUTexPage;\r
3774    uls=pxSsubtexLeft[usLRUTexPage];\r
3775    uls->l=0;ul=uls+1;\r
3776    rfree.l=0;\r
3777 \r
3778    if(rx>252 && ry>252)\r
3779     {uls->l=1;ul->l=0xffffffff;}\r
3780    else\r
3781     {\r
3782      if(rx<253)\r
3783       {\r
3784        uls->l=uls->l+1;\r
3785        ul->c[3]=rx;\r
3786        ul->c[2]=255-rx;\r
3787        ul->c[1]=0;\r
3788        ul->c[0]=ry;\r
3789        ul++;\r
3790       }\r
3791      if(ry<253)\r
3792       {\r
3793        uls->l=uls->l+1; \r
3794        ul->c[3]=0;\r
3795        ul->c[2]=255;\r
3796        ul->c[1]=ry;\r
3797        ul->c[0]=255-ry;\r
3798       }\r
3799     }\r
3800    tsg->pos.l=1;tsx=tsg+1;\r
3801   }\r
3802 \r
3803  rfree.c[3]+=cXAdj;\r
3804  rfree.c[1]+=cYAdj;\r
3805 \r
3806  tsx->cTexID   =*pCache=iC;\r
3807  tsx->pos      = npos;\r
3808  tsx->ClutID   = GivenClutId;\r
3809  tsx->posTX    = rfree.c[3];\r
3810  tsx->posTY    = rfree.c[1];\r
3811 \r
3812  cx=gl_ux[7]-rfree.c[3];\r
3813  cy=gl_ux[5]-rfree.c[1];\r
3814 \r
3815  gl_ux[0]-=cx;\r
3816  gl_ux[1]-=cx;\r
3817  gl_ux[2]-=cx;\r
3818  gl_ux[3]-=cx;\r
3819  gl_vy[0]-=cy;\r
3820  gl_vy[1]-=cy;\r
3821  gl_vy[2]-=cy;\r
3822  gl_vy[3]-=cy;\r
3823 \r
3824  XTexS=rfree.c[3];\r
3825  YTexS=rfree.c[1];\r
3826 \r
3827  return &tsx->Opaque;\r
3828 }\r
3829                    \r
3830 /////////////////////////////////////////////////////////////////////////////\r
3831 /////////////////////////////////////////////////////////////////////////////\r
3832 /////////////////////////////////////////////////////////////////////////////\r
3833 //\r
3834 // search cache for free place (on compress)\r
3835 //\r
3836 /////////////////////////////////////////////////////////////////////////////\r
3837 /////////////////////////////////////////////////////////////////////////////\r
3838 /////////////////////////////////////////////////////////////////////////////\r
3839 \r
3840 BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx)\r
3841 {\r
3842  int i,j,k,iMax,iC;unsigned long rx,ry,mx,my;\r
3843  EXLong * ul=0, * uls, rfree;\r
3844  unsigned char cXAdj=1,cYAdj=1;\r
3845 \r
3846  rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3];\r
3847  ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1];\r
3848 \r
3849  rx+=3;if(rx>255) {cXAdj=0;rx=255;}\r
3850  ry+=3;if(ry>255) {cYAdj=0;ry=255;}\r
3851 \r
3852  iC=usLRUTexPage;\r
3853 \r
3854  for(k=0;k<iSortTexCnt;k++)\r
3855   {\r
3856    uls=pxSsubtexLeft[iC];\r
3857    iMax=uls->l;ul=uls+1;\r
3858 \r
3859    //--------------------------------------------------//\r
3860    // first time\r
3861 \r
3862    if(!iMax)\r
3863     {\r
3864      rfree.l=0;\r
3865 \r
3866      if(rx>252 && ry>252)\r
3867       {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;}\r
3868 \r
3869      if(rx<253)\r
3870       {\r
3871        uls->l=uls->l+1;\r
3872        ul->c[3]=rx;\r
3873        ul->c[2]=255-rx;\r
3874        ul->c[1]=0;\r
3875        ul->c[0]=ry;\r
3876        ul++;\r
3877       }\r
3878 \r
3879      if(ry<253)\r
3880       {\r
3881        uls->l=uls->l+1;\r
3882        ul->c[3]=0;\r
3883        ul->c[2]=255;\r
3884        ul->c[1]=ry;\r
3885        ul->c[0]=255-ry;\r
3886       }\r
3887      ul=0;\r
3888      goto TENDLOOP;\r
3889     }\r
3890 \r
3891    //--------------------------------------------------//\r
3892    for(i=0;i<iMax;i++,ul++)\r
3893     {\r
3894      if(ul->l!=0xffffffff &&\r
3895         ry<=ul->c[0]      &&\r
3896         rx<=ul->c[2])\r
3897       {\r
3898        rfree=*ul;\r
3899        mx=ul->c[2]-2;\r
3900        my=ul->c[0]-2;\r
3901 \r
3902        if(rx<mx && ry<my)\r
3903         {\r
3904          ul->c[3]+=rx;\r
3905          ul->c[2]-=rx;\r
3906          ul->c[0]=ry;\r
3907 \r
3908          for(ul=uls+1,j=0;j<iMax;j++,ul++)\r
3909           if(ul->l==0xffffffff) break;\r
3910 \r
3911          if(j<CSUBSIZE-2)\r
3912           {\r
3913            if(j==iMax) uls->l=uls->l+1;\r
3914 \r
3915            ul->c[3]=rfree.c[3];\r
3916            ul->c[2]=rfree.c[2];\r
3917            ul->c[1]=rfree.c[1]+ry;\r
3918            ul->c[0]=rfree.c[0]-ry;\r
3919           }\r
3920         }\r
3921        else if(rx<mx)\r
3922         {\r
3923          ul->c[3]+=rx;\r
3924          ul->c[2]-=rx;\r
3925         }\r
3926        else if(ry<my)\r
3927         {\r
3928          ul->c[1]+=ry;\r
3929          ul->c[0]-=ry;\r
3930         }\r
3931        else\r
3932         {\r
3933          ul->l=0xffffffff;\r
3934         }\r
3935        ul=0;\r
3936        goto TENDLOOP;\r
3937       }\r
3938     }\r
3939 \r
3940    //--------------------------------------------------//\r
3941 \r
3942    iC++; if(iC>=iSortTexCnt) iC=0;\r
3943   }\r
3944 \r
3945  //----------------------------------------------------//\r
3946  // check, if free space got\r
3947  //----------------------------------------------------//\r
3948 \r
3949 TENDLOOP:\r
3950  if(ul) return FALSE;\r
3951 \r
3952  rfree.c[3]+=cXAdj;\r
3953  rfree.c[1]+=cYAdj;\r
3954 \r
3955  tsx->cTexID   = iC;\r
3956  tsx->posTX    = rfree.c[3];\r
3957  tsx->posTY    = rfree.c[1];\r
3958 \r
3959  XTexS=rfree.c[3];\r
3960  YTexS=rfree.c[1];\r
3961 \r
3962  return TRUE;\r
3963 }\r
3964 \r
3965 /////////////////////////////////////////////////////////////////////////////\r
3966 /////////////////////////////////////////////////////////////////////////////\r
3967 /////////////////////////////////////////////////////////////////////////////\r
3968 //\r
3969 // compress texture cache (to make place for new texture part, if needed)\r
3970 //\r
3971 /////////////////////////////////////////////////////////////////////////////\r
3972 /////////////////////////////////////////////////////////////////////////////\r
3973 /////////////////////////////////////////////////////////////////////////////\r
3974 \r
3975 void CompressTextureSpace(void)\r
3976 {\r
3977  textureSubCacheEntryS * tsx, * tsg, * tsb;\r
3978  int i,j,k,m,n,iMax;EXLong * ul, r,opos;\r
3979  short sOldDST=DrawSemiTrans,cx,cy;\r
3980  long  lOGTP=GlobalTexturePage;\r
3981  unsigned long l,row;\r
3982  unsigned long * lSRCPtr;\r
3983 \r
3984  opos.l=*((unsigned long *)&gl_ux[4]);\r
3985 \r
3986  // 1. mark all textures as free\r
3987  for(i=0;i<iSortTexCnt;i++)\r
3988   {ul=pxSsubtexLeft[i];ul->l=0;}\r
3989  usLRUTexPage=0;\r
3990 \r
3991  // 2. compress\r
3992  for(j=0;j<3;j++)\r
3993   {\r
3994    for(k=0;k<MAXTPAGES;k++)\r
3995     {\r
3996      tsg=pscSubtexStore[j][k];\r
3997 \r
3998      if((!(dwTexPageComp&(1<<k))))\r
3999       {\r
4000        (tsg+SOFFA)->pos.l=0;\r
4001        (tsg+SOFFB)->pos.l=0;\r
4002        (tsg+SOFFC)->pos.l=0;\r
4003        (tsg+SOFFD)->pos.l=0;\r
4004        continue;\r
4005       }\r
4006 \r
4007      for(m=0;m<4;m++,tsg+=SOFFB)\r
4008       {\r
4009        iMax=tsg->pos.l;\r
4010 \r
4011        tsx=tsg+1;\r
4012        for(i=0;i<iMax;i++,tsx++)\r
4013         {\r
4014          if(tsx->ClutID)\r
4015           {\r
4016            r.l=tsx->pos.l;\r
4017            for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++)\r
4018             {\r
4019              if(tsx->ClutID==tsb->ClutID)\r
4020               {\r
4021                r.c[3]=min(r.c[3],tsb->pos.c[3]);\r
4022                r.c[2]=max(r.c[2],tsb->pos.c[2]);\r
4023                r.c[1]=min(r.c[1],tsb->pos.c[1]);\r
4024                r.c[0]=max(r.c[0],tsb->pos.c[0]);\r
4025                tsb->ClutID=0;\r
4026               }\r
4027             }\r
4028 \r
4029 //           if(r.l!=tsx->pos.l)\r
4030             {\r
4031              cx=((tsx->ClutID << 4) & 0x3F0);          \r
4032              cy=((tsx->ClutID >> 6) & CLUTYMASK);\r
4033 \r
4034              if(j!=2)\r
4035               {\r
4036                // palette check sum\r
4037                l=0;lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
4038                if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
4039                else     for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
4040                l=((l+HIWORD(l))&0x3fffL)<<16;\r
4041                if(l!=(tsx->ClutID&(0x00003fff<<16)))\r
4042                 {\r
4043                  tsx->ClutID=0;continue;\r
4044                 }\r
4045               }\r
4046 \r
4047              tsx->pos.l=r.l;\r
4048              if(!GetCompressTexturePlace(tsx))         // no place?\r
4049               {\r
4050                for(i=0;i<3;i++)                        // -> clean up everything\r
4051                 for(j=0;j<MAXTPAGES;j++)\r
4052                  {\r
4053                   tsb=pscSubtexStore[i][j];\r
4054                   (tsb+SOFFA)->pos.l=0;\r
4055                   (tsb+SOFFB)->pos.l=0;\r
4056                   (tsb+SOFFC)->pos.l=0;\r
4057                   (tsb+SOFFD)->pos.l=0;\r
4058                  }\r
4059                for(i=0;i<iSortTexCnt;i++)\r
4060                 {ul=pxSsubtexLeft[i];ul->l=0;}\r
4061                usLRUTexPage=0;\r
4062                DrawSemiTrans=sOldDST;\r
4063                GlobalTexturePage=lOGTP;\r
4064                *((unsigned long *)&gl_ux[4])=opos.l;\r
4065                dwTexPageComp=0;\r
4066 \r
4067                return;\r
4068               }\r
4069 \r
4070              if(tsx->ClutID&(1<<30)) DrawSemiTrans=1;\r
4071              else                    DrawSemiTrans=0;\r
4072              *((unsigned long *)&gl_ux[4])=r.l;\r
4073    \r
4074              gTexName=uiStexturePage[tsx->cTexID];\r
4075              LoadSubTexFn(k,j,cx,cy);\r
4076              uiStexturePage[tsx->cTexID]=gTexName;\r
4077              tsx->Opaque=ubOpaqueDraw;\r
4078             }\r
4079           }\r
4080         }\r
4081 \r
4082        if(iMax)  \r
4083         {\r
4084          tsx=tsg+iMax;\r
4085          while(!tsx->ClutID && iMax) {tsx--;iMax--;}\r
4086          tsg->pos.l=iMax;\r
4087         }\r
4088 \r
4089       }                      \r
4090     }\r
4091   }\r
4092 \r
4093  if(dwTexPageComp==0xffffffff) dwTexPageComp=0;\r
4094 \r
4095  *((unsigned long *)&gl_ux[4])=opos.l;\r
4096  GlobalTexturePage=lOGTP;\r
4097  DrawSemiTrans=sOldDST;\r
4098 }\r
4099 \r
4100 /////////////////////////////////////////////////////////////////////////////\r
4101 /////////////////////////////////////////////////////////////////////////////\r
4102 /////////////////////////////////////////////////////////////////////////////\r
4103 //\r
4104 // main entry for searching/creating textures, called from prim.c\r
4105 //\r
4106 /////////////////////////////////////////////////////////////////////////////\r
4107 /////////////////////////////////////////////////////////////////////////////\r
4108 /////////////////////////////////////////////////////////////////////////////\r
4109 \r
4110 GLuint SelectSubTextureS(long TextureMode, unsigned long GivenClutId) \r
4111 {\r
4112  unsigned char * OPtr;unsigned short iCache;short cx,cy;\r
4113 \r
4114  // sort sow/tow infos for fast access\r
4115 \r
4116  unsigned char ma1,ma2,mi1,mi2;\r
4117  if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];}\r
4118  else                  {mi1=gl_ux[0];ma1=gl_ux[1];}\r
4119  if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];}\r
4120  else                  {mi2=gl_ux[2];ma2=gl_ux[3];}\r
4121  if(mi1>mi2) gl_ux[7]=mi2; \r
4122  else        gl_ux[7]=mi1;\r
4123  if(ma1>ma2) gl_ux[6]=ma1; \r
4124  else        gl_ux[6]=ma2;\r
4125 \r
4126  if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];}\r
4127  else                  {mi1=gl_vy[0];ma1=gl_vy[1];}\r
4128  if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];}\r
4129  else                  {mi2=gl_vy[2];ma2=gl_vy[3];}\r
4130  if(mi1>mi2) gl_ux[5]=mi2; \r
4131  else        gl_ux[5]=mi1;\r
4132  if(ma1>ma2) gl_ux[4]=ma1; \r
4133  else        gl_ux[4]=ma2;\r
4134 \r
4135  // get clut infos in one 32 bit val\r
4136 \r
4137  if(TextureMode==2)                                    // no clut here\r
4138   {\r
4139    GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0;\r
4140  \r
4141    if(iFrameTexType && Fake15BitTexture()) \r
4142     return (GLuint)gTexName;\r
4143   }           \r
4144  else \r
4145   {\r
4146    cx=((GivenClutId << 4) & 0x3F0);                    // but here\r
4147    cy=((GivenClutId >> 6) & CLUTYMASK);\r
4148    GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED;\r
4149 \r
4150    // palette check sum.. removed MMX asm, this easy func works as well\r
4151     {\r
4152      unsigned long l=0,row;\r
4153 \r
4154      unsigned long * lSRCPtr=(unsigned long *)(psxVuw+cx+(cy*1024));\r
4155      if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;\r
4156      else               for(row=1;row<9;row++)   l+=((*lSRCPtr++)-1)<<row;\r
4157      l=(l+HIWORD(l))&0x3fffL;\r
4158      GivenClutId|=(l<<16);\r
4159     }\r
4160 \r
4161   }\r
4162 \r
4163  // search cache\r
4164  iCache=0;\r
4165  OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
4166 \r
4167  // cache full? compress and try again\r
4168  if(iCache==0xffff)\r
4169   {\r
4170    CompressTextureSpace();\r
4171    OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);\r
4172   }\r
4173 \r
4174  // found? fine\r
4175  usLRUTexPage=iCache;\r
4176  if(!OPtr) return uiStexturePage[iCache];\r
4177 \r
4178  // not found? upload texture and store infos in cache\r
4179  gTexName=uiStexturePage[iCache];\r
4180  LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy);\r
4181  uiStexturePage[iCache]=gTexName;\r
4182  *OPtr=ubOpaqueDraw;\r
4183  return (GLuint) gTexName;\r
4184 }\r
4185 \r
4186 /////////////////////////////////////////////////////////////////////////////\r
4187 /////////////////////////////////////////////////////////////////////////////\r
4188 /////////////////////////////////////////////////////////////////////////////\r