Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / OGLCombinerNV.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19 #include "OGLExtensions.h"
20
21 #include "OGLCombinerNV.h"
22 #include "OGLRender.h"
23 #include "OGLGraphicsContext.h"
24
25 //========================================================================
26 #define MUX_E_F             (MUX_PRIMLODFRAC+1)
27 #define MUX_SPARE1          (MUX_E_F+1)
28 #define MUX_SECONDARY_COLOR (MUX_SPARE1+1)
29 #define MUX_NOT_USED        MUX_ERR
30 #define MUX_COMBINED_SIGNED     (MUX_SECONDARY_COLOR+1)     //Use only by Nvidia register combiner
31
32
33 typedef struct {
34     GLenum  input;
35     GLenum  mapping;
36     GLenum  componentUsage;
37 }RGBMapType;
38
39 RGBMapType RGBmap1[] =
40 {
41     {GL_ZERO,                   GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_0 = 0,
42     {GL_ZERO,                   GL_UNSIGNED_INVERT_NV,      GL_RGB},    //MUX_1,    = ZERO NEG
43     {GL_SPARE0_NV,              GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_COMBINED,
44     {GL_TEXTURE0_ARB,           GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_TEXEL0,
45     {GL_TEXTURE1_ARB,           GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_TEXEL1,
46     {GL_CONSTANT_COLOR0_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_PRIM,
47     {GL_PRIMARY_COLOR_NV,       GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_SHADE,
48     {GL_CONSTANT_COLOR1_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_ENV,
49     {GL_SPARE0_NV,              GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_COMBALPHA,
50     {GL_TEXTURE0_ARB,           GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_T0_ALPHA,
51     {GL_TEXTURE1_ARB,           GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_T1_ALPHA,
52     {GL_CONSTANT_COLOR0_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_PRIM_ALPHA,
53     {GL_PRIMARY_COLOR_NV,       GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_SHADE_ALPHA,
54     {GL_CONSTANT_COLOR1_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_ALPHA},  //MUX_ENV_ALPHA,
55     {GL_CONSTANT_COLOR1_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_LODFRAC,
56     {GL_CONSTANT_COLOR1_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_PRIMLODFRAC,
57     {GL_E_TIMES_F_NV,           GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_E_F,
58     {GL_SPARE1_NV,              GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_SPARE1,
59     {GL_SECONDARY_COLOR_NV,     GL_UNSIGNED_IDENTITY_NV,    GL_RGB},    //MUX_SECONDARY_COLOR,
60     {GL_SPARE0_NV,              GL_SIGNED_IDENTITY_NV,      GL_RGB},    //MUX_COMBINED_SIGNED,
61 };
62
63
64 //========================================================================
65 COGLColorCombinerNvidia::COGLColorCombinerNvidia(CRender *pRender) :
66     COGLColorCombiner4(pRender)
67 {
68     m_bNVSupported = false;
69     delete m_pDecodedMux;
70     m_pDecodedMux = new COGLDecodedMux;
71     m_pDecodedMux->m_maxConstants=2;
72 }
73
74 COGLColorCombinerNvidia::~COGLColorCombinerNvidia()
75 {
76     m_vCompiledSettings.clear();
77 }
78
79
80 bool COGLColorCombinerNvidia::Initialize(void)
81 {
82     m_bNVSupported = false;
83
84     if( COGLColorCombiner4::Initialize() )
85     {
86         m_bSupportMultiTexture = true;
87         
88         COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
89         if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") || pcontext->IsExtensionSupported("GL_NV_register_combiners") )
90         {
91             m_bNVSupported = true;
92             glEnable(GL_REGISTER_COMBINERS_NV);
93             return true;
94         }
95         else
96         {
97             DebugMessage(M64MSG_ERROR, "Your video card does not support Nvidia OpenGL extension combiner");
98             glDisable(GL_REGISTER_COMBINERS_NV);
99             return false;
100         }
101     }
102
103     glDisable(GL_REGISTER_COMBINERS_NV);
104     return false;
105 }
106
107 void COGLColorCombinerNvidia::InitCombinerCycle12(void)
108 {
109     if( !m_bNVSupported )   {COGLColorCombiner4::InitCombinerCycle12(); return;}
110
111     glEnable(GL_REGISTER_COMBINERS_NV);
112
113 #ifdef DEBUGGER
114     if( debuggerDropCombiners )
115     {
116         m_vCompiledSettings.clear();
117         m_dwLastMux0 = m_dwLastMux1 = 0;
118         debuggerDropCombiners = false;
119     }
120 #endif
121
122     m_pOGLRender->EnableMultiTexture();
123     bool combinerIsChanged = false;
124
125     if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1  || m_lastIndex < 0 )
126     {
127         combinerIsChanged = true;
128         m_lastIndex = FindCompiledMux();
129         if( m_lastIndex < 0 )       // Can not found
130         {
131             NVRegisterCombinerParserType result;
132             ParseDecodedMux(result);
133             m_lastIndex= SaveParserResult(result);
134         }
135
136         m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
137         m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
138         GenerateNVRegisterCombinerSetting(m_lastIndex);
139     }
140
141     m_pOGLRender->SetAllTexelRepeatFlag();
142
143     if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
144     {
145         gRDP.texturesAreReloaded = false; 
146         if( m_bCycleChanged || combinerIsChanged )
147         {
148             GenerateNVRegisterCombinerSettingConstants(m_lastIndex);
149             GenerateNVRegisterCombinerSetting(m_lastIndex);
150             ApplyFogAtFinalStage();
151         }
152         else if( gRDP.colorsAreReloaded )
153         {
154             GenerateNVRegisterCombinerSettingConstants(m_lastIndex);
155         }
156
157         gRDP.colorsAreReloaded = false;
158     }
159 }
160
161 void COGLColorCombinerNvidia::ParseDecodedMux(NVRegisterCombinerParserType &result) // Compile the decodedMux into NV register combiner setting
162 {
163     //int stagesForRGB=0;
164     //int stagesForAlpha=0;
165     //int stages=0;
166
167     COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
168     mux.To_AB_Add_CD_Format();
169
170     result.stagesUsed=0;
171
172     if( StagesNeedToUse(mux, N64Cycle0RGB) == 0 )
173     {
174         // Nothing to be done for RGB
175         ByPassGeneralStage(result.s1rgb);
176         ByPassGeneralStage(result.s2rgb);
177         ByPassFinalStage(result.finalrgb);
178     }
179     else if( StagesNeedToUse(mux, N64Cycle0RGB) == 1 )
180     {
181         result.stagesUsed = 1;
182         Parse1Mux(mux, N64Cycle0RGB, result.s1rgb);
183         if( StagesNeedToUse(mux, N64Cycle1RGB) == 0 )
184         {
185             ByPassGeneralStage(result.s2rgb);
186             ByPassFinalStage(result.finalrgb);
187         }
188         else
189         {
190             result.stagesUsed = 2;
191             Parse1MuxForStage2AndFinalStage(mux, N64Cycle1RGB, result.s2rgb, result.finalrgb);
192         }
193     }
194     else
195     {
196         result.stagesUsed = 2;
197         Parse1Mux2Stages(mux, N64Cycle0RGB, result.s1rgb, result.s2rgb);
198         Parse1MuxForFinalStage(mux, N64Cycle1RGB, result.finalrgb);
199     }
200
201     // Debug texel1
202     /*
203     if( m_pDecodedMux->m_bTexel0IsUsed && m_pDecodedMux->m_bTexel1IsUsed )
204     {
205         result.finalrgb.a = MUX_TEXEL0;
206         result.finalrgb.b = MUX_TEXEL1;
207         result.finalrgb.c = MUX_0;
208         result.finalrgb.d = MUX_0;
209     }
210     */
211
212     if( StagesNeedToUse(mux, N64Cycle0Alpha) == 0 )
213     {
214         // Nothing to be done for Alpha
215         ByPassGeneralStage(result.s1alpha);
216         ByPassGeneralStage(result.s2alpha);
217         ByPassFinalStage(result.finalalpha);
218     }
219     else if( Parse1Mux2Stages(mux, N64Cycle0Alpha, result.s1alpha, result.s2alpha) == 1 )
220     {
221         // Only 1 NV stage is used
222         if( result.stagesUsed == 0 )    result.stagesUsed = 1;
223         if( StagesNeedToUse(mux, N64Cycle1Alpha) == 0 )
224         {
225             ByPassGeneralStage(result.s2alpha);
226         }
227         else
228         {
229             Parse1Mux(mux, N64Cycle1Alpha, result.s2alpha);
230             result.stagesUsed = 2;
231         }
232     }
233     else
234     {
235         // The 1st is used 2 stages, skip the 2nd N64 alpha setting
236         result.stagesUsed = 2;
237         result.s2alpha.a=MUX_COMBINED;
238         result.s2alpha.b=MUX_1;
239         result.s2alpha.c=m_pDecodedMux->m_n64Combiners[N64Cycle0Alpha].d;
240         result.s2alpha.d=MUX_1;
241     }
242
243     // Parse Alpha setting, alpha does not have a final stage
244     ByPassFinalStage(result.finalalpha);
245     ParseDecodedMuxForConstant(result);
246 }
247
248 void COGLColorCombinerNvidia::ParseDecodedMuxForConstant(NVRegisterCombinerParserType &result)
249 {
250     result.constant0 = MUX_0;
251     result.constant1 = MUX_0;
252     bool const0Used=false;
253     bool const1Used=false;
254     if( m_pDecodedMux->isUsed(MUX_PRIM) )
255     {
256         result.constant0 = MUX_PRIM;
257         const0Used = true;
258     }
259     if( m_pDecodedMux->isUsed(MUX_ENV) )
260     {
261         if( const0Used )
262         {
263             result.constant1 = MUX_ENV;
264             const1Used = true;
265         }
266         else
267         {
268             result.constant0 = MUX_ENV;
269             const0Used = true;
270         }
271     }
272     if( m_pDecodedMux->isUsed(MUX_LODFRAC) && !const1Used )
273     {
274         if( !const1Used )
275         {
276             result.constant1 = MUX_LODFRAC;
277             const1Used = true;
278         }
279         else if( !const0Used )
280         {
281             result.constant0 = MUX_LODFRAC;
282             const0Used = true;
283         }
284     }
285
286     if( m_pDecodedMux->isUsed(MUX_PRIMLODFRAC) && !const1Used )
287     {
288         if( !const1Used )
289         {
290             result.constant1 = MUX_PRIMLODFRAC;
291             const1Used = true;
292         }
293         else if( !const0Used )
294         {
295             result.constant0 = MUX_PRIMLODFRAC;
296             const0Used = true;
297         }
298     }
299 }
300
301 int COGLColorCombinerNvidia::StagesNeedToUse(COGLDecodedMux &mux, N64StageNumberType stage)
302 {
303     N64CombinerType &m = mux.m_n64Combiners[stage];
304
305     switch(mux.splitType[stage])
306     {
307     case CM_FMT_TYPE_NOT_USED:
308         return 0;
309     case CM_FMT_TYPE_D:             // = A              ==> can be done in 1 NV stage
310     case CM_FMT_TYPE_A_ADD_D:           // = A+D            ==> can be done in 1 NV stage
311     case CM_FMT_TYPE_A_MOD_C:           // = A*C            ==> can be done in 1 NV stage
312     case CM_FMT_TYPE_A_SUB_B:           // = A-B            ==> can be done in 1 NV stage
313     case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D          ==> can be done in 1 NV stage
314     case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B      ==> can be done in 1 NV stage
315     case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C        ==> can be done in 1 NV stage
316     case CM_FMT_TYPE_AB_ADD_CD:         // = AB+CD
317     case CM_FMT_TYPE_AB_SUB_CD:         // = AB-CD
318         return 1;
319     case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D          ==> can not be done in 1 stage
320         if( m.a == m.d )    // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
321             return 1;
322         else    // Need two NV stages for this N64 combiner
323             return 2;
324     case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D      ==> can not be done in 1 stage
325     default:
326         //if( m.a == m.d )  // = (A-B)*C+A = A(C+1)-B*C = A-B*C
327         //  return 1;
328         //else 
329         if( m.d == m.c )    // = (A-B)*C+C = A*C+(1-B)*C
330             return 1;
331         else    // = (A-B)*C+D, need two NV stages
332             return 2;
333     }
334 }
335
336 bool isTex(uint8 val)
337 {
338     if( (val&MUX_MASK) == MUX_TEXEL0 || (val&MUX_MASK) == MUX_TEXEL1 )
339         return true;
340     else
341         return false;
342 }
343 int COGLColorCombinerNvidia::Parse1Mux(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res)           // Compile the decodedMux into NV register combiner setting
344 {
345     // Parse 1 N64 combiner, generate result and return how many NV stage is needed.
346     // result will be put into only 1 NV stage, not the 2nd one even if 2nd one is needed.
347     // The caller of this function will handle the 2nd NV stage if it is needed
348
349
350     // Up to here, the m_pDecodedMux is already simplied, N64 stage 1 and stage 2 have been
351     // adjusted so stage1 is almost always complicated than stage 2
352
353     // The stage type in decodedMux is still in (A-B)*C+D format
354     // we need to parser and translate it to A*B+C*D format for NV register general combiner
355     // and to A*D+(1-A)*C+D format for the NV final combiner
356
357     // Remember that N64 has two stages, NV has two general combiner stages and 1 final combiner stage
358     // NV should be able to simulate exactly all possible N64 combiner settings
359 /*
360     CM_FMT_TYPE1_D,                 // = A              ==> can be done in 1 NV stage
361     CM_FMT_TYPE2_A_ADD_D,           // = A+D            ==> can be done in 1 NV stage
362     CM_FMT_TYPE3_A_MOD_C,           // = A*C            ==> can be done in 1 NV stage
363     CM_FMT_TYPE4_A_SUB_B,           // = A-B            ==> can be done in 1 NV stage
364     CM_FMT_TYPE5_A_MOD_C_ADD_D,     // = A*C+D          ==> can be done in 1 NV stage
365     CM_FMT_TYPE6_A_LERP_B_C,        // = (A-B)*C+B      ==> can be done in 1 NV stage
366     CM_FMT_TYPE8_A_SUB_B_MOD_C,     // = (A-B)*C        ==> can be done in 1 NV stage
367     
368     CM_FMT_TYPE7_A_SUB_B_ADD_D,     // = A-B+C          ==> can not be done in 1 stage
369     CM_FMT_TYPE9_A_B_C_D,           // = (A-B)*C+D      ==> can not be done in 1 stage
370
371     the last two ones, since we can neither do it in the final stage, if the 1st N64 stage
372     happen to be one of the two types and have used the two NV general combiners, and if the 2nd N64
373     combiner happens to be one of the two types as well, then we have to simplify the N64 combiner so
374     to implement it. In such as case, the N64 combiners are too complicated, we just do what either as
375     we can to implement it.
376
377     Use UNSIGNED_INVERT of ZERO ==> ONE
378
379     // If the 1st N64 stage can not be done in 1 NV stage, then we will do 1st N64 stage
380     // by using 2 NV general combiner stages, and the 2nd N64 stage by using the NV final
381     // combiner stage.
382
383     // RGB channel and alpha channel is the same in the general combiner, but different in
384     // the final combiner. In fact, final combiner does not do anything for alpha channel
385     // so alpha channel setting of both N64 combiner must be implemented by the two NV general
386     // combiner
387
388     If we can not implement the two alpha setting in 2 NV combiner stages, we will do what either
389     as we can.
390
391     */
392     N64CombinerType &m = mux.m_n64Combiners[stage];
393
394     switch(mux.splitType[stage])
395     {
396     case CM_FMT_TYPE_NOT_USED:
397         res.a=MUX_0;
398         res.b=MUX_0;
399         res.c=MUX_0;
400         res.d=MUX_0;
401         return 0;
402         break;
403     case CM_FMT_TYPE_D:             // = A              ==> can be done in 1 NV stage
404         res.a=m.d;
405         res.b=MUX_1;
406         res.c=MUX_0;
407         res.d=MUX_0;
408         return 1;
409         break;
410     case CM_FMT_TYPE_A_ADD_D:           // = A+D            ==> can be done in 1 NV stage
411         res.a=m.a;
412         res.b=MUX_1;
413         res.c=m.d;
414         res.d=MUX_1;
415         return 1;
416         break;
417     case CM_FMT_TYPE_A_MOD_C:           // = A*C            ==> can be done in 1 NV stage
418         res.a=m.a;
419         res.b=m.c;
420         res.c=MUX_0;
421         res.d=MUX_0;
422         return 1;
423         break;
424     case CM_FMT_TYPE_A_SUB_B:           // = A-B            ==> can be done in 1 NV stage
425         res.a=m.a;
426         res.b=MUX_1;
427         res.c=m.b|MUX_NEG;
428         res.d=MUX_1;
429         return 1;
430         break;
431     case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D          ==> can be done in 1 NV stage
432         res.a=m.a;
433         res.b=m.c;
434         res.c=m.d;
435         res.d=MUX_1;
436         return 1;
437         break;
438     case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B      ==> can be done in 1 NV stage
439                                         // = AC+(1-C)B
440         res.a=m.a;
441         res.b=m.c;
442         res.c=m.c^MUX_COMPLEMENT;
443         res.d=m.b;
444         return 1;
445         break;
446     case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C        ==> can be done in 1 NV stage
447         res.a=m.a;
448         res.b=m.c;
449         res.c=m.b|MUX_NEG;
450         res.d=m.c;
451         return 1;
452         break;
453     case CM_FMT_TYPE_AB_ADD_CD:         // = AB+CD
454         res.a = m.a;
455         res.b = m.b;
456         res.c = m.c;
457         res.d = m.d;
458         return 1;
459         break;
460     case CM_FMT_TYPE_AB_SUB_CD:         // = AB-CD
461         res.a = m.a;
462         res.b = m.b;
463         res.c = m.c|MUX_NEG;
464         res.d = m.d;
465         return 1;
466         break;
467     case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D          ==> can not be done in 1 stage
468         if( m.a == m.d )    // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
469         {
470             res.a=m.a;
471             res.b=MUX_1;
472             res.c=m.b|MUX_NEG;
473             res.d=MUX_1;
474             return 1;
475         }
476         else    // Need two NV stages for this N64 combiner
477         {
478             // Stage 1: R1=A-B
479             res.a=m.a;
480             res.b=MUX_1;
481
482             if( isTex(res.b) || !isTex(res.d) )
483             {
484                 res.c=m.b|MUX_NEG;
485                 res.d=MUX_1;
486             }
487             else
488             {
489                 res.c=m.d;
490                 res.d=MUX_1;
491             }
492             return 2;
493         }
494         break;
495     case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D      ==> can not be done in 1 stage
496     default:
497         if( m.a == m.d )    // = (A-B)*C+A = A(C+1)-B*C = A-B*C
498         {
499             res.a=m.a;
500             res.b=m.c;
501             res.c=m.b|MUX_NEG;
502             res.d=m.c;
503             return 1;
504         }
505         else if( m.d == m.c )   // = (A-B)*C+C = A*C+(1-B)*C
506         {
507             res.a=m.a;
508             res.b=m.c;
509             res.c=m.b^MUX_COMPLEMENT;
510             res.d=m.c;
511             return 1;
512         }
513         else    // = (A-B)*C+D, need two NV stages
514         {
515             // Stage 1: R1=(A-B)*C = AC-BC
516             if( isTex(m.d) )
517             {
518                 // = A*C+D
519                 res.a=m.a;
520                 res.b=m.c;
521                 res.c=m.d;
522                 res.d=MUX_1;
523             }
524             else
525             {
526                 // = (A-B)*C = A*C - B*C
527                 res.a=m.a;
528                 res.b=m.c;
529                 res.c=m.b|MUX_NEG;
530                 res.d=m.c;
531             }
532             return 2;
533         }
534         break;
535     }
536 }
537
538 int COGLColorCombinerNvidia::Parse1Mux2Stages(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res, NVGeneralCombinerType &res2)
539 {
540     N64CombinerType &m = mux.m_n64Combiners[stage];
541     switch(mux.splitType[stage])
542     {
543     case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D          ==> can not be done in 1 stage
544         if( m.a != m.d )    // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
545         {
546             // Stage 1: R1=A-B
547             res.a=m.a;
548             res.b=MUX_1;
549             res.c=m.b|MUX_NEG;
550             res.d=MUX_1;
551
552             res2.a=MUX_COMBINED_SIGNED;
553             res2.b=MUX_1;
554             res2.c=m.d;
555             res2.d=MUX_1;
556
557             return 2;
558         }
559         break;
560     case CM_FMT_TYPE_A_B_C_D:       // = (A-B)*C+D      ==> can not be done in 1 stage
561     case CM_FMT_TYPE_A_B_C_A:       // = (A-B)*C+D      ==> can not be done in 1 stage
562         //if( m.a != m.d && m.d != m.c )
563         {
564             // Stage 1: R1=(A-B)*C = AC-BC
565             res.a=m.a;
566             res.b=m.c;
567             res.c=m.b|MUX_NEG;
568             res.d=m.c;
569
570             res2.a=MUX_COMBINED_SIGNED;
571             res2.b=MUX_1;
572             res2.c=m.d;
573             res2.d=MUX_1;
574
575             return 2;
576         }
577         break;
578      default:
579        break;
580     }
581     return Parse1Mux(mux, stage, res);
582 }
583
584
585 void COGLColorCombinerNvidia::Parse1MuxForFinalStage(COGLDecodedMux &mux, N64StageNumberType stage, NVFinalCombinerType &res)
586 {
587     N64CombinerType &m = mux.m_n64Combiners[stage];
588
589     // Final stage equation is: AB+(1-A)C+D
590     switch(mux.splitType[stage])
591     {
592     case CM_FMT_TYPE_NOT_USED:
593         res.a=MUX_0;
594         res.b=MUX_0;
595         res.c=MUX_0;
596         res.d=MUX_0;
597         break;
598     case CM_FMT_TYPE_D:             // = A              ==> can be done in 1 NV stage
599         res.a=m.a;
600         res.b=MUX_1;
601         res.c=MUX_0;
602         res.d=MUX_0;
603         break;
604     case CM_FMT_TYPE_A_ADD_D:           // = A+D            ==> can be done in 1 NV stage
605         res.a=m.a;
606         res.b=MUX_1;
607         res.c=MUX_0;
608         res.d=m.d;
609         break;
610     case CM_FMT_TYPE_A_MOD_C:           // = A*C            ==> can be done in 1 NV stage
611         res.a=m.a;
612         res.b=m.c;
613         res.c=MUX_0;
614         res.d=MUX_0;
615         break;
616     case CM_FMT_TYPE_A_SUB_B:           // = A-B            ==> can be done in 1 NV stage
617         res.a=m.a;
618         res.b=MUX_1;
619         res.c=MUX_0;
620         res.d=m.b|MUX_NEG;
621         break;
622     case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D          ==> can be done in 1 NV stage
623         res.a=m.a;
624         res.b=m.c;
625         res.c=MUX_0;
626         res.d=m.d;
627         break;
628     case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B      ==> can be done in 1 NV stage
629                                         // = AC+(1-B)C
630         res.a = m.c;
631         res.b = MUX_0;
632         res.c = m.b;
633         res.d = MUX_E_F;
634         res.e = m.a;
635         res.f = m.c;
636         break;
637     case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C        ==> can be done in 1 NV stage
638         res.a=m.c;
639         res.b=m.a;
640         res.c=m.b;
641         res.d=m.b|MUX_NEG;
642         break;
643     case CM_FMT_TYPE_AB_ADD_CD:         // = AB+CD
644         res.a = m.a;
645         res.b = m.b;
646         res.e = m.c;
647         res.f = m.d;
648         res.c = MUX_0;
649         res.d = MUX_E_F;
650         break;
651     case CM_FMT_TYPE_AB_SUB_CD:         // = AB-CD
652         res.a = m.a;
653         res.b = m.b;
654         res.e = m.c|MUX_NEG;
655         res.f = m.d;
656         res.c = MUX_0;
657         res.d = MUX_E_F;
658         break;
659     case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D          ==> can not be done in 1 stage
660         if( m.a == m.d )    // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
661         {
662             res.a=m.a;
663             res.b=MUX_1;
664             res.c=MUX_0;
665             res.d=m.b|MUX_NEG;
666         }
667         else    // Need two NV stages for this N64 combiner
668         {
669             TRACE0("NV Combiner parse, check me, not fully support this combiner");
670             // final combiner can not fully support this combiner setting
671             // Stage 1: R1=A-B
672             res.a=m.a;
673             res.b=MUX_1;
674             res.c=MUX_0;
675             res.d=m.b|MUX_NEG;
676         }
677         break;
678     case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D      ==> can not be done in 1 stage
679     default:
680         if( m.a == m.d )    // = (A-B)*C+A = A(C+1)-B*C = A-B*C
681         {
682             /*
683             res.a=m.c;
684             res.b=m.b|MUX_NEG;
685             res.c=MUX_0;
686             res.d=m.a;
687             */
688             res.a=m.c;
689             res.b=m.a;
690             res.c=m.b;
691             res.d=MUX_0;
692         }
693         else if( m.d == m.c )   // = (A-B)*C+C = A*C+(1-B)*C
694         {
695             res.a=m.b;
696             res.b=MUX_0;
697             res.c=m.c;
698             res.d=MUX_E_F;
699             res.e=m.a;
700             res.f=m.c;
701         }
702         else    // = (A-B)*C+D, need two NV stages
703         {
704             TRACE0("NV Combiner parse, check me, not fully support this combiner");
705             // final combiner can not fully support this combiner setting
706             // Stage 1: R1=(A-B)*C = AC-BC
707             res.a=m.c;
708             res.b=m.a;
709             res.c=m.b;
710             res.d=m.b|MUX_NEG;
711         }
712         break;
713     }
714     res.g=MUX_COMBINED;
715 }
716
717 int COGLColorCombinerNvidia::Parse1MuxForStage2AndFinalStage(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res, NVFinalCombinerType &fres)
718 {
719     if( Parse1Mux(mux, stage, res) == 1 )
720     {
721         ByPassFinalStage(fres);
722         return 1;
723     }
724     else
725     {
726         ByPassFinalStage(fres);
727         fres.a=MUX_COMBINED;
728         fres.b=MUX_1;
729         fres.d = mux.m_n64Combiners[stage].d;
730         fres.g=MUX_COMBINED;
731         return 2;
732     }
733 }
734
735 void COGLColorCombinerNvidia::ByPassFinalStage(NVFinalCombinerType &fres)
736 {
737     fres.a=MUX_0;
738     fres.b=MUX_0;
739     fres.c=MUX_0;
740     fres.d=MUX_COMBINED;
741     fres.e=MUX_0;
742     fres.f=MUX_0;
743     fres.g=MUX_COMBINED;
744 }
745
746 void COGLColorCombinerNvidia::ByPassGeneralStage(NVGeneralCombinerType &res)
747 {
748     res.a=MUX_1;
749     res.b=MUX_COMBINED;
750     res.c=MUX_0;
751     res.d=MUX_0;
752 }
753
754 int COGLColorCombinerNvidia::FindCompiledMux(void)
755 {
756     for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
757     {
758         if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
759             return i;
760     }
761
762     return -1;
763 }
764 void COGLColorCombinerNvidia::GenerateNVRegisterCombinerSettingConstants(int index)
765 {
766     NVRegisterCombinerSettingType &info = m_vCompiledSettings[index];
767     uint8 consts[2] = {info.constant0,info.constant1};
768
769     float *pf;
770
771     for( int i=0; i<2; i++ )
772     {
773         switch( consts[i] )
774         {
775         case MUX_PRIM:
776             pf = GetPrimitiveColorfv();
777             pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,pf);
778             break;
779         case MUX_ENV:
780             pf = GetEnvColorfv();
781             pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,pf);
782             break;
783         case MUX_LODFRAC:
784         case MUX_PRIMLODFRAC:
785             {
786                 float frac = gRDP.primLODFrac / 255.0f;
787                 float tempf[4] = {frac,frac,frac,frac};
788                 pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,tempf);
789                 break;
790             }
791         }
792     }
793 }
794
795 void COGLColorCombinerNvidia::GenerateNVRegisterCombinerSetting(int index)
796 {
797     if( index < 0 || index >= (int)m_vCompiledSettings.size() )
798     {
799         TRACE0("NV Register combiner, vector index out of range");
800         return;
801     }
802
803     NVRegisterCombinerSettingType &info = m_vCompiledSettings[index];
804
805     pglCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV,info.numOfStages);
806
807     uint32 i;
808     
809     if( info.numOfStages > 0 )
810     {
811         for( i=0; i<4; i++ )
812         {
813             pglCombinerInputNV(GL_COMBINER0_NV, GL_RGB, info.stage1RGB[i].variable, info.stage1RGB[i].input, 
814                 info.stage1RGB[i].mapping, info.stage1RGB[i].componentUsage );
815         }
816
817         for( i=0; i<4; i++ )
818         {
819             pglCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, info.stage1Alpha[i].variable, info.stage1Alpha[i].input, 
820                 info.stage1Alpha[i].mapping, info.stage1Alpha[i].componentUsage );
821         }
822
823         pglCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, info.stage1outputRGB.abOutput, info.stage1outputRGB.cdOutput,
824             info.stage1outputRGB.sumOutput, info.stage1outputRGB.scale, info.stage1outputRGB.bias, info.stage1outputRGB.abDotProduct,
825             info.stage1outputRGB.cdDotProduct, info.stage1outputRGB.muxSum);
826
827         pglCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, info.stage2outputAlpha.abOutput, info.stage2outputAlpha.cdOutput,
828             info.stage2outputAlpha.sumOutput, info.stage2outputAlpha.scale, info.stage2outputAlpha.bias, info.stage2outputAlpha.abDotProduct,
829             info.stage2outputAlpha.cdDotProduct, info.stage2outputAlpha.muxSum);
830
831         if( info.numOfStages > 1 )
832         {
833             for( i=0; i<4; i++ )
834             {
835                 pglCombinerInputNV(GL_COMBINER1_NV, GL_RGB, info.stage2RGB[i].variable, 
836                     info.stage2RGB[i].input, info.stage2RGB[i].mapping, info.stage2RGB[i].componentUsage );
837             }
838
839             for( i=0; i<4; i++ )
840             {
841                 pglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, info.stage2Alpha[i].variable, info.stage2Alpha[i].input, 
842                     info.stage2Alpha[i].mapping, info.stage2Alpha[i].componentUsage );
843             }
844
845             pglCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, info.stage2outputRGB.abOutput, info.stage2outputRGB.cdOutput,
846                 info.stage2outputRGB.sumOutput, info.stage2outputRGB.scale, info.stage2outputRGB.bias, info.stage2outputRGB.abDotProduct,
847                 info.stage2outputRGB.cdDotProduct, info.stage2outputRGB.muxSum);
848
849             pglCombinerOutputNV(GL_COMBINER1_NV, GL_ALPHA, info.stage2outputAlpha.abOutput, info.stage2outputAlpha.cdOutput,
850                 info.stage2outputAlpha.sumOutput, info.stage2outputAlpha.scale, info.stage2outputAlpha.bias, info.stage2outputAlpha.abDotProduct,
851                 info.stage2outputAlpha.cdDotProduct, info.stage2outputAlpha.muxSum);
852         }
853     }
854
855     for( i=0; i<7; i++ )
856     {
857         pglFinalCombinerInputNV(info.finalStage[i].variable, info.finalStage[i].input, 
858             info.finalStage[i].mapping, info.finalStage[i].componentUsage );
859     }
860 }
861
862 GLenum COGLColorCombinerNvidia::ConstMap(uint8 c)
863 {
864     switch(c)
865     {
866     case MUX_0:
867         return GL_ZERO;
868     case MUX_1:
869         return GL_ZERO;
870     case MUX_COMBINED:
871     case MUX_TEXEL0:
872     case MUX_TEXEL1:
873     case MUX_PRIM:
874     case MUX_SHADE:
875     case MUX_ENV:
876     case MUX_COMBALPHA:
877     case MUX_T0_ALPHA:
878     case MUX_T1_ALPHA:
879     case MUX_PRIM_ALPHA:
880     case MUX_SHADE_ALPHA:
881     case MUX_ENV_ALPHA:
882     case MUX_LODFRAC:
883     case MUX_PRIMLODFRAC:
884         break;
885     }
886         return GL_ZERO;
887
888 }
889
890 void Set1Variable(GLenum variable, uint8 val, NVCombinerInputType &record, const NVRegisterCombinerParserType &result, bool forRGB=true)
891 {
892     record.variable = variable;
893     record.componentUsage = RGBmap1[val&MUX_MASK].componentUsage;
894     record.input = RGBmap1[val&MUX_MASK].input;
895     record.mapping = RGBmap1[val&MUX_MASK].mapping;
896
897     switch( val&MUX_MASK )
898     {
899     case MUX_PRIM:
900     case MUX_ENV:
901     case MUX_PRIMLODFRAC:
902     case MUX_LODFRAC:
903         if( (val&MUX_MASK) == result.constant0 ) 
904         {
905             record.input = GL_CONSTANT_COLOR0_NV;
906         }
907         else if( (val&MUX_MASK) == result.constant1 )
908         {
909             record.input = GL_CONSTANT_COLOR1_NV;
910         }
911         else
912         {
913             record.input = GL_ZERO;
914         }
915         break;
916     }
917
918     if( val&MUX_NEG )
919     {
920         record.mapping = GL_SIGNED_NEGATE_NV;
921     }
922     else if( val == MUX_1 )
923     {
924         record.mapping = GL_UNSIGNED_INVERT_NV;
925     }
926     else if( val & MUX_COMPLEMENT )
927     {
928         record.mapping = GL_UNSIGNED_INVERT_NV;
929     }
930
931     if( val & MUX_ALPHAREPLICATE || !forRGB )
932     {
933         record.componentUsage = GL_ALPHA;
934     }
935 }
936
937 int COGLColorCombinerNvidia::SaveParserResult(const NVRegisterCombinerParserType &result)
938 {
939     NVRegisterCombinerSettingType save;
940
941     // Stage 1 RGB
942     Set1Variable(GL_VARIABLE_A_NV, result.s1rgb.a, save.stage1RGB[0], result);
943     Set1Variable(GL_VARIABLE_B_NV, result.s1rgb.b, save.stage1RGB[1], result);
944     Set1Variable(GL_VARIABLE_C_NV, result.s1rgb.c, save.stage1RGB[2], result);
945     Set1Variable(GL_VARIABLE_D_NV, result.s1rgb.d, save.stage1RGB[3], result);
946
947     // Stage 1 Alpha
948     Set1Variable(GL_VARIABLE_A_NV, result.s1alpha.a, save.stage1Alpha[0], result, false);
949     Set1Variable(GL_VARIABLE_B_NV, result.s1alpha.b, save.stage1Alpha[1], result, false);
950     Set1Variable(GL_VARIABLE_C_NV, result.s1alpha.c, save.stage1Alpha[2], result, false);
951     Set1Variable(GL_VARIABLE_D_NV, result.s1alpha.d, save.stage1Alpha[3], result, false);
952
953     // Stage 2 RGB
954     Set1Variable(GL_VARIABLE_A_NV, result.s2rgb.a, save.stage2RGB[0], result);
955     Set1Variable(GL_VARIABLE_B_NV, result.s2rgb.b, save.stage2RGB[1], result);
956     Set1Variable(GL_VARIABLE_C_NV, result.s2rgb.c, save.stage2RGB[2], result);
957     Set1Variable(GL_VARIABLE_D_NV, result.s2rgb.d, save.stage2RGB[3], result);
958
959     // Stage 2 Alpha
960     Set1Variable(GL_VARIABLE_A_NV, result.s2alpha.a, save.stage2Alpha[0], result, false);
961     Set1Variable(GL_VARIABLE_B_NV, result.s2alpha.b, save.stage2Alpha[1], result, false);
962     Set1Variable(GL_VARIABLE_C_NV, result.s2alpha.c, save.stage2Alpha[2], result, false);
963     Set1Variable(GL_VARIABLE_D_NV, result.s2alpha.d, save.stage2Alpha[3], result, false);
964
965     // Final Stage RGB
966     Set1Variable(GL_VARIABLE_A_NV, result.finalrgb.a, save.finalStage[0], result);
967     Set1Variable(GL_VARIABLE_B_NV, result.finalrgb.b, save.finalStage[1], result);
968     Set1Variable(GL_VARIABLE_C_NV, result.finalrgb.c, save.finalStage[2], result);
969     Set1Variable(GL_VARIABLE_D_NV, result.finalrgb.d, save.finalStage[3], result);
970     Set1Variable(GL_VARIABLE_E_NV, result.finalrgb.e, save.finalStage[4], result);
971     //save.finalStage[4].componentUsage = GL_ALPHA;
972     Set1Variable(GL_VARIABLE_F_NV, result.finalrgb.f, save.finalStage[5], result);
973     //save.finalStage[5].componentUsage = GL_ALPHA;
974     Set1Variable(GL_VARIABLE_G_NV, result.finalrgb.g, save.finalStage[6], result);
975     save.finalStage[6].componentUsage = GL_ALPHA;
976
977     save.numOfStages = result.stagesUsed;
978     save.dwMux0 = m_pDecodedMux->m_dwMux0;
979     save.dwMux1 = m_pDecodedMux->m_dwMux1;
980
981     save.stage1outputRGB.scale = GL_NONE;
982     save.stage1outputRGB.sumOutput = GL_SPARE0_NV;
983     save.stage1outputRGB.abDotProduct = GL_FALSE;
984     save.stage1outputRGB.cdDotProduct = GL_FALSE;
985     save.stage1outputRGB.abOutput = GL_SPARE1_NV;
986     save.stage1outputRGB.cdOutput = GL_SECONDARY_COLOR_NV;
987     save.stage1outputRGB.bias = GL_NONE;
988     save.stage1outputRGB.muxSum = GL_FALSE;
989     
990     save.stage1outputAlpha.scale = GL_NONE;
991     save.stage1outputAlpha.sumOutput = GL_SPARE0_NV;
992     save.stage1outputAlpha.abDotProduct = GL_FALSE;
993     save.stage1outputAlpha.cdDotProduct = GL_FALSE;
994     save.stage1outputAlpha.abOutput = GL_SPARE1_NV;
995     save.stage1outputAlpha.cdOutput = GL_SECONDARY_COLOR_NV;
996     save.stage1outputAlpha.bias = GL_NONE;
997     save.stage1outputAlpha.muxSum = GL_FALSE;
998     
999     save.stage2outputRGB.scale = GL_NONE;
1000     save.stage2outputRGB.sumOutput = GL_SPARE0_NV;
1001     save.stage2outputRGB.abDotProduct = GL_FALSE;
1002     save.stage2outputRGB.cdDotProduct = GL_FALSE;
1003     save.stage2outputRGB.abOutput = GL_SPARE1_NV;
1004     save.stage2outputRGB.cdOutput = GL_SECONDARY_COLOR_NV;
1005     save.stage2outputRGB.bias = GL_NONE;
1006     save.stage2outputRGB.muxSum = GL_FALSE;
1007     
1008     save.stage2outputAlpha.scale = GL_NONE;
1009     save.stage2outputAlpha.sumOutput = GL_SPARE0_NV;
1010     save.stage2outputAlpha.abDotProduct = GL_FALSE;
1011     save.stage2outputAlpha.cdDotProduct = GL_FALSE;
1012     save.stage2outputAlpha.abOutput = GL_SPARE1_NV;
1013     save.stage2outputAlpha.cdOutput = GL_SECONDARY_COLOR_NV;
1014     save.stage2outputAlpha.bias = GL_NONE;
1015     save.stage2outputAlpha.muxSum = GL_FALSE;
1016
1017     save.constant0 = result.constant0;
1018     save.constant1 = result.constant1;
1019
1020 #ifdef DEBUGGER
1021     memcpy(&(save.parseResult),&result, sizeof(result));
1022     if( logCombiners )
1023     {
1024         TRACE0("\nNew Mux:\n");
1025         DisplayMuxString();
1026         COGLColorCombiner::DisplaySimpleMuxString();
1027         DisplayNVCombinerString(save);
1028     }
1029 #endif
1030
1031     m_vCompiledSettings.push_back(save);
1032
1033     return m_vCompiledSettings.size()-1;    // Return the index of the last element
1034 }
1035
1036
1037 void COGLColorCombinerNvidia::DisableCombiner(void)
1038 {
1039     glDisable(GL_REGISTER_COMBINERS_NV);
1040     COGLColorCombiner4::DisableCombiner();
1041 }
1042
1043 void COGLColorCombinerNvidia::InitCombinerCycleCopy(void)
1044 {
1045     glDisable(GL_REGISTER_COMBINERS_NV);
1046     COGLColorCombiner4::InitCombinerCycleCopy();
1047 }
1048
1049 void COGLColorCombinerNvidia::InitCombinerCycleFill(void)
1050 {
1051     glDisable(GL_REGISTER_COMBINERS_NV);
1052     COGLColorCombiner4::InitCombinerCycleFill();
1053 }
1054
1055 void COGLColorCombinerNvidia::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
1056 {
1057     glDisable(GL_REGISTER_COMBINERS_NV);
1058     COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile);
1059 }
1060
1061 void COGLColorCombinerNvidia::ApplyFogAtFinalStage()
1062 {
1063     // If we need to enable fog at final stage, the current flag stage setting
1064     // will be affect, which means correct combiner setting at final stage is lost
1065     // in order to use fog
1066     if( glIsEnabled(GL_FOG) )
1067     {
1068         // Use final stage as: cmb*fogfactor+fog*(1-fogfactor)
1069         pglFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
1070         pglFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1071         pglFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1072         pglFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1073     }
1074 }
1075
1076 #ifdef DEBUGGER
1077 extern const char *translatedCombTypes[];
1078 void COGLColorCombinerNvidia::DisplaySimpleMuxString(void)
1079 {
1080     COGLColorCombiner::DisplaySimpleMuxString();
1081     TRACE0("\nNV Combiner setting\n");
1082     uint32 index = FindCompiledMux();
1083     if( index >= 0 )
1084     {
1085         NVRegisterCombinerSettingType &record = m_vCompiledSettings[index];
1086         DisplayNVCombinerString(record);
1087     }
1088 }
1089
1090 char* FormatStrForFinalStage(uint8 val, char* buf)
1091 {
1092     if( (val&MUX_MASK) == MUX_E_F )
1093     {
1094         strcpy(buf, "E_F");
1095         return buf;
1096     }
1097     else
1098         return DecodedMux::FormatStr(val, buf);
1099 }
1100
1101 void COGLColorCombinerNvidia::DisplayNVCombinerString(NVRegisterCombinerSettingType &record)
1102 {
1103     NVRegisterCombinerParserType &result = record.parseResult;
1104
1105     char buf[2000];
1106     char buf0[30];
1107     char buf1[30];
1108     char buf2[30];
1109     char buf3[30];
1110     char buf4[30];
1111     char buf5[30];
1112     char buf6[30];
1113     buf[0]='\0';
1114
1115     TRACE0("\n\n");
1116     TRACE0("\nNvidia combiner stages:\n");
1117
1118     DebuggerAppendMsg("//aRGB0:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s1rgb.a, buf0), 
1119         DecodedMux::FormatStr(result.s1rgb.b, buf1), DecodedMux::FormatStr(result.s1rgb.c, buf2),DecodedMux::FormatStr(result.s1rgb.d, buf3));      
1120     DebuggerAppendMsg("//aA0:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s1alpha.a, buf0), 
1121         DecodedMux::FormatStr(result.s1alpha.b, buf1), DecodedMux::FormatStr(result.s1alpha.c, buf2),DecodedMux::FormatStr(result.s1alpha.d, buf3));        
1122     if( record.numOfStages == 2 )
1123     {
1124         DebuggerAppendMsg("//aRGB1:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s2rgb.a, buf0), 
1125             DecodedMux::FormatStr(result.s2rgb.b, buf1), DecodedMux::FormatStr(result.s2rgb.c, buf2),DecodedMux::FormatStr(result.s2rgb.d, buf3));      
1126         DebuggerAppendMsg("//aA1:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s2alpha.a, buf0), 
1127             DecodedMux::FormatStr(result.s2alpha.b, buf1), DecodedMux::FormatStr(result.s2alpha.c, buf2),DecodedMux::FormatStr(result.s2alpha.d, buf3));        
1128     }
1129     DebuggerAppendMsg("//Final:\t%s * %s + (1 - %s) * %s + %s\n\tE=%s, F=%s\n", FormatStrForFinalStage(result.finalrgb.a, buf0), 
1130         FormatStrForFinalStage(result.finalrgb.b, buf1), FormatStrForFinalStage(result.finalrgb.a, buf2),
1131         FormatStrForFinalStage(result.finalrgb.c, buf3), FormatStrForFinalStage(result.finalrgb.d, buf4),
1132         FormatStrForFinalStage(result.finalrgb.e, buf5), FormatStrForFinalStage(result.finalrgb.f, buf6));
1133
1134     if( result.constant0 != MUX_0 )
1135     {
1136         DebuggerAppendMsg("//Constant 0:\t%s\n", DecodedMux::FormatStr(result.constant0, buf0));
1137     }
1138     if( result.constant1 != MUX_0 )
1139     {
1140         DebuggerAppendMsg("//Constant 1:\t%s\n", DecodedMux::FormatStr(result.constant1, buf0));
1141     }
1142     TRACE0("\n\n");
1143 }
1144
1145 #endif
1146