ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glitch64 / combiner.cpp
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 <string.h>
25 #include <stdlib.h>
26 #endif // _WIN32
27 #include <math.h>
28 #include <stdio.h>
29 #include "glide.h"
30 #include "main.h"
31
32 #define GLchar  char
33
34 void vbo_draw();
35
36 static int fct[4], source0[4], operand0[4], source1[4], operand1[4], source2[4], operand2[4];
37 static int fcta[4],sourcea0[4],operanda0[4],sourcea1[4],operanda1[4],sourcea2[4],operanda2[4];
38 static int alpha_ref, alpha_func;
39 bool alpha_test = 0;
40
41 float texture_env_color[4];
42 float ccolor0[4];
43 float ccolor1[4];
44 static float chroma_color[4];
45 int fog_enabled;
46 static int chroma_enabled;
47 static int chroma_other_color;
48 static int chroma_other_alpha;
49 static int dither_enabled;
50 int blackandwhite0;
51 int blackandwhite1;
52
53 float fogStart,fogEnd;
54 float fogColor[4];
55
56 #ifdef _WIN32
57 static float farF;
58 static float nearF;
59 #endif // _WIN32
60
61 int need_lambda[2];
62 float lambda_color[2][4];
63
64 // shaders variables
65 int need_to_compile;
66
67 static GLuint fragment_shader_object;
68 static GLuint fragment_depth_shader_object;
69 static GLuint vertex_shader_object;
70 static GLuint program_object_default;
71 static GLuint program_object_depth;
72 static GLuint program_object;
73 static int constant_color_location;
74 static int ccolor0_location;
75 static int ccolor1_location;
76 static int first_color = 1;
77 static int first_alpha = 1;
78 static int first_texture0 = 1;
79 static int first_texture1 = 1;
80 static int tex0_combiner_ext = 0;
81 static int tex1_combiner_ext = 0;
82 static int c_combiner_ext = 0;
83 static int a_combiner_ext = 0;
84
85 #define GLSL_VERSION "100"
86
87 #define SHADER_HEADER \
88 "#version " GLSL_VERSION "          \n" \
89 "#define gl_Color vFrontColor       \n" \
90 "#define gl_FrontColor vFrontColor  \n" \
91 "#define gl_TexCoord vTexCoord      \n"
92
93 #define SHADER_VARYING \
94 "varying highp vec4 gl_FrontColor;  \n" \
95 "varying highp vec4 gl_TexCoord[4]; \n"
96
97 static const char* fragment_shader_header =
98 SHADER_HEADER
99 "precision lowp float;             \n"
100 "uniform sampler2D texture0;       \n"
101 "uniform sampler2D texture1;       \n"
102 "uniform sampler2D ditherTex;      \n"
103 "uniform vec4 constant_color;      \n"
104 "uniform vec4 ccolor0;             \n"
105 "uniform vec4 ccolor1;             \n"
106 "uniform vec4 chroma_color;        \n"
107 "uniform float lambda;             \n"
108 "uniform vec3 fogColor;            \n"
109 "uniform float alphaRef;           \n"
110 SHADER_VARYING
111 "                                  \n"
112 "void test_chroma(vec4 ctexture1); \n"
113 "                                  \n"
114 "                                  \n"
115 "void main()                       \n"
116 "{                                 \n"
117 ;
118
119 // using gl_FragCoord is terribly slow on ATI and varying variables don't work for some unknown
120 // reason, so we use the unused components of the texture2 coordinates
121 static const char* fragment_shader_dither =
122 " \n"
123 /*"  float dithx = (gl_TexCoord[2].b + 1.0)*0.5*1000.0; \n"
124 "  float dithy = (gl_TexCoord[2].a + 1.0)*0.5*1000.0; \n"
125 "  if(texture2D(ditherTex, vec2((dithx-32.0*floor(dithx/32.0))/32.0, \n"
126 "                               (dithy-32.0*floor(dithy/32.0))/32.0)).a > 0.5) discard; \n"*/
127 ;
128
129 static const char* fragment_shader_default =
130 "  gl_FragColor = texture2D(texture0, vec2(gl_TexCoord[0])); \n"
131 ;
132
133 static const char* fragment_shader_readtex0color =
134 "  vec4 readtex0 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"
135 ;
136
137 static const char* fragment_shader_readtex0bw =
138 "  vec4 readtex0 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"
139 "  readtex0 = vec4(vec3(readtex0.b),                          \n"
140 "                  readtex0.r + readtex0.g * 8.0 / 256.0);    \n"
141 ;
142 static const char* fragment_shader_readtex0bw_2 =
143 "  vec4 readtex0 = vec4(dot(texture2D(texture0, vec2(gl_TexCoord[0])), vec4(1.0/3, 1.0/3, 1.0/3, 0)));                        \n"
144 ;
145
146 static const char* fragment_shader_readtex1color =
147 "  vec4 readtex1 = texture2D(texture1, vec2(gl_TexCoord[1])); \n"
148 ;
149
150 static const char* fragment_shader_readtex1bw =
151 "  vec4 readtex1 = texture2D(texture1, vec2(gl_TexCoord[1])); \n"
152 "  readtex1 = vec4(vec3(readtex1.b),                          \n"
153 "                  readtex1.r + readtex1.g * 8.0 / 256.0);    \n"
154 ;
155 static const char* fragment_shader_readtex1bw_2 =
156 "  vec4 readtex1 = vec4(dot(texture2D(texture1, vec2(gl_TexCoord[1])), vec4(1.0/3, 1.0/3, 1.0/3, 0)));                        \n"
157 ;
158
159 static const char* fragment_shader_fog =
160 "  float fog;                                                                         \n"
161 "  fog = gl_TexCoord[0].b;                                                            \n"
162 "  gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fog); \n"
163 ;
164
165 static const char* fragment_shader_end =
166 "if(gl_FragColor.a <= alphaRef) {discard;}   \n"
167 "                                \n"
168 "}                               \n"
169 ;
170
171 static const char* fragment_shader_alt_end =
172 "                                \n"
173 "}                               \n"
174 ;
175
176 static const char* vertex_shader =
177 SHADER_HEADER
178 "#define Z_MAX 65536.0                                          \n"
179 "attribute highp vec4 aVertex;                                  \n"
180 "attribute mediump vec4 aColor;                                   \n"   //*SEB* highp -> mediump
181 "attribute highp vec4 aMultiTexCoord0;                          \n"
182 "attribute highp vec4 aMultiTexCoord1;                          \n"
183 "attribute float aFog;                                          \n"
184 "uniform vec3 vertexOffset;                                     \n" //Moved some calculations from grDrawXXX to shader
185 "uniform vec4 textureSizes;                                     \n" 
186 "uniform vec3 fogModeEndScale;                                  \n" //0 = Mode, 1 = gl_Fog.end, 2 = gl_Fog.scale
187 SHADER_VARYING
188 "                                                               \n"
189 "void main()                                                    \n"
190 "{                                                              \n"
191 "  float q = aVertex.w;                                                     \n"
192 "  float invertY = vertexOffset.z;                                          \n" //Usually 1.0 but -1.0 when rendering to a texture (see inverted_culling grRenderBuffer)
193 "  gl_Position.x = (aVertex.x - vertexOffset.x) / vertexOffset.x;           \n"
194 "  gl_Position.y = invertY *-(aVertex.y - vertexOffset.y) / vertexOffset.y; \n"
195 "  gl_Position.z = aVertex.z / Z_MAX;                                       \n"
196 "  gl_Position.w = 1.0;                                                     \n"
197 "  gl_Position /= q;                                                        \n"
198 "  gl_FrontColor = aColor.bgra;                                             \n"
199 "                                                                           \n"
200 "  gl_TexCoord[0] = vec4(aMultiTexCoord0.xy / q / textureSizes.xy,0,1);     \n"
201 "  gl_TexCoord[1] = vec4(aMultiTexCoord1.xy / q / textureSizes.zw,0,1);     \n"
202 "                                                                           \n"
203 "  float fogV = (1.0 / mix(q,aFog,fogModeEndScale[0])) / 255.0;             \n"
204 "  //if(fogMode == 2) {                                                     \n"
205 "  //  fogV = 1.0 / aFog / 255                                              \n"
206 "  //}                                                                      \n"
207 "                                                                           \n"
208 "  float f = (fogModeEndScale[1] - fogV) * fogModeEndScale[2];              \n"
209 "  f = clamp(f, 0.0, 1.0);                                                  \n"
210 "  gl_TexCoord[0].b = f;                                                    \n"
211 "  gl_TexCoord[2].b = aVertex.x;                                            \n" 
212 "  gl_TexCoord[2].a = aVertex.y;                                            \n" 
213 "}                                                                          \n" 
214 ;
215
216 static char fragment_shader_color_combiner[1024];
217 static char fragment_shader_alpha_combiner[1024];
218 static char fragment_shader_texture1[1024];
219 static char fragment_shader_texture0[1024];
220 static char fragment_shader_chroma[1024];
221 static char shader_log[2048];
222
223 void check_compile(GLuint shader)
224 {
225   GLint success;
226   glGetShaderiv(shader,GL_COMPILE_STATUS,&success);
227   if(!success)
228   {
229     char log[1024];
230     glGetShaderInfoLog(shader,1024,NULL,log);
231     LOGINFO(log);
232   }
233 }
234
235 void check_link(GLuint program)
236 {
237   GLint success;
238   glGetProgramiv(program,GL_LINK_STATUS,&success);
239   if(!success)
240   {
241     char log[1024];
242     glGetProgramInfoLog(program,1024,NULL,log);
243     LOGINFO(log);
244   }
245 }
246
247 void init_combiner()
248 {
249   int texture[4] = {0, 0, 0, 0};
250
251   glActiveTexture(GL_TEXTURE0);
252   glEnable(GL_TEXTURE_2D);
253
254   // creating a fake texture
255   glBindTexture(GL_TEXTURE_2D, default_texture);
256   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
257   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
258   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
259
260   glActiveTexture(GL_TEXTURE1);
261   glBindTexture(GL_TEXTURE_2D, default_texture);
262   glEnable(GL_TEXTURE_2D);
263
264   int texture0_location;
265   int texture1_location;
266   char *fragment_shader;
267   int log_length;
268
269 //#ifndef ANDROID
270 #if 0
271 //      unfortunatly, Pandora has not the gl_FragDepthEXT extension... So I disable this block.
272   // depth shader
273   fragment_depth_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
274
275   char s[512];
276   // ZIGGY convert a 565 texture into depth component
277   sprintf(s, "gl_FragDepthEXT = dot(texture2D(texture0, vec2(gl_TexCoord[0])), vec4(31*64*32, 63*32, 31, 0))*%g + %g; \n", zscale/2/65535.0, 1-zscale/2);
278   fragment_shader = (char*)malloc(strlen(fragment_shader_header)+
279     strlen(s)+
280     strlen(fragment_shader_end)+1);
281   strcpy(fragment_shader, fragment_shader_header);
282   strcat(fragment_shader, s);
283   strcat(fragment_shader, fragment_shader_end);
284   glShaderSource(fragment_depth_shader_object, 1, (const GLchar**)&fragment_shader, NULL);
285   free(fragment_shader);
286
287   glCompileShader(fragment_depth_shader_object);
288   check_compile(fragment_depth_shader_object);
289 #endif
290
291   // default shader
292   fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
293
294   fragment_shader = (char*)malloc(strlen(fragment_shader_header)+
295     strlen(fragment_shader_default)+
296     strlen(fragment_shader_alt_end)+1);
297   strcpy(fragment_shader, fragment_shader_header);
298   strcat(fragment_shader, fragment_shader_default);
299   strcat(fragment_shader, fragment_shader_alt_end);     /*SEB*/
300   glShaderSource(fragment_shader_object, 1, (const GLchar**)&fragment_shader, NULL);
301   free(fragment_shader);
302
303   glCompileShader(fragment_shader_object);
304   check_compile(fragment_shader_object);
305
306   vertex_shader_object = glCreateShader(GL_VERTEX_SHADER);
307   glShaderSource(vertex_shader_object, 1, &vertex_shader, NULL);
308   glCompileShader(vertex_shader_object);
309   check_compile(vertex_shader_object);
310
311   // depth program
312   program_object = glCreateProgram();
313   program_object_depth = program_object;
314   glAttachShader(program_object, fragment_depth_shader_object);
315   glAttachShader(program_object, vertex_shader_object);
316
317   glBindAttribLocation(program_object,POSITION_ATTR,"aPosition");
318   glBindAttribLocation(program_object,COLOUR_ATTR,"aColor");
319   glBindAttribLocation(program_object,TEXCOORD_0_ATTR,"aMultiTexCoord0");
320   glBindAttribLocation(program_object,TEXCOORD_1_ATTR,"aMultiTexCoord1");
321   glBindAttribLocation(program_object,FOG_ATTR,"aFog");
322
323   glLinkProgram(program_object);
324   check_link(program_object);
325   glUseProgram(program_object);
326
327   texture0_location = glGetUniformLocation(program_object, "texture0");
328   texture1_location = glGetUniformLocation(program_object, "texture1");
329   glUniform1i(texture0_location, 0);
330   glUniform1i(texture1_location, 1);
331
332   // default program
333   program_object = glCreateProgram();
334   program_object_default = program_object;
335   glAttachShader(program_object, fragment_shader_object);
336   glAttachShader(program_object, vertex_shader_object);
337
338   glBindAttribLocation(program_object,POSITION_ATTR,"aPosition");
339   glBindAttribLocation(program_object,COLOUR_ATTR,"aColor");
340   glBindAttribLocation(program_object,TEXCOORD_0_ATTR,"aMultiTexCoord0");
341   glBindAttribLocation(program_object,TEXCOORD_1_ATTR,"aMultiTexCoord1");
342   glBindAttribLocation(program_object,FOG_ATTR,"aFog");
343
344   glLinkProgram(program_object);
345   check_link(program_object);
346   glUseProgram(program_object);
347
348   texture0_location = glGetUniformLocation(program_object, "texture0");
349   texture1_location = glGetUniformLocation(program_object, "texture1");
350   glUniform1i(texture0_location, 0);
351   glUniform1i(texture1_location, 1);
352
353   strcpy(fragment_shader_color_combiner, "");
354   strcpy(fragment_shader_alpha_combiner, "");
355   strcpy(fragment_shader_texture1, "vec4 ctexture1 = texture2D(texture0, vec2(gl_TexCoord[0])); \n");
356   strcpy(fragment_shader_texture0, "");
357
358   first_color = 1;
359   first_alpha = 1;
360   first_texture0 = 1;
361   first_texture1 = 1;
362   need_to_compile = 0;
363   fog_enabled = 0;
364   chroma_enabled = 0;
365   dither_enabled = 0;
366   blackandwhite0 = 0;
367   blackandwhite1 = 0;
368 }
369
370 void compile_chroma_shader()
371 {
372   strcpy(fragment_shader_chroma, "\nvoid test_chroma(vec4 ctexture1)\n{\n");
373
374   switch(chroma_other_alpha)
375   {
376   case GR_COMBINE_OTHER_ITERATED:
377     strcat(fragment_shader_chroma, "float alpha = gl_Color.a; \n");
378     break;
379   case GR_COMBINE_OTHER_TEXTURE:
380     strcat(fragment_shader_chroma, "float alpha = ctexture1.a; \n");
381     break;
382   case GR_COMBINE_OTHER_CONSTANT:
383     strcat(fragment_shader_chroma, "float alpha = constant_color.a; \n");
384     break;
385   default:
386     display_warning("unknown compile_choma_shader_alpha : %x", chroma_other_alpha);
387   }
388
389   switch(chroma_other_color)
390   {
391   case GR_COMBINE_OTHER_ITERATED:
392     strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(gl_Color),alpha); \n");
393     break;
394   case GR_COMBINE_OTHER_TEXTURE:
395     strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(ctexture1),alpha); \n");
396     break;
397   case GR_COMBINE_OTHER_CONSTANT:
398     strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(constant_color),alpha); \n");
399     break;
400   default:
401     display_warning("unknown compile_choma_shader_alpha : %x", chroma_other_color);
402   }
403
404   strcat(fragment_shader_chroma, "if (color.rgb == chroma_color.rgb) discard; \n");
405   strcat(fragment_shader_chroma, "}");
406 }
407
408 typedef struct _shader_program_key
409 {
410   int color_combiner;
411   int alpha_combiner;
412   int texture0_combiner;
413   int texture1_combiner;
414   int texture0_combinera;
415   int texture1_combinera;
416   int fog_enabled;
417   int chroma_enabled;
418   int dither_enabled;
419   int blackandwhite0;
420   int blackandwhite1;
421   int alpha_test;                       //*SEB*
422   GLuint fragment_shader_object;
423   GLuint program_object;
424   int texture0_location;
425   int texture1_location;
426   int vertexOffset_location;
427   int textureSizes_location;
428   int fogModeEndScale_location;
429   int fogColor_location;
430   int alphaRef_location;
431   int ditherTex_location;
432   int chroma_color_location;
433 } shader_program_key;
434
435 static shader_program_key* shader_programs = NULL;
436 static int number_of_programs = 0;
437 static int color_combiner_key;
438 static int alpha_combiner_key;
439 static int texture0_combiner_key;
440 static int texture1_combiner_key;
441 static int texture0_combinera_key;
442 static int texture1_combinera_key;
443
444 void update_uniforms(shader_program_key prog)
445 {
446   glUniform1i(prog.texture0_location, 0);
447   glUniform1i(prog.texture1_location, 1);
448
449   glUniform3f(prog.vertexOffset_location,widtho,heighto,inverted_culling ? -1.0f : 1.0f);
450   glUniform4f(prog.textureSizes_location,tex0_width,tex0_height,tex1_width,tex1_height);
451
452   glUniform3f(prog.fogModeEndScale_location,
453     fog_enabled != 2 ? 0.0f : 1.0f,
454     fogEnd,
455     1.0f / (fogEnd - fogStart)
456     );
457
458   if(prog.fogColor_location != -1)
459   {
460     glUniform3f(prog.fogColor_location,fogColor[0],fogColor[1],fogColor[2]);
461   }
462
463   glUniform1f(prog.alphaRef_location,alpha_test ? alpha_ref/255.0f : -1.0f);
464
465   constant_color_location = glGetUniformLocation(program_object, "constant_color");
466   glUniform4f(constant_color_location, texture_env_color[0], texture_env_color[1],
467     texture_env_color[2], texture_env_color[3]);
468
469   ccolor0_location = glGetUniformLocation(program_object, "ccolor0");
470   glUniform4f(ccolor0_location, ccolor0[0], ccolor0[1], ccolor0[2], ccolor0[3]);
471
472   ccolor1_location = glGetUniformLocation(program_object, "ccolor1");
473   glUniform4f(ccolor1_location, ccolor1[0], ccolor1[1], ccolor1[2], ccolor1[3]);
474
475   glUniform4f(prog.chroma_color_location, chroma_color[0], chroma_color[1],
476     chroma_color[2], chroma_color[3]);
477
478   if(dither_enabled)
479   {
480     glUniform1i(prog.ditherTex_location, 2);
481   }
482
483   set_lambda();
484 }
485
486 void disable_textureSizes() 
487 {
488   int textureSizes_location = glGetUniformLocation(program_object_default,"textureSizes");
489   glUniform4f(textureSizes_location,1,1,1,1);
490 }
491
492 void compile_shader()
493 {
494   int texture0_location;
495   int texture1_location;
496   int ditherTex_location;
497   int vertexOffset_location;
498   int textureSizes_location;
499   char *fragment_shader;
500   int i;
501   int chroma_color_location;
502   int log_length;
503   
504   int noalpha;
505
506   need_to_compile = 0;
507
508   for(i=0; i<number_of_programs; i++)
509   {
510     shader_program_key prog = shader_programs[i];
511     if(prog.color_combiner == color_combiner_key &&
512       prog.alpha_combiner == alpha_combiner_key &&
513       prog.texture0_combiner == texture0_combiner_key &&
514       prog.texture1_combiner == texture1_combiner_key &&
515       prog.texture0_combinera == texture0_combinera_key &&
516       prog.texture1_combinera == texture1_combinera_key &&
517       prog.fog_enabled == fog_enabled &&
518           prog.alpha_test == alpha_test &&                              //*SEB*
519       prog.chroma_enabled == chroma_enabled &&
520       prog.dither_enabled == dither_enabled &&
521       prog.blackandwhite0 == blackandwhite0 &&
522       prog.blackandwhite1 == blackandwhite1)
523     {
524       program_object = shader_programs[i].program_object;
525       glUseProgram(program_object);
526       update_uniforms(prog);
527       return;
528     }
529   }
530
531   if(shader_programs != NULL) {
532         if ((number_of_programs+1)>1024)
533                 shader_programs = (shader_program_key*)realloc(shader_programs, (number_of_programs+1)*sizeof(shader_program_key));
534   }
535   else
536     shader_programs = (shader_program_key*)malloc(sizeof(shader_program_key)*1024);
537         //printf("number of shaders %d\n", number_of_programs);
538
539   shader_programs[number_of_programs].color_combiner = color_combiner_key;
540   shader_programs[number_of_programs].alpha_combiner = alpha_combiner_key;
541   shader_programs[number_of_programs].texture0_combiner = texture0_combiner_key;
542   shader_programs[number_of_programs].texture1_combiner = texture1_combiner_key;
543   shader_programs[number_of_programs].texture0_combinera = texture0_combinera_key;
544   shader_programs[number_of_programs].texture1_combinera = texture1_combinera_key;
545   shader_programs[number_of_programs].fog_enabled = fog_enabled;
546   shader_programs[number_of_programs].chroma_enabled = chroma_enabled;
547   shader_programs[number_of_programs].dither_enabled = dither_enabled;
548   shader_programs[number_of_programs].blackandwhite0 = blackandwhite0;
549   shader_programs[number_of_programs].blackandwhite1 = blackandwhite1;
550   shader_programs[number_of_programs].alpha_test = alpha_test;          //*SEB*
551
552   if(chroma_enabled)
553   {
554     strcat(fragment_shader_texture1, "test_chroma(ctexture1); \n");
555     compile_chroma_shader();
556   }
557
558   fragment_shader = (char*)malloc(4096);
559
560   strcpy(fragment_shader, fragment_shader_header);
561   if(dither_enabled) strcat(fragment_shader, fragment_shader_dither);
562   switch (blackandwhite0) {
563     case 1: strcat(fragment_shader, fragment_shader_readtex0bw); break;
564     case 2: strcat(fragment_shader, fragment_shader_readtex0bw_2); break;
565     default: strcat(fragment_shader, fragment_shader_readtex0color);
566   }
567   switch (blackandwhite1) {
568     case 1: strcat(fragment_shader, fragment_shader_readtex1bw); break;
569     case 2: strcat(fragment_shader, fragment_shader_readtex1bw_2); break;
570     default: strcat(fragment_shader, fragment_shader_readtex1color);
571   }
572   strcat(fragment_shader, fragment_shader_texture0);
573   strcat(fragment_shader, fragment_shader_texture1);
574   strcat(fragment_shader, fragment_shader_color_combiner);
575   strcat(fragment_shader, fragment_shader_alpha_combiner);
576   if(fog_enabled) strcat(fragment_shader, fragment_shader_fog);
577   if (alpha_test)
578                 strcat(fragment_shader, fragment_shader_end);
579   else
580                 strcat(fragment_shader, fragment_shader_alt_end);               //*SEB*
581   if(chroma_enabled) strcat(fragment_shader, fragment_shader_chroma);
582
583   shader_programs[number_of_programs].fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
584   glShaderSource(shader_programs[number_of_programs].fragment_shader_object, 1, (const GLchar**)&fragment_shader, NULL);
585
586   glCompileShader(shader_programs[number_of_programs].fragment_shader_object);
587   check_compile(shader_programs[number_of_programs].fragment_shader_object);
588
589   program_object = glCreateProgram();
590   shader_programs[number_of_programs].program_object = program_object;
591
592   glBindAttribLocation(program_object,POSITION_ATTR,"aPosition");
593   glBindAttribLocation(program_object,COLOUR_ATTR,"aColor");
594   glBindAttribLocation(program_object,TEXCOORD_0_ATTR,"aMultiTexCoord0");
595   glBindAttribLocation(program_object,TEXCOORD_1_ATTR,"aMultiTexCoord1");
596   glBindAttribLocation(program_object,FOG_ATTR,"aFog");
597
598   glAttachShader(program_object, shader_programs[number_of_programs].fragment_shader_object);
599   glAttachShader(program_object, vertex_shader_object);
600
601   glLinkProgram(program_object);
602   check_link(program_object);
603   glUseProgram(program_object);
604
605
606   shader_programs[number_of_programs].texture0_location = glGetUniformLocation(program_object, "texture0");
607   shader_programs[number_of_programs].texture1_location = glGetUniformLocation(program_object, "texture1");
608   shader_programs[number_of_programs].vertexOffset_location = glGetUniformLocation(program_object, "vertexOffset");
609   shader_programs[number_of_programs].textureSizes_location = glGetUniformLocation(program_object, "textureSizes");
610   shader_programs[number_of_programs].fogModeEndScale_location = glGetUniformLocation(program_object, "fogModeEndScale");
611   shader_programs[number_of_programs].fogColor_location = glGetUniformLocation(program_object, "fogColor");
612   shader_programs[number_of_programs].alphaRef_location = glGetUniformLocation(program_object, "alphaRef");
613
614   update_uniforms(shader_programs[number_of_programs]);
615
616   number_of_programs++;
617 }
618
619 void free_combiners()
620 {
621   free(shader_programs);
622   shader_programs = NULL;
623   number_of_programs = 0;
624 }
625
626 void set_copy_shader()
627 {
628   int texture0_location;
629   int alphaRef_location;
630
631   glUseProgram(program_object_default);
632   texture0_location = glGetUniformLocation(program_object_default, "texture0");
633   glUniform1i(texture0_location, 0);
634
635   alphaRef_location = glGetUniformLocation(program_object_default, "alphaRef");
636   if(alphaRef_location != -1)
637       glUniform1f(alphaRef_location,alpha_test ? alpha_ref/255.0f : -1.0f);
638 }
639
640 void set_depth_shader()
641 {
642   int texture0_location;
643   int alphaRef_location;
644
645   glUseProgram(program_object_depth);
646   texture0_location = glGetUniformLocation(program_object_depth, "texture0");
647   glUniform1i(texture0_location, 0);
648
649   alphaRef_location = glGetUniformLocation(program_object_depth, "alphaRef");
650   if(alphaRef_location != -1)
651       glUniform1f(alphaRef_location,alpha_test ? alpha_ref/255.0f : -1.0f);
652 }
653
654 void set_lambda()
655 {
656   int lambda_location = glGetUniformLocation(program_object, "lambda");
657   glUniform1f(lambda_location, lambda);
658 }
659
660 FX_ENTRY void FX_CALL 
661 grConstantColorValue( GrColor_t value )
662 {
663   LOG("grConstantColorValue(%d)\r\n", value);
664   switch(lfb_color_fmt)
665   {
666   case GR_COLORFORMAT_ARGB:
667     texture_env_color[3] = ((value >> 24) & 0xFF) / 255.0f;
668     texture_env_color[0] = ((value >> 16) & 0xFF) / 255.0f;
669     texture_env_color[1] = ((value >>  8) & 0xFF) / 255.0f;
670     texture_env_color[2] = (value & 0xFF) / 255.0f;
671     break;
672   case GR_COLORFORMAT_RGBA:
673     texture_env_color[0] = ((value >> 24) & 0xFF) / 255.0f;
674     texture_env_color[1] = ((value >> 16) & 0xFF) / 255.0f;
675     texture_env_color[2] = ((value >>  8) & 0xFF) / 255.0f;
676     texture_env_color[3] = (value & 0xFF) / 255.0f;
677     break;
678   default:
679     display_warning("grConstantColorValue: unknown color format : %x", lfb_color_fmt);
680   }
681
682   vbo_draw();
683
684   constant_color_location = glGetUniformLocation(program_object, "constant_color");
685   glUniform4f(constant_color_location, texture_env_color[0], texture_env_color[1], 
686     texture_env_color[2], texture_env_color[3]);
687 }
688
689 void writeGLSLColorOther(int other)
690 {
691   switch(other)
692   {
693   case GR_COMBINE_OTHER_ITERATED:
694     strcat(fragment_shader_color_combiner, "vec4 color_other = gl_Color; \n");
695     break;
696   case GR_COMBINE_OTHER_TEXTURE:
697     strcat(fragment_shader_color_combiner, "vec4 color_other = ctexture1; \n");
698     break;
699   case GR_COMBINE_OTHER_CONSTANT:
700     strcat(fragment_shader_color_combiner, "vec4 color_other = constant_color; \n");
701     break;
702   default:
703     display_warning("unknown writeGLSLColorOther : %x", other);
704   }
705 }
706
707 void writeGLSLColorLocal(int local)
708 {
709   switch(local)
710   {
711   case GR_COMBINE_LOCAL_ITERATED:
712     strcat(fragment_shader_color_combiner, "vec4 color_local = gl_Color; \n");
713     break;
714   case GR_COMBINE_LOCAL_CONSTANT:
715     strcat(fragment_shader_color_combiner, "vec4 color_local = constant_color; \n");
716     break;
717   default:
718     display_warning("unknown writeGLSLColorLocal : %x", local);
719   }
720 }
721
722 void writeGLSLColorFactor(int factor, int local, int need_local, int other, int need_other)
723 {
724   switch(factor)
725   {
726   case GR_COMBINE_FACTOR_ZERO:
727     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(0.0); \n");
728     break;
729   case GR_COMBINE_FACTOR_LOCAL:
730     if(need_local) writeGLSLColorLocal(local);
731     strcat(fragment_shader_color_combiner, "vec4 color_factor = color_local; \n");
732     break;
733   case GR_COMBINE_FACTOR_OTHER_ALPHA:
734     if(need_other) writeGLSLColorOther(other);
735     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_other.a); \n");
736     break;
737   case GR_COMBINE_FACTOR_LOCAL_ALPHA:
738     if(need_local) writeGLSLColorLocal(local);
739     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_local.a); \n");
740     break;
741   case GR_COMBINE_FACTOR_TEXTURE_ALPHA:
742     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(ctexture1.a); \n");
743     break;
744   case GR_COMBINE_FACTOR_TEXTURE_RGB:
745     strcat(fragment_shader_color_combiner, "vec4 color_factor = ctexture1; \n");
746     break;
747   case GR_COMBINE_FACTOR_ONE:
748     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0); \n");
749     break;
750   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL:
751     if(need_local) writeGLSLColorLocal(local);
752     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - color_local; \n");
753     break;
754   case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA:
755     if(need_other) writeGLSLColorOther(other);
756     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_other.a); \n");
757     break;
758   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA:
759     if(need_local) writeGLSLColorLocal(local);
760     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_local.a); \n");
761     break;
762   case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA:
763     strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(ctexture1.a); \n");
764     break;
765   default:
766     display_warning("unknown writeGLSLColorFactor : %x", factor);
767   }
768 }
769
770 FX_ENTRY void FX_CALL 
771 grColorCombine(
772                GrCombineFunction_t function, GrCombineFactor_t factor,
773                GrCombineLocal_t local, GrCombineOther_t other,
774                FxBool invert )
775 {
776   LOG("grColorCombine(%d,%d,%d,%d,%d)\r\n", function, factor, local, other, invert);
777   static int last_function = 0;
778   static int last_factor = 0;
779   static int last_local = 0;
780   static int last_other = 0;
781
782   if(last_function == function && last_factor == factor &&
783     last_local == local && last_other == other && first_color == 0 && !c_combiner_ext) return;
784   first_color = 0;
785   c_combiner_ext = 0;
786
787   last_function = function;
788   last_factor = factor;
789   last_local = local;
790   last_other = other;
791
792   if (invert) display_warning("grColorCombine : inverted result");
793
794   color_combiner_key = function | (factor << 4) | (local << 8) | (other << 10);
795   chroma_other_color = other;
796
797   strcpy(fragment_shader_color_combiner, "");
798   switch(function)
799   {
800   case GR_COMBINE_FUNCTION_ZERO:
801     strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(0.0); \n");
802     break;
803   case GR_COMBINE_FUNCTION_LOCAL:
804     writeGLSLColorLocal(local);
805     strcat(fragment_shader_color_combiner, "gl_FragColor = color_local; \n");
806     break;
807   case GR_COMBINE_FUNCTION_LOCAL_ALPHA:
808     writeGLSLColorLocal(local);
809     strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(color_local.a); \n");
810     break;
811   case GR_COMBINE_FUNCTION_SCALE_OTHER:
812     writeGLSLColorOther(other);
813     writeGLSLColorFactor(factor,local,1,other,0);
814     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other; \n");
815     break;
816   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL:
817     writeGLSLColorLocal(local);
818     writeGLSLColorOther(other);
819     writeGLSLColorFactor(factor,local,0,other,0);
820     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + color_local; \n");
821     break;
822   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA:
823     writeGLSLColorLocal(local);
824     writeGLSLColorOther(other);
825     writeGLSLColorFactor(factor,local,0,other,0);
826     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + vec4(color_local.a); \n");
827     break;
828   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL:
829     writeGLSLColorLocal(local);
830     writeGLSLColorOther(other);
831     writeGLSLColorFactor(factor,local,0,other,0);
832     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local); \n");
833     break;
834   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL:
835     writeGLSLColorLocal(local);
836     writeGLSLColorOther(other);
837     writeGLSLColorFactor(factor,local,0,other,0);
838     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + color_local; \n");
839     break;
840   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA:
841     writeGLSLColorLocal(local);
842     writeGLSLColorOther(other);
843     writeGLSLColorFactor(factor,local,0,other,0);
844     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + vec4(color_local.a); \n");
845     break;
846   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL:
847     writeGLSLColorLocal(local);
848     writeGLSLColorFactor(factor,local,0,other,1);
849     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + color_local; \n");
850     break;
851   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA:
852     writeGLSLColorLocal(local);
853     writeGLSLColorFactor(factor,local,0,other,1);
854     strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + vec4(color_local.a); \n");
855     break;
856   default:
857     strcpy(fragment_shader_color_combiner, fragment_shader_default);
858     display_warning("grColorCombine : unknown function : %x", function);
859   }
860   //compile_shader();
861   need_to_compile = 1;
862 }
863
864 /*
865 int setOtherAlphaSource(int other)
866 {
867   switch(other)
868   {
869   case GR_COMBINE_OTHER_ITERATED:
870     return GL_PRIMARY_COLOR_ARB;
871     break;
872   case GR_COMBINE_OTHER_TEXTURE:
873     return GL_PREVIOUS_ARB;
874     break;
875   case GR_COMBINE_OTHER_CONSTANT:
876     return GL_CONSTANT_ARB;
877     break;
878   default:
879     display_warning("unknwown other alpha source : %x", other);
880   }
881   return 0;
882 }
883
884 int setLocalAlphaSource(int local)
885 {
886   switch(local)
887   {
888   case GR_COMBINE_LOCAL_ITERATED:
889     return GL_PRIMARY_COLOR_ARB;
890     break;
891   case GR_COMBINE_LOCAL_CONSTANT:
892     return GL_CONSTANT_ARB;
893     break;
894   default:
895     display_warning("unknwown local alpha source : %x", local);
896   }
897   return 0;
898 }
899 */
900
901 void writeGLSLAlphaOther(int other)
902 {
903   switch(other)
904   {
905   case GR_COMBINE_OTHER_ITERATED:
906     strcat(fragment_shader_alpha_combiner, "float alpha_other = gl_Color.a; \n");
907     break;
908   case GR_COMBINE_OTHER_TEXTURE:
909     strcat(fragment_shader_alpha_combiner, "float alpha_other = ctexture1.a; \n");
910     break;
911   case GR_COMBINE_OTHER_CONSTANT:
912     strcat(fragment_shader_alpha_combiner, "float alpha_other = constant_color.a; \n");
913     break;
914   default:
915     display_warning("unknown writeGLSLAlphaOther : %x", other);
916   }
917 }
918
919 void writeGLSLAlphaLocal(int local)
920 {
921   switch(local)
922   {
923   case GR_COMBINE_LOCAL_ITERATED:
924     strcat(fragment_shader_alpha_combiner, "float alpha_local = gl_Color.a; \n");
925     break;
926   case GR_COMBINE_LOCAL_CONSTANT:
927     strcat(fragment_shader_alpha_combiner, "float alpha_local = constant_color.a; \n");
928     break;
929   default:
930     display_warning("unknown writeGLSLAlphaLocal : %x", local);
931   }
932 }
933
934 void writeGLSLAlphaFactor(int factor, int local, int need_local, int other, int need_other)
935 {
936   switch(factor)
937   {
938   case GR_COMBINE_FACTOR_ZERO:
939     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 0.0; \n");
940     break;
941   case GR_COMBINE_FACTOR_LOCAL:
942     if(need_local) writeGLSLAlphaLocal(local);
943     strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n");
944     break;
945   case GR_COMBINE_FACTOR_OTHER_ALPHA:
946     if(need_other) writeGLSLAlphaOther(other);
947     strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_other; \n");
948     break;
949   case GR_COMBINE_FACTOR_LOCAL_ALPHA:
950     if(need_local) writeGLSLAlphaLocal(local);
951     strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n");
952     break;
953   case GR_COMBINE_FACTOR_TEXTURE_ALPHA:
954     strcat(fragment_shader_alpha_combiner, "float alpha_factor = ctexture1.a; \n");
955     break;
956   case GR_COMBINE_FACTOR_ONE:
957     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0; \n");
958     break;
959   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL:
960     if(need_local) writeGLSLAlphaLocal(local);
961     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n");
962     break;
963   case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA:
964     if(need_other) writeGLSLAlphaOther(other);
965     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_other; \n");
966     break;
967   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA:
968     if(need_local) writeGLSLAlphaLocal(local);
969     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n");
970     break;
971   case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA:
972     strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - ctexture1.a; \n");
973     break;
974   default:
975     display_warning("unknown writeGLSLAlphaFactor : %x", factor);
976   }
977 }
978
979 FX_ENTRY void FX_CALL
980 grAlphaCombine(
981                GrCombineFunction_t function, GrCombineFactor_t factor,
982                GrCombineLocal_t local, GrCombineOther_t other,
983                FxBool invert
984                )
985 {
986   LOG("grAlphaCombine(%d,%d,%d,%d,%d)\r\n", function, factor, local, other, invert);
987   static int last_function = 0;
988   static int last_factor = 0;
989   static int last_local = 0;
990   static int last_other = 0;
991
992   if(last_function == function && last_factor == factor &&
993     last_local == local && last_other == other && first_alpha == 0 && !a_combiner_ext) return;
994   first_alpha = 0;
995   a_combiner_ext = 0;
996
997   last_function = function;
998   last_factor = factor;
999   last_local = local;
1000   last_other = other;
1001
1002   if (invert) display_warning("grAlphaCombine : inverted result");
1003
1004   alpha_combiner_key = function | (factor << 4) | (local << 8) | (other << 10);
1005   chroma_other_alpha = other;
1006
1007   strcpy(fragment_shader_alpha_combiner, "");
1008
1009   switch(function)
1010   {
1011   case GR_COMBINE_FUNCTION_ZERO:
1012     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = 0.0; \n");
1013     break;
1014   case GR_COMBINE_FUNCTION_LOCAL:
1015     writeGLSLAlphaLocal(local);
1016     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n");
1017     break;
1018   case GR_COMBINE_FUNCTION_LOCAL_ALPHA:
1019     writeGLSLAlphaLocal(local);
1020     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n");
1021     break;
1022   case GR_COMBINE_FUNCTION_SCALE_OTHER:
1023     writeGLSLAlphaOther(other);
1024     writeGLSLAlphaFactor(factor,local,1,other,0);
1025     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other; \n");
1026     break;
1027   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL:
1028     writeGLSLAlphaLocal(local);
1029     writeGLSLAlphaOther(other);
1030     writeGLSLAlphaFactor(factor,local,0,other,0);
1031     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n");
1032     break;
1033   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA:
1034     writeGLSLAlphaLocal(local);
1035     writeGLSLAlphaOther(other);
1036     writeGLSLAlphaFactor(factor,local,0,other,0);
1037     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n");
1038     break;
1039   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL:
1040     writeGLSLAlphaLocal(local);
1041     writeGLSLAlphaOther(other);
1042     writeGLSLAlphaFactor(factor,local,0,other,0);
1043     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local); \n");
1044     break;
1045   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL:
1046     writeGLSLAlphaLocal(local);
1047     writeGLSLAlphaOther(other);
1048     writeGLSLAlphaFactor(factor,local,0,other,0);
1049     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n");
1050     break;
1051   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1052     writeGLSLAlphaLocal(local);
1053     writeGLSLAlphaOther(other);
1054     writeGLSLAlphaFactor(factor,local,0,other,0);
1055     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n");
1056     break;
1057   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL:
1058     writeGLSLAlphaLocal(local);
1059     writeGLSLAlphaFactor(factor,local,0,other,1);
1060     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n");
1061     break;
1062   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1063     writeGLSLAlphaLocal(local);
1064     writeGLSLAlphaFactor(factor,local,0,other,1);
1065     strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n");
1066     break;
1067   default:
1068     display_warning("grAlphaCombine : unknown function : %x", function);
1069   }
1070
1071   //compile_shader();
1072   need_to_compile = 1;
1073 }
1074
1075 void writeGLSLTextureColorFactor(int num_tex, int factor)
1076 {
1077   switch(factor)
1078   {
1079   case GR_COMBINE_FACTOR_ZERO:
1080     if(num_tex == 0)
1081       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n");
1082     else
1083       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(0.0); \n");
1084     break;
1085   case GR_COMBINE_FACTOR_LOCAL:
1086     if(num_tex == 0)
1087       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = readtex0; \n");
1088     else
1089       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = readtex1; \n");
1090     break;
1091   case GR_COMBINE_FACTOR_OTHER_ALPHA:
1092     if(num_tex == 0)
1093       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n");
1094     else
1095       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(ctexture0.a); \n");
1096     break;
1097   case GR_COMBINE_FACTOR_LOCAL_ALPHA:
1098     if(num_tex == 0)
1099       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(readtex0.a); \n");
1100     else
1101       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(readtex1.a); \n");
1102     break;
1103   case GR_COMBINE_FACTOR_DETAIL_FACTOR:
1104     if(num_tex == 0)
1105       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(lambda); \n");
1106     else
1107       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(lambda); \n");
1108     break;
1109   case GR_COMBINE_FACTOR_ONE:
1110     if(num_tex == 0)
1111       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0); \n");
1112     else
1113       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0); \n");
1114     break;
1115   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL:
1116     if(num_tex == 0)
1117       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - readtex0; \n");
1118     else
1119       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - readtex1; \n");
1120     break;
1121   case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA:
1122     if(num_tex == 0)
1123       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(0.0); \n");
1124     else
1125       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(ctexture0.a); \n");
1126     break;
1127   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA:
1128     if(num_tex == 0)
1129       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(readtex0.a); \n");
1130     else
1131       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(readtex1.a); \n");
1132     break;
1133   case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR:
1134     if(num_tex == 0)
1135       strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(lambda); \n");
1136     else
1137       strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(lambda); \n");
1138     break;
1139   default:
1140     display_warning("unknown writeGLSLTextureColorFactor : %x", factor);
1141   }
1142 }
1143
1144 void writeGLSLTextureAlphaFactor(int num_tex, int factor)
1145 {
1146   switch(factor)
1147   {
1148   case GR_COMBINE_FACTOR_ZERO:
1149     if(num_tex == 0)
1150       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n");
1151     else
1152       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 0.0; \n");
1153     break;
1154   case GR_COMBINE_FACTOR_LOCAL:
1155     if(num_tex == 0)
1156       strcat(fragment_shader_texture0, "float texture0_alpha_factor = readtex0.a; \n");
1157     else
1158       strcat(fragment_shader_texture1, "float texture1_alpha_factor = readtex1.a; \n");
1159     break;
1160   case GR_COMBINE_FACTOR_OTHER_ALPHA:
1161     if(num_tex == 0)
1162       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n");
1163     else
1164       strcat(fragment_shader_texture1, "float texture1_alpha_factor = ctexture0.a; \n");
1165     break;
1166   case GR_COMBINE_FACTOR_LOCAL_ALPHA:
1167     if(num_tex == 0)
1168       strcat(fragment_shader_texture0, "float texture0_alpha_factor = readtex0.a; \n");
1169     else
1170       strcat(fragment_shader_texture1, "float texture1_alpha_factor = readtex1.a; \n");
1171     break;
1172   case GR_COMBINE_FACTOR_DETAIL_FACTOR:
1173     if(num_tex == 0)
1174       strcat(fragment_shader_texture0, "float texture0_alpha_factor = lambda; \n");
1175     else
1176       strcat(fragment_shader_texture1, "float texture1_alpha_factor = lambda; \n");
1177     break;
1178   case GR_COMBINE_FACTOR_ONE:
1179     if(num_tex == 0)
1180       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0; \n");
1181     else
1182       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0; \n");
1183     break;
1184   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL:
1185     if(num_tex == 0)
1186       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - readtex0.a; \n");
1187     else
1188       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - readtex1.a; \n");
1189     break;
1190   case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA:
1191     if(num_tex == 0)
1192       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - 0.0; \n");
1193     else
1194       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - ctexture0.a; \n");
1195     break;
1196   case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA:
1197     if(num_tex == 0)
1198       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - readtex0.a; \n");
1199     else
1200       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - readtex1.a; \n");
1201     break;
1202   case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR:
1203     if(num_tex == 0)
1204       strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - lambda; \n");
1205     else
1206       strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - lambda; \n");
1207     break;
1208   default:
1209     display_warning("unknown writeGLSLTextureAlphaFactor : %x", factor);
1210   }
1211 }
1212
1213 FX_ENTRY void FX_CALL 
1214 grTexCombine(
1215              GrChipID_t tmu,
1216              GrCombineFunction_t rgb_function,
1217              GrCombineFactor_t rgb_factor, 
1218              GrCombineFunction_t alpha_function,
1219              GrCombineFactor_t alpha_factor,
1220              FxBool rgb_invert,
1221              FxBool alpha_invert
1222              )
1223 {
1224   LOG("grTexCombine(%d,%d,%d,%d,%d,%d,%d)\r\n", tmu, rgb_function, rgb_factor, alpha_function, alpha_factor, rgb_invert, alpha_invert);
1225   int num_tex;
1226
1227   if (tmu == GR_TMU0) num_tex = 1;
1228   else num_tex = 0;
1229
1230   if(num_tex == 0)
1231   {
1232     static int last_function = 0;
1233     static int last_factor = 0;
1234     static int last_afunction = 0;
1235     static int last_afactor = 0;
1236     static int last_rgb_invert = 0;
1237
1238     if(last_function == rgb_function && last_factor == rgb_factor &&
1239       last_afunction == alpha_function && last_afactor == alpha_factor &&
1240       last_rgb_invert == rgb_invert && first_texture0 == 0 && !tex0_combiner_ext) return;
1241     first_texture0 = 0;
1242     tex0_combiner_ext = 0;
1243
1244     last_function = rgb_function;
1245     last_factor = rgb_factor;
1246     last_afunction = alpha_function;
1247     last_afactor = alpha_factor;
1248     last_rgb_invert= rgb_invert;
1249     texture0_combiner_key = rgb_function | (rgb_factor << 4) | 
1250       (alpha_function << 8) | (alpha_factor << 12) | 
1251       (rgb_invert << 16);
1252     texture0_combinera_key = 0;
1253     strcpy(fragment_shader_texture0, "");
1254   }
1255   else
1256   {
1257     static int last_function = 0;
1258     static int last_factor = 0;
1259     static int last_afunction = 0;
1260     static int last_afactor = 0;
1261     static int last_rgb_invert = 0;
1262
1263     if(last_function == rgb_function && last_factor == rgb_factor &&
1264       last_afunction == alpha_function && last_afactor == alpha_factor &&
1265       last_rgb_invert == rgb_invert && first_texture1 == 0 && !tex1_combiner_ext) return;
1266     first_texture1 = 0;
1267     tex1_combiner_ext = 0;
1268
1269     last_function = rgb_function;
1270     last_factor = rgb_factor;
1271     last_afunction = alpha_function;
1272     last_afactor = alpha_factor;
1273     last_rgb_invert = rgb_invert;
1274
1275     texture1_combiner_key = rgb_function | (rgb_factor << 4) | 
1276       (alpha_function << 8) | (alpha_factor << 12) |
1277       (rgb_invert << 16);
1278     texture1_combinera_key = 0;
1279     strcpy(fragment_shader_texture1, "");
1280   }
1281
1282   switch(rgb_function)
1283   {
1284   case GR_COMBINE_FUNCTION_ZERO:
1285     if(num_tex == 0)
1286       strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(0.0); \n");
1287     else
1288       strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(0.0); \n");
1289     break;
1290   case GR_COMBINE_FUNCTION_LOCAL:
1291     if(num_tex == 0)
1292       strcat(fragment_shader_texture0, "vec4 ctexture0 = readtex0; \n");
1293     else
1294       strcat(fragment_shader_texture1, "vec4 ctexture1 = readtex1; \n");
1295     break;
1296   case GR_COMBINE_FUNCTION_LOCAL_ALPHA:
1297     if(num_tex == 0)
1298       strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(readtex0.a); \n");
1299     else
1300       strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(readtex1.a); \n");
1301     break;
1302   case GR_COMBINE_FUNCTION_SCALE_OTHER:
1303     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1304     if(num_tex == 0)
1305       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0); \n");
1306     else
1307       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0; \n");
1308     break;
1309   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL:
1310     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1311     if(num_tex == 0)
1312       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + readtex0; \n");
1313     else
1314       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + readtex1; \n");
1315     break;
1316   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA:
1317     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1318     if(num_tex == 0)
1319       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + vec4(readtex0.a); \n");
1320     else
1321       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + vec4(readtex1.a); \n");
1322     break;
1323   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL:
1324     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1325     if(num_tex == 0)
1326       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0); \n");
1327     else
1328       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1); \n");
1329     break;
1330   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL:
1331     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1332     if(num_tex == 0)
1333       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0) + readtex0; \n");
1334     else
1335       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1) + readtex1; \n");
1336     break;
1337   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1338     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1339     if(num_tex == 0)
1340       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - readtex0) + vec4(readtex0.a); \n");
1341     else
1342       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - readtex1) + vec4(readtex1.a); \n");
1343     break;
1344   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL:
1345     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1346     if(num_tex == 0)
1347       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-readtex0) + readtex0; \n");
1348     else
1349       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-readtex1) + readtex1; \n");
1350     break;
1351   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1352     writeGLSLTextureColorFactor(num_tex, rgb_factor);
1353     if(num_tex == 0)
1354       strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-readtex0) + vec4(readtex0.a); \n");
1355     else
1356       strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-readtex1) + vec4(readtex1.a); \n");
1357     break;
1358   default:
1359     if(num_tex == 0)
1360       strcat(fragment_shader_texture0, "vec4 ctexture0 = readtex0; \n");
1361     else
1362       strcat(fragment_shader_texture1, "vec4 ctexture1 = readtex1; \n");
1363     display_warning("grTextCombine : unknown rgb function : %x", rgb_function);
1364   }
1365
1366   if (rgb_invert)
1367   {
1368     if(num_tex == 0)
1369       strcat(fragment_shader_texture0, "ctexture0 = vec4(1.0) - ctexture0; \n");
1370     else
1371       strcat(fragment_shader_texture1, "ctexture1 = vec4(1.0) - ctexture1; \n");
1372   }
1373
1374   switch(alpha_function)
1375   {
1376   case GR_COMBINE_FACTOR_ZERO:
1377     if(num_tex == 0)
1378       strcat(fragment_shader_texture0, "ctexture0.a = 0.0; \n");
1379     else
1380       strcat(fragment_shader_texture1, "ctexture1.a = 0.0; \n");
1381     break;
1382   case GR_COMBINE_FUNCTION_LOCAL:
1383     if(num_tex == 0)
1384       strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n");
1385     else
1386       strcat(fragment_shader_texture1, "ctexture1.a = readtex1.a; \n");
1387     break;
1388   case GR_COMBINE_FUNCTION_LOCAL_ALPHA:
1389     if(num_tex == 0)
1390       strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n");
1391     else
1392       strcat(fragment_shader_texture1, "ctexture1.a = readtex1.a; \n");
1393     break;
1394   case GR_COMBINE_FUNCTION_SCALE_OTHER:
1395     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1396     if(num_tex == 0)
1397       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0; \n");
1398     else
1399       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a; \n");
1400     break;
1401   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL:
1402     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1403     if(num_tex == 0)
1404       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + readtex0.a; \n");
1405     else
1406       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + readtex1.a; \n");
1407     break;
1408   case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA:
1409     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1410     if(num_tex == 0)
1411       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + readtex0.a; \n");
1412     else
1413       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + readtex1.a; \n");
1414     break;
1415   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL:
1416     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1417     if(num_tex == 0)
1418       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a); \n");
1419     else
1420       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a); \n");
1421     break;
1422   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL:
1423     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1424     if(num_tex == 0)
1425       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a) + readtex0.a; \n");
1426     else
1427       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a) + readtex1.a; \n");
1428     break;
1429   case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1430     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1431     if(num_tex == 0)
1432       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - readtex0.a) + readtex0.a; \n");
1433     else
1434       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - readtex1.a) + readtex1.a; \n");
1435     break;
1436   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL:
1437     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1438     if(num_tex == 0)
1439       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-readtex0.a) + readtex0.a; \n");
1440     else
1441       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-readtex1.a) + readtex1.a; \n");
1442     break;
1443   case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA:
1444     writeGLSLTextureAlphaFactor(num_tex, alpha_factor);
1445     if(num_tex == 0)
1446       strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-readtex0.a) + readtex0.a; \n");
1447     else
1448       strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-readtex1.a) + readtex1.a; \n");
1449     break;
1450   default:
1451     if(num_tex == 0)
1452       strcat(fragment_shader_texture0, "ctexture0.a = readtex0.a; \n");
1453     else
1454       strcat(fragment_shader_texture1, "ctexture1.a = ctexture0.a; \n");
1455     display_warning("grTextCombine : unknown alpha function : %x", alpha_function);
1456   }
1457
1458   if (alpha_invert)
1459   {
1460     if(num_tex == 0)
1461       strcat(fragment_shader_texture0, "ctexture0.a = 1.0 - ctexture0.a; \n");
1462     else
1463       strcat(fragment_shader_texture1, "ctexture1.a = 1.0 - ctexture1.a; \n");
1464   }
1465   need_to_compile = 1;
1466 }
1467
1468 FX_ENTRY void FX_CALL
1469 grAlphaBlendFunction(
1470                      GrAlphaBlendFnc_t rgb_sf,   GrAlphaBlendFnc_t rgb_df,
1471                      GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df
1472                      )
1473 {
1474   int sfactorRGB = 0, dfactorRGB = 0, sfactorAlpha = 0, dfactorAlpha = 0;
1475   LOG("grAlphaBlendFunction(%d,%d,%d,%d)\r\n", rgb_sf, rgb_df, alpha_sf, alpha_df);
1476
1477   switch(rgb_sf)
1478   {
1479   case GR_BLEND_ZERO:
1480     sfactorRGB = GL_ZERO;
1481     break;
1482   case GR_BLEND_SRC_ALPHA:
1483     sfactorRGB = GL_SRC_ALPHA;
1484     break;
1485   case GR_BLEND_ONE:
1486     sfactorRGB = GL_ONE;
1487     break;
1488   case GR_BLEND_ONE_MINUS_SRC_ALPHA:
1489     sfactorRGB = GL_ONE_MINUS_SRC_ALPHA;
1490     break;
1491   default:
1492     display_warning("grAlphaBlendFunction : rgb_sf = %x", rgb_sf);
1493   }
1494
1495   switch(rgb_df)
1496   {
1497   case GR_BLEND_ZERO:
1498     dfactorRGB = GL_ZERO;
1499     break;
1500   case GR_BLEND_SRC_ALPHA:
1501     dfactorRGB = GL_SRC_ALPHA;
1502     break;
1503   case GR_BLEND_ONE:
1504     dfactorRGB = GL_ONE;
1505     break;
1506   case GR_BLEND_ONE_MINUS_SRC_ALPHA:
1507     dfactorRGB = GL_ONE_MINUS_SRC_ALPHA;
1508     break;
1509   default:
1510     display_warning("grAlphaBlendFunction : rgb_df = %x", rgb_df);
1511   }
1512
1513   switch(alpha_sf)
1514   {
1515   case GR_BLEND_ZERO:
1516     sfactorAlpha = GL_ZERO;
1517     break;
1518   case GR_BLEND_ONE:
1519     sfactorAlpha = GL_ONE;
1520     break;
1521   default:
1522     display_warning("grAlphaBlendFunction : alpha_sf = %x", alpha_sf);
1523   }
1524
1525   switch(alpha_df)
1526   {
1527   case GR_BLEND_ZERO:
1528     dfactorAlpha = GL_ZERO;
1529     break;
1530   case GR_BLEND_ONE:
1531     dfactorAlpha = GL_ONE;
1532     break;
1533   default:
1534     display_warning("grAlphaBlendFunction : alpha_df = %x", alpha_df);
1535   }
1536   glEnable(GL_BLEND);
1537   glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
1538 /*
1539   if (blend_func_separate_support)
1540     glBlendFuncSeparateEXT(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
1541   else
1542     glBlendFunc(sfactorRGB, dfactorRGB);
1543 */
1544 }
1545
1546 FX_ENTRY void FX_CALL
1547 grAlphaTestReferenceValue( GrAlpha_t value )
1548 {
1549   LOG("grAlphaTestReferenceValue(%d)\r\n", value);
1550   alpha_ref = value;
1551   grAlphaTestFunction(alpha_func);
1552 }
1553
1554 FX_ENTRY void FX_CALL
1555 grAlphaTestFunction( GrCmpFnc_t function )
1556 {
1557   LOG("grAlphaTestFunction(%d)\r\n", function);
1558   alpha_func = function;
1559   switch(function)
1560   {
1561   case GR_CMP_GREATER:
1562     //glAlphaFunc(GL_GREATER, alpha_ref/255.0f);
1563     break;
1564   case GR_CMP_GEQUAL:
1565     //glAlphaFunc(GL_GEQUAL, alpha_ref/255.0f);
1566     break;
1567   case GR_CMP_ALWAYS:
1568     //glAlphaFunc(GL_ALWAYS, alpha_ref/255.0f);
1569     //glDisable(GL_ALPHA_TEST);
1570     alpha_test = false;
1571     return;
1572     break;
1573   default:
1574     display_warning("grAlphaTestFunction : unknown function : %x", function);
1575   }
1576   //glEnable(GL_ALPHA_TEST);
1577   alpha_test = true;
1578 }
1579
1580 // fog
1581
1582 FX_ENTRY void FX_CALL 
1583 grFogMode( GrFogMode_t mode )
1584 {
1585   LOG("grFogMode(%d)\r\n", mode);
1586   switch(mode)
1587   {
1588   case GR_FOG_DISABLE:
1589     //glDisable(GL_FOG);
1590     fog_enabled = 0;
1591     break;
1592   case GR_FOG_WITH_TABLE_ON_Q:
1593     //glEnable(GL_FOG);
1594     //glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1595     fog_enabled = 1;
1596     break;
1597   case GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT:
1598     //glEnable(GL_FOG);
1599     //glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1600     fog_enabled = 2;
1601     break;
1602   default:
1603     display_warning("grFogMode : unknown mode : %x", mode);
1604   }
1605   need_to_compile = 1;
1606 }
1607
1608 FX_ENTRY float FX_CALL
1609 guFogTableIndexToW( int i )
1610 {
1611   LOG("guFogTableIndexToW(%d)\r\n", i);
1612   return (float)(pow(2.0, 3.0+(double)(i>>2)) / (8-(i&3)));
1613 }
1614
1615 FX_ENTRY void FX_CALL
1616 guFogGenerateLinear(GrFog_t *fogtable,
1617                     float nearZ, float farZ )
1618 {
1619   LOG("guFogGenerateLinear(%f,%f)\r\n", nearZ, farZ);
1620 /*
1621   glFogi(GL_FOG_MODE, GL_LINEAR);
1622   glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1623   glFogf(GL_FOG_START, nearZ / 255.0f);
1624   glFogf(GL_FOG_END, farZ / 255.0f);
1625 */
1626   fogStart = nearZ / 255.0f;
1627   fogEnd = farZ / 255.0f;
1628 }
1629
1630 FX_ENTRY void FX_CALL 
1631 grFogTable( const GrFog_t ft[] )
1632 {
1633   LOG("grFogTable()\r\n");
1634 }
1635
1636 FX_ENTRY void FX_CALL 
1637 grFogColorValue( GrColor_t fogcolor )
1638 {
1639   LOG("grFogColorValue(%x)\r\n", fogcolor);
1640
1641   switch(lfb_color_fmt)
1642   {
1643   case GR_COLORFORMAT_ARGB:
1644     fogColor[3] = ((fogcolor >> 24) & 0xFF) / 255.0f;
1645     fogColor[0] = ((fogcolor >> 16) & 0xFF) / 255.0f;
1646     fogColor[1] = ((fogcolor >>  8) & 0xFF) / 255.0f;
1647     fogColor[2] = (fogcolor & 0xFF) / 255.0f;
1648     break;
1649   case GR_COLORFORMAT_RGBA:
1650     fogColor[0] = ((fogcolor >> 24) & 0xFF) / 255.0f;
1651     fogColor[1] = ((fogcolor >> 16) & 0xFF) / 255.0f;
1652     fogColor[2] = ((fogcolor >>  8) & 0xFF) / 255.0f;
1653     fogColor[3] = (fogcolor & 0xFF) / 255.0f;
1654     break;
1655   default:
1656     display_warning("grFogColorValue: unknown color format : %x", lfb_color_fmt);
1657   }
1658
1659   //glFogfv(GL_FOG_COLOR, color); 
1660 }
1661
1662 // chroma
1663
1664 FX_ENTRY void FX_CALL 
1665 grChromakeyMode( GrChromakeyMode_t mode )
1666 {
1667   LOG("grChromakeyMode(%d)\r\n", mode);
1668   switch(mode)
1669   {
1670   case GR_CHROMAKEY_DISABLE:
1671     chroma_enabled = 0;
1672     break;
1673   case GR_CHROMAKEY_ENABLE:
1674     chroma_enabled = 1;
1675     break;
1676   default:
1677     display_warning("grChromakeyMode : unknown mode : %x", mode);
1678   }
1679   need_to_compile = 1;
1680 }
1681
1682 FX_ENTRY void FX_CALL 
1683 grChromakeyValue( GrColor_t value )
1684 {
1685   LOG("grChromakeyValue(%x)\r\n", value);
1686   int chroma_color_location;
1687
1688   switch(lfb_color_fmt)
1689   {
1690   case GR_COLORFORMAT_ARGB:
1691     chroma_color[3] = 1.0;//((value >> 24) & 0xFF) / 255.0f;
1692     chroma_color[0] = ((value >> 16) & 0xFF) / 255.0f;
1693     chroma_color[1] = ((value >>  8) & 0xFF) / 255.0f;
1694     chroma_color[2] = (value & 0xFF) / 255.0f;
1695     break;
1696   case GR_COLORFORMAT_RGBA:
1697     chroma_color[0] = ((value >> 24) & 0xFF) / 255.0f;
1698     chroma_color[1] = ((value >> 16) & 0xFF) / 255.0f;
1699     chroma_color[2] = ((value >>  8) & 0xFF) / 255.0f;
1700     chroma_color[3] = 1.0;//(value & 0xFF) / 255.0f;
1701     break;
1702   default:
1703     display_warning("grChromakeyValue: unknown color format : %x", lfb_color_fmt);
1704   }
1705   vbo_draw();
1706   chroma_color_location = glGetUniformLocation(program_object, "chroma_color");
1707   glUniform4f(chroma_color_location, chroma_color[0], chroma_color[1],
1708     chroma_color[2], chroma_color[3]);
1709 }
1710
1711 static void setPattern()
1712 {
1713   int i;
1714   GLubyte stip[32*4];
1715   for(i=0; i<32; i++)
1716   {
1717     unsigned int val = (rand() << 17) | ((rand() & 1) << 16) | (rand() << 1) | (rand() & 1);
1718     stip[i*4+0] = (val >> 24) & 0xFF;
1719     stip[i*4+1] = (val >> 16) & 0xFF;
1720     stip[i*4+2] = (val >> 8) & 0xFF;
1721     stip[i*4+3] = val & 0xFF;
1722   }
1723   GLubyte texture[32*32*4];
1724   for(i=0; i<32; i++)
1725   {
1726     int j;
1727     for(j=0; j<4; j++)
1728     {
1729       texture[(i*32+j*8+0)*4+3] = ((stip[i*4+j] >> 7) & 1) ? 255 : 0;
1730       texture[(i*32+j*8+1)*4+3] = ((stip[i*4+j] >> 6) & 1) ? 255 : 0;
1731       texture[(i*32+j*8+2)*4+3] = ((stip[i*4+j] >> 5) & 1) ? 255 : 0;
1732       texture[(i*32+j*8+3)*4+3] = ((stip[i*4+j] >> 4) & 1) ? 255 : 0;
1733       texture[(i*32+j*8+4)*4+3] = ((stip[i*4+j] >> 3) & 1) ? 255 : 0;
1734       texture[(i*32+j*8+5)*4+3] = ((stip[i*4+j] >> 2) & 1) ? 255 : 0;
1735       texture[(i*32+j*8+6)*4+3] = ((stip[i*4+j] >> 1) & 1) ? 255 : 0;
1736       texture[(i*32+j*8+7)*4+3] = ((stip[i*4+j] >> 0) & 1) ? 255 : 0;
1737     }
1738   }
1739   glActiveTexture(GL_TEXTURE2);
1740   glEnable(GL_TEXTURE_2D);
1741   glBindTexture(GL_TEXTURE_2D, 33*1024*1024);
1742   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
1743   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1744   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1745   glDisable(GL_TEXTURE_2D);
1746 }
1747
1748 FX_ENTRY void FX_CALL
1749 grStipplePattern(
1750                  GrStipplePattern_t stipple)
1751 {
1752   LOG("grStipplePattern(%x)\r\n", stipple);
1753   srand(stipple);
1754   setPattern();
1755 }
1756
1757 FX_ENTRY void FX_CALL
1758 grStippleMode( GrStippleMode_t mode )
1759 {
1760   LOG("grStippleMode(%d)\r\n", mode);
1761   switch(mode)
1762   {
1763   case GR_STIPPLE_DISABLE:
1764     dither_enabled = 0;
1765     glActiveTexture(GL_TEXTURE2);
1766     glDisable(GL_TEXTURE_2D);
1767     break;
1768   case GR_STIPPLE_PATTERN:
1769     setPattern();
1770     dither_enabled = 1;
1771     glActiveTexture(GL_TEXTURE2);
1772     glEnable(GL_TEXTURE_2D);
1773     break;
1774   case GR_STIPPLE_ROTATE:
1775     setPattern();
1776     dither_enabled = 1;
1777     glActiveTexture(GL_TEXTURE2);
1778     glEnable(GL_TEXTURE_2D);
1779     break;
1780   default:
1781     display_warning("grStippleMode:%x", mode);
1782   }
1783   need_to_compile = 1;
1784 }
1785
1786 FX_ENTRY void FX_CALL 
1787 grColorCombineExt(GrCCUColor_t a, GrCombineMode_t a_mode,
1788                   GrCCUColor_t b, GrCombineMode_t b_mode,
1789                   GrCCUColor_t c, FxBool c_invert,
1790                   GrCCUColor_t d, FxBool d_invert,
1791                   FxU32 shift, FxBool invert)
1792 {
1793   LOG("grColorCombineExt(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\r\n", a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert);
1794   if (invert) display_warning("grColorCombineExt : inverted result");
1795   if (shift) display_warning("grColorCombineExt : shift = %d", shift);
1796
1797   color_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
1798     ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
1799     ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
1800     ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
1801   c_combiner_ext = 1;
1802   strcpy(fragment_shader_color_combiner, "");
1803
1804   switch(a)
1805   {
1806   case GR_CMBX_ZERO:
1807     strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(0.0); \n");
1808     break;
1809   case GR_CMBX_TEXTURE_ALPHA:
1810     strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(ctexture1.a); \n");
1811     break;
1812   case GR_CMBX_CONSTANT_ALPHA:
1813     strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(constant_color.a); \n");
1814     break;
1815   case GR_CMBX_CONSTANT_COLOR:
1816     strcat(fragment_shader_color_combiner, "vec4 cs_a = constant_color; \n");
1817     break;
1818   case GR_CMBX_ITALPHA:
1819     strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(gl_Color.a); \n");
1820     break;
1821   case GR_CMBX_ITRGB:
1822     strcat(fragment_shader_color_combiner, "vec4 cs_a = gl_Color; \n");
1823     break;
1824   case GR_CMBX_TEXTURE_RGB:
1825     strcat(fragment_shader_color_combiner, "vec4 cs_a = ctexture1; \n");
1826     break;
1827   default:
1828     display_warning("grColorCombineExt : a = %x", a);
1829     strcat(fragment_shader_color_combiner, "vec4 cs_a = vec4(0.0); \n");
1830   }
1831
1832   switch(a_mode)
1833   {
1834   case GR_FUNC_MODE_ZERO:
1835     strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(0.0); \n");
1836     break;
1837   case GR_FUNC_MODE_X:
1838     strcat(fragment_shader_color_combiner, "vec4 c_a = cs_a; \n");
1839     break;
1840   case GR_FUNC_MODE_ONE_MINUS_X:
1841     strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(1.0) - cs_a; \n");
1842     break;
1843   case GR_FUNC_MODE_NEGATIVE_X:
1844     strcat(fragment_shader_color_combiner, "vec4 c_a = -cs_a; \n");
1845     break;
1846   default:
1847     display_warning("grColorCombineExt : a_mode = %x", a_mode);
1848     strcat(fragment_shader_color_combiner, "vec4 c_a = vec4(0.0); \n");
1849   }
1850
1851   switch(b)
1852   {
1853   case GR_CMBX_ZERO:
1854     strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(0.0); \n");
1855     break;
1856   case GR_CMBX_TEXTURE_ALPHA:
1857     strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(ctexture1.a); \n");
1858     break;
1859   case GR_CMBX_CONSTANT_ALPHA:
1860     strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(constant_color.a); \n");
1861     break;
1862   case GR_CMBX_CONSTANT_COLOR:
1863     strcat(fragment_shader_color_combiner, "vec4 cs_b = constant_color; \n");
1864     break;
1865   case GR_CMBX_ITALPHA:
1866     strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(gl_Color.a); \n");
1867     break;
1868   case GR_CMBX_ITRGB:
1869     strcat(fragment_shader_color_combiner, "vec4 cs_b = gl_Color; \n");
1870     break;
1871   case GR_CMBX_TEXTURE_RGB:
1872     strcat(fragment_shader_color_combiner, "vec4 cs_b = ctexture1; \n");
1873     break;
1874   default:
1875     display_warning("grColorCombineExt : b = %x", b);
1876     strcat(fragment_shader_color_combiner, "vec4 cs_b = vec4(0.0); \n");
1877   }
1878
1879   switch(b_mode)
1880   {
1881   case GR_FUNC_MODE_ZERO:
1882     strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(0.0); \n");
1883     break;
1884   case GR_FUNC_MODE_X:
1885     strcat(fragment_shader_color_combiner, "vec4 c_b = cs_b; \n");
1886     break;
1887   case GR_FUNC_MODE_ONE_MINUS_X:
1888     strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(1.0) - cs_b; \n");
1889     break;
1890   case GR_FUNC_MODE_NEGATIVE_X:
1891     strcat(fragment_shader_color_combiner, "vec4 c_b = -cs_b; \n");
1892     break;
1893   default:
1894     display_warning("grColorCombineExt : b_mode = %x", b_mode);
1895     strcat(fragment_shader_color_combiner, "vec4 c_b = vec4(0.0); \n");
1896   }
1897
1898   switch(c)
1899   {
1900   case GR_CMBX_ZERO:
1901     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(0.0); \n");
1902     break;
1903   case GR_CMBX_TEXTURE_ALPHA:
1904     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(ctexture1.a); \n");
1905     break;
1906   case GR_CMBX_ALOCAL:
1907     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(c_b.a); \n");
1908     break;
1909   case GR_CMBX_AOTHER:
1910     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(c_a.a); \n");
1911     break;
1912   case GR_CMBX_B:
1913     strcat(fragment_shader_color_combiner, "vec4 c_c = cs_b; \n");
1914     break;
1915   case GR_CMBX_CONSTANT_ALPHA:
1916     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(constant_color.a); \n");
1917     break;
1918   case GR_CMBX_CONSTANT_COLOR:
1919     strcat(fragment_shader_color_combiner, "vec4 c_c = constant_color; \n");
1920     break;
1921   case GR_CMBX_ITALPHA:
1922     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(gl_Color.a); \n");
1923     break;
1924   case GR_CMBX_ITRGB:
1925     strcat(fragment_shader_color_combiner, "vec4 c_c = gl_Color; \n");
1926     break;
1927   case GR_CMBX_TEXTURE_RGB:
1928     strcat(fragment_shader_color_combiner, "vec4 c_c = ctexture1; \n");
1929     break;
1930   default:
1931     display_warning("grColorCombineExt : c = %x", c);
1932     strcat(fragment_shader_color_combiner, "vec4 c_c = vec4(0.0); \n");
1933   }
1934
1935   if(c_invert)
1936     strcat(fragment_shader_color_combiner, "c_c = vec4(1.0) - c_c; \n");
1937
1938   switch(d)
1939   {
1940   case GR_CMBX_ZERO:
1941     strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(0.0); \n");
1942     break;
1943   case GR_CMBX_ALOCAL:
1944     strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(c_b.a); \n");
1945     break;
1946   case GR_CMBX_B:
1947     strcat(fragment_shader_color_combiner, "vec4 c_d = cs_b; \n");
1948     break;
1949   case GR_CMBX_TEXTURE_RGB:
1950     strcat(fragment_shader_color_combiner, "vec4 c_d = ctexture1; \n");
1951     break;
1952   case GR_CMBX_ITRGB:
1953     strcat(fragment_shader_color_combiner, "vec4 c_d = gl_Color; \n");
1954     break;
1955   default:
1956     display_warning("grColorCombineExt : d = %x", d);
1957     strcat(fragment_shader_color_combiner, "vec4 c_d = vec4(0.0); \n");
1958   }
1959
1960   if(d_invert)
1961     strcat(fragment_shader_color_combiner, "c_d = vec4(1.0) - c_d; \n");
1962
1963   strcat(fragment_shader_color_combiner, "gl_FragColor = (c_a + c_b) * c_c + c_d; \n");
1964
1965   need_to_compile = 1;
1966 }
1967
1968 FX_ENTRY void FX_CALL
1969 grAlphaCombineExt(GrACUColor_t a, GrCombineMode_t a_mode,
1970                   GrACUColor_t b, GrCombineMode_t b_mode,
1971                   GrACUColor_t c, FxBool c_invert,
1972                   GrACUColor_t d, FxBool d_invert,
1973                   FxU32 shift, FxBool invert)
1974 {
1975   LOG("grAlphaCombineExt(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert);
1976   if (invert) display_warning("grAlphaCombineExt : inverted result");
1977   if (shift) display_warning("grAlphaCombineExt : shift = %d", shift);
1978
1979   alpha_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
1980     ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
1981     ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
1982     ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
1983   a_combiner_ext = 1;
1984   strcpy(fragment_shader_alpha_combiner, "");
1985
1986   switch(a)
1987   {
1988   case GR_CMBX_ZERO:
1989     strcat(fragment_shader_alpha_combiner, "float as_a = 0.0; \n");
1990     break;
1991   case GR_CMBX_TEXTURE_ALPHA:
1992     strcat(fragment_shader_alpha_combiner, "float as_a = ctexture1.a; \n");
1993     break;
1994   case GR_CMBX_CONSTANT_ALPHA:
1995     strcat(fragment_shader_alpha_combiner, "float as_a = constant_color.a; \n");
1996     break;
1997   case GR_CMBX_ITALPHA:
1998     strcat(fragment_shader_alpha_combiner, "float as_a = gl_Color.a; \n");
1999     break;
2000   default:
2001     display_warning("grAlphaCombineExt : a = %x", a);
2002     strcat(fragment_shader_alpha_combiner, "float as_a = 0.0; \n");
2003   }
2004
2005   switch(a_mode)
2006   {
2007   case GR_FUNC_MODE_ZERO:
2008     strcat(fragment_shader_alpha_combiner, "float a_a = 0.0; \n");
2009     break;
2010   case GR_FUNC_MODE_X:
2011     strcat(fragment_shader_alpha_combiner, "float a_a = as_a; \n");
2012     break;
2013   case GR_FUNC_MODE_ONE_MINUS_X:
2014     strcat(fragment_shader_alpha_combiner, "float a_a = 1.0 - as_a; \n");
2015     break;
2016   case GR_FUNC_MODE_NEGATIVE_X:
2017     strcat(fragment_shader_alpha_combiner, "float a_a = -as_a; \n");
2018     break;
2019   default:
2020     display_warning("grAlphaCombineExt : a_mode = %x", a_mode);
2021     strcat(fragment_shader_alpha_combiner, "float a_a = 0.0; \n");
2022   }
2023
2024   switch(b)
2025   {
2026   case GR_CMBX_ZERO:
2027     strcat(fragment_shader_alpha_combiner, "float as_b = 0.0; \n");
2028     break;
2029   case GR_CMBX_TEXTURE_ALPHA:
2030     strcat(fragment_shader_alpha_combiner, "float as_b = ctexture1.a; \n");
2031     break;
2032   case GR_CMBX_CONSTANT_ALPHA:
2033     strcat(fragment_shader_alpha_combiner, "float as_b = constant_color.a; \n");
2034     break;
2035   case GR_CMBX_ITALPHA:
2036     strcat(fragment_shader_alpha_combiner, "float as_b = gl_Color.a; \n");
2037     break;
2038   default:
2039     display_warning("grAlphaCombineExt : b = %x", b);
2040     strcat(fragment_shader_alpha_combiner, "float as_b = 0.0; \n");
2041   }
2042
2043   switch(b_mode)
2044   {
2045   case GR_FUNC_MODE_ZERO:
2046     strcat(fragment_shader_alpha_combiner, "float a_b = 0.0; \n");
2047     break;
2048   case GR_FUNC_MODE_X:
2049     strcat(fragment_shader_alpha_combiner, "float a_b = as_b; \n");
2050     break;
2051   case GR_FUNC_MODE_ONE_MINUS_X:
2052     strcat(fragment_shader_alpha_combiner, "float a_b = 1.0 - as_b; \n");
2053     break;
2054   case GR_FUNC_MODE_NEGATIVE_X:
2055     strcat(fragment_shader_alpha_combiner, "float a_b = -as_b; \n");
2056     break;
2057   default:
2058     display_warning("grAlphaCombineExt : b_mode = %x", b_mode);
2059     strcat(fragment_shader_alpha_combiner, "float a_b = 0.0; \n");
2060   }
2061
2062   switch(c)
2063   {
2064   case GR_CMBX_ZERO:
2065     strcat(fragment_shader_alpha_combiner, "float a_c = 0.0; \n");
2066     break;
2067   case GR_CMBX_TEXTURE_ALPHA:
2068     strcat(fragment_shader_alpha_combiner, "float a_c = ctexture1.a; \n");
2069     break;
2070   case GR_CMBX_ALOCAL:
2071     strcat(fragment_shader_alpha_combiner, "float a_c = as_b; \n");
2072     break;
2073   case GR_CMBX_AOTHER:
2074     strcat(fragment_shader_alpha_combiner, "float a_c = as_a; \n");
2075     break;
2076   case GR_CMBX_B:
2077     strcat(fragment_shader_alpha_combiner, "float a_c = as_b; \n");
2078     break;
2079   case GR_CMBX_CONSTANT_ALPHA:
2080     strcat(fragment_shader_alpha_combiner, "float a_c = constant_color.a; \n");
2081     break;
2082   case GR_CMBX_ITALPHA:
2083     strcat(fragment_shader_alpha_combiner, "float a_c = gl_Color.a; \n");
2084     break;
2085   default:
2086     display_warning("grAlphaCombineExt : c = %x", c);
2087     strcat(fragment_shader_alpha_combiner, "float a_c = 0.0; \n");
2088   }
2089
2090   if(c_invert)
2091     strcat(fragment_shader_alpha_combiner, "a_c = 1.0 - a_c; \n");
2092
2093   switch(d)
2094   {
2095   case GR_CMBX_ZERO:
2096     strcat(fragment_shader_alpha_combiner, "float a_d = 0.0; \n");
2097     break;
2098   case GR_CMBX_TEXTURE_ALPHA:
2099     strcat(fragment_shader_alpha_combiner, "float a_d = ctexture1.a; \n");
2100     break;
2101   case GR_CMBX_ALOCAL:
2102     strcat(fragment_shader_alpha_combiner, "float a_d = as_b; \n");
2103     break;
2104   case GR_CMBX_B:
2105     strcat(fragment_shader_alpha_combiner, "float a_d = as_b; \n");
2106     break;
2107   default:
2108     display_warning("grAlphaCombineExt : d = %x", d);
2109     strcat(fragment_shader_alpha_combiner, "float a_d = 0.0; \n");
2110   }
2111
2112   if(d_invert)
2113     strcat(fragment_shader_alpha_combiner, "a_d = 1.0 - a_d; \n");
2114
2115   strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = (a_a + a_b) * a_c + a_d; \n");
2116
2117   need_to_compile = 1;
2118 }
2119
2120 FX_ENTRY void FX_CALL 
2121 grTexColorCombineExt(GrChipID_t       tmu,
2122                      GrTCCUColor_t a, GrCombineMode_t a_mode,
2123                      GrTCCUColor_t b, GrCombineMode_t b_mode,
2124                      GrTCCUColor_t c, FxBool c_invert,
2125                      GrTCCUColor_t d, FxBool d_invert,
2126                      FxU32 shift, FxBool invert)
2127 {
2128   int num_tex;
2129   LOG("grTexColorCombineExt(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", tmu, a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert);
2130
2131   if (invert) display_warning("grTexColorCombineExt : inverted result");
2132   if (shift) display_warning("grTexColorCombineExt : shift = %d", shift);
2133
2134   if (tmu == GR_TMU0) num_tex = 1;
2135   else num_tex = 0;
2136
2137   if(num_tex == 0)
2138   {
2139     texture0_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
2140       ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
2141       ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
2142       ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
2143     tex0_combiner_ext = 1;
2144     strcpy(fragment_shader_texture0, "");
2145   }
2146   else
2147   {
2148     texture1_combiner_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
2149       ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
2150       ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
2151       ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
2152     tex1_combiner_ext = 1;
2153     strcpy(fragment_shader_texture1, "");
2154   }
2155
2156   switch(a)
2157   {
2158   case GR_CMBX_ZERO:
2159     if(num_tex == 0)
2160       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n");
2161     else
2162       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(0.0); \n");
2163     break;
2164   case GR_CMBX_ITALPHA:
2165     if(num_tex == 0)
2166       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(gl_Color.a); \n");
2167     else
2168       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(gl_Color.a); \n");
2169     break;
2170   case GR_CMBX_ITRGB:
2171     if(num_tex == 0)
2172       strcat(fragment_shader_texture0, "vec4 ctex0s_a = gl_Color; \n");
2173     else
2174       strcat(fragment_shader_texture1, "vec4 ctex1s_a = gl_Color; \n");
2175     break;
2176   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2177     if(num_tex == 0)
2178       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(readtex0.a); \n");
2179     else
2180       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(readtex1.a); \n");
2181     break;
2182   case GR_CMBX_LOCAL_TEXTURE_RGB:
2183     if(num_tex == 0)
2184       strcat(fragment_shader_texture0, "vec4 ctex0s_a = readtex0; \n");
2185     else
2186       strcat(fragment_shader_texture1, "vec4 ctex1s_a = readtex1; \n");
2187     break;
2188   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2189     if(num_tex == 0)
2190       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n");
2191     else
2192       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(ctexture0.a); \n");
2193     break;
2194   case GR_CMBX_OTHER_TEXTURE_RGB:
2195     if(num_tex == 0)
2196       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n");
2197     else
2198       strcat(fragment_shader_texture1, "vec4 ctex1s_a = ctexture0; \n");
2199     break;
2200   case GR_CMBX_TMU_CCOLOR:
2201     if(num_tex == 0)
2202       strcat(fragment_shader_texture0, "vec4 ctex0s_a = ccolor0; \n");
2203     else
2204       strcat(fragment_shader_texture1, "vec4 ctex1s_a = ccolor1; \n");
2205     break;
2206   case GR_CMBX_TMU_CALPHA:
2207     if(num_tex == 0)
2208       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(ccolor0.a); \n");
2209     else
2210       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(ccolor1.a); \n");
2211     break;
2212   default:
2213     display_warning("grTexColorCombineExt : a = %x", a);
2214     if(num_tex == 0)
2215       strcat(fragment_shader_texture0, "vec4 ctex0s_a = vec4(0.0); \n");
2216     else
2217       strcat(fragment_shader_texture1, "vec4 ctex1s_a = vec4(0.0); \n");
2218   }
2219
2220   switch(a_mode)
2221   {
2222   case GR_FUNC_MODE_ZERO:
2223     if(num_tex == 0)
2224       strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(0.0); \n");
2225     else
2226       strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(0.0); \n");
2227     break;
2228   case GR_FUNC_MODE_X:
2229     if(num_tex == 0)
2230       strcat(fragment_shader_texture0, "vec4 ctex0_a = ctex0s_a; \n");
2231     else
2232       strcat(fragment_shader_texture1, "vec4 ctex1_a = ctex1s_a; \n");
2233     break;
2234   case GR_FUNC_MODE_ONE_MINUS_X:
2235     if(num_tex == 0)
2236       strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(1.0) - ctex0s_a; \n");
2237     else
2238       strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(1.0) - ctex1s_a; \n");
2239     break;
2240   case GR_FUNC_MODE_NEGATIVE_X:
2241     if(num_tex == 0)
2242       strcat(fragment_shader_texture0, "vec4 ctex0_a = -ctex0s_a; \n");
2243     else
2244       strcat(fragment_shader_texture1, "vec4 ctex1_a = -ctex1s_a; \n");
2245     break;
2246   default:
2247     display_warning("grTexColorCombineExt : a_mode = %x", a_mode);
2248     if(num_tex == 0)
2249       strcat(fragment_shader_texture0, "vec4 ctex0_a = vec4(0.0); \n");
2250     else
2251       strcat(fragment_shader_texture1, "vec4 ctex1_a = vec4(0.0); \n");
2252   }
2253
2254   switch(b)
2255   {
2256   case GR_CMBX_ZERO:
2257     if(num_tex == 0)
2258       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n");
2259     else
2260       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(0.0); \n");
2261     break;
2262   case GR_CMBX_ITALPHA:
2263     if(num_tex == 0)
2264       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(gl_Color.a); \n");
2265     else
2266       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(gl_Color.a); \n");
2267     break;
2268   case GR_CMBX_ITRGB:
2269     if(num_tex == 0)
2270       strcat(fragment_shader_texture0, "vec4 ctex0s_b = gl_Color; \n");
2271     else
2272       strcat(fragment_shader_texture1, "vec4 ctex1s_b = gl_Color; \n");
2273     break;
2274   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2275     if(num_tex == 0)
2276       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(readtex0.a); \n");
2277     else
2278       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(readtex1.a); \n");
2279     break;
2280   case GR_CMBX_LOCAL_TEXTURE_RGB:
2281     if(num_tex == 0)
2282       strcat(fragment_shader_texture0, "vec4 ctex0s_b = readtex0; \n");
2283     else
2284       strcat(fragment_shader_texture1, "vec4 ctex1s_b = readtex1; \n");
2285     break;
2286   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2287     if(num_tex == 0)
2288       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n");
2289     else
2290       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(ctexture0.a); \n");
2291     break;
2292   case GR_CMBX_OTHER_TEXTURE_RGB:
2293     if(num_tex == 0)
2294       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n");
2295     else
2296       strcat(fragment_shader_texture1, "vec4 ctex1s_b = ctexture0; \n");
2297     break;
2298   case GR_CMBX_TMU_CALPHA:
2299     if(num_tex == 0)
2300       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(ccolor0.a); \n");
2301     else
2302       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(ccolor1.a); \n");
2303     break;
2304   case GR_CMBX_TMU_CCOLOR:
2305     if(num_tex == 0)
2306       strcat(fragment_shader_texture0, "vec4 ctex0s_b = ccolor0; \n");
2307     else
2308       strcat(fragment_shader_texture1, "vec4 ctex1s_b = ccolor1; \n");
2309     break;
2310   default:
2311     display_warning("grTexColorCombineExt : b = %x", b);
2312     if(num_tex == 0)
2313       strcat(fragment_shader_texture0, "vec4 ctex0s_b = vec4(0.0); \n");
2314     else
2315       strcat(fragment_shader_texture1, "vec4 ctex1s_b = vec4(0.0); \n");
2316   }
2317
2318   switch(b_mode)
2319   {
2320   case GR_FUNC_MODE_ZERO:
2321     if(num_tex == 0)
2322       strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(0.0); \n");
2323     else
2324       strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(0.0); \n");
2325     break;
2326   case GR_FUNC_MODE_X:
2327     if(num_tex == 0)
2328       strcat(fragment_shader_texture0, "vec4 ctex0_b = ctex0s_b; \n");
2329     else
2330       strcat(fragment_shader_texture1, "vec4 ctex1_b = ctex1s_b; \n");
2331     break;
2332   case GR_FUNC_MODE_ONE_MINUS_X:
2333     if(num_tex == 0)
2334       strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(1.0) - ctex0s_b; \n");
2335     else
2336       strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(1.0) - ctex1s_b; \n");
2337     break;
2338   case GR_FUNC_MODE_NEGATIVE_X:
2339     if(num_tex == 0)
2340       strcat(fragment_shader_texture0, "vec4 ctex0_b = -ctex0s_b; \n");
2341     else
2342       strcat(fragment_shader_texture1, "vec4 ctex1_b = -ctex1s_b; \n");
2343     break;
2344   default:
2345     display_warning("grTexColorCombineExt : b_mode = %x", b_mode);
2346     if(num_tex == 0)
2347       strcat(fragment_shader_texture0, "vec4 ctex0_b = vec4(0.0); \n");
2348     else
2349       strcat(fragment_shader_texture1, "vec4 ctex1_b = vec4(0.0); \n");
2350   }
2351
2352   switch(c)
2353   {
2354   case GR_CMBX_ZERO:
2355     if(num_tex == 0)
2356       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n");
2357     else
2358       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(0.0); \n");
2359     break;
2360   case GR_CMBX_B:
2361     if(num_tex == 0)
2362       strcat(fragment_shader_texture0, "vec4 ctex0_c = ctex0s_b; \n");
2363     else
2364       strcat(fragment_shader_texture1, "vec4 ctex1_c = ctex1s_b; \n");
2365     break;
2366   case GR_CMBX_DETAIL_FACTOR:
2367     if(num_tex == 0)
2368       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(lambda); \n");
2369     else
2370       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(lambda); \n");
2371     break;
2372   case GR_CMBX_ITRGB:
2373     if(num_tex == 0)
2374       strcat(fragment_shader_texture0, "vec4 ctex0_c = gl_Color; \n");
2375     else
2376       strcat(fragment_shader_texture1, "vec4 ctex1_c = gl_Color; \n");
2377     break;
2378   case GR_CMBX_ITALPHA:
2379     if(num_tex == 0)
2380       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(gl_Color.a); \n");
2381     else
2382       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(gl_Color.a); \n");
2383     break;
2384   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2385     if(num_tex == 0)
2386       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(readtex0.a); \n");
2387     else
2388       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(readtex1.a); \n");
2389     break;
2390   case GR_CMBX_LOCAL_TEXTURE_RGB:
2391     if(num_tex == 0)
2392       strcat(fragment_shader_texture0, "vec4 ctex0_c = readtex0; \n");
2393     else
2394       strcat(fragment_shader_texture1, "vec4 ctex1_c = readtex1; \n");
2395     break;
2396   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2397     if(num_tex == 0)
2398       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n");
2399     else
2400       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(ctexture0.a); \n");
2401     break;
2402   case GR_CMBX_OTHER_TEXTURE_RGB:
2403     if(num_tex == 0)
2404       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n");
2405     else
2406       strcat(fragment_shader_texture1, "vec4 ctex1_c = ctexture0; \n");
2407     break;
2408   case GR_CMBX_TMU_CALPHA:
2409     if(num_tex == 0)
2410       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(ccolor0.a); \n");
2411     else
2412       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(ccolor1.a); \n");
2413     break;
2414   case GR_CMBX_TMU_CCOLOR:
2415     if(num_tex == 0)
2416       strcat(fragment_shader_texture0, "vec4 ctex0_c = ccolor0; \n");
2417     else
2418       strcat(fragment_shader_texture1, "vec4 ctex1_c = ccolor1; \n");
2419     break;
2420   default:
2421     display_warning("grTexColorCombineExt : c = %x", c);
2422     if(num_tex == 0)
2423       strcat(fragment_shader_texture0, "vec4 ctex0_c = vec4(0.0); \n");
2424     else
2425       strcat(fragment_shader_texture1, "vec4 ctex1_c = vec4(0.0); \n");
2426   }
2427
2428   if(c_invert)
2429   {
2430     if(num_tex == 0)
2431       strcat(fragment_shader_texture0, "ctex0_c = vec4(1.0) - ctex0_c; \n");
2432     else
2433       strcat(fragment_shader_texture1, "ctex1_c = vec4(1.0) - ctex1_c; \n");
2434   }
2435
2436   switch(d)
2437   {
2438   case GR_CMBX_ZERO:
2439     if(num_tex == 0)
2440       strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(0.0); \n");
2441     else
2442       strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(0.0); \n");
2443     break;
2444   case GR_CMBX_B:
2445     if(num_tex == 0)
2446       strcat(fragment_shader_texture0, "vec4 ctex0_d = ctex0s_b; \n");
2447     else
2448       strcat(fragment_shader_texture1, "vec4 ctex1_d = ctex1s_b; \n");
2449     break;
2450   case GR_CMBX_ITRGB:
2451     if(num_tex == 0)
2452       strcat(fragment_shader_texture0, "vec4 ctex0_d = gl_Color; \n");
2453     else
2454       strcat(fragment_shader_texture1, "vec4 ctex1_d = gl_Color; \n");
2455     break;
2456   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2457     if(num_tex == 0)
2458       strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(readtex0.a); \n");
2459     else
2460       strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(readtex1.a); \n");
2461     break;
2462   default:
2463     display_warning("grTexColorCombineExt : d = %x", d);
2464     if(num_tex == 0)
2465       strcat(fragment_shader_texture0, "vec4 ctex0_d = vec4(0.0); \n");
2466     else
2467       strcat(fragment_shader_texture1, "vec4 ctex1_d = vec4(0.0); \n");
2468   }
2469
2470   if(d_invert)
2471   {
2472     if(num_tex == 0)
2473       strcat(fragment_shader_texture0, "ctex0_d = vec4(1.0) - ctex0_d; \n");
2474     else
2475       strcat(fragment_shader_texture1, "ctex1_d = vec4(1.0) - ctex1_d; \n");
2476   }
2477
2478   if(num_tex == 0)
2479     strcat(fragment_shader_texture0, "vec4 ctexture0 = (ctex0_a + ctex0_b) * ctex0_c + ctex0_d; \n");
2480   else
2481     strcat(fragment_shader_texture1, "vec4 ctexture1 = (ctex1_a + ctex1_b) * ctex1_c + ctex1_d; \n");
2482   need_to_compile = 1;
2483 }
2484
2485 FX_ENTRY void FX_CALL 
2486 grTexAlphaCombineExt(GrChipID_t       tmu,
2487                      GrTACUColor_t a, GrCombineMode_t a_mode,
2488                      GrTACUColor_t b, GrCombineMode_t b_mode,
2489                      GrTACUColor_t c, FxBool c_invert,
2490                      GrTACUColor_t d, FxBool d_invert,
2491                      FxU32 shift, FxBool invert)
2492 {
2493   int num_tex;
2494   LOG("grTexAlphaCombineExt(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", tmu, a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert);
2495
2496   if (invert) display_warning("grTexAlphaCombineExt : inverted result");
2497   if (shift) display_warning("grTexAlphaCombineExt : shift = %d", shift);
2498
2499   if (tmu == GR_TMU0) num_tex = 1;
2500   else num_tex = 0;
2501
2502   if(num_tex == 0)
2503   {
2504     texture0_combinera_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
2505       ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
2506       ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
2507       ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
2508   }
2509   else
2510   {
2511     texture1_combinera_key = 0x80000000 | (a & 0x1F) | ((a_mode & 3) << 5) | 
2512       ((b & 0x1F) << 7) | ((b_mode & 3) << 12) |
2513       ((c & 0x1F) << 14) | ((c_invert & 1) << 19) |
2514       ((d & 0x1F) << 20) | ((d_invert & 1) << 25);
2515   }
2516
2517   switch(a)
2518   {
2519   case GR_CMBX_ITALPHA:
2520     if(num_tex == 0)
2521       strcat(fragment_shader_texture0, "ctex0s_a.a = gl_Color.a; \n");
2522     else
2523       strcat(fragment_shader_texture1, "ctex1s_a.a = gl_Color.a; \n");
2524     break;
2525   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2526     if(num_tex == 0)
2527       strcat(fragment_shader_texture0, "ctex0s_a.a = readtex0.a; \n");
2528     else
2529       strcat(fragment_shader_texture1, "ctex1s_a.a = readtex1.a; \n");
2530     break;
2531   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2532     if(num_tex == 0)
2533       strcat(fragment_shader_texture0, "ctex0s_a.a = 0.0; \n");
2534     else
2535       strcat(fragment_shader_texture1, "ctex1s_a.a = ctexture0.a; \n");
2536     break;
2537   case GR_CMBX_TMU_CALPHA:
2538     if(num_tex == 0)
2539       strcat(fragment_shader_texture0, "ctex0s_a.a = ccolor0.a; \n");
2540     else
2541       strcat(fragment_shader_texture1, "ctex1s_a.a = ccolor1.a; \n");
2542     break;
2543   default:
2544     display_warning("grTexAlphaCombineExt : a = %x", a);
2545     if(num_tex == 0)
2546       strcat(fragment_shader_texture0, "ctex0s_a.a = 0.0; \n");
2547     else
2548       strcat(fragment_shader_texture1, "ctex1s_a.a = 0.0; \n");
2549   }
2550
2551   switch(a_mode)
2552   {
2553   case GR_FUNC_MODE_ZERO:
2554     if(num_tex == 0)
2555       strcat(fragment_shader_texture0, "ctex0_a.a = 0.0; \n");
2556     else
2557       strcat(fragment_shader_texture1, "ctex1_a.a = 0.0; \n");
2558     break;
2559   case GR_FUNC_MODE_X:
2560     if(num_tex == 0)
2561       strcat(fragment_shader_texture0, "ctex0_a.a = ctex0s_a.a; \n");
2562     else
2563       strcat(fragment_shader_texture1, "ctex1_a.a = ctex1s_a.a; \n");
2564     break;
2565   case GR_FUNC_MODE_ONE_MINUS_X:
2566     if(num_tex == 0)
2567       strcat(fragment_shader_texture0, "ctex0_a.a = 1.0 - ctex0s_a.a; \n");
2568     else
2569       strcat(fragment_shader_texture1, "ctex1_a.a = 1.0 - ctex1s_a.a; \n");
2570     break;
2571   case GR_FUNC_MODE_NEGATIVE_X:
2572     if(num_tex == 0)
2573       strcat(fragment_shader_texture0, "ctex0_a.a = -ctex0s_a.a; \n");
2574     else
2575       strcat(fragment_shader_texture1, "ctex1_a.a = -ctex1s_a.a; \n");
2576     break;
2577   default:
2578     display_warning("grTexAlphaCombineExt : a_mode = %x", a_mode);
2579     if(num_tex == 0)
2580       strcat(fragment_shader_texture0, "ctex0_a.a = 0.0; \n");
2581     else
2582       strcat(fragment_shader_texture1, "ctex1_a.a = 0.0; \n");
2583   }
2584
2585   switch(b)
2586   {
2587   case GR_CMBX_ITALPHA:
2588     if(num_tex == 0)
2589       strcat(fragment_shader_texture0, "ctex0s_b.a = gl_Color.a; \n");
2590     else
2591       strcat(fragment_shader_texture1, "ctex1s_b.a = gl_Color.a; \n");
2592     break;
2593   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2594     if(num_tex == 0)
2595       strcat(fragment_shader_texture0, "ctex0s_b.a = readtex0.a; \n");
2596     else
2597       strcat(fragment_shader_texture1, "ctex1s_b.a = readtex1.a; \n");
2598     break;
2599   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2600     if(num_tex == 0)
2601       strcat(fragment_shader_texture0, "ctex0s_b.a = 0.0; \n");
2602     else
2603       strcat(fragment_shader_texture1, "ctex1s_b.a = ctexture0.a; \n");
2604     break;
2605   case GR_CMBX_TMU_CALPHA:
2606     if(num_tex == 0)
2607       strcat(fragment_shader_texture0, "ctex0s_b.a = ccolor0.a; \n");
2608     else
2609       strcat(fragment_shader_texture1, "ctex1s_b.a = ccolor1.a; \n");
2610     break;
2611   default:
2612     display_warning("grTexAlphaCombineExt : b = %x", b);
2613     if(num_tex == 0)
2614       strcat(fragment_shader_texture0, "ctex0s_b.a = 0.0; \n");
2615     else
2616       strcat(fragment_shader_texture1, "ctex1s_b.a = 0.0; \n");
2617   }
2618
2619   switch(b_mode)
2620   {
2621   case GR_FUNC_MODE_ZERO:
2622     if(num_tex == 0)
2623       strcat(fragment_shader_texture0, "ctex0_b.a = 0.0; \n");
2624     else
2625       strcat(fragment_shader_texture1, "ctex1_b.a = 0.0; \n");
2626     break;
2627   case GR_FUNC_MODE_X:
2628     if(num_tex == 0)
2629       strcat(fragment_shader_texture0, "ctex0_b.a = ctex0s_b.a; \n");
2630     else
2631       strcat(fragment_shader_texture1, "ctex1_b.a = ctex1s_b.a; \n");
2632     break;
2633   case GR_FUNC_MODE_ONE_MINUS_X:
2634     if(num_tex == 0)
2635       strcat(fragment_shader_texture0, "ctex0_b.a = 1.0 - ctex0s_b.a; \n");
2636     else
2637       strcat(fragment_shader_texture1, "ctex1_b.a = 1.0 - ctex1s_b.a; \n");
2638     break;
2639   case GR_FUNC_MODE_NEGATIVE_X:
2640     if(num_tex == 0)
2641       strcat(fragment_shader_texture0, "ctex0_b.a = -ctex0s_b.a; \n");
2642     else
2643       strcat(fragment_shader_texture1, "ctex1_b.a = -ctex1s_b.a; \n");
2644     break;
2645   default:
2646     display_warning("grTexAlphaCombineExt : b_mode = %x", b_mode);
2647     if(num_tex == 0)
2648       strcat(fragment_shader_texture0, "ctex0_b.a = 0.0; \n");
2649     else
2650       strcat(fragment_shader_texture1, "ctex1_b.a = 0.0; \n");
2651   }
2652
2653   switch(c)
2654   {
2655   case GR_CMBX_ZERO:
2656     if(num_tex == 0)
2657       strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n");
2658     else
2659       strcat(fragment_shader_texture1, "ctex1_c.a = 0.0; \n");
2660     break;
2661   case GR_CMBX_B:
2662     if(num_tex == 0)
2663       strcat(fragment_shader_texture0, "ctex0_c.a = ctex0s_b.a; \n");
2664     else
2665       strcat(fragment_shader_texture1, "ctex1_c.a = ctex1s_b.a; \n");
2666     break;
2667   case GR_CMBX_DETAIL_FACTOR:
2668     if(num_tex == 0)
2669       strcat(fragment_shader_texture0, "ctex0_c.a = lambda; \n");
2670     else
2671       strcat(fragment_shader_texture1, "ctex1_c.a = lambda; \n");
2672     break;
2673   case GR_CMBX_ITALPHA:
2674     if(num_tex == 0)
2675       strcat(fragment_shader_texture0, "ctex0_c.a = gl_Color.a; \n");
2676     else
2677       strcat(fragment_shader_texture1, "ctex1_c.a = gl_Color.a; \n");
2678     break;
2679   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2680     if(num_tex == 0)
2681       strcat(fragment_shader_texture0, "ctex0_c.a = readtex0.a; \n");
2682     else
2683       strcat(fragment_shader_texture1, "ctex1_c.a = readtex1.a; \n");
2684     break;
2685   case GR_CMBX_OTHER_TEXTURE_ALPHA:
2686     if(num_tex == 0)
2687       strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n");
2688     else
2689       strcat(fragment_shader_texture1, "ctex1_c.a = ctexture0.a; \n");
2690     break;
2691   case GR_CMBX_TMU_CALPHA:
2692     if(num_tex == 0)
2693       strcat(fragment_shader_texture0, "ctex0_c.a = ccolor0.a; \n");
2694     else
2695       strcat(fragment_shader_texture1, "ctex1_c.a = ccolor1.a; \n");
2696     break;
2697   default:
2698     display_warning("grTexAlphaCombineExt : c = %x", c);
2699     if(num_tex == 0)
2700       strcat(fragment_shader_texture0, "ctex0_c.a = 0.0; \n");
2701     else
2702       strcat(fragment_shader_texture1, "ctex1_c.a = 0.0; \n");
2703   }
2704
2705   if(c_invert)
2706   {
2707     if(num_tex == 0)
2708       strcat(fragment_shader_texture0, "ctex0_c.a = 1.0 - ctex0_c.a; \n");
2709     else
2710       strcat(fragment_shader_texture1, "ctex1_c.a = 1.0 - ctex1_c.a; \n");
2711   }
2712
2713   switch(d)
2714   {
2715   case GR_CMBX_ZERO:
2716     if(num_tex == 0)
2717       strcat(fragment_shader_texture0, "ctex0_d.a = 0.0; \n");
2718     else
2719       strcat(fragment_shader_texture1, "ctex1_d.a = 0.0; \n");
2720     break;
2721   case GR_CMBX_B:
2722     if(num_tex == 0)
2723       strcat(fragment_shader_texture0, "ctex0_d.a = ctex0s_b.a; \n");
2724     else
2725       strcat(fragment_shader_texture1, "ctex1_d.a = ctex1s_b.a; \n");
2726     break;
2727   case GR_CMBX_ITALPHA:
2728     if(num_tex == 0)
2729       strcat(fragment_shader_texture0, "ctex0_d.a = gl_Color.a; \n");
2730     else
2731       strcat(fragment_shader_texture1, "ctex1_d.a = gl_Color.a; \n");
2732     break;
2733   case GR_CMBX_ITRGB:
2734     if(num_tex == 0)
2735       strcat(fragment_shader_texture0, "ctex0_d.a = gl_Color.a; \n");
2736     else
2737       strcat(fragment_shader_texture1, "ctex1_d.a = gl_Color.a; \n");
2738     break;
2739   case GR_CMBX_LOCAL_TEXTURE_ALPHA:
2740     if(num_tex == 0)
2741       strcat(fragment_shader_texture0, "ctex0_d.a = readtex0.a; \n");
2742     else
2743       strcat(fragment_shader_texture1, "ctex1_d.a = readtex1.a; \n");
2744     break;
2745   default:
2746     display_warning("grTexAlphaCombineExt : d = %x", d);
2747     if(num_tex == 0)
2748       strcat(fragment_shader_texture0, "ctex0_d.a = 0.0; \n");
2749     else
2750       strcat(fragment_shader_texture1, "ctex1_d.a = 0.0; \n");
2751   }
2752
2753   if(d_invert)
2754   {
2755     if(num_tex == 0)
2756       strcat(fragment_shader_texture0, "ctex0_d.a = 1.0 - ctex0_d.a; \n");
2757     else
2758       strcat(fragment_shader_texture1, "ctex1_d.a = 1.0 - ctex1_d.a; \n");
2759   }
2760
2761   if(num_tex == 0)
2762     strcat(fragment_shader_texture0, "ctexture0.a = (ctex0_a.a + ctex0_b.a) * ctex0_c.a + ctex0_d.a; \n");
2763   else
2764     strcat(fragment_shader_texture1, "ctexture1.a = (ctex1_a.a + ctex1_b.a) * ctex1_c.a + ctex1_d.a; \n");
2765
2766   need_to_compile = 1;
2767 }
2768
2769 FX_ENTRY void FX_CALL
2770 grConstantColorValueExt(GrChipID_t    tmu,
2771                         GrColor_t     value)
2772 {
2773   int num_tex;
2774   LOG("grConstantColorValueExt(%d,%d)\r\n", tmu, value);
2775
2776   if (tmu == GR_TMU0) num_tex = 1;
2777   else num_tex = 0;
2778
2779   switch(lfb_color_fmt)
2780   {
2781   case GR_COLORFORMAT_ARGB:
2782     if(num_tex == 0)
2783     {
2784       ccolor0[3] = ((value >> 24) & 0xFF) / 255.0f;
2785       ccolor0[0] = ((value >> 16) & 0xFF) / 255.0f;
2786       ccolor0[1] = ((value >>  8) & 0xFF) / 255.0f;
2787       ccolor0[2] = (value & 0xFF) / 255.0f;
2788     }
2789     else
2790     {
2791       ccolor1[3] = ((value >> 24) & 0xFF) / 255.0f;
2792       ccolor1[0] = ((value >> 16) & 0xFF) / 255.0f;
2793       ccolor1[1] = ((value >>  8) & 0xFF) / 255.0f;
2794       ccolor1[2] = (value & 0xFF) / 255.0f;
2795     }
2796     break;
2797   case GR_COLORFORMAT_RGBA:
2798     if(num_tex == 0)
2799     {
2800       ccolor0[0] = ((value >> 24) & 0xFF) / 255.0f;
2801       ccolor0[1] = ((value >> 16) & 0xFF) / 255.0f;
2802       ccolor0[2] = ((value >>  8) & 0xFF) / 255.0f;
2803       ccolor0[3] = (value & 0xFF) / 255.0f;
2804     }
2805     else
2806     {
2807       ccolor1[0] = ((value >> 24) & 0xFF) / 255.0f;
2808       ccolor1[1] = ((value >> 16) & 0xFF) / 255.0f;
2809       ccolor1[2] = ((value >>  8) & 0xFF) / 255.0f;
2810       ccolor1[3] = (value & 0xFF) / 255.0f;
2811     }
2812     break;
2813   default:
2814     display_warning("grConstantColorValue: unknown color format : %x", lfb_color_fmt);
2815   }
2816
2817   vbo_draw();
2818   if(num_tex == 0)
2819   {
2820     ccolor0_location = glGetUniformLocation(program_object, "ccolor0");
2821     glUniform4f(ccolor0_location, ccolor0[0], ccolor0[1], ccolor0[2], ccolor0[3]);
2822   }
2823   else
2824   {
2825     ccolor1_location = glGetUniformLocation(program_object, "ccolor1");
2826     glUniform4f(ccolor1_location, ccolor1[0], ccolor1[1], ccolor1[2], ccolor1[3]);
2827   }
2828 }