Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / Combiner.cpp
CommitLineData
292f9317 1/*
2Copyright (C) 2002 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18*/
19
20#include "Combiner.h"
21#include "Config.h"
22#include "RenderBase.h"
23
24//static BOOL g_bHiliteRGBAHack = FALSE;
25
26
27#ifdef DEBUGGER
28const char *constStrs[] = {
29 "MUX_0",
30 "MUX_1",
31 "MUX_COMBINED",
32 "MUX_TEXEL0",
33 "MUX_TEXEL1",
34 "MUX_PRIM",
35 "MUX_SHADE",
36 "MUX_ENV",
37 "MUX_COMBALPHA",
38 "MUX_T0_ALPHA",
39 "MUX_T1_ALPHA",
40 "MUX_PRIM_ALPHA",
41 "MUX_SHADE_ALPHA",
42 "MUX_ENV_ALPHA",
43 "MUX_LODFRAC",
44 "MUX_PRIMLODFRAC",
45 "MUX_K5",
46 "MUX_UNK",
47};
48
49const char *cycleTypeStrs[] = {
50 "1 Cycle",
51 "2 Cycle",
52 "Copy Mode",
53 "Fill Mode"
54};
55
56const char* constStr(uint32 op)
57{
58if(op<=MUX_UNK)
59 return constStrs[op];
60else
61 return "Invalid-Const";
62}
63#endif
64
65void swap(uint8 &a, uint8 &b)
66{
67 uint8 c=a;
68 a=b;
69 b=c;
70}
71
72
73//========================================================================
74
75//========================================================================
76
77inline IColor GetIColor(uint8 flag, uint32 curCol)
78{
79 IColor newc;
80 switch(flag&MUX_MASK)
81 {
82 case MUX_0:
83 newc = 0;
84 break;
85 case MUX_1:
86 newc = 0xFFFFFFFF;
87 break;
88 case MUX_PRIM:
89 newc = gRDP.primitiveColor;
90 break;
91 case MUX_ENV:
92 newc = gRDP.envColor;
93 break;
94 case MUX_COMBINED:
95 case MUX_SHADE:
96 newc = curCol;
97 break;
98 case MUX_K5:
99 newc = 0xFFFFFFFF;
100 break;
101 case MUX_UNK:
102 newc = curCol;
103 if( options.enableHackForGames == HACK_FOR_CONKER )
104 newc = 0xFFFFFFFF;
105 break;
106 default:
107 newc = curCol;
108 break;
109 }
110
111 if( flag&MUX_COMPLEMENT )
112 {
113 newc.Complement();
114 }
115
116 if( flag&MUX_ALPHAREPLICATE )
117 {
118 newc.AlphaReplicate();
119 }
120
121 return newc;
122}
123
124COLOR CalculateConstFactor(uint32 colorOp, uint32 alphaOp, uint32 curCol)
125{
126 N64CombinerType m;
127 IColor color(curCol);
128 IColor alpha(curCol);
129
130 // For color channel
131 *(uint32*)&m = colorOp;
132 if( m.c != MUX_0 && m.a!=m.b)
133 {
134 if( m.a != MUX_0 ) color = GetIColor(m.a, curCol);
135 if( m.b != MUX_0 ) color -= GetIColor(m.b, curCol);
136 if( m.c != MUX_1 ) color *= GetIColor(m.c, curCol);
137 }
138 if( m.d != MUX_0 ) color += GetIColor(m.d, curCol);
139
140 // For alpha channel
141 *(uint32*)&m = alphaOp;
142 if( m.c != MUX_0 && m.a!=m.b)
143 {
144 if( m.a != MUX_0 ) alpha = GetIColor(m.a, curCol);
145 if( m.b != MUX_0 ) alpha -= GetIColor(m.b, curCol);
146 if( m.c != MUX_1 ) alpha *= GetIColor(m.c, curCol);
147 }
148 if( m.d != MUX_0 ) alpha += GetIColor(m.d, curCol);
149
150 return (COLOR)(((uint32)color&0x00FFFFFF)|((uint32)alpha&0xFF000000));
151}
152
153
154COLOR CColorCombiner::GetConstFactor(uint32 colorFlag, uint32 alphaFlag, uint32 defaultColor)
155{
156 // Allows a combine mode to select what TFACTOR should be
157 uint32 color = defaultColor;
158 uint32 alpha = defaultColor;
159
160 switch (colorFlag&MUX_MASK)
161 {
162 case MUX_0:
163 break;
164 case MUX_FORCE_0:
165 color = 0;
166 break;
167 case MUX_1:
168 color = 0xFFFFFFFF;
169 break;
170 case MUX_PRIM:
171 color = gRDP.primitiveColor;
172 break;
173 case MUX_ENV:
174 color = gRDP.envColor;
175 break;
176 case MUX_LODFRAC:
177 color = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac);
178 break;
179 case MUX_PRIMLODFRAC:
180 color = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac);
181 break;
182 case MUX_PRIM_ALPHA:
183 {
184 IColor col(gRDP.primitiveColor);
185 col.AlphaReplicate();
186 color = (COLOR)col;
187 }
188 break;
189 case MUX_ENV_ALPHA:
190 {
191 IColor col(gRDP.envColor);
192 col.AlphaReplicate();
193 color = (COLOR)col;
194 }
195 break;
196 case MUX_K5:
197 color = 0xFFFFFFFF;
198 break;
199 case MUX_UNK:
200 color = defaultColor;
201 if( options.enableHackForGames == HACK_FOR_CONKER ) color = 0xFFFFFFFF;
202 break;
203 default:
204 color = defaultColor;
205 break;
206 }
207
208 if( colorFlag & MUX_COMPLEMENT )
209 {
210 color = 0xFFFFFFFF - color;
211 }
212 if( colorFlag & MUX_ALPHAREPLICATE )
213 {
214 color = color>>24;
215 color = color | (color<<8) | (color <<16) | (color<<24);
216 }
217
218 color &= 0x00FFFFFF; // For color channel only, not the alpha channel
219
220
221 switch (alphaFlag&MUX_MASK)
222 {
223 case MUX_0:
224 break;
225 case MUX_FORCE_0:
226 alpha = 0;
227 break;
228 case MUX_1:
229 alpha = 0xFFFFFFFF;
230 break;
231 case MUX_PRIM:
232 alpha = gRDP.primitiveColor;
233 break;
234 case MUX_ENV:
235 alpha = gRDP.envColor;
236 break;
237 case MUX_LODFRAC:
238 alpha = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac);
239 break;
240 case MUX_PRIMLODFRAC:
241 alpha = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac);
242 break;
243 case MUX_PRIM_ALPHA:
244 {
245 IColor col(gRDP.primitiveColor);
246 col.AlphaReplicate();
247 alpha = (COLOR)col;
248 }
249 break;
250 case MUX_ENV_ALPHA:
251 {
252 IColor col(gRDP.envColor);
253 col.AlphaReplicate();
254 alpha = (COLOR)col;
255 }
256 break;
257 default:
258 alpha = defaultColor;
259 break;
260 }
261
262 if( alphaFlag & MUX_COMPLEMENT )
263 {
264 alpha = 0xFFFFFFFF - alpha;
265 }
266
267 alpha &= 0xFF000000;
268
269 return (color|alpha);
270}
271
272//*****************************************************************************
273//
274//*****************************************************************************
275bool gUsingPrimColour = false;
276bool gUsingEnvColour = false;
277
278int CountTexel1Cycle(N64CombinerType &m)
279{
280 int hasTexel[2];
281 uint8 *p = (uint8*)&m;
282
283 for( int i=0; i<2; i++)
284 {
285 hasTexel[i]=0;
286 for( int j=0; j<4; j++)
287 {
288 if( (p[j]&MUX_MASK) == MUX_TEXEL0+i )
289 {
290 hasTexel[i]=1;
291 break;
292 }
293 }
294 }
295
296 return hasTexel[0]+hasTexel[1];
297}
298
299uint32 GetTexelNumber(N64CombinerType &m)
300{
301 if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1 )
302 return TEX_1;
303 else
304 return TEX_0;
305}
306
307bool IsTxtrUsed(N64CombinerType &m)
308{
309 if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1 )
310 return true;
311 if( (m.a&MUX_MASK) == MUX_TEXEL0 || (m.b&MUX_MASK) == MUX_TEXEL0 || (m.c&MUX_MASK) == MUX_TEXEL0 || (m.d&MUX_MASK) == MUX_TEXEL0 )
312 return true;
313 else
314 return false;
315}
316
317//========================================================================
318
319void CColorCombiner::InitCombinerMode(void)
320{
321#ifdef DEBUGGER
322 LOG_UCODE(cycleTypeStrs[gRDP.otherMode.cycle_type]);
323 if( debuggerDropDecodedMux )
324 {
325 UpdateCombiner(m_pDecodedMux->m_dwMux0, m_pDecodedMux->m_dwMux1);
326 }
327#endif
328
329 if( currentRomOptions.bNormalCombiner )
330 {
331 DisableCombiner();
332 }
333 else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY )
334 {
335 InitCombinerCycleCopy();
336 m_bCycleChanged = true;
337 }
338 else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
339 //else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL && gRSP.ucode != 5 ) //hack
340 {
341 InitCombinerCycleFill();
342 m_bCycleChanged = true;
343 }
344 else
345 {
346 InitCombinerCycle12();
347 m_bCycleChanged = false;
348 }
349}
350
351
352bool bConkerHideShadow=false;
353void CColorCombiner::UpdateCombiner(uint32 dwMux0, uint32 dwMux1)
354{
355#ifdef DEBUGGER
356 if( debuggerDropDecodedMux )
357 {
358 debuggerDropDecodedMux = false;
359 m_pDecodedMux->m_dwMux0 = m_pDecodedMux->m_dwMux1 = 0;
360 m_DecodedMuxList.clear();
361 }
362#endif
363
364 DecodedMux &m_decodedMux = *m_pDecodedMux;
365 if( m_decodedMux.m_dwMux0 != dwMux0 || m_decodedMux.m_dwMux1 != dwMux1 )
366 {
367 if( options.enableHackForGames == HACK_FOR_DR_MARIO )
368 {
369 // Hack for Dr. Mario
370 if( dwMux1 == 0xfffcf239 &&
371 ((m_decodedMux.m_dwMux0 == dwMux0 && dwMux0 == 0x00ffffff &&
372 m_decodedMux.m_dwMux1 != dwMux1 && m_decodedMux.m_dwMux1 == 0xfffcf279 ) ||
373 (m_decodedMux.m_dwMux0 == 0x00ffb3ff && m_decodedMux.m_dwMux1 == 0xff64fe7f && dwMux0 == 0x00ffffff ) ))
374 {
375 //dwMux1 = 0xffcf23A;
376 dwMux1 = 0xfffcf438;
377 }
378 }
379 uint64 mux64 = (((uint64)dwMux1)<<32)+dwMux0;
380 int index=m_DecodedMuxList.find(mux64);
381
382 if( options.enableHackForGames == HACK_FOR_CONKER )
383 {
384 // Conker's shadow, to disable the shadow
385 //Mux=0x00ffe9ff Used in CONKER BFD
386 //Color0: (0 - 0) * 0 + SHADE
387 //Color1: (0 - 0) * 0 + SHADE
388 //Alpha0: (1 - TEXEL0) * SHADE + 0
389 //Alpha1: (1 - TEXEL0) * SHADE + 0
390 if( dwMux1 == 0xffd21f0f && dwMux0 == 0x00ffe9ff )
391 {
392 bConkerHideShadow = true;
393 }
394 else
395 {
396 bConkerHideShadow = false;
397 }
398 }
399
400 if( index >= 0 )
401 {
402 m_decodedMux = m_DecodedMuxList[index];
403 }
404 else
405 {
406 m_decodedMux.Decode(dwMux0, dwMux1);
407 m_decodedMux.splitType[0] = CM_FMT_TYPE_NOT_CHECKED;
408 m_decodedMux.splitType[1] = CM_FMT_TYPE_NOT_CHECKED;
409 m_decodedMux.splitType[2] = CM_FMT_TYPE_NOT_CHECKED;
410 m_decodedMux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED;
411
412 m_decodedMux.Hack();
413
414 if( !m_bSupportMultiTexture )
415 {
416 m_decodedMux.ReplaceVal(MUX_TEXEL1, MUX_TEXEL0);
417 m_decodedMux.ReplaceVal(MUX_LODFRAC,1);
418 m_decodedMux.ReplaceVal(MUX_PRIMLODFRAC,1);
419 }
420
421 m_decodedMux.Simplify();
422 if( m_supportedStages>1)
423 m_decodedMux.SplitComplexStages();
424
425 m_DecodedMuxList.add(m_decodedMux.m_u64Mux, *m_pDecodedMux);
426#ifdef DEBUGGER
427 if( logCombiners )
428 {
429 TRACE0("Add a new mux");
430 DisplayMuxString();
431 }
432#endif
433 }
434
435 m_bTex0Enabled = m_decodedMux.m_bTexel0IsUsed;
436 m_bTex1Enabled = m_decodedMux.m_bTexel1IsUsed;
437 m_bTexelsEnable = m_bTex0Enabled||m_bTex1Enabled;
438
439 gRSP.bProcessDiffuseColor = (m_decodedMux.m_dwShadeColorChannelFlag != MUX_0 || m_decodedMux.m_dwShadeAlphaChannelFlag != MUX_0);
440 gRSP.bProcessSpecularColor = false;
441 }
442}
443
444
445#ifdef DEBUGGER
446void CColorCombiner::DisplayMuxString(void)
447{
448 if( gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY)
449 {
450 TRACE0("COPY Mode\n");
451 }
452 else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL)
453 {
454 TRACE0("FILL Mode\n");
455 }
456
457 m_pDecodedMux->DisplayMuxString("Used");
458}
459
460void CColorCombiner::DisplaySimpleMuxString(void)
461{
462 m_pDecodedMux->DisplaySimpliedMuxString("Used");
463}
464#endif
465