Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glitch64 / textures.cpp.sav
CommitLineData
98e75f2d 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
44int TMU_SIZE = 8*2048*2048;
45static unsigned char* texture = NULL;
46
47int packed_pixels_support = -1;
48int ati_sucks = -1;
49float largest_supported_anisotropy = 1.0f;
50
51#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
52#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
53#endif
54
55int tex0_width, tex0_height, tex1_width, tex1_height;
56float lambda;
57
58static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
59static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
60
61unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
62
63typedef struct _texlist
64{
65 unsigned int id;
66 struct _texlist *next;
67} texlist;
68
69static int nbTex = 0;
70static texlist *list = NULL;
71
72#ifdef _WIN32
73extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
74extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
75extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
76#endif
77void 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
115void 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
138void 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
149void 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
161FX_ENTRY FxU32 FX_CALL
162grTexMinAddress( 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
171FX_ENTRY FxU32 FX_CALL
172grTexMaxAddress( 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
181FX_ENTRY FxU32 FX_CALL
182grTexTextureMemRequired( 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
230FX_ENTRY FxU32 FX_CALL
231grTexCalcMemRequired(
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
280int 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
324int 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
411FX_ENTRY void FX_CALL
412grTexDownloadMipMap( 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
737int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
738
739FX_ENTRY void FX_CALL
740grTexSource( 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
820FX_ENTRY void FX_CALL
821grTexDetailControl(
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
845FX_ENTRY void FX_CALL
846grTexLodBiasValue(GrChipID_t tmu, float bias )
847{
848 LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
849}
850
851FX_ENTRY void FX_CALL
852grTexFilterMode(
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
886FX_ENTRY void FX_CALL
887grTexClampMode(
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}