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