Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glitch64 / textures.cpp.sav
1 /*
2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002  Dave2001
4 * Copyright (c) 2003-2009  Sergey 'Gonetz' Lipski
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #ifdef _WIN32
22 #include <windows.h>
23 #else // _WIN32
24 #include <stdlib.h>
25 #endif // _WIN32
26 #include "glide.h"
27 #include "main.h"
28 #include <stdio.h>
29 #include <string.h>
30
31 /* Napalm extensions to GrTextureFormat_t */
32 #define GR_TEXFMT_ARGB_CMP_FXT1           0x11
33 #define GR_TEXFMT_ARGB_8888               0x12
34 #define GR_TEXFMT_YUYV_422                0x13
35 #define GR_TEXFMT_UYVY_422                0x14
36 #define GR_TEXFMT_AYUV_444                0x15
37 #define GR_TEXFMT_ARGB_CMP_DXT1           0x16
38 #define GR_TEXFMT_ARGB_CMP_DXT2           0x17
39 #define GR_TEXFMT_ARGB_CMP_DXT3           0x18
40 #define GR_TEXFMT_ARGB_CMP_DXT4           0x19
41 #define GR_TEXFMT_ARGB_CMP_DXT5           0x1A
42 #define GR_TEXTFMT_RGB_888                0xFF
43
44 int TMU_SIZE = 8*2048*2048;
45 static unsigned char* texture = NULL;
46
47 int packed_pixels_support = -1;
48 int ati_sucks = -1;
49 float largest_supported_anisotropy = 1.0f;
50
51 #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
52 #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
53 #endif
54
55 int tex0_width, tex0_height, tex1_width, tex1_height;
56 float lambda;
57
58 static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
59 static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
60
61 unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
62
63 typedef struct _texlist
64 {
65   unsigned int id;
66   struct _texlist *next;
67 } texlist;
68
69 static int nbTex = 0;
70 static texlist *list = NULL;
71
72 #ifdef _WIN32
73 extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
74 extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
75 extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
76 #endif
77 void remove_tex(unsigned int idmin, unsigned int idmax)
78 {
79   unsigned int *t;
80   int n = 0;
81   texlist *aux = list;
82   int sz = nbTex;
83   if (aux == NULL) return;
84   t = (unsigned int*)malloc(sz * sizeof(int));
85   while (aux && aux->id >= idmin && aux->id < idmax)
86   {
87     if (n >= sz)
88       t = (unsigned int *) realloc(t, ++sz*sizeof(int));
89     t[n++] = aux->id;
90     aux = aux->next;
91     free(list);
92     list = aux;
93     nbTex--;
94   }
95   while (aux != NULL && aux->next != NULL)
96   {
97     if (aux->next->id >= idmin && aux->next->id < idmax)
98     {
99       texlist *aux2 = aux->next->next;
100       if (n >= sz)
101         t = (unsigned int *) realloc(t, ++sz*sizeof(int));
102       t[n++] = aux->next->id;
103       free(aux->next);
104       aux->next = aux2;
105       nbTex--;
106     }
107     aux = aux->next;
108   }
109   glDeleteTextures(n, t);
110   free(t);
111 //printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
112 }
113
114
115 void add_tex(unsigned int id)
116 {
117   texlist *aux = list;
118   texlist *aux2;
119 //printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
120   if (list == NULL || id < list->id)
121   {
122     nbTex++;
123     list = (texlist*)malloc(sizeof(texlist));
124     list->next = aux;
125     list->id = id;
126     return;
127   }
128   while (aux->next != NULL && aux->next->id < id) aux = aux->next;
129   // ZIGGY added this test so that add_tex now accept re-adding an existing texture
130   if (aux->next != NULL && aux->next->id == id) return;
131   nbTex++;
132   aux2 = aux->next;
133   aux->next = (texlist*)malloc(sizeof(texlist));
134   aux->next->id = id;
135   aux->next->next = aux2;
136 }
137
138 void init_textures()
139 {
140   tex0_width = tex0_height = tex1_width = tex1_height = 2;
141   // ZIGGY because remove_tex isn't called (Pj64 doesn't like it), it's better
142   // to leave these so that they'll be reused (otherwise we have a memory leak)
143   //    list = NULL;
144   //    nbTex = 0;
145
146   if (!texture) texture = (unsigned char*)malloc(2048*2048*4);
147 }
148
149 void free_textures()
150 {
151 #ifndef WIN32
152   // ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
153   remove_tex(0x00000000, 0xFFFFFFFF);
154 #endif
155   if (texture != NULL) {
156     free(texture);
157     texture = NULL;
158   }
159 }
160
161 FX_ENTRY FxU32 FX_CALL
162 grTexMinAddress( GrChipID_t tmu )
163 {
164   LOG("grTexMinAddress(%d)\r\n", tmu);
165   if (UMAmode)
166     return 0;
167   else
168     return tmu*TMU_SIZE;
169 }
170
171 FX_ENTRY FxU32 FX_CALL
172 grTexMaxAddress( GrChipID_t tmu )
173 {
174   LOG("grTexMaxAddress(%d)\r\n", tmu);
175   if (UMAmode)
176     return TMU_SIZE*2 - 1;
177   else
178     return tmu*TMU_SIZE + TMU_SIZE - 1;
179 }
180
181 FX_ENTRY FxU32 FX_CALL
182 grTexTextureMemRequired( FxU32     evenOdd,
183                         GrTexInfo *info   )
184 {
185   int width, height;
186   LOG("grTextureMemRequired(%d)\r\n", evenOdd);
187   if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");
188
189   if (info->aspectRatioLog2 < 0)
190   {
191     height = 1 << info->largeLodLog2;
192     width = height >> -info->aspectRatioLog2;
193   }
194   else
195   {
196     width = 1 << info->largeLodLog2;
197     height = width >> info->aspectRatioLog2;
198   }
199
200   switch(info->format)
201   {
202   case GR_TEXFMT_ALPHA_8:
203   case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
204   case GR_TEXFMT_ALPHA_INTENSITY_44:
205     return width*height;
206     break;
207   case GR_TEXFMT_ARGB_1555:
208   case GR_TEXFMT_ARGB_4444:
209   case GR_TEXFMT_ALPHA_INTENSITY_88:
210   case GR_TEXFMT_RGB_565:
211     return (width*height)<<1;
212     break;
213   case GR_TEXFMT_ARGB_8888:
214     return (width*height)<<2;
215     break;
216   case GR_TEXFMT_ARGB_CMP_DXT1:  // FXT1,DXT1,5 support - H.Morii
217     return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
218   case GR_TEXFMT_ARGB_CMP_DXT3:
219     return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
220   case GR_TEXFMT_ARGB_CMP_DXT5:
221     return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
222   case GR_TEXFMT_ARGB_CMP_FXT1:
223     return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
224   default:
225     display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);
226   }
227   return 0;
228 }
229
230 FX_ENTRY FxU32 FX_CALL
231 grTexCalcMemRequired(
232                      GrLOD_t lodmin, GrLOD_t lodmax,
233                      GrAspectRatio_t aspect, GrTextureFormat_t fmt)
234 {
235   int width, height;
236   LOG("grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);
237   if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");
238
239   if (aspect < 0)
240   {
241     height = 1 << lodmax;
242     width = height >> -aspect;
243   }
244   else
245   {
246     width = 1 << lodmax;
247     height = width >> aspect;
248   }
249
250   switch(fmt)
251   {
252   case GR_TEXFMT_ALPHA_8:
253   case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
254   case GR_TEXFMT_ALPHA_INTENSITY_44:
255     return width*height;
256     break;
257   case GR_TEXFMT_ARGB_1555:
258   case GR_TEXFMT_ARGB_4444:
259   case GR_TEXFMT_ALPHA_INTENSITY_88:
260   case GR_TEXFMT_RGB_565:
261     return (width*height)<<1;
262     break;
263   case GR_TEXFMT_ARGB_8888:
264     return (width*height)<<2;
265     break;
266   case GR_TEXFMT_ARGB_CMP_DXT1:  // FXT1,DXT1,5 support - H.Morii
267     return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
268   case GR_TEXFMT_ARGB_CMP_DXT3:
269     return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
270   case GR_TEXFMT_ARGB_CMP_DXT5:
271     return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
272   case GR_TEXFMT_ARGB_CMP_FXT1:
273     return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
274   default:
275     display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);
276   }
277   return 0;
278 }
279
280 int grTexFormatSize(int fmt)
281 {
282   int factor = -1;
283   switch(fmt) {
284   case GR_TEXFMT_ALPHA_8:
285   case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
286     factor = 1;
287     break;
288   case GR_TEXFMT_ALPHA_INTENSITY_44:
289     factor = 1;
290     break;
291   case GR_TEXFMT_RGB_565:
292     factor = 2;
293     break;
294   case GR_TEXFMT_ARGB_1555:
295     factor = 2;
296     break;
297   case GR_TEXFMT_ALPHA_INTENSITY_88:
298     factor = 2;
299     break;
300   case GR_TEXFMT_ARGB_4444:
301     factor = 2;
302     break;
303   case GR_TEXFMT_ARGB_8888:
304     factor = 4;
305     break;
306   case GR_TEXFMT_ARGB_CMP_DXT1:  // FXT1,DXT1,5 support - H.Morii
307     factor = 8;                  // HACKALERT: factor holds block bytes
308     break;
309   case GR_TEXFMT_ARGB_CMP_DXT3:  // FXT1,DXT1,5 support - H.Morii
310     factor = 16;                  // HACKALERT: factor holds block bytes
311     break;
312   case GR_TEXFMT_ARGB_CMP_DXT5:
313     factor = 16;
314     break;
315   case GR_TEXFMT_ARGB_CMP_FXT1:
316     factor = 8;
317     break;
318   default:
319     display_warning("grTexFormatSize : unknown texture format: %x", fmt);
320   }
321   return factor;
322 }
323
324 int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
325 {
326     *gltexfmt = GL_RGBA;
327     *glpixfmt = GL_RGBA;
328     *glpackfmt = GL_UNSIGNED_BYTE;
329     return 0;
330 /*
331   int factor = -1;
332   switch(fmt) {
333   case GR_TEXFMT_ALPHA_8:
334     factor = 1;
335     *gltexfmt = GL_INTENSITY8;
336     *glpixfmt = GL_LUMINANCE;
337     *glpackfmt = GL_UNSIGNED_BYTE;
338     break;
339   case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
340     factor = 1;
341     *gltexfmt = GL_LUMINANCE8;
342     *glpixfmt = GL_LUMINANCE;
343     *glpackfmt = GL_UNSIGNED_BYTE;
344     break;
345   case GR_TEXFMT_ALPHA_INTENSITY_44:
346     break;
347   case GR_TEXFMT_RGB_565:
348     factor = 2;
349     *gltexfmt = GL_RGB;
350     *glpixfmt = GL_RGB;
351     *glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
352     break;
353   case GR_TEXFMT_ARGB_1555:
354     if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)
355     factor = 2;
356     *gltexfmt = GL_RGB5_A1;
357     *glpixfmt = GL_BGRA;
358     *glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
359     break;
360   case GR_TEXFMT_ALPHA_INTENSITY_88:
361     factor = 2;
362     *gltexfmt = GL_LUMINANCE8_ALPHA8;
363     *glpixfmt = GL_LUMINANCE_ALPHA;
364     *glpackfmt = GL_UNSIGNED_BYTE;
365     break;
366   case GR_TEXFMT_ARGB_4444:
367     factor = 2;
368     *gltexfmt = GL_RGBA4;
369     *glpixfmt = GL_BGRA;
370     *glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
371     break;
372   case GR_TEXFMT_ARGB_8888:
373     factor = 4;
374     *gltexfmt = GL_RGBA8;
375     *glpixfmt = GL_BGRA;
376     *glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
377     break;
378   case GR_TEXFMT_ARGB_CMP_DXT1:  // FXT1,DXT1,5 support - H.Morii
379     // HACKALERT: 3Dfx Glide uses GR_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.
380     // GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.
381     factor = 8; // HACKALERT: factor holds block bytes
382     *gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // these variables aren't used
383     *glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
384     *glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
385     break;
386   case GR_TEXFMT_ARGB_CMP_DXT3:
387     factor = 16;
388     *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
389     *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
390     *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
391     break;
392   case GR_TEXFMT_ARGB_CMP_DXT5:
393     factor = 16;
394     *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
395     *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
396     *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
397     break;
398   case GR_TEXFMT_ARGB_CMP_FXT1:
399     factor = 8;
400     *gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
401     *glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
402     *glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // XXX: what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?
403     break;
404   default:
405     display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);
406   }
407   return factor;
408 */
409 }
410
411 FX_ENTRY void FX_CALL
412 grTexDownloadMipMap( GrChipID_t tmu,
413                     FxU32      startAddress,
414                     FxU32      evenOdd,
415                     GrTexInfo  *info )
416 {
417   int width, height, i, j;
418   int factor;
419   int glformat = 0;
420   int gltexfmt, glpixfmt, glpackfmt;
421   LOG("grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
422   if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");
423
424   if (info->aspectRatioLog2 < 0)
425   {
426     height = 1 << info->largeLodLog2;
427     width = height >> -info->aspectRatioLog2;
428   }
429   else
430   {
431     width = 1 << info->largeLodLog2;
432     height = width >> info->aspectRatioLog2;
433   }
434
435   if (!packed_pixels_support)
436     factor = -1;
437   else
438     factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
439 //printf("grTexDownloadMipmap, id=%x, size=%ix%i, format=%x\n", startAddress+1, width, height, info->format);
440   if (factor < 0) {
441     gltexfmt = GL_RGBA;
442     glpixfmt = GL_RGBA;
443     glpackfmt = GL_UNSIGNED_BYTE;
444
445     // VP fixed the texture conversions to be more accurate, also swapped
446     // the for i/j loops so that is is less likely to break the memory cache
447     register int n = 0, m = 0;
448     switch(info->format)
449     {
450     case GR_TEXFMT_ALPHA_8:
451  /*     for (i=0; i<height; i++)
452       {
453         for (j=0; j<width; j++)
454         {
455           unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
456           texel |= (texel << 8);
457           texel |= (texel << 16);
458           ((unsigned int*)texture)[n] = texel;
459           m++;
460           n++;
461         }
462       }
463       factor = 1;
464       glformat = GL_RGBA;*/
465
466      for (i=0; i<height; i++)
467       {
468         for (j=0; j<width; j++)
469         {
470           unsigned short texel = (unsigned short)((unsigned char*)info->data)[m];
471           ((unsigned short*)texture)[n] = texel|(texel<<8);
472           m++;
473           n++;
474         }
475       }
476
477       glformat = gltexfmt = glpixfmt = GL_LUMINANCE_ALPHA;
478       glpackfmt = GL_UNSIGNED_BYTE;
479       factor = 1;
480       break;
481     case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
482 /*      for (i=0; i<height; i++)
483       {
484         for (j=0; j<width; j++)
485         {
486           unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
487           texel |= (0xFF000000 | (texel << 16) | (texel << 8));
488           ((unsigned int*)texture)[n] = texel;
489           m++;
490           n++;
491         }
492       }*/
493       factor = 1;
494 //      glformat = GL_ALPHA;
495       memcpy(texture, info->data, width*height);
496       glformat = gltexfmt = glpixfmt = GL_LUMINANCE;
497       glpackfmt = GL_UNSIGNED_BYTE;
498       factor = 1;
499       break;
500     case GR_TEXFMT_ALPHA_INTENSITY_44:
501 #if 1
502       for (i=0; i<height; i++)
503       {
504         for (j=0; j<width; j++)
505         {
506 /*          unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
507 #if 1
508           // accurate conversion
509           unsigned int texel_hi = (texel & 0x000000F0) << 20;
510           unsigned int texel_low = texel & 0x0000000F;
511           texel_low |= (texel_low << 4);
512           texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);
513 #else
514           unsigned int texel_hi = (texel & 0x000000F0) << 24;
515           unsigned int texel_low = (texel & 0x0000000F) << 4;
516           texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);
517 #endif
518           ((unsigned int*)texture)[n] = texel_hi;
519 */
520           unsigned char texel = ((unsigned char*)info->data)[m];
521           unsigned short texel_hi = (texel & 0x000000F0) << 4;
522           unsigned short texel_low = texel & 0x0000000F;
523           texel_low |= (texel_low << 4);
524           texel_hi |= ((texel_hi << 4) | (texel_low));
525           ((unsigned short*)texture)[n] = texel_hi;
526           m++;
527           n++;
528         }
529       }
530       factor = 1;
531       glformat = gltexfmt = glpixfmt = GL_LUMINANCE_ALPHA;
532       glpackfmt = GL_UNSIGNED_BYTE;
533 //      glformat = GL_LUMINANCE_ALPHA;
534 #endif
535       break;
536     case GR_TEXFMT_RGB_565:
537 /*      for (i=0; i<height; i++)
538       {
539         for (j=0; j<width; j++)
540         {*/
541 /*          unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
542           unsigned int B = texel & 0x0000F800;
543           unsigned int G = texel & 0x000007E0;
544           unsigned int R = texel & 0x0000001F;
545 #if 0
546           // accurate conversion 
547           ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);
548 #else
549           ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);
550 #endif
551 */
552 /*        const unsigned short texel = ((unsigned short*)info->data)[m];
553           const unsigned short B = (texel & 0xF800)>>11;
554           const unsigned short G = texel & 0x07E0;
555           const unsigned short R = (texel & 0x001F)<<11;
556           ((unsigned short*)texture)[n] = R|G|B;
557           m++;
558           n++;
559         }
560       }*/
561       memcpy(texture, info->data, width*height*2);
562       factor = 2;
563 //      glformat = GL_RGB;
564       glformat = gltexfmt = glpixfmt = GL_RGB;
565       glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
566       break;
567     case GR_TEXFMT_ARGB_1555:
568       for (i=0; i<height; i++)
569       {
570         for (j=0; j<width; j++)
571         {
572 /*          unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
573           unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;
574           unsigned int B = texel & 0x00007C00;
575           unsigned int G = texel & 0x000003E0;
576           unsigned int R = texel & 0x0000001F;
577 #if 0
578           // accurate conversion
579           ((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);
580 #else
581           ((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);
582 #endif
583 */
584           unsigned short texel = ((unsigned short*)info->data)[m];
585           unsigned short A = (texel & 0x8000)>>15;
586           ((unsigned short*)texture)[n] = A|(texel&0x7fff)<<1;
587 /*
588           unsigned short B = (texel & 0x7C00)>>9;
589           unsigned short G = texel & 0x03E0<<1;
590           unsigned short R = (texel & 0x001F)<<11;
591           ((unsigned short*)texture)[n] = A|R|G|B;*/
592           m++;
593           n++;
594         }
595       }
596       factor = 2;
597 //      glformat = GL_RGBA;
598       glformat = gltexfmt = glpixfmt = GL_RGBA;
599       glpackfmt = GL_UNSIGNED_SHORT_5_5_5_1;
600       break;
601     case GR_TEXFMT_ALPHA_INTENSITY_88:
602 /*      for (i=0; i<height; i++)
603       {
604         for (j=0; j<width; j++)
605         {
606           unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];
607           unsigned int I = (unsigned int)(AI & 0x000000FF);
608           ((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;
609           m++;
610           n++;
611         }
612       }*/
613       memcpy(texture, info->data, width*height*2);
614       factor = 2;
615       glformat = GL_LUMINANCE_ALPHA;
616       glformat = gltexfmt = glpixfmt = GL_LUMINANCE_ALPHA;
617       glpackfmt = GL_UNSIGNED_BYTE;
618       break;
619     case GR_TEXFMT_ARGB_4444:
620
621       for (i=0; i<height; i++)
622       {
623         for (j=0; j<width; j++)
624         {
625 /*          unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
626           unsigned int A = texel & 0x0000F000;
627           unsigned int B = texel & 0x00000F00;
628           unsigned int G = texel & 0x000000F0;
629           unsigned int R = texel & 0x0000000F;
630 #if 0
631           // accurate conversion
632           ((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);
633 #else
634           ((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);
635 #endif
636 */
637           unsigned short texel = ((unsigned short*)info->data)[m];
638           unsigned int A = (texel & 0xF000)>>12;
639           ((unsigned short*)texture)[n] = A|(texel&0x0fff)<<4;
640           m++;
641           n++;
642         }
643       }
644       factor = 2;
645       glformat = GL_RGBA;
646       glformat = gltexfmt = glpixfmt = GL_RGBA;
647       glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4;
648       break;
649     case GR_TEXFMT_ARGB_8888:
650       for (i=0; i<height; i++)
651       {
652         for (j=0; j<width; j++)
653         {
654           unsigned int texel = ((unsigned int*)info->data)[m];
655           unsigned int A = texel & 0xFF000000;
656           unsigned int B = texel & 0x00FF0000;
657           unsigned int G = texel & 0x0000FF00;
658           unsigned int R = texel & 0x000000FF;
659           ((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);
660           m++;
661           n++;
662         }
663       }
664       factor = 4;
665       glformat = GL_RGBA;
666       break;
667 /*
668     case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
669       factor = 8;                 // HACKALERT: factor holds block bytes
670       glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
671       break;
672     case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
673       factor = 16;                 // HACKALERT: factor holds block bytes
674       glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
675       break;
676     case GR_TEXFMT_ARGB_CMP_DXT5:
677       factor = 16;
678       glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
679       break;
680     case GR_TEXFMT_ARGB_CMP_FXT1:
681       factor = 8;
682       glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
683       break;
684 */
685     default:
686       display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);
687       factor = 0;
688     }
689   }
690
691   if (nbTextureUnits <= 2)
692     glActiveTexture(GL_TEXTURE1);
693   else
694     glActiveTexture(GL_TEXTURE2);
695
696   switch(info->format)
697   {
698   case GR_TEXFMT_ARGB_CMP_DXT1:
699   case GR_TEXFMT_ARGB_CMP_DXT3:
700   case GR_TEXFMT_ARGB_CMP_DXT5:
701   case GR_TEXFMT_ARGB_CMP_FXT1:
702     remove_tex(startAddress+1, startAddress+1+((width*height*factor)>>4));
703     break;
704   default:
705     remove_tex(startAddress+1, startAddress+1+(width*height*factor));
706   }
707
708   add_tex(startAddress+1);
709   glBindTexture(GL_TEXTURE_2D, startAddress+1);
710
711   if (largest_supported_anisotropy > 1.0f)
712     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
713
714 //*SEB*  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
715 //printf("new texture, id=%x, size=%ix%i, fmt=%x/%x\n", startAddress+1, width, height, gltexfmt, glpackfmt);
716   glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, texture);
717 /*
718   switch(info->format)
719   {
720   case GR_TEXFMT_ARGB_CMP_DXT1:
721   case GR_TEXFMT_ARGB_CMP_DXT3:
722   case GR_TEXFMT_ARGB_CMP_DXT5:
723   case GR_TEXFMT_ARGB_CMP_FXT1:
724     glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor)>>4, info->data);
725     break;
726   default:
727     if (glformat) {
728       glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
729     } else
730       glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
731   }
732 */
733
734   glBindTexture(GL_TEXTURE_2D, default_texture);
735 }
736
737 int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
738
739 FX_ENTRY void FX_CALL
740 grTexSource( GrChipID_t tmu,
741             FxU32      startAddress,
742             FxU32      evenOdd,
743             GrTexInfo  *info )
744 {
745   LOG("grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
746
747   if (tmu == GR_TMU1 || nbTextureUnits <= 2)
748   {
749     if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
750     glActiveTexture(GL_TEXTURE0);
751
752     if (info->aspectRatioLog2 < 0)
753     {
754       tex0_height = 256;
755       tex0_width = tex0_height >> -info->aspectRatioLog2;
756     }
757     else
758     {
759       tex0_width = 256;
760       tex0_height = tex0_width >> info->aspectRatioLog2;
761     }
762
763     glBindTexture(GL_TEXTURE_2D, startAddress+1);
764 #ifdef VPDEBUG
765     dump_tex(startAddress+1);
766 #endif
767     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
768     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
769     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
770     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
771   }
772   else
773   {
774     glActiveTexture(GL_TEXTURE1);
775
776     if (info->aspectRatioLog2 < 0)
777     {
778       tex1_height = 256;
779       tex1_width = tex1_height >> -info->aspectRatioLog2;
780     }
781     else
782     {
783       tex1_width = 256;
784       tex1_height = tex1_width >> info->aspectRatioLog2;
785     }
786
787     glBindTexture(GL_TEXTURE_2D, startAddress+1);
788 #ifdef VPDEBUG
789     dump_tex(startAddress+1);
790 #endif
791     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
792     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
793     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
794     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
795   }
796   if(!CheckTextureBufferFormat(tmu, startAddress+1, info))
797   {
798     if(tmu == 0 && blackandwhite1 != 0)
799     {
800       blackandwhite1 = 0;
801       need_to_compile = 1;
802     }
803     if(tmu == 1 && blackandwhite0 != 0)
804     {
805       blackandwhite0 = 0;
806       need_to_compile = 1;
807     }
808   }
809
810 #if 0
811   extern int auxbuffer;
812   static int oldbuffer;
813   FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
814   if (auxbuffer == GR_BUFFER_AUXBUFFER && auxbuffer != oldbuffer)
815     grAuxBufferExt(auxbuffer);
816   oldbuffer = auxbuffer;
817 #endif
818 }
819
820 FX_ENTRY void FX_CALL
821 grTexDetailControl(
822                    GrChipID_t tmu,
823                    int lod_bias,
824                    FxU8 detail_scale,
825                    float detail_max
826                    )
827 {
828   LOG("grTexDetailControl(%d,%d,%d,%d)\r\n", tmu, lod_bias, detail_scale, detail_max);
829   if (lod_bias != 31 && detail_scale != 7)
830   {
831     if (!lod_bias && !detail_scale && !detail_max) return;
832     else
833       display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);
834   }
835   lambda = detail_max;
836   if(lambda > 1.0f)
837   {
838     lambda = 1.0f - (255.0f - lambda);
839   }
840   if(lambda > 1.0f) display_warning("lambda:%f", lambda);
841
842   set_lambda();
843 }
844
845 FX_ENTRY void FX_CALL
846 grTexLodBiasValue(GrChipID_t tmu, float bias )
847 {
848   LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
849 }
850
851 FX_ENTRY void FX_CALL
852 grTexFilterMode(
853                 GrChipID_t tmu,
854                 GrTextureFilterMode_t minfilter_mode,
855                 GrTextureFilterMode_t magfilter_mode
856                 )
857 {
858   LOG("grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);
859   if (tmu == GR_TMU1 || nbTextureUnits <= 2)
860   {
861     if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
862     if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
863     else min_filter0 = GL_LINEAR;
864
865     if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
866     else mag_filter0 = GL_LINEAR;
867
868     glActiveTexture(GL_TEXTURE0);
869     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
870     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
871   }
872   else
873   {
874     if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
875     else min_filter1 = GL_LINEAR;
876
877     if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
878     else mag_filter1 = GL_LINEAR;
879
880     glActiveTexture(GL_TEXTURE1);
881     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
882     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
883   }
884 }
885
886 FX_ENTRY void FX_CALL
887 grTexClampMode(
888                GrChipID_t tmu,
889                GrTextureClampMode_t s_clampmode,
890                GrTextureClampMode_t t_clampmode
891                )
892 {
893   LOG("grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);
894   if (tmu == GR_TMU1 || nbTextureUnits <= 2)
895   {
896     if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
897     switch(s_clampmode)
898     {
899     case GR_TEXTURECLAMP_WRAP:
900       wrap_s0 = GL_REPEAT;
901       break;
902     case GR_TEXTURECLAMP_CLAMP:
903       wrap_s0 = GL_CLAMP_TO_EDGE;
904       break;
905     case GR_TEXTURECLAMP_MIRROR_EXT:
906       wrap_s0 = GL_MIRRORED_REPEAT;
907       break;
908     default:
909       display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
910     }
911     switch(t_clampmode)
912     {
913     case GR_TEXTURECLAMP_WRAP:
914       wrap_t0 = GL_REPEAT;
915       break;
916     case GR_TEXTURECLAMP_CLAMP:
917       wrap_t0 = GL_CLAMP_TO_EDGE;
918       break;
919     case GR_TEXTURECLAMP_MIRROR_EXT:
920       wrap_t0 = GL_MIRRORED_REPEAT;
921       break;
922     default:
923       display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
924     }
925     glActiveTexture(GL_TEXTURE0);
926     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
927     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
928   }
929   else
930   {
931     switch(s_clampmode)
932     {
933     case GR_TEXTURECLAMP_WRAP:
934       wrap_s1 = GL_REPEAT;
935       break;
936     case GR_TEXTURECLAMP_CLAMP:
937       wrap_s1 = GL_CLAMP_TO_EDGE;
938       break;
939     case GR_TEXTURECLAMP_MIRROR_EXT:
940       wrap_s1 = GL_MIRRORED_REPEAT;
941       break;
942     default:
943       display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
944     }
945     switch(t_clampmode)
946     {
947     case GR_TEXTURECLAMP_WRAP:
948       wrap_t1 = GL_REPEAT;
949       break;
950     case GR_TEXTURECLAMP_CLAMP:
951       wrap_t1 = GL_CLAMP_TO_EDGE;
952       break;
953     case GR_TEXTURECLAMP_MIRROR_EXT:
954       wrap_t1 = GL_MIRRORED_REPEAT;
955       break;
956     default:
957       display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
958     }
959     glActiveTexture(GL_TEXTURE1);
960     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
961     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
962   }
963 }