GLES2N64 (from mupen64plus-ae) plugin. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / gles2n64 / src / Textures.cpp
1 #include <time.h>
2 #include <stdlib.h>
3 #include <memory.h>
4
5 #ifndef min
6 #define min(a,b) ((a) < (b) ? (a) : (b))
7 #endif
8
9 #include "Common.h"
10 #include "Config.h"
11 #include "OpenGL.h"
12 #include "Textures.h"
13 #include "GBI.h"
14 #include "RSP.h"
15 #include "gDP.h"
16 #include "gSP.h"
17 #include "N64.h"
18 #include "CRC.h"
19 #include "convert.h"
20 #include "2xSAI.h"
21 //#include "FrameBuffer.h"
22
23 #define FORMAT_NONE     0
24 #define FORMAT_I8       1
25 #define FORMAT_IA88     2
26 #define FORMAT_RGBA4444 3
27 #define FORMAT_RGBA5551 4
28 #define FORMAT_RGBA8888 5
29
30 //#define PRINT_TEXTUREFORMAT
31
32 TextureCache    cache;
33
34 typedef u32 (*GetTexelFunc)( void *src, u16 x, u16 i, u8 palette );
35
36 u32 GetNone( void *src, u16 x, u16 i, u8 palette )
37 {
38     return 0x00000000;
39 }
40
41 u32 GetCI4IA_RGBA4444( void *src, u16 x, u16 i, u8 palette )
42 {
43     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
44     if (x & 1)
45         return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
46     else
47         return IA88_RGBA4444( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
48 }
49
50 u32 GetCI4IA_RGBA8888( void *src, u16 x, u16 i, u8 palette )
51 {
52     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
53     if (x & 1)
54         return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
55     else
56         return IA88_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
57 }
58
59 u32 GetCI4RGBA_RGBA5551( void *src, u16 x, u16 i, u8 palette )
60 {
61     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
62     if (x & 1)
63         return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
64     else
65         return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
66 }
67
68 u32 GetCI4RGBA_RGBA8888( void *src, u16 x, u16 i, u8 palette )
69 {
70     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
71     if (x & 1)
72         return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
73     else
74         return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
75 }
76
77 u32 GetIA31_RGBA8888( void *src, u16 x, u16 i, u8 palette )
78 {
79     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
80     return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
81 }
82
83 u32 GetIA31_RGBA4444( void *src, u16 x, u16 i, u8 palette )
84 {
85     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
86     return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
87 }
88
89 u32 GetIA31_IA88( void *src, u16 x, u16 i, u8 palette )
90 {
91     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
92     return IA31_IA88( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
93 }
94
95 u32 GetI4_RGBA8888( void *src, u16 x, u16 i, u8 palette )
96 {
97     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
98     return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
99 }
100
101 u32 GetI4_RGBA4444( void *src, u16 x, u16 i, u8 palette )
102 {
103     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
104     return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
105 }
106
107 u32 GetI4_I8( void *src, u16 x, u16 i, u8 palette )
108 {
109     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
110     return I4_I8( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
111 }
112
113
114 u32 GetI4_IA88( void *src, u16 x, u16 i, u8 palette )
115 {
116     u8 color4B = ((u8*)src)[(x>>1)^(i<<1)];
117     return I4_IA88( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
118 }
119
120 u32 GetCI8IA_RGBA4444( void *src, u16 x, u16 i, u8 palette )
121 {
122     return IA88_RGBA4444( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
123 }
124
125 u32 GetCI8IA_RGBA8888( void *src, u16 x, u16 i, u8 palette )
126 {
127     return IA88_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
128 }
129
130 u32 GetCI8RGBA_RGBA5551( void *src, u16 x, u16 i, u8 palette )
131 {
132     return RGBA5551_RGBA5551( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
133 }
134
135 u32 GetCI8RGBA_RGBA8888( void *src, u16 x, u16 i, u8 palette )
136 {
137     return RGBA5551_RGBA8888( *(u16*)&TMEM[256 + ((u8*)src)[x^(i<<1)]] );
138 }
139
140 u32 GetIA44_RGBA8888( void *src, u16 x, u16 i, u8 palette )
141 {
142     return IA44_RGBA8888(((u8*)src)[x^(i<<1)]);
143 }
144
145 u32 GetIA44_RGBA4444( void *src, u16 x, u16 i, u8 palette )
146 {
147     return IA44_RGBA4444(((u8*)src)[x^(i<<1)]);
148 }
149
150 u32 GetIA44_IA88( void *src, u16 x, u16 i, u8 palette )
151 {
152     return IA44_IA88(((u8*)src)[x^(i<<1)]);
153 }
154
155 u32 GetI8_RGBA8888( void *src, u16 x, u16 i, u8 palette )
156 {
157     return I8_RGBA8888(((u8*)src)[x^(i<<1)]);
158 }
159
160 u32 GetI8_I8( void *src, u16 x, u16 i, u8 palette )
161 {
162     return ((u8*)src)[x^(i<<1)];
163 }
164
165 u32 GetI8_IA88( void *src, u16 x, u16 i, u8 palette )
166 {
167     return I8_IA88(((u8*)src)[x^(i<<1)]);
168 }
169
170 u32 GetI8_RGBA4444( void *src, u16 x, u16 i, u8 palette )
171 {
172     return I8_RGBA4444(((u8*)src)[x^(i<<1)]);
173 }
174
175 u32 GetRGBA5551_RGBA8888( void *src, u16 x, u16 i, u8 palette )
176 {
177     return RGBA5551_RGBA8888( ((u16*)src)[x^i] );
178 }
179
180 u32 GetRGBA5551_RGBA5551( void *src, u16 x, u16 i, u8 palette )
181 {
182     return RGBA5551_RGBA5551( ((u16*)src)[x^i] );
183 }
184
185 u32 GetIA88_RGBA8888( void *src, u16 x, u16 i, u8 palette )
186 {
187     return IA88_RGBA8888(((u16*)src)[x^i]);
188 }
189
190 u32 GetIA88_RGBA4444( void *src, u16 x, u16 i, u8 palette )
191 {
192     return IA88_RGBA4444(((u16*)src)[x^i]);
193 }
194
195 u32 GetIA88_IA88( void *src, u16 x, u16 i, u8 palette )
196 {
197     return IA88_IA88(((u16*)src)[x^i]);
198 }
199
200 u32 GetRGBA8888_RGBA8888( void *src, u16 x, u16 i, u8 palette )
201 {
202     return ((u32*)src)[x^i];
203 }
204
205 u32 GetRGBA8888_RGBA4444( void *src, u16 x, u16 i, u8 palette )
206 {
207     return RGBA8888_RGBA4444(((u32*)src)[x^i]);
208 }
209
210
211 struct TextureFormat
212 {
213     int format;
214     GetTexelFunc getTexel;
215     int lineShift, maxTexels;
216 };
217
218
219 TextureFormat textureFormatIA[4*6] =
220 {
221     // 4-bit
222     {   FORMAT_RGBA5551,    GetCI4RGBA_RGBA5551,    4,  4096 }, // RGBA (SELECT)
223     {   FORMAT_NONE,        GetNone,                4,  8192 }, // YUV
224     {   FORMAT_RGBA5551,    GetCI4RGBA_RGBA5551,    4,  4096 }, // CI
225     {   FORMAT_IA88,        GetIA31_IA88,           4,  8192 }, // IA
226     {   FORMAT_IA88,        GetI4_IA88,             4,  8192 }, // I
227     {   FORMAT_RGBA8888,    GetCI4IA_RGBA8888,      4,  4096 }, // IA Palette
228     // 8-bit
229     {   FORMAT_RGBA5551,    GetCI8RGBA_RGBA5551,    3,  2048 }, // RGBA (SELECT)
230     {   FORMAT_NONE,        GetNone,                3,  4096 }, // YUV
231     {   FORMAT_RGBA5551,    GetCI8RGBA_RGBA5551,    3,  2048 }, // CI
232     {   FORMAT_IA88,        GetIA44_IA88,           3,  4096 }, // IA
233     {   FORMAT_IA88,        GetI8_IA88,             3,  4096 }, // I
234     {   FORMAT_RGBA8888,    GetCI8IA_RGBA8888,      3,  2048 }, // IA Palette
235     // 16-bit
236     {   FORMAT_RGBA5551,    GetRGBA5551_RGBA5551,   2,  2048 }, // RGBA
237     {   FORMAT_NONE,        GetNone,                2,  2048 }, // YUV
238     {   FORMAT_NONE,        GetNone,                2,  2048 }, // CI
239     {   FORMAT_IA88,        GetIA88_IA88,           2,  2048 }, // IA
240     {   FORMAT_NONE,        GetNone,                2,  2048 }, // I
241     {   FORMAT_NONE,        GetNone,                2,  2048 }, // IA Palette
242     // 32-bit
243     {   FORMAT_RGBA8888,    GetRGBA8888_RGBA8888,   2,  1024 }, // RGBA
244     {   FORMAT_NONE,        GetNone,                2,  1024 }, // YUV
245     {   FORMAT_NONE,        GetNone,                2,  1024 }, // CI
246     {   FORMAT_NONE,        GetNone,                2,  1024 }, // IA
247     {   FORMAT_NONE,        GetNone,                2,  1024 }, // I
248     {   FORMAT_NONE,        GetNone,                2,  1024 }, // IA Palette
249 };
250
251 TextureFormat textureFormatRGBA[4*6] =
252 {
253     // 4-bit
254     {   FORMAT_RGBA5551,    GetCI4RGBA_RGBA5551,    4,  4096 }, // RGBA (SELECT)
255     {   FORMAT_NONE,        GetNone,                4,  8192 }, // YUV
256     {   FORMAT_RGBA5551,    GetCI4RGBA_RGBA5551,    4,  4096 }, // CI
257     {   FORMAT_RGBA4444,    GetIA31_RGBA4444,       4,  8192 }, // IA
258     {   FORMAT_RGBA4444,    GetI4_RGBA4444,         4,  8192 }, // I
259     {   FORMAT_RGBA8888,    GetCI4IA_RGBA8888,      4,  4096 }, // IA Palette
260     // 8-bit
261     {   FORMAT_RGBA5551,    GetCI8RGBA_RGBA5551,    3,  2048 }, // RGBA (SELECT)
262     {   FORMAT_NONE,        GetNone,                3,  4096 }, // YUV
263     {   FORMAT_RGBA5551,    GetCI8RGBA_RGBA5551,    3,  2048 }, // CI
264     {   FORMAT_RGBA4444,    GetIA44_RGBA4444,       3,  4096 }, // IA
265     {   FORMAT_RGBA8888,    GetI8_RGBA8888,         3,  4096 }, // I
266     {   FORMAT_RGBA8888,    GetCI8IA_RGBA8888,      3,  2048 }, // IA Palette
267     // 16-bit
268     {   FORMAT_RGBA5551,    GetRGBA5551_RGBA5551,   2,  2048 }, // RGBA
269     {   FORMAT_NONE,        GetNone,                2,  2048 }, // YUV
270     {   FORMAT_NONE,        GetNone,                2,  2048 }, // CI
271     {   FORMAT_RGBA8888,    GetIA88_RGBA8888,       2,  2048 }, // IA
272     {   FORMAT_NONE,        GetNone,                2,  2048 }, // I
273     {   FORMAT_NONE,        GetNone,                2,  2048 }, // IA Palette
274     // 32-bit
275     {   FORMAT_RGBA8888,    GetRGBA8888_RGBA8888,   2,  1024 }, // RGBA
276     {   FORMAT_NONE,        GetNone,                2,  1024 }, // YUV
277     {   FORMAT_NONE,        GetNone,                2,  1024 }, // CI
278     {   FORMAT_NONE,        GetNone,                2,  1024 }, // IA
279     {   FORMAT_NONE,        GetNone,                2,  1024 }, // I
280     {   FORMAT_NONE,        GetNone,                2,  1024 }, // IA Palette
281 };
282
283
284 TextureFormat *textureFormat = textureFormatIA;
285
286 void __texture_format_rgba(int size, int format, TextureFormat *texFormat)
287 {
288     if (size < G_IM_SIZ_16b)
289     {
290         if (gDP.otherMode.textureLUT == G_TT_NONE)
291             *texFormat = textureFormat[size*6 + G_IM_FMT_I];
292         else if (gDP.otherMode.textureLUT == G_TT_RGBA16)
293             *texFormat = textureFormat[size*6 + G_IM_FMT_CI];
294         else
295             *texFormat = textureFormat[size*6 + G_IM_FMT_IA];
296     }
297     else
298     {
299         *texFormat = textureFormat[size*6 + G_IM_FMT_RGBA];
300     }
301 }
302
303 void __texture_format_ci(int size, int format, TextureFormat *texFormat)
304 {
305     switch(size)
306     {
307         case G_IM_SIZ_4b:
308             if (gDP.otherMode.textureLUT == G_TT_IA16)
309                 *texFormat = textureFormat[G_IM_SIZ_4b*6 + G_IM_FMT_CI_IA];
310             else
311                 *texFormat = textureFormat[G_IM_SIZ_4b*6 + G_IM_FMT_CI];
312             break;
313
314         case G_IM_SIZ_8b:
315             if (gDP.otherMode.textureLUT == G_TT_NONE)
316                 *texFormat = textureFormat[G_IM_SIZ_8b*6 + G_IM_FMT_I];
317             else if (gDP.otherMode.textureLUT == G_TT_IA16)
318                 *texFormat = textureFormat[G_IM_SIZ_8b*6 + G_IM_FMT_CI_IA];
319             else
320                 *texFormat = textureFormat[G_IM_SIZ_8b*6 + G_IM_FMT_CI];
321             break;
322
323         default:
324             *texFormat = textureFormat[size*6 + format];
325     }
326 }
327
328 void __texture_format(int size, int format, TextureFormat *texFormat)
329 {
330     if (format == G_IM_FMT_RGBA)
331     {
332         __texture_format_rgba(size, format, texFormat);
333     }
334     else if (format == G_IM_FMT_YUV)
335     {
336         *texFormat = textureFormat[size*6 + G_IM_FMT_YUV];
337     }
338     else if (format == G_IM_FMT_CI)
339     {
340         __texture_format_ci(size, format, texFormat);
341     }
342     else if (format == G_IM_FMT_IA)
343     {
344         if (gDP.otherMode.textureLUT != G_TT_NONE)
345             __texture_format_ci(size, format, texFormat);
346         else
347             *texFormat = textureFormat[size*6 + G_IM_FMT_IA];
348     }
349     else if (format == G_IM_FMT_I)
350     {
351         if (gDP.otherMode.textureLUT == G_TT_NONE)
352             *texFormat = textureFormat[size*6 + G_IM_FMT_I];
353         else
354             __texture_format_ci(size, format, texFormat);
355     }
356 }
357
358
359 int isTexCacheInit = 0;
360
361 void TextureCache_Init()
362 {
363     u32 dummyTexture[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
364
365     isTexCacheInit = 1;
366     cache.current[0] = NULL;
367     cache.current[1] = NULL;
368     cache.top = NULL;
369     cache.bottom = NULL;
370     cache.numCached = 0;
371     cache.cachedBytes = 0;
372
373 #ifdef __HASHMAP_OPT
374     cache.hash.init(11);
375 #endif
376
377     if (config.texture.useIA) textureFormat = textureFormatIA;
378     else textureFormat = textureFormatRGBA;
379
380     glPixelStorei(GL_PACK_ALIGNMENT, 1);
381     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
382     glGenTextures( 32, cache.glNoiseNames );
383
384     srand(time(NULL));
385     u8 noise[64*64*2];
386     for (u32 i = 0; i < 32; i++)
387     {
388         glBindTexture( GL_TEXTURE_2D, cache.glNoiseNames[i] );
389         for (u32 y = 0; y < 64; y++)
390         {
391             for (u32 x = 0; x < 64; x++)
392             {
393                 u32 r = (rand()&0xFF);
394                 noise[y*64*2+x*2] = r;
395                 noise[y*64*2+x*2+1] = r;
396             }
397         }
398         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 64, 64, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, noise);
399     }
400
401     cache.dummy = TextureCache_AddTop();
402     cache.dummy->address = 0;
403     cache.dummy->clampS = 1;
404     cache.dummy->clampT = 1;
405     cache.dummy->clampWidth = 4;
406     cache.dummy->clampHeight = 4;
407     cache.dummy->crc = 0;
408     cache.dummy->format = 0;
409     cache.dummy->size = 0;
410     cache.dummy->width = 4;
411     cache.dummy->height = 4;
412     cache.dummy->realWidth = 0;
413     cache.dummy->realHeight = 0;
414     cache.dummy->maskS = 0;
415     cache.dummy->maskT = 0;
416     cache.dummy->scaleS = 0.5f;
417     cache.dummy->scaleT = 0.5f;
418     cache.dummy->shiftScaleS = 1.0f;
419     cache.dummy->shiftScaleT = 1.0f;
420     cache.dummy->textureBytes = 64;
421     cache.dummy->tMem = 0;
422
423     glBindTexture( GL_TEXTURE_2D, cache.dummy->glName );
424     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummyTexture);
425
426     cache.cachedBytes = cache.dummy->textureBytes;
427     TextureCache_ActivateDummy(0);
428     TextureCache_ActivateDummy(1);
429     CRC_BuildTable();
430 }
431
432 bool TextureCache_Verify()
433 {
434     u16 i = 0;
435     CachedTexture *current;
436
437     current = cache.top;
438
439     while (current)
440     {
441         i++;
442         current = current->lower;
443     }
444     if (i != cache.numCached) return false;
445
446     i = 0;
447     current = cache.bottom;
448     while (current)
449     {
450         i++;
451         current = current->higher;
452     }
453     if (i != cache.numCached) return false;
454
455     return true;
456 }
457
458 void TextureCache_RemoveBottom()
459 {
460     CachedTexture *newBottom = cache.bottom->higher;
461
462 #ifdef __HASHMAP_OPT
463     CachedTexture* tex= cache.hash.find(cache.bottom->crc);
464     if (tex == cache.bottom)
465         cache.hash.insert(cache.bottom->crc, NULL);
466 #endif
467
468     glDeleteTextures( 1, &cache.bottom->glName );
469     cache.cachedBytes -= cache.bottom->textureBytes;
470
471     if (cache.bottom == cache.top)
472         cache.top = NULL;
473
474     free( cache.bottom );
475
476     cache.bottom = newBottom;
477
478     if (cache.bottom)
479         cache.bottom->lower = NULL;
480
481     cache.numCached--;
482 }
483
484 void TextureCache_Remove( CachedTexture *texture )
485 {
486     if ((texture == cache.bottom) && (texture == cache.top))
487     {
488         cache.top = NULL;
489         cache.bottom = NULL;
490     }
491     else if (texture == cache.bottom)
492     {
493         cache.bottom = texture->higher;
494
495         if (cache.bottom)
496             cache.bottom->lower = NULL;
497     }
498     else if (texture == cache.top)
499     {
500         cache.top = texture->lower;
501
502         if (cache.top)
503             cache.top->higher = NULL;
504     }
505     else
506     {
507         texture->higher->lower = texture->lower;
508         texture->lower->higher = texture->higher;
509     }
510
511 #ifdef __HASHMAP_OPT
512     CachedTexture* tex= cache.hash.find(texture->crc);
513     if (tex == texture);
514         cache.hash.insert(texture->crc, NULL);
515 #endif
516
517     glDeleteTextures( 1, &texture->glName );
518     cache.cachedBytes -= texture->textureBytes;
519     free( texture );
520
521     cache.numCached--;
522 }
523
524 CachedTexture *TextureCache_AddTop()
525 {
526     while (cache.cachedBytes > TEXTURECACHE_MAX)
527     {
528         if (cache.bottom != cache.dummy)
529             TextureCache_RemoveBottom();
530         else if (cache.dummy->higher)
531             TextureCache_Remove( cache.dummy->higher );
532     }
533
534     CachedTexture *newtop = (CachedTexture*)malloc( sizeof( CachedTexture ) );
535
536     glGenTextures( 1, &newtop->glName );
537
538     newtop->lower = cache.top;
539     newtop->higher = NULL;
540
541     if (cache.top)
542         cache.top->higher = newtop;
543
544     if (!cache.bottom)
545         cache.bottom = newtop;
546
547     cache.top = newtop;
548
549     cache.numCached++;
550
551     return newtop;
552 }
553
554 void TextureCache_MoveToTop( CachedTexture *newtop )
555 {
556     if (newtop == cache.top) return;
557
558     if (newtop == cache.bottom)
559     {
560         cache.bottom = newtop->higher;
561         cache.bottom->lower = NULL;
562     }
563     else
564     {
565         newtop->higher->lower = newtop->lower;
566         newtop->lower->higher = newtop->higher;
567     }
568
569     newtop->higher = NULL;
570     newtop->lower = cache.top;
571     cache.top->higher = newtop;
572     cache.top = newtop;
573 }
574
575 void TextureCache_Destroy()
576 {
577     while (cache.bottom)
578         TextureCache_RemoveBottom();
579
580     glDeleteTextures( 32, cache.glNoiseNames );
581     glDeleteTextures( 1, &cache.dummy->glName  );
582
583 #ifdef __HASHMAP_OPT
584     cache.hash.destroy();
585 #endif
586
587     cache.top = NULL;
588     cache.bottom = NULL;
589 }
590
591
592
593 void TextureCache_LoadBackground( CachedTexture *texInfo )
594 {
595     u32 *dest, *scaledDest;
596     u8 *swapped, *src;
597     u32 numBytes, bpl;
598     u32 x, y, j, tx, ty;
599     u16 clampSClamp,  clampTClamp;
600
601     int bytePerPixel=0;
602     TextureFormat   texFormat;
603     GetTexelFunc    getTexel;
604     GLint glWidth=0, glHeight=0;
605     GLenum glType=0;
606     GLenum glFormat=0;
607
608     __texture_format(texInfo->size, texInfo->format, &texFormat);
609
610 #ifdef PRINT_TEXTUREFORMAT
611     printf("BG LUT=%i, TEXTURE SIZE=%i, FORMAT=%i -> GL FORMAT=%i\n", gDP.otherMode.textureLUT, texInfo->size, texInfo->format, texFormat.format); fflush(stdout);
612 #endif
613
614     if (texFormat.format == FORMAT_NONE)
615     {
616         LOG(LOG_WARNING, "No Texture Conversion function available, size=%i format=%i\n", texInfo->size, texInfo->format);
617     }
618
619     switch(texFormat.format)
620     {
621         case FORMAT_I8:
622             glFormat = GL_LUMINANCE;
623             glType = GL_UNSIGNED_BYTE;
624             bytePerPixel = 1;
625             break;
626         case FORMAT_IA88:
627             glFormat = GL_LUMINANCE_ALPHA;
628             glType = GL_UNSIGNED_BYTE;
629             bytePerPixel = 2;
630             break;
631         case FORMAT_RGBA4444:
632             glFormat = GL_RGBA;
633             glType = GL_UNSIGNED_SHORT_4_4_4_4;
634             bytePerPixel = 2;
635             break;
636         case FORMAT_RGBA5551:
637             glFormat = GL_RGBA;
638             glType = GL_UNSIGNED_SHORT_5_5_5_1;
639             bytePerPixel = 2;
640             break;
641         case FORMAT_RGBA8888:
642             glFormat = GL_RGBA;
643             glType = GL_UNSIGNED_BYTE;
644             bytePerPixel = 4;
645             break;
646     }
647
648     glWidth = texInfo->realWidth;
649     glHeight = texInfo->realHeight;
650     texInfo->textureBytes = (glWidth * glHeight) * bytePerPixel;
651     getTexel = texFormat.getTexel;
652
653     bpl = gSP.bgImage.width << gSP.bgImage.size >> 1;
654     numBytes = bpl * gSP.bgImage.height;
655     swapped = (u8*) malloc(numBytes);
656     dest = (u32*) malloc(texInfo->textureBytes);
657
658     if (!dest || !swapped)
659     {
660         LOG(LOG_ERROR, "Malloc failed!\n");
661         return;
662     }
663
664     UnswapCopy(&RDRAM[gSP.bgImage.address], swapped, numBytes);
665
666     clampSClamp = texInfo->width - 1;
667     clampTClamp = texInfo->height - 1;
668
669     j = 0;
670     for (y = 0; y < texInfo->realHeight; y++)
671     {
672         ty = min(y, clampTClamp);
673         src = &swapped[bpl * ty];
674         for (x = 0; x < texInfo->realWidth; x++)
675         {
676             tx = min(x, clampSClamp);
677             if (bytePerPixel == 4)
678                 ((u32*)dest)[j++] = getTexel(src, tx, 0, texInfo->palette);
679             else if (bytePerPixel == 2)
680                 ((u16*)dest)[j++] = getTexel(src, tx, 0, texInfo->palette);
681             else if (bytePerPixel == 1)
682                 ((u8*)dest)[j++] = getTexel(src, tx, 0, texInfo->palette);
683         }
684     }
685
686     if (!config.texture.sai2x || (texFormat.format == FORMAT_I8 || texFormat.format == FORMAT_IA88))
687     {
688         glTexImage2D( GL_TEXTURE_2D, 0, glFormat, glWidth, glHeight, 0, glFormat, glType, dest);
689     }
690     else
691     {
692         LOG(LOG_VERBOSE, "Using 2xSAI Filter on Texture\n");
693         texInfo->textureBytes <<= 2;
694
695         scaledDest = (u32*) malloc( texInfo->textureBytes );
696
697         if (glType == GL_UNSIGNED_BYTE)
698             _2xSaI8888( (u32*)dest, (u32*)scaledDest, texInfo->realWidth, texInfo->realHeight, texInfo->clampS, texInfo->clampT );
699         if (glType == GL_UNSIGNED_SHORT_4_4_4_4)
700             _2xSaI4444( (u16*)dest, (u16*)scaledDest, texInfo->realWidth, texInfo->realHeight, texInfo->clampS, texInfo->clampT );
701         else
702             _2xSaI5551( (u16*)dest, (u16*)scaledDest, texInfo->realWidth, texInfo->realHeight, texInfo->clampS, texInfo->clampT );
703
704         glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texInfo->realWidth << 1, texInfo->realHeight << 1, 0, GL_RGBA, glType, scaledDest );
705
706         free( scaledDest );
707     }
708
709     free(dest);
710     free(swapped);
711
712
713     if (config.texture.enableMipmap)
714         glGenerateMipmap(GL_TEXTURE_2D);
715 }
716
717 void TextureCache_Load( CachedTexture *texInfo )
718 {
719     u32 *dest, *scaledDest;
720
721     void *src;
722     u16 x, y, i, j, tx, ty, line;
723     u16 mirrorSBit, maskSMask, clampSClamp;
724     u16 mirrorTBit, maskTMask, clampTClamp;
725
726     int bytePerPixel=0;
727     TextureFormat   texFormat;
728     GetTexelFunc    getTexel;
729     GLint glWidth=0, glHeight=0;
730     GLenum glType=0;
731     GLenum glFormat=0;
732
733     __texture_format(texInfo->size, texInfo->format, &texFormat);
734
735 #ifdef PRINT_TEXTUREFORMAT
736     printf("TEX LUT=%i, TEXTURE SIZE=%i, FORMAT=%i -> GL FORMAT=%i\n", gDP.otherMode.textureLUT, texInfo->size, texInfo->format, texFormat.format); fflush(stdout);
737 #endif
738
739     if (texFormat.format == FORMAT_NONE)
740     {
741         LOG(LOG_WARNING, "No Texture Conversion function available, size=%i format=%i\n", texInfo->size, texInfo->format);
742     }
743
744     switch(texFormat.format)
745     {
746         case FORMAT_I8:
747             glFormat = GL_LUMINANCE;
748             glType = GL_UNSIGNED_BYTE;
749             bytePerPixel = 1;
750             break;
751         case FORMAT_IA88:
752             glFormat = GL_LUMINANCE_ALPHA;
753             glType = GL_UNSIGNED_BYTE;
754             bytePerPixel = 2;
755             break;
756         case FORMAT_RGBA4444:
757             glFormat = GL_RGBA;
758             glType = GL_UNSIGNED_SHORT_4_4_4_4;
759             bytePerPixel = 2;
760             break;
761         case FORMAT_RGBA5551:
762             glFormat = GL_RGBA;
763             glType = GL_UNSIGNED_SHORT_5_5_5_1;
764             bytePerPixel = 2;
765             break;
766         case FORMAT_RGBA8888:
767             glFormat = GL_RGBA;
768             glType = GL_UNSIGNED_BYTE;
769             bytePerPixel = 4;
770             break;
771     }
772
773     glWidth = texInfo->realWidth;
774     glHeight = texInfo->realHeight;
775     texInfo->textureBytes = (glWidth * glHeight) * bytePerPixel;
776     getTexel = texFormat.getTexel;
777
778     dest = (u32*)malloc(texInfo->textureBytes);
779
780     if (!dest)
781     {
782         LOG(LOG_ERROR, "Malloc failed!\n");
783         return;
784     }
785
786
787     line = texInfo->line;
788
789     if (texInfo->size == G_IM_SIZ_32b)
790         line <<= 1;
791
792     if (texInfo->maskS)
793     {
794         clampSClamp = texInfo->clampS ? texInfo->clampWidth - 1 : (texInfo->mirrorS ? (texInfo->width << 1) - 1 : texInfo->width - 1);
795         maskSMask = (1 << texInfo->maskS) - 1;
796         mirrorSBit = texInfo->mirrorS ? (1 << texInfo->maskS) : 0;
797     }
798     else
799     {
800         clampSClamp = min( texInfo->clampWidth, texInfo->width ) - 1;
801         maskSMask = 0xFFFF;
802         mirrorSBit = 0x0000;
803     }
804
805     if (texInfo->maskT)
806     {
807         clampTClamp = texInfo->clampT ? texInfo->clampHeight - 1 : (texInfo->mirrorT ? (texInfo->height << 1) - 1: texInfo->height - 1);
808         maskTMask = (1 << texInfo->maskT) - 1;
809         mirrorTBit = texInfo->mirrorT ? (1 << texInfo->maskT) : 0;
810     }
811     else
812     {
813         clampTClamp = min( texInfo->clampHeight, texInfo->height ) - 1;
814         maskTMask = 0xFFFF;
815         mirrorTBit = 0x0000;
816     }
817
818     // Hack for Zelda warp texture
819     if (((texInfo->tMem << 3) + (texInfo->width * texInfo->height << texInfo->size >> 1)) > 4096)
820     {
821         texInfo->tMem = 0;
822     }
823
824     // limit clamp values to min-0 (Perfect Dark has height=0 textures, making negative clamps)
825     if (clampTClamp & 0x8000) clampTClamp = 0;
826     if (clampSClamp & 0x8000) clampSClamp = 0;
827
828     j = 0;
829     for (y = 0; y < texInfo->realHeight; y++)
830     {
831         ty = min(y, clampTClamp) & maskTMask;
832         if (y & mirrorTBit) ty ^= maskTMask;
833         src = &TMEM[(texInfo->tMem + line * ty) & 511];
834         i = (ty & 1) << 1;
835         for (x = 0; x < texInfo->realWidth; x++)
836         {
837             tx = min(x, clampSClamp) & maskSMask;
838
839             if (x & mirrorSBit) tx ^= maskSMask;
840
841             if (bytePerPixel == 4)
842             {
843                 ((u32*)dest)[j] = getTexel(src, tx, i, texInfo->palette);
844             }
845             else if (bytePerPixel == 2)
846             {
847                 ((u16*)dest)[j] = getTexel(src, tx, i, texInfo->palette);
848             }
849             else if (bytePerPixel == 1)
850             {
851                 ((u8*)dest)[j] = getTexel(src, tx, i, texInfo->palette);
852             }
853             j++;
854         }
855     }
856
857     if (!config.texture.sai2x || (texFormat.format == FORMAT_I8) || (texFormat.format == FORMAT_IA88))
858     {
859 #ifdef PRINT_TEXTUREFORMAT
860         printf("j=%u DEST=0x%x SIZE=%i F=0x%x, W=%i, H=%i, T=0x%x\n", j, dest, texInfo->textureBytes,glFormat, glWidth, glHeight, glType); fflush(stdout);
861 #endif
862         glTexImage2D( GL_TEXTURE_2D, 0, glFormat, glWidth, glHeight, 0, glFormat, glType, dest);
863     }
864     else
865     {
866         LOG(LOG_VERBOSE, "Using 2xSAI Filter on Texture\n");
867
868         texInfo->textureBytes <<= 2;
869
870         scaledDest = (u32*)malloc( texInfo->textureBytes );
871
872         if (glType == GL_UNSIGNED_BYTE)
873             _2xSaI8888( (u32*)dest, (u32*)scaledDest, texInfo->realWidth, texInfo->realHeight, 1, 1 );
874         else if (glType == GL_UNSIGNED_SHORT_4_4_4_4)
875             _2xSaI4444( (u16*)dest, (u16*)scaledDest, texInfo->realWidth, texInfo->realHeight, 1, 1 );
876         else
877             _2xSaI5551( (u16*)dest, (u16*)scaledDest, texInfo->realWidth, texInfo->realHeight, 1, 1 );
878
879         glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texInfo->realWidth << 1, texInfo->realHeight << 1, 0, GL_RGBA, glType, scaledDest );
880
881         free( scaledDest );
882     }
883
884     free(dest);
885
886     if (config.texture.enableMipmap)
887         glGenerateMipmap(GL_TEXTURE_2D);
888
889 }
890
891 #define max(a,b) ((a) > (b) ? (a) : (b))
892
893 u32 TextureCache_CalculateCRC( u32 t, u32 width, u32 height )
894 {
895     u32 crc;
896     u32 y, /*i,*/ bpl, lineBytes, line;
897     void *src;
898
899     bpl = width << gSP.textureTile[t]->size >> 1;
900     lineBytes = gSP.textureTile[t]->line << 3;
901
902     line = gSP.textureTile[t]->line;
903     if (gSP.textureTile[t]->size == G_IM_SIZ_32b)
904         line <<= 1;
905
906     crc = 0xFFFFFFFF;
907
908 #ifdef __CRC_OPT
909     unsigned n = (config.texture.fastCRC) ? max(1, height / 8) : 1;
910 #else
911     unsigned n = 1;
912 #endif
913
914     for (y = 0; y < height; y += n)
915     {
916         src = (void*) &TMEM[(gSP.textureTile[t]->tmem + (y * line)) & 511];
917         crc = CRC_Calculate( crc, src, bpl );
918     }
919
920     if (gSP.textureTile[t]->format == G_IM_FMT_CI)
921     {
922         if (gSP.textureTile[t]->size == G_IM_SIZ_4b)
923             crc = CRC_Calculate( crc, &gDP.paletteCRC16[gSP.textureTile[t]->palette], 4 );
924         else if (gSP.textureTile[t]->size == G_IM_SIZ_8b)
925             crc = CRC_Calculate( crc, &gDP.paletteCRC256, 4 );
926     }
927     return crc;
928 }
929
930 void TextureCache_ActivateTexture( u32 t, CachedTexture *texture )
931 {
932
933 #ifdef __HASHMAP_OPT
934     cache.hash.insert(texture->crc, texture);
935 #endif
936
937     glActiveTexture( GL_TEXTURE0 + t );
938     glBindTexture( GL_TEXTURE_2D, texture->glName );
939
940     // Set filter mode. Almost always bilinear, but check anyways
941     if ((gDP.otherMode.textureFilter == G_TF_BILERP) || (gDP.otherMode.textureFilter == G_TF_AVERAGE) || (config.texture.forceBilinear))
942     {
943         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
944         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
945     }
946     else
947     {
948         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
949         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
950     }
951
952     // Set clamping modes
953     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (texture->clampS) ? GL_CLAMP_TO_EDGE : GL_REPEAT );
954     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (texture->clampT) ? GL_CLAMP_TO_EDGE : GL_REPEAT );
955
956     if (config.texture.maxAnisotropy > 0)
957     {
958         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, config.texture.maxAnisotropy);
959     }
960
961     texture->lastDList = RSP.DList;
962     TextureCache_MoveToTop( texture );
963     cache.current[t] = texture;
964 }
965
966 void TextureCache_ActivateDummy( u32 t)
967 {
968     glActiveTexture(GL_TEXTURE0 + t);
969     glBindTexture(GL_TEXTURE_2D, cache.dummy->glName );
970     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
971     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
972 }
973
974 int _background_compare(CachedTexture *current, u32 crc)
975 {
976     if ((current != NULL) &&
977         (current->crc == crc) &&
978         (current->width == gSP.bgImage.width) &&
979         (current->height == gSP.bgImage.height) &&
980         (current->format == gSP.bgImage.format) &&
981         (current->size == gSP.bgImage.size))
982         return 1;
983     else
984         return 0;
985 }
986
987 void TextureCache_UpdateBackground()
988 {
989     u32 numBytes = gSP.bgImage.width * gSP.bgImage.height << gSP.bgImage.size >> 1;
990     u32 crc;
991
992     crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[gSP.bgImage.address], numBytes );
993
994     if (gSP.bgImage.format == G_IM_FMT_CI)
995     {
996         if (gSP.bgImage.size == G_IM_SIZ_4b)
997             crc = CRC_Calculate( crc, &gDP.paletteCRC16[gSP.bgImage.palette], 4 );
998         else if (gSP.bgImage.size == G_IM_SIZ_8b)
999             crc = CRC_Calculate( crc, &gDP.paletteCRC256, 4 );
1000     }
1001
1002     //before we traverse cache, check to see if texture is already bound:
1003     if (_background_compare(cache.current[0], crc))
1004     {
1005         return;
1006     }
1007
1008 #ifdef __HASHMAP_OPT
1009     CachedTexture *tex = cache.hash.find(crc);
1010     if (tex)
1011     {
1012         if (_background_compare(tex, crc))
1013         {
1014             TextureCache_ActivateTexture(0, tex);
1015             cache.hits++;
1016             return;
1017         }
1018     }
1019 #endif
1020
1021     CachedTexture *current = cache.top;
1022     while (current)
1023     {
1024         if (_background_compare(current, crc))
1025         {
1026             TextureCache_ActivateTexture( 0, current );
1027             cache.hits++;
1028             return;
1029         }
1030         current = current->lower;
1031     }
1032     cache.misses++;
1033
1034     glActiveTexture(GL_TEXTURE0);
1035     cache.current[0] = TextureCache_AddTop();
1036
1037     glBindTexture( GL_TEXTURE_2D, cache.current[0]->glName );
1038     cache.current[0]->address = gSP.bgImage.address;
1039     cache.current[0]->crc = crc;
1040     cache.current[0]->format = gSP.bgImage.format;
1041     cache.current[0]->size = gSP.bgImage.size;
1042     cache.current[0]->width = gSP.bgImage.width;
1043     cache.current[0]->height = gSP.bgImage.height;
1044     cache.current[0]->clampWidth = gSP.bgImage.width;
1045     cache.current[0]->clampHeight = gSP.bgImage.height;
1046     cache.current[0]->palette = gSP.bgImage.palette;
1047     cache.current[0]->maskS = 0;
1048     cache.current[0]->maskT = 0;
1049     cache.current[0]->mirrorS = 0;
1050     cache.current[0]->mirrorT = 0;
1051     cache.current[0]->clampS = 1;
1052     cache.current[0]->clampT = 1;
1053     cache.current[0]->line = 0;
1054     cache.current[0]->tMem = 0;
1055     cache.current[0]->lastDList = RSP.DList;
1056
1057     cache.current[0]->realWidth = (config.texture.pow2) ? pow2(gSP.bgImage.width ) : gSP.bgImage.width;
1058     cache.current[0]->realHeight = (config.texture.pow2) ? pow2(gSP.bgImage.height) : gSP.bgImage.height;
1059
1060     cache.current[0]->scaleS = 1.0f / (f32)(cache.current[0]->realWidth);
1061     cache.current[0]->scaleT = 1.0f / (f32)(cache.current[0]->realHeight);
1062     cache.current[0]->shiftScaleS = 1.0f;
1063     cache.current[0]->shiftScaleT = 1.0f;
1064
1065     TextureCache_LoadBackground( cache.current[0] );
1066     TextureCache_ActivateTexture( 0, cache.current[0] );
1067
1068     cache.cachedBytes += cache.current[0]->textureBytes;
1069 }
1070
1071 int _texture_compare(u32 t, CachedTexture *current, u32 crc,  u32 width, u32 height, u32 clampWidth, u32 clampHeight)
1072 {
1073     if  ((current != NULL) &&
1074         (current->crc == crc) &&
1075         (current->width == width) &&
1076         (current->height == height) &&
1077         (current->clampWidth == clampWidth) &&
1078         (current->clampHeight == clampHeight) &&
1079         (current->maskS == gSP.textureTile[t]->masks) &&
1080         (current->maskT == gSP.textureTile[t]->maskt) &&
1081         (current->mirrorS == gSP.textureTile[t]->mirrors) &&
1082         (current->mirrorT == gSP.textureTile[t]->mirrort) &&
1083         (current->clampS == gSP.textureTile[t]->clamps) &&
1084         (current->clampT == gSP.textureTile[t]->clampt) &&
1085         (current->format == gSP.textureTile[t]->format) &&
1086         (current->size == gSP.textureTile[t]->size))
1087         return 1;
1088     else
1089         return 0;
1090 }
1091
1092
1093 void TextureCache_Update( u32 t )
1094 {
1095     CachedTexture *current;
1096
1097     u32 crc, maxTexels;
1098     u32 tileWidth, maskWidth, loadWidth, lineWidth, clampWidth, height;
1099     u32 tileHeight, maskHeight, loadHeight, lineHeight, clampHeight, width;
1100
1101     if (gDP.textureMode == TEXTUREMODE_BGIMAGE)
1102     {
1103         TextureCache_UpdateBackground();
1104         return;
1105     }
1106
1107     TextureFormat texFormat;
1108     __texture_format(gSP.textureTile[t]->size, gSP.textureTile[t]->format, &texFormat);
1109
1110     maxTexels = texFormat.maxTexels;
1111
1112     // Here comes a bunch of code that just calculates the texture size...I wish there was an easier way...
1113     tileWidth = gSP.textureTile[t]->lrs - gSP.textureTile[t]->uls + 1;
1114     tileHeight = gSP.textureTile[t]->lrt - gSP.textureTile[t]->ult + 1;
1115
1116     maskWidth = 1 << gSP.textureTile[t]->masks;
1117     maskHeight = 1 << gSP.textureTile[t]->maskt;
1118
1119     loadWidth = gDP.loadTile->lrs - gDP.loadTile->uls + 1;
1120     loadHeight = gDP.loadTile->lrt - gDP.loadTile->ult + 1;
1121
1122     lineWidth = gSP.textureTile[t]->line << texFormat.lineShift;
1123
1124     if (lineWidth) // Don't allow division by zero
1125         lineHeight = min( maxTexels / lineWidth, tileHeight );
1126     else
1127         lineHeight = 0;
1128
1129     if (gDP.textureMode == TEXTUREMODE_TEXRECT)
1130     {
1131         u32 texRectWidth = gDP.texRect.width - gSP.textureTile[t]->uls;
1132         u32 texRectHeight = gDP.texRect.height - gSP.textureTile[t]->ult;
1133
1134         if (gSP.textureTile[t]->masks && ((maskWidth * maskHeight) <= maxTexels))
1135             width = maskWidth;
1136         else if ((tileWidth * tileHeight) <= maxTexels)
1137             width = tileWidth;
1138         else if ((tileWidth * texRectHeight) <= maxTexels)
1139             width = tileWidth;
1140         else if ((texRectWidth * tileHeight) <= maxTexels)
1141             width = gDP.texRect.width;
1142         else if ((texRectWidth * texRectHeight) <= maxTexels)
1143             width = gDP.texRect.width;
1144         else if (gDP.loadType == LOADTYPE_TILE)
1145             width = loadWidth;
1146         else
1147             width = lineWidth;
1148
1149         if (gSP.textureTile[t]->maskt && ((maskWidth * maskHeight) <= maxTexels))
1150             height = maskHeight;
1151         else if ((tileWidth * tileHeight) <= maxTexels)
1152             height = tileHeight;
1153         else if ((tileWidth * texRectHeight) <= maxTexels)
1154             height = gDP.texRect.height;
1155         else if ((texRectWidth * tileHeight) <= maxTexels)
1156             height = tileHeight;
1157         else if ((texRectWidth * texRectHeight) <= maxTexels)
1158             height = gDP.texRect.height;
1159         else if (gDP.loadType == LOADTYPE_TILE)
1160             height = loadHeight;
1161         else
1162             height = lineHeight;
1163     }
1164     else
1165     {
1166         if (gSP.textureTile[t]->masks && ((maskWidth * maskHeight) <= maxTexels))
1167             width = maskWidth;
1168         else if ((tileWidth * tileHeight) <= maxTexels)
1169             width = tileWidth;
1170         else if (gDP.loadType == LOADTYPE_TILE)
1171             width = loadWidth;
1172         else
1173             width = lineWidth;
1174
1175         if (gSP.textureTile[t]->maskt && ((maskWidth * maskHeight) <= maxTexels))
1176             height = maskHeight;
1177         else if ((tileWidth * tileHeight) <= maxTexels)
1178             height = tileHeight;
1179         else if (gDP.loadType == LOADTYPE_TILE)
1180             height = loadHeight;
1181         else
1182             height = lineHeight;
1183     }
1184
1185     clampWidth = gSP.textureTile[t]->clamps ? tileWidth : width;
1186     clampHeight = gSP.textureTile[t]->clampt ? tileHeight : height;
1187
1188     if (clampWidth > 256)
1189         gSP.textureTile[t]->clamps = 0;
1190     if (clampHeight > 256)
1191         gSP.textureTile[t]->clampt = 0;
1192
1193     // Make sure masking is valid
1194     if (maskWidth > width)
1195     {
1196         gSP.textureTile[t]->masks = powof( width );
1197         maskWidth = 1 << gSP.textureTile[t]->masks;
1198     }
1199
1200     if (maskHeight > height)
1201     {
1202         gSP.textureTile[t]->maskt = powof( height );
1203         maskHeight = 1 << gSP.textureTile[t]->maskt;
1204     }
1205
1206     crc = TextureCache_CalculateCRC( t, width, height );
1207
1208     //before we traverse cache, check to see if texture is already bound:
1209     if (_texture_compare(t, cache.current[t], crc, width, height, clampWidth, clampHeight))
1210     {
1211         cache.hits++;
1212         return;
1213     }
1214
1215 #ifdef __HASHMAP_OPT
1216     CachedTexture *tex = cache.hash.find(crc);
1217     if (tex)
1218     {
1219         if (_texture_compare(t, tex, crc, width, height, clampWidth, clampHeight))
1220         {
1221             TextureCache_ActivateTexture( t, tex);
1222             cache.hits++;
1223             return;
1224         }
1225     }
1226 #endif
1227
1228     current = cache.top;
1229     while (current)
1230     {
1231         if  (_texture_compare(t, current, crc, width, height, clampWidth, clampHeight))
1232         {
1233             TextureCache_ActivateTexture( t, current );
1234             cache.hits++;
1235             return;
1236         }
1237
1238         current = current->lower;
1239     }
1240
1241     cache.misses++;
1242
1243     glActiveTexture( GL_TEXTURE0 + t);
1244
1245     cache.current[t] = TextureCache_AddTop();
1246
1247     if (cache.current[t] == NULL)
1248     {
1249         LOG(LOG_ERROR, "Texture Cache Failure\n");
1250     }
1251
1252     glBindTexture( GL_TEXTURE_2D, cache.current[t]->glName );
1253
1254     cache.current[t]->address = gDP.textureImage.address;
1255     cache.current[t]->crc = crc;
1256
1257     cache.current[t]->format = gSP.textureTile[t]->format;
1258     cache.current[t]->size = gSP.textureTile[t]->size;
1259
1260     cache.current[t]->width = width;
1261     cache.current[t]->height = height;
1262     cache.current[t]->clampWidth = clampWidth;
1263     cache.current[t]->clampHeight = clampHeight;
1264     cache.current[t]->palette = gSP.textureTile[t]->palette;
1265     cache.current[t]->maskS = gSP.textureTile[t]->masks;
1266     cache.current[t]->maskT = gSP.textureTile[t]->maskt;
1267     cache.current[t]->mirrorS = gSP.textureTile[t]->mirrors;
1268     cache.current[t]->mirrorT = gSP.textureTile[t]->mirrort;
1269     cache.current[t]->clampS = gSP.textureTile[t]->clamps;
1270     cache.current[t]->clampT = gSP.textureTile[t]->clampt;
1271     cache.current[t]->line = gSP.textureTile[t]->line;
1272     cache.current[t]->tMem = gSP.textureTile[t]->tmem;
1273     cache.current[t]->lastDList = RSP.DList;
1274
1275
1276     if (cache.current[t]->clampS)
1277         cache.current[t]->realWidth = (config.texture.pow2) ? pow2(clampWidth) : clampWidth;
1278     else if (cache.current[t]->mirrorS)
1279         cache.current[t]->realWidth = maskWidth << 1;
1280     else
1281         cache.current[t]->realWidth = (config.texture.pow2) ? pow2(width) : width;
1282
1283     if (cache.current[t]->clampT)
1284         cache.current[t]->realHeight = (config.texture.pow2) ? pow2(clampHeight) : clampHeight;
1285     else if (cache.current[t]->mirrorT)
1286         cache.current[t]->realHeight = maskHeight << 1;
1287     else
1288         cache.current[t]->realHeight = (config.texture.pow2) ? pow2(height) : height;
1289
1290
1291     cache.current[t]->scaleS = 1.0f / (f32)(cache.current[t]->realWidth);
1292     cache.current[t]->scaleT = 1.0f / (f32)(cache.current[t]->realHeight);
1293
1294     // Hack for Zelda Sun
1295     if ((config.hackZelda) && (gDP.combine.mux == 0x00262a60150c937fLL))
1296     {
1297         if ((cache.current[t]->format = G_IM_FMT_I) && (cache.current[t]->size == G_IM_SIZ_8b) &&
1298             (cache.current[t]->width == 64))
1299         {
1300             cache.current[t]->scaleS *= 0.5f;
1301             cache.current[t]->scaleT *= 0.5f;
1302         }
1303     }
1304
1305     cache.current[t]->shiftScaleS = 1.0f;
1306     cache.current[t]->shiftScaleT = 1.0f;
1307
1308     cache.current[t]->offsetS = config.texture.sai2x ? 0.25f : 0.5f;
1309     cache.current[t]->offsetT = config.texture.sai2x ? 0.25f : 0.5f;
1310
1311     if (gSP.textureTile[t]->shifts > 10)
1312         cache.current[t]->shiftScaleS = (f32)(1 << (16 - gSP.textureTile[t]->shifts));
1313     else if (gSP.textureTile[t]->shifts > 0)
1314         cache.current[t]->shiftScaleS /= (f32)(1 << gSP.textureTile[t]->shifts);
1315
1316     if (gSP.textureTile[t]->shiftt > 10)
1317         cache.current[t]->shiftScaleT = (f32)(1 << (16 - gSP.textureTile[t]->shiftt));
1318     else if (gSP.textureTile[t]->shiftt > 0)
1319         cache.current[t]->shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt);
1320
1321     TextureCache_Load( cache.current[t] );
1322     TextureCache_ActivateTexture( t, cache.current[t] );
1323
1324     cache.cachedBytes += cache.current[t]->textureBytes;
1325 }
1326
1327 void TextureCache_ActivateNoise(u32 t)
1328 {
1329     glActiveTexture(GL_TEXTURE0 + t);
1330     glBindTexture(GL_TEXTURE_2D, cache.glNoiseNames[RSP.DList & 0x1F]);
1331     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1332     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1333 }
1334