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