Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / CNvTNTCombiner.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 <SDL_opengl.h>
20
21 #include "CNvTNTCombiner.h"
22
23 CNvTNTCombiner::CNvTNTCombiner()
24 {
25     m_lastIndexTNT = 0;
26 }
27
28 CNvTNTCombiner::~CNvTNTCombiner()
29 {
30 }
31
32
33 int CNvTNTCombiner::FindCompiledMux( )
34 {
35     for( uint32 i=0; i<m_vCompiledTNTSettings.size(); i++ )
36     {
37         if( m_vCompiledTNTSettings[i].dwMux0 == (*m_ppDecodedMux)->m_dwMux0 && m_vCompiledTNTSettings[i].dwMux1 == (*m_ppDecodedMux)->m_dwMux1 )
38         {
39             m_lastIndexTNT = i;
40             return i;
41         }
42     }
43
44     return -1;
45 }
46
47 bool isTex(uint32 val);
48 bool isComb(uint32 val);
49
50 int CNvTNTCombiner::ParseDecodedMux()
51 {
52     TNT2CombinerSaveType res;
53     res.numOfUnits = 2;
54
55     (*m_ppDecodedMux)->To_AB_Add_CD_Format();
56
57     for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
58     {
59         // For each texture unit, set both RGB and Alpha channel
60         // Keep in mind that the m_pDecodeMux has been reformated and simplified very well
61
62         TNT2CombinerType &unit = res.units[i/2];
63         TNT2CombType &comb = unit.Combs[i%2];
64
65         CombinerFormatType type = (*m_ppDecodedMux)->splitType[i];
66         N64CombinerType &m = (*m_ppDecodedMux)->m_n64Combiners[i];
67
68         comb.arg0 = comb.arg1 = comb.arg2 = comb.arg3 = MUX_0;
69         unit.ops[i%2] = 0x0104; //Add;
70         //Subtract
71
72         switch( type )
73         {
74         case CM_FMT_TYPE_NOT_USED:
75             comb.arg0 = MUX_COMBINED;
76             comb.arg1 = MUX_1;
77             comb.arg2 = MUX_0;
78             comb.arg3 = MUX_1;
79         case CM_FMT_TYPE_D:             // = A
80             comb.arg0 = m.d;
81             comb.arg1 = MUX_1;
82             comb.arg2 = MUX_0;
83             comb.arg3 = MUX_0;
84             break;
85         case CM_FMT_TYPE_A_ADD_D:           // = A+D
86             comb.arg0 = m.a;
87             comb.arg1 = MUX_1;
88             comb.arg2 = m.d;
89             comb.arg3 = MUX_1;
90             if( isComb(m.d) )
91             {
92                 swap(comb.arg0, comb.arg2);
93                 swap(comb.arg1, comb.arg3);
94             }
95             break;
96         case CM_FMT_TYPE_A_SUB_B:           // = A-B
97             comb.arg0 = m.a^MUX_COMPLEMENT;
98             comb.arg1 = MUX_1;
99             unit.ops[i%2] = GL_SUBTRACT_ARB;
100             comb.arg2 = m.b;
101             comb.arg3 = MUX_1;
102             break;
103         case CM_FMT_TYPE_A_MOD_C:           // = A*C
104             comb.arg0 = m.a;
105             comb.arg1 = m.c;
106             comb.arg2 = MUX_0;
107             comb.arg3 = MUX_0;
108             break;
109         case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
110             comb.arg0 = m.a;
111             comb.arg1 = m.c;
112             comb.arg2 = m.d;
113             comb.arg3 = MUX_1;
114             if( isComb(m.d) )
115             {
116                 swap(comb.arg0, comb.arg2);
117                 swap(comb.arg1, comb.arg3);
118             }
119             break;
120         case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
121             comb.arg0 = m.a;
122             comb.arg1 = m.c;
123             comb.arg2 = m.c^MUX_COMPLEMENT;
124             comb.arg3 = m.b;
125             if( isComb(m.b) )
126             {
127                 swap(comb.arg0, comb.arg2);
128                 swap(comb.arg1, comb.arg3);
129             }
130             break;
131         case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D
132             // fix me, to use 2 texture units
133             if( isTex(m.b) && isTex(m.d) )
134             {
135                 comb.arg0 = m.a;
136                 comb.arg1 = m.b;
137                 comb.arg2 = m.d;
138                 comb.arg3 = MUX_1;
139                 if( isComb(m.d) )
140                 {
141                     swap(comb.arg0, comb.arg2);
142                     swap(comb.arg1, comb.arg3);
143                 }
144             }
145             else if( isTex(m.b) && !isComb(m.d) )
146             {
147                 comb.arg0 = m.a^MUX_COMPLEMENT;
148                 comb.arg1 = MUX_1;
149                 comb.arg2 = m.b;
150                 comb.arg3 = MUX_1;
151                 unit.ops[i%2] = GL_SUBTRACT_ARB;
152             }
153             else if( !isTex(m.b) && isTex(m.d) )
154             {
155                 comb.arg0 = m.a;
156                 comb.arg1 = MUX_1;
157                 comb.arg2 = m.d;
158                 comb.arg3 = MUX_1;
159                 if( isComb(m.d) )
160                 {
161                     swap(comb.arg0, comb.arg2);
162                     swap(comb.arg1, comb.arg3);
163                 }
164             }
165             else
166             {
167                 comb.arg0 = m.a;
168                 comb.arg1 = m.b;
169                 comb.arg2 = m.d;
170                 comb.arg3 = MUX_1;
171                 if( isComb(m.d) )
172                 {
173                     swap(comb.arg0, comb.arg2);
174                     swap(comb.arg1, comb.arg3);
175                 }
176             }
177             break;
178         case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C
179             comb.arg0 = m.a^MUX_COMPLEMENT;
180             comb.arg1 = m.c;
181             comb.arg2 = m.c;
182             comb.arg3 = m.b;
183             unit.ops[i%2] = GL_SUBTRACT_ARB;
184             break;
185         case CM_FMT_TYPE_AB_ADD_CD:         // = AB+CD
186             comb.arg0 = m.a;
187             comb.arg1 = m.b;
188             comb.arg2 = m.c;
189             comb.arg3 = m.d;
190             if( isComb(m.d) || isComb(m.c) )
191             {
192                 swap(comb.arg0, comb.arg2);
193                 swap(comb.arg1, comb.arg3);
194             }
195
196             break;
197         case CM_FMT_TYPE_AB_SUB_CD:         // = AB-CD
198             comb.arg0 = m.a^MUX_COMPLEMENT;
199             comb.arg1 = m.b;
200             unit.ops[i%2] = GL_SUBTRACT_ARB;
201             comb.arg2 = m.c;
202             comb.arg3 = m.d;
203             break;
204         case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
205         default:
206             if( !isComb(m.d) && !isTex(m.d) )
207             {
208                 comb.arg0 = m.a^MUX_COMPLEMENT;
209                 comb.arg1 = m.c;
210                 unit.ops[i%2] = GL_SUBTRACT_ARB;
211                 comb.arg2 = m.c;
212                 comb.arg3 = m.b;
213             }
214             else if( !isComb(m.b) && !isTex(m.b) )
215             {
216                 comb.arg0 = m.a;
217                 comb.arg1 = m.c;
218                 comb.arg2 = m.d;
219                 comb.arg3 = MUX_1;
220                 if( isComb(m.d) )
221                 {
222                     swap(comb.arg0, comb.arg2);
223                     swap(comb.arg1, comb.arg3);
224                 }
225             }
226             else if( !isComb(m.c) && !isTex(m.c) )
227             {
228                 comb.arg0 = m.a;
229                 comb.arg1 = m.b;
230                 comb.arg2 = m.d;
231                 comb.arg3 = MUX_1;
232                 if( isComb(m.d) )
233                 {
234                     swap(comb.arg0, comb.arg2);
235                     swap(comb.arg1, comb.arg3);
236                 }
237             }
238             else
239             {
240                 comb.arg0 = m.a;
241                 comb.arg1 = m.c;
242                 comb.arg2 = m.d;
243                 comb.arg3 = MUX_1;
244                 if( isComb(m.d) )
245                 {
246                     swap(comb.arg0, comb.arg2);
247                     swap(comb.arg1, comb.arg3);
248                 }
249             }
250             break;
251         }
252     }
253
254     ParseDecodedMuxForConstants(res);
255     return SaveParserResult(res);
256 }
257
258 int CNvTNTCombiner::SaveParserResult(TNT2CombinerSaveType &result)
259 {
260     result.dwMux0 = (*m_ppDecodedMux)->m_dwMux0;
261     result.dwMux1 = (*m_ppDecodedMux)->m_dwMux1;
262
263     m_vCompiledTNTSettings.push_back(result);
264     m_lastIndexTNT = m_vCompiledTNTSettings.size()-1;
265
266 #ifdef DEBUGGER
267     if( logCombiners )
268     {
269         DisplaySimpleMuxString();
270     }
271 #endif
272
273     return m_lastIndexTNT;
274 }
275
276 void CNvTNTCombiner::ParseDecodedMuxForConstants(TNT2CombinerSaveType &res)
277 {
278     res.unit1.constant = MUX_0;
279     res.unit2.constant = MUX_0;
280
281     for( int i=0; i<2; i++ )
282     {
283         if( (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIM, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIM, i,ALPHA_CHANNEL) )
284         {
285             res.units[i].constant = MUX_PRIM;
286         }
287         else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_ENV, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_ENV, i,ALPHA_CHANNEL) )
288         {
289             res.units[i].constant = MUX_ENV;
290         }
291         else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_LODFRAC, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_LODFRAC, i,ALPHA_CHANNEL) )
292         {
293             res.units[i].constant = MUX_LODFRAC;
294         }
295         else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIMLODFRAC, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIMLODFRAC, i,ALPHA_CHANNEL) )
296         {
297             res.units[i].constant = MUX_PRIMLODFRAC;
298         }
299     }
300 }
301
302 #ifdef DEBUGGER
303 extern const char *translatedCombTypes[];
304 void CNvTNTCombiner::DisplaySimpleMuxString()
305 {
306     char buf0[30];
307     char buf1[30];
308     char buf2[30];
309     char buf3[30];
310
311     TNT2CombinerSaveType &result = m_vCompiledTNTSettings[m_lastIndexTNT];
312
313     TRACE0("\nNVidia TNT2+ Combiner\n");        
314     DebuggerAppendMsg("//aRGB0:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit1.rgbArg0,buf0), DecodedMux::FormatStr(result.unit1.rgbArg1,buf1), result.unit1.rgbOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit1.rgbArg2,buf2), DecodedMux::FormatStr(result.unit1.rgbArg3,buf3));        
315     DebuggerAppendMsg("//aRGB1:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit2.rgbArg0,buf0), DecodedMux::FormatStr(result.unit2.rgbArg1,buf1), result.unit2.rgbOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit2.rgbArg2,buf2), DecodedMux::FormatStr(result.unit2.rgbArg3,buf3));        
316     DebuggerAppendMsg("//aAlpha0:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit1.alphaArg0,buf0), DecodedMux::FormatStr(result.unit1.alphaArg1,buf1), result.unit1.alphaOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit1.alphaArg2,buf2), DecodedMux::FormatStr(result.unit1.alphaArg3,buf3));        
317     DebuggerAppendMsg("//aAlpha1:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit2.alphaArg0,buf0), DecodedMux::FormatStr(result.unit2.alphaArg1,buf1), result.unit2.alphaOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit2.alphaArg2,buf2), DecodedMux::FormatStr(result.unit2.alphaArg3,buf3));
318     if( result.unit1.constant != MUX_0 )
319         DebuggerAppendMsg("//Constant for unit 1:\t%s\n", DecodedMux::FormatStr(result.unit1.constant,buf0));
320     if( result.unit2.constant != MUX_0 )
321         DebuggerAppendMsg("//Constant for unit 2:\t%s\n", DecodedMux::FormatStr(result.unit2.constant,buf0));
322     TRACE0("\n\n");
323 }
324 #endif
325