2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
4 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
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
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.
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
30 #include "../Glide64/ticks.h"
32 /* Napalm extensions to GrTextureFormat_t */
33 #define GR_TEXFMT_ARGB_CMP_FXT1 0x11
34 #define GR_TEXFMT_ARGB_8888 0x12
35 #define GR_TEXFMT_YUYV_422 0x13
36 #define GR_TEXFMT_UYVY_422 0x14
37 #define GR_TEXFMT_AYUV_444 0x15
38 #define GR_TEXFMT_ARGB_CMP_DXT1 0x16
39 #define GR_TEXFMT_ARGB_CMP_DXT2 0x17
40 #define GR_TEXFMT_ARGB_CMP_DXT3 0x18
41 #define GR_TEXFMT_ARGB_CMP_DXT4 0x19
42 #define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
43 #define GR_TEXTFMT_RGB_888 0xFF
45 int TMU_SIZE = 8*2048*2048;
46 static unsigned char* texture = NULL;
48 int packed_pixels_support = -1;
50 float largest_supported_anisotropy = 1.0f;
52 #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
53 #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
56 int tex0_width, tex0_height, tex1_width, tex1_height;
59 static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
60 static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
62 unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
66 typedef struct _texbsp
70 struct _texbsp *right;
74 static texbsp *list = NULL;
75 #elif defined(TEXREDBLACK)
76 typedef struct _texbsp
81 struct _texbsp *right;
82 struct _texbsp *parent;
86 static texbsp *list = NULL;
88 typedef struct _texlist
91 struct _texlist *next;
95 static texlist *list = NULL;
99 extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
100 extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
101 extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
104 // utilitie function for red-black tree
105 // taken from Wikipedia
106 // http://en.wikipedia.org/wiki/Red-black_tree
109 //**** Family stuff ****
110 texbsp *grandparent(texbsp *n)
112 if ((n != NULL) && (n->parent != NULL))
113 return n->parent->parent;
117 texbsp *sibling(texbsp *n)
119 if ((n != NULL) && (n->parent != NULL))
120 if (n == n->parent->left)
121 return n->parent->right;
123 return n->parent->left;
127 texbsp *uncle(texbsp *n)
129 texbsp *g = grandparent(n);
131 return NULL; // No grandparent means no uncle
132 if (n->parent == g->left)
137 //**** Search functions ****
138 texbsp* lookup_node(GLuint key)
142 int comp_result = (int)key - (int)n->id;
143 if (comp_result == 0) {
145 } else if (comp_result < 0) {
153 GLuint rbtree_lookup(GLuint key)
155 texbsp* n = lookup_node(key);
156 return n == NULL ? NULL : n->id;
158 //**** Basic insertion / replace ****
159 texbsp* new_node(GLuint id, int node_color, texbsp* left, texbsp* right)
161 texbsp* result = malloc(sizeof(texbsp));
163 result->color = node_color;
165 result->right = right;
166 if (left != NULL) left->parent = result;
167 if (right != NULL) right->parent = result;
168 result->parent = NULL;
171 void replace_node(texbsp* oldn, texbsp* newn)
173 if (oldn->parent == NULL) {
176 if (oldn == oldn->parent->left)
177 oldn->parent->left = newn;
179 oldn->parent->right = newn;
182 newn->parent = oldn->parent;
185 //**** Rotation functions ****
186 void rotate_left(texbsp* n)
188 texbsp* r = n->right;
191 if (r->left != NULL) {
197 void rotate_right(texbsp* n)
202 if (L->right != NULL) {
203 L->right->parent = n;
208 //**** Insertion cases ****
209 void insert_case1(texbsp *n)
211 if (n->parent == NULL)
216 void insert_case2(texbsp *n)
218 if (n->parent->color == BLACK)
223 void insert_case3(texbsp *n)
225 texbsp *u = uncle(n), *g;
227 if ((u != NULL) && (u->color == RED)) {
228 n->parent->color = BLACK;
237 void insert_case4(texbsp *n)
239 texbsp *g = grandparent(n);
241 if ((n == n->parent->right) && (n->parent == g->left)) {
242 rotate_left(n->parent);
244 } else if ((n == n->parent->left) && (n->parent == g->right)) {
245 rotate_right(n->parent);
250 void insert_case5(texbsp *n)
252 struct node *g = grandparent(n);
254 n->parent->color = BLACK;
256 if (n == n->parent->left)
261 void rbtree_insert(GLuint key)
263 texbsp* inserted_node = new_node(key, RED, NULL, NULL);
265 list = inserted_node;
269 int comp_result = (int)key - (int)n->id;
270 if (comp_result == 0) {
271 free (inserted_node);
273 } else if (comp_result < 0) {
274 if (n->left == NULL) {
275 n->left = inserted_node;
281 if (n->right == NULL) {
282 n->right = inserted_node;
289 inserted_node->parent = n;
291 insert_case1(t, inserted_node);
293 //**** Removing cases ****
296 void remove_tex(unsigned int idmin, unsigned int idmax)
299 GLuint texlist[nbTex];
301 // 1st look at initial point that is <= at idmin and than go right until id > idmax. Deleting all in between, and reattach list is needed
303 bool reattach = false;
304 texbsp *debut, *fin, *temp;
306 if (list==NULL) return;
307 if ((idmin==0x00000000) && (idmax==0xffffffff)) {
308 // delete everything, quite easy
311 while ((debut) && (fin)) {
313 texlist[nbdel++]=debut->id;
319 texlist[nbdel++]=fin->id;
325 texlist[nbdel++]=list->id;
328 glDeleteTextures(nbdel, texlist);
332 // General case, range delete
333 // find starting point.
335 while ((debut->id > idmin) && (debut->right!=NULL)) {
336 debut = debut->right;
338 while ((debut->left!=NULL) && (debut->left->id < idmin)) {
343 while ((debut!=NULL) && (debut->id >= idmin) && (debut->id < idmax))
346 texlist[nbdel++]=debut->id;
351 if (fin) fin->left = debut;
352 if (debut) debut->right = fin;
353 if (debut) list = debut; else list = fin; //change ankor
354 glDeleteTextures(nbdel, texlist);
362 if (aux == NULL) return;
363 t = (unsigned int*)malloc(sz * sizeof(int));
364 while (aux && aux->id >= idmin && aux->id < idmax)
367 t = (unsigned int *) realloc(t, ++sz*sizeof(int));
374 while (aux != NULL && aux->next != NULL)
376 if (aux->next->id >= idmin && aux->next->id < idmax)
378 texlist *aux2 = aux->next->next;
380 t = (unsigned int *) realloc(t, ++sz*sizeof(int));
381 t[n++] = aux->next->id;
388 glDeleteTextures(n, t);
390 //printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
395 void add_tex(unsigned int id)
398 //printf("add_tex(%u)\n", id);
400 //printf("add root\n");
401 list = (texbsp*)malloc(sizeof(texbsp));
402 list->left = NULL; list->right = NULL;
408 if (bsp->id>=id) { // go left
409 // printf("Go left\n");
410 while ((bsp->left!=NULL) && (bsp->left->id > id))
414 if (bsp->id = id) return;
415 texbsp *aux = bsp->left;
416 texbsp *ins = (texbsp*)malloc(sizeof(texbsp));
421 if (aux) aux->right = ins;
423 list=bsp; // new ankor
426 //printf("Go right\n");
427 while ((bsp->right!=NULL) && (bsp->right->id < id))
432 //printf("stopped at %u\n", bsp->id);
433 if (bsp->id = id) return;
434 texbsp *aux = bsp->right;
435 texbsp *ins = (texbsp*)malloc(sizeof(texbsp));
440 if (aux) aux->left = ins;
442 list=bsp; // new ankor
448 //printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
449 if (list == NULL || id < list->id)
452 list = (texlist*)malloc(sizeof(texlist));
457 while (aux->next != NULL && aux->next->id < id) aux = aux->next;
458 // ZIGGY added this test so that add_tex now accept re-adding an existing texture
459 if (aux->next != NULL && aux->next->id == id) return;
462 aux->next = (texlist*)malloc(sizeof(texlist));
464 aux->next->next = aux2;
470 tex0_width = tex0_height = tex1_width = tex1_height = 2;
471 // ZIGGY because remove_tex isn't called (Pj64 doesn't like it), it's better
472 // to leave these so that they'll be reused (otherwise we have a memory leak)
476 if (!texture) texture = (unsigned char*)malloc(2048*2048*4);
482 // ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
483 remove_tex(0x00000000, 0xFFFFFFFF);
485 if (texture != NULL) {
491 FX_ENTRY FxU32 FX_CALL
492 grTexMinAddress( GrChipID_t tmu )
494 LOG("grTexMinAddress(%d)\r\n", tmu);
501 FX_ENTRY FxU32 FX_CALL
502 grTexMaxAddress( GrChipID_t tmu )
504 LOG("grTexMaxAddress(%d)\r\n", tmu);
506 return TMU_SIZE*2 - 1;
508 return tmu*TMU_SIZE + TMU_SIZE - 1;
511 FX_ENTRY FxU32 FX_CALL
512 grTexTextureMemRequired( FxU32 evenOdd,
516 LOG("grTextureMemRequired(%d)\r\n", evenOdd);
517 if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");
519 if (info->aspectRatioLog2 < 0)
521 height = 1 << info->largeLodLog2;
522 width = height >> -info->aspectRatioLog2;
526 width = 1 << info->largeLodLog2;
527 height = width >> info->aspectRatioLog2;
532 case GR_TEXFMT_ALPHA_8:
533 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
534 case GR_TEXFMT_ALPHA_INTENSITY_44:
537 case GR_TEXFMT_ARGB_1555:
538 case GR_TEXFMT_ARGB_4444:
539 case GR_TEXFMT_ALPHA_INTENSITY_88:
540 case GR_TEXFMT_RGB_565:
541 return (width*height)<<1;
543 case GR_TEXFMT_ARGB_8888:
544 return (width*height)<<2;
546 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
547 return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
548 case GR_TEXFMT_ARGB_CMP_DXT3:
549 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
550 case GR_TEXFMT_ARGB_CMP_DXT5:
551 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
552 case GR_TEXFMT_ARGB_CMP_FXT1:
553 return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
555 display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);
560 FX_ENTRY FxU32 FX_CALL
561 grTexCalcMemRequired(
562 GrLOD_t lodmin, GrLOD_t lodmax,
563 GrAspectRatio_t aspect, GrTextureFormat_t fmt)
566 LOG("grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);
567 if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");
571 height = 1 << lodmax;
572 width = height >> -aspect;
577 height = width >> aspect;
582 case GR_TEXFMT_ALPHA_8:
583 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
584 case GR_TEXFMT_ALPHA_INTENSITY_44:
587 case GR_TEXFMT_ARGB_1555:
588 case GR_TEXFMT_ARGB_4444:
589 case GR_TEXFMT_ALPHA_INTENSITY_88:
590 case GR_TEXFMT_RGB_565:
591 return (width*height)<<1;
593 case GR_TEXFMT_ARGB_8888:
594 return (width*height)<<2;
596 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
597 return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
598 case GR_TEXFMT_ARGB_CMP_DXT3:
599 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
600 case GR_TEXFMT_ARGB_CMP_DXT5:
601 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
602 case GR_TEXFMT_ARGB_CMP_FXT1:
603 return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
605 display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);
610 int grTexFormatSize(int fmt)
614 case GR_TEXFMT_ALPHA_8:
615 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
618 case GR_TEXFMT_ALPHA_INTENSITY_44:
621 case GR_TEXFMT_RGB_565:
624 case GR_TEXFMT_ARGB_1555:
627 case GR_TEXFMT_ALPHA_INTENSITY_88:
630 case GR_TEXFMT_ARGB_4444:
633 case GR_TEXFMT_ARGB_8888:
636 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
637 factor = 8; // HACKALERT: factor holds block bytes
639 case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
640 factor = 16; // HACKALERT: factor holds block bytes
642 case GR_TEXFMT_ARGB_CMP_DXT5:
645 case GR_TEXFMT_ARGB_CMP_FXT1:
649 display_warning("grTexFormatSize : unknown texture format: %x", fmt);
654 int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
658 *glpackfmt = GL_UNSIGNED_BYTE;
663 case GR_TEXFMT_ALPHA_8:
665 *gltexfmt = GL_INTENSITY8;
666 *glpixfmt = GL_LUMINANCE;
667 *glpackfmt = GL_UNSIGNED_BYTE;
669 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
671 *gltexfmt = GL_LUMINANCE8;
672 *glpixfmt = GL_LUMINANCE;
673 *glpackfmt = GL_UNSIGNED_BYTE;
675 case GR_TEXFMT_ALPHA_INTENSITY_44:
677 case GR_TEXFMT_RGB_565:
681 *glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
683 case GR_TEXFMT_ARGB_1555:
684 if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)
686 *gltexfmt = GL_RGB5_A1;
688 *glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
690 case GR_TEXFMT_ALPHA_INTENSITY_88:
692 *gltexfmt = GL_LUMINANCE8_ALPHA8;
693 *glpixfmt = GL_LUMINANCE_ALPHA;
694 *glpackfmt = GL_UNSIGNED_BYTE;
696 case GR_TEXFMT_ARGB_4444:
698 *gltexfmt = GL_RGBA4;
700 *glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
702 case GR_TEXFMT_ARGB_8888:
704 *gltexfmt = GL_RGBA8;
706 *glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
708 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
709 // HACKALERT: 3Dfx Glide uses GR_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.
710 // GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.
711 factor = 8; // HACKALERT: factor holds block bytes
712 *gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // these variables aren't used
713 *glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
714 *glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
716 case GR_TEXFMT_ARGB_CMP_DXT3:
718 *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
719 *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
720 *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
722 case GR_TEXFMT_ARGB_CMP_DXT5:
724 *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
725 *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
726 *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
728 case GR_TEXFMT_ARGB_CMP_FXT1:
730 *gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
731 *glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
732 *glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // XXX: what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?
735 display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);
741 FX_ENTRY void FX_CALL
742 grTexDownloadMipMap( GrChipID_t tmu,
747 int width, height, i, j;
750 int gltexfmt, glpixfmt, glpackfmt;
751 LOG("grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
752 if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");
754 if (info->aspectRatioLog2 < 0)
756 height = 1 << info->largeLodLog2;
757 width = height >> -info->aspectRatioLog2;
761 width = 1 << info->largeLodLog2;
762 height = width >> info->aspectRatioLog2;
765 if (!packed_pixels_support)
768 factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
772 // VP fixed the texture conversions to be more accurate, also swapped
773 // the for i/j loops so that is is less likely to break the memory cache
774 register int n = 0, m = 0;
777 case GR_TEXFMT_ALPHA_8:
778 for (i=0; i<height; i++)
780 for (j=0; j<width; j++)
782 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
783 texel |= (texel << 8);
784 texel |= (texel << 16);
785 ((unsigned int*)texture)[n] = texel;
793 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
794 for (i=0; i<height; i++)
796 for (j=0; j<width; j++)
798 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
799 texel |= (0xFF000000 | (texel << 16) | (texel << 8));
800 ((unsigned int*)texture)[n] = texel;
808 case GR_TEXFMT_ALPHA_INTENSITY_44:
810 for (i=0; i<height; i++)
812 for (j=0; j<width; j++)
814 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
816 /* accurate conversion */
817 unsigned int texel_hi = (texel & 0x000000F0) << 20;
818 unsigned int texel_low = texel & 0x0000000F;
819 texel_low |= (texel_low << 4);
820 texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);
822 unsigned int texel_hi = (texel & 0x000000F0) << 24;
823 unsigned int texel_low = (texel & 0x0000000F) << 4;
824 texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);
826 ((unsigned int*)texture)[n] = texel_hi;
832 glformat = GL_LUMINANCE_ALPHA;
835 case GR_TEXFMT_RGB_565:
836 for (i=0; i<height; i++)
838 for (j=0; j<width; j++)
840 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
841 unsigned int B = texel & 0x0000F800;
842 unsigned int G = texel & 0x000007E0;
843 unsigned int R = texel & 0x0000001F;
845 /* accurate conversion */
846 ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);
848 ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);
857 case GR_TEXFMT_ARGB_1555:
858 for (i=0; i<height; i++)
860 for (j=0; j<width; j++)
862 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
863 unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;
864 unsigned int B = texel & 0x00007C00;
865 unsigned int G = texel & 0x000003E0;
866 unsigned int R = texel & 0x0000001F;
868 /* accurate conversion */
869 ((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);
871 ((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);
880 case GR_TEXFMT_ALPHA_INTENSITY_88:
881 for (i=0; i<height; i++)
883 for (j=0; j<width; j++)
885 unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];
886 unsigned int I = (unsigned int)(AI & 0x000000FF);
887 ((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;
893 glformat = GL_LUMINANCE_ALPHA;
895 case GR_TEXFMT_ARGB_4444:
897 for (i=0; i<height; i++)
899 for (j=0; j<width; j++)
901 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
902 unsigned int A = texel & 0x0000F000;
903 unsigned int B = texel & 0x00000F00;
904 unsigned int G = texel & 0x000000F0;
905 unsigned int R = texel & 0x0000000F;
907 /* accurate conversion */
908 ((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);
910 ((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);
919 case GR_TEXFMT_ARGB_8888:
920 for (i=0; i<height; i++)
922 for (j=0; j<width; j++)
924 unsigned int texel = ((unsigned int*)info->data)[m];
925 unsigned int A = texel & 0xFF000000;
926 unsigned int B = texel & 0x00FF0000;
927 unsigned int G = texel & 0x0000FF00;
928 unsigned int R = texel & 0x000000FF;
929 ((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);
938 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
939 factor = 8; // HACKALERT: factor holds block bytes
940 glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
942 case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
943 factor = 16; // HACKALERT: factor holds block bytes
944 glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
946 case GR_TEXFMT_ARGB_CMP_DXT5:
948 glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
950 case GR_TEXFMT_ARGB_CMP_FXT1:
952 glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
956 display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);
961 if (nbTextureUnits <= 2)
962 glActiveTexture(GL_TEXTURE1);
964 glActiveTexture(GL_TEXTURE2);
968 case GR_TEXFMT_ARGB_CMP_DXT1:
969 case GR_TEXFMT_ARGB_CMP_DXT3:
970 case GR_TEXFMT_ARGB_CMP_DXT5:
971 case GR_TEXFMT_ARGB_CMP_FXT1:
972 remove_tex(startAddress+1, startAddress+1+((width*height*factor)>>4));
975 remove_tex(startAddress+1, startAddress+1+(width*height*factor));
978 add_tex(startAddress+1);
979 glBindTexture(GL_TEXTURE_2D, startAddress+1);
981 if (largest_supported_anisotropy > 1.0f)
982 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
984 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
988 case GR_TEXFMT_ARGB_CMP_DXT1:
989 case GR_TEXFMT_ARGB_CMP_DXT3:
990 case GR_TEXFMT_ARGB_CMP_DXT5:
991 case GR_TEXFMT_ARGB_CMP_FXT1:
992 glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor)>>4, info->data);
996 glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
998 glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
1002 glBindTexture(GL_TEXTURE_2D, default_texture);
1005 int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
1007 FX_ENTRY void FX_CALL
1008 grTexSource( GrChipID_t tmu,
1013 LOG("grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
1015 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
1017 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
1018 glActiveTexture(GL_TEXTURE0);
1020 if (info->aspectRatioLog2 < 0)
1023 tex0_width = tex0_height >> -info->aspectRatioLog2;
1028 tex0_height = tex0_width >> info->aspectRatioLog2;
1031 glBindTexture(GL_TEXTURE_2D, startAddress+1);
1033 dump_tex(startAddress+1);
1035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
1036 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
1037 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
1038 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
1042 glActiveTexture(GL_TEXTURE1);
1044 if (info->aspectRatioLog2 < 0)
1047 tex1_width = tex1_height >> -info->aspectRatioLog2;
1052 tex1_height = tex1_width >> info->aspectRatioLog2;
1055 glBindTexture(GL_TEXTURE_2D, startAddress+1);
1057 dump_tex(startAddress+1);
1059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
1060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
1061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
1062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
1064 if(!CheckTextureBufferFormat(tmu, startAddress+1, info))
1066 if(tmu == 0 && blackandwhite1 != 0)
1069 need_to_compile = 1;
1071 if(tmu == 1 && blackandwhite0 != 0)
1074 need_to_compile = 1;
1079 extern int auxbuffer;
1080 static int oldbuffer;
1081 FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
1082 if (auxbuffer == GR_BUFFER_AUXBUFFER && auxbuffer != oldbuffer)
1083 grAuxBufferExt(auxbuffer);
1084 oldbuffer = auxbuffer;
1088 FX_ENTRY void FX_CALL
1096 LOG("grTexDetailControl(%d,%d,%d,%d)\r\n", tmu, lod_bias, detail_scale, detail_max);
1097 if (lod_bias != 31 && detail_scale != 7)
1099 if (!lod_bias && !detail_scale && !detail_max) return;
1101 display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);
1103 lambda = detail_max;
1106 lambda = 1.0f - (255.0f - lambda);
1108 if(lambda > 1.0f) display_warning("lambda:%f", lambda);
1113 FX_ENTRY void FX_CALL
1114 grTexLodBiasValue(GrChipID_t tmu, float bias )
1116 LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
1119 FX_ENTRY void FX_CALL
1122 GrTextureFilterMode_t minfilter_mode,
1123 GrTextureFilterMode_t magfilter_mode
1126 LOG("grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);
1127 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
1129 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
1130 if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
1131 else min_filter0 = GL_LINEAR;
1133 if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
1134 else mag_filter0 = GL_LINEAR;
1136 glActiveTexture(GL_TEXTURE0);
1137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
1138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
1142 if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
1143 else min_filter1 = GL_LINEAR;
1145 if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
1146 else mag_filter1 = GL_LINEAR;
1148 glActiveTexture(GL_TEXTURE1);
1149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
1150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
1154 FX_ENTRY void FX_CALL
1157 GrTextureClampMode_t s_clampmode,
1158 GrTextureClampMode_t t_clampmode
1161 LOG("grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);
1162 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
1164 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
1167 case GR_TEXTURECLAMP_WRAP:
1168 wrap_s0 = GL_REPEAT;
1170 case GR_TEXTURECLAMP_CLAMP:
1171 wrap_s0 = GL_CLAMP_TO_EDGE;
1173 case GR_TEXTURECLAMP_MIRROR_EXT:
1174 wrap_s0 = GL_MIRRORED_REPEAT;
1177 display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
1181 case GR_TEXTURECLAMP_WRAP:
1182 wrap_t0 = GL_REPEAT;
1184 case GR_TEXTURECLAMP_CLAMP:
1185 wrap_t0 = GL_CLAMP_TO_EDGE;
1187 case GR_TEXTURECLAMP_MIRROR_EXT:
1188 wrap_t0 = GL_MIRRORED_REPEAT;
1191 display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
1193 glActiveTexture(GL_TEXTURE0);
1194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
1195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
1201 case GR_TEXTURECLAMP_WRAP:
1202 wrap_s1 = GL_REPEAT;
1204 case GR_TEXTURECLAMP_CLAMP:
1205 wrap_s1 = GL_CLAMP_TO_EDGE;
1207 case GR_TEXTURECLAMP_MIRROR_EXT:
1208 wrap_s1 = GL_MIRRORED_REPEAT;
1211 display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
1215 case GR_TEXTURECLAMP_WRAP:
1216 wrap_t1 = GL_REPEAT;
1218 case GR_TEXTURECLAMP_CLAMP:
1219 wrap_t1 = GL_CLAMP_TO_EDGE;
1221 case GR_TEXTURECLAMP_MIRROR_EXT:
1222 wrap_t1 = GL_MIRRORED_REPEAT;
1225 display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
1227 glActiveTexture(GL_TEXTURE1);
1228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
1229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);