Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/CNvTNTCombiner.cpp
2 views
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
326
327