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