Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / Blender.cpp
CommitLineData
292f9317 1/*
2Copyright (C) 2003 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#include "Render.h"
20
21const char * sc_szBlClr[4] = { "In", "Mem", "Bl", "Fog" };
22const char * sc_szBlA1[4] = { "AIn", "AFog", "AShade", "0" };
23const char * sc_szBlA2[4] = { "1-A", "AMem", "1", "0" };
24
25//========================================================================
26void CBlender::InitBlenderMode(void) // Set Alpha Blender mode
27{
28 //1. Z_COMPARE -- Enable / Disable Zbuffer compare
29 // 1 - Enable ZBuffer
30 // 0 - Disable ZBuffer
31
32 //2. Z_UPDATE -- Enable / Disable Zbuffer update
33 // 1 - Enable ZBuffer writeable
34 // 0 - Zbuffer not writeable
35
36 //3. AA_EN and IM_RD -- Anti-Alias
37 // AA_EN - Enable anti-aliase
38 // AA_EN | IM_RD - Reduced anti-aliase
39 // IM_RD - ??
40 // - - Disable anti-aliase
41
42 //4. ZMode
43 // #define ZMODE_OPA 0 -- Usually used with Z_COMPARE and Z_UPDATE
44 // or used without neither Z_COMPARE or Z_UPDATE
45 // if used with Z_COMPARE and Z_UPDATE, then this is
46 // the regular ZBuffer mode, with compare and update
47 // #define ZMODE_INTER 0x400
48 // #define ZMODE_XLU 0x800 -- Usually used with Z_COMPARE, but not with Z_UPDATE
49 // Do only compare, no zbuffer update.
50 // Not output if the z value is the same
51 // #define ZMODE_DEC 0xc00 -- Usually used with Z_COMPARE, but not with Z_UPDATE
52 // Do only compare, no update, but because this is
53 // decal mode, so image should be updated even
54 // the z value is the same as compared.
55
56 CRender *render = CRender::g_pRender;
57
58 // Alpha Blender Modes
59
60 /*
616. FORCE_BL - Alpha blending at blender stage
62 1 - Enable alpha blending at blender
63 0 - Disable alpha blending at blender
64
65 Alpha blending at blender is usually used to render XLU surface
66 if enabled, then use the blending setting of C1 and C2
67
687. ALPHA_CVG_SEL - Output full alpha from the color combiner, usually not used together
69 with FORCE_BL. If it is used together with FORCE_BL, then ignore this
70
718. CVG_X_ALPHA - Before output the color from color combiner, mod it with alpha
72
739. TEX_EDGE - Ignore this
74
7510.CLR_ON_CVG - Used with XLU surfaces, ignore it
76
7711.CVG_DST
78#define CVG_DST_CLAMP 0 - Usually used with OPA surface
79#define CVG_DST_WRAP 0x100 - Usually used with XLU surface or OPA line
80#define CVG_DST_FULL 0x200 - ?
81#define CVG_DST_SAVE 0x300 - ?
82
83
84Possible Blending Inputs:
85
86 In - Input from color combiner
87 Mem - Input from current frame buffer
88 Fog - Fog generator
89 BL - Blender
90
91Possible Blending Factors:
92 A-IN - Alpha from color combiner
93 A-MEM - Alpha from current frame buffer
94 (1-A) -
95 A-FOG - Alpha of fog color
96 A-SHADE - Alpha of shade
97 1 - 1
98 0 - 0
99*/
100#define BLEND_NOOP 0x0000
101
102#define BLEND_NOOP5 0xcc48 // Fog * 0 + Mem * 1
103#define BLEND_NOOP4 0xcc08 // Fog * 0 + In * 1
104#define BLEND_FOG_ASHADE 0xc800
105#define BLEND_FOG_3 0xc000 // Fog * AIn + In * 1-A
106#define BLEND_FOG_MEM 0xc440 // Fog * AFog + Mem * 1-A
107#define BLEND_FOG_APRIM 0xc400 // Fog * AFog + In * 1-A
108
109#define BLEND_BLENDCOLOR 0x8c88
110#define BLEND_BI_AFOG 0x8400 // Bl * AFog + In * 1-A
111#define BLEND_BI_AIN 0x8040 // Bl * AIn + Mem * 1-A
112
113#define BLEND_MEM 0x4c40 // Mem*0 + Mem*(1-0)?!
114#define BLEND_FOG_MEM_3 0x44c0 // Mem * AFog + Fog * 1-A
115
116#define BLEND_NOOP3 0x0c48 // In * 0 + Mem * 1
117#define BLEND_PASS 0x0c08 // In * 0 + In * 1
118#define BLEND_FOG_MEM_IN_MEM 0x0440 // In * AFog + Mem * 1-A
119#define BLEND_FOG_MEM_FOG_MEM 0x04c0 // In * AFog + Fog * 1-A
120#define BLEND_OPA 0x0044 // In * AIn + Mem * AMem
121#define BLEND_XLU 0x0040
122#define BLEND_MEM_ALPHA_IN 0x4044 // Mem * AIn + Mem * AMem
123
124
125 uint32 blendmode_1 = (uint32)( gRDP.otherMode.blender & 0xcccc );
126 uint32 blendmode_2 = (uint32)( gRDP.otherMode.blender & 0x3333 );
127 uint32 cycletype = gRDP.otherMode.cycle_type;
128
129 switch( cycletype )
130 {
131 case CYCLE_TYPE_FILL:
132 //BlendFunc(BLEND_ONE, BLEND_ZERO);
133 //Enable();
134 Disable();
135 break;
136 case CYCLE_TYPE_COPY:
137 //Disable();
138 BlendFunc(BLEND_ONE, BLEND_ZERO);
139 Enable();
140 break;
141 case CYCLE_TYPE_2:
142 if( gRDP.otherMode.force_bl && gRDP.otherMode.z_cmp )
143 {
144 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
145 Enable();
146 break;
147 }
148
149 /*
150 if( gRDP.otherMode.alpha_cvg_sel && gRDP.otherMode.cvg_x_alpha==0 )
151 {
152 BlendFunc(BLEND_ONE, BLEND_ZERO);
153 Enable();
154 break;
155 }
156 */
157
158 switch( blendmode_1+blendmode_2 )
159 {
160 case BLEND_PASS+(BLEND_PASS>>2): // In * 0 + In * 1
161 case BLEND_FOG_APRIM+(BLEND_PASS>>2):
162 BlendFunc(BLEND_ONE, BLEND_ZERO);
163 if( gRDP.otherMode.alpha_cvg_sel )
164 {
165 Enable();
166 }
167 else
168 {
169 Disable();
170 }
171
172 render->SetAlphaTestEnable( ((gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3)==1 ? TRUE : FALSE);
173 break;
174 case BLEND_PASS+(BLEND_OPA>>2):
175 // 0x0c19
176 // Cycle1: In * 0 + In * 1
177 // Cycle2: In * AIn + Mem * AMem
178 if( gRDP.otherMode.cvg_x_alpha && gRDP.otherMode.alpha_cvg_sel )
179 {
180 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
181 Enable();
182 }
183 else
184 {
185 BlendFunc(BLEND_ONE, BLEND_ZERO);
186 Enable();
187 }
188 break;
189 case BLEND_PASS + (BLEND_XLU>>2):
190 // 0x0c18
191 // Cycle1: In * 0 + In * 1
192 // Cycle2: In * AIn + Mem * 1-A
193 case BLEND_FOG_ASHADE + (BLEND_XLU>>2):
194 //Cycle1: Fog * AShade + In * 1-A
195 //Cycle2: In * AIn + Mem * 1-A
196 case BLEND_FOG_APRIM + (BLEND_XLU>>2):
197 //Cycle1: Fog * AFog + In * 1-A
198 //Cycle2: In * AIn + Mem * 1-A
199 //case BLEND_FOG_MEM_FOG_MEM + (BLEND_OPA>>2):
200 //Cycle1: In * AFog + Fog * 1-A
201 //Cycle2: In * AIn + Mem * AMem
202 case BLEND_FOG_MEM_FOG_MEM + (BLEND_PASS>>2):
203 //Cycle1: In * AFog + Fog * 1-A
204 //Cycle2: In * 0 + In * 1
205 case BLEND_XLU + (BLEND_XLU>>2):
206 //Cycle1: Fog * AFog + In * 1-A
207 //Cycle2: In * AIn + Mem * 1-A
208 case BLEND_BI_AFOG + (BLEND_XLU>>2):
209 //Cycle1: Bl * AFog + In * 1-A
210 //Cycle2: In * AIn + Mem * 1-A
211 case BLEND_XLU + (BLEND_FOG_MEM_IN_MEM>>2):
212 //Cycle1: In * AIn + Mem * 1-A
213 //Cycle2: In * AFog + Mem * 1-A
214 case BLEND_PASS + (BLEND_FOG_MEM_IN_MEM>>2):
215 //Cycle1: In * 0 + In * 1
216 //Cycle2: In * AFog + Mem * 1-A
217 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
218 Enable();
219 break;
220 case BLEND_FOG_MEM_FOG_MEM + (BLEND_OPA>>2):
221 //Cycle1: In * AFog + Fog * 1-A
222 //Cycle2: In * AIn + Mem * AMem
223 BlendFunc(BLEND_ONE, BLEND_ZERO);
224 Enable();
225 break;
226
227 case BLEND_FOG_APRIM + (BLEND_OPA>>2):
228 // For Golden Eye
229 //Cycle1: Fog * AFog + In * 1-A
230 //Cycle2: In * AIn + Mem * AMem
231 case BLEND_FOG_ASHADE + (BLEND_OPA>>2):
232 //Cycle1: Fog * AShade + In * 1-A
233 //Cycle2: In * AIn + Mem * AMem
234 case BLEND_BI_AFOG + (BLEND_OPA>>2):
235 //Cycle1: Bl * AFog + In * 1-A
236 //Cycle2: In * AIn + Mem * 1-AMem
237 case BLEND_FOG_ASHADE + (BLEND_NOOP>>2):
238 //Cycle1: Fog * AShade + In * 1-A
239 //Cycle2: In * AIn + In * 1-A
240 case BLEND_NOOP + (BLEND_OPA>>2):
241 //Cycle1: In * AIn + In * 1-A
242 //Cycle2: In * AIn + Mem * AMem
243 case BLEND_NOOP4 + (BLEND_NOOP>>2):
244 //Cycle1: Fog * AIn + In * 1-A
245 //Cycle2: In * 0 + In * 1
246 case BLEND_FOG_ASHADE+(BLEND_PASS>>2):
247 //Cycle1: Fog * AShade + In * 1-A
248 //Cycle2: In * 0 + In * 1
249 case BLEND_FOG_3+(BLEND_PASS>>2):
250 BlendFunc(BLEND_ONE, BLEND_ZERO);
251 Enable();
252 break;
253 case BLEND_FOG_ASHADE+0x0301:
254 // c800 - Cycle1: Fog * AShade + In * 1-A
255 // 0301 - Cycle2: In * 0 + In * AMem
256 BlendFunc(BLEND_SRCALPHA, BLEND_ZERO);
257 Enable();
258 break;
259 case 0x0c08+0x1111:
260 // 0c08 - Cycle1: In * 0 + In * 1
261 // 1111 - Cycle2: Mem * AFog + Mem * AMem
262 BlendFunc(BLEND_ZERO, BLEND_DESTALPHA);
263 Enable();
264 break;
265 default:
266#ifdef DEBUGGER
267 if( pauseAtNext )
268 {
269 uint32 dwM1A_1 = (gRDP.otherMode.blender>>14) & 0x3;
270 uint32 dwM1B_1 = (gRDP.otherMode.blender>>10) & 0x3;
271 uint32 dwM2A_1 = (gRDP.otherMode.blender>>6) & 0x3;
272 uint32 dwM2B_1 = (gRDP.otherMode.blender>>2) & 0x3;
273
274 uint32 dwM1A_2 = (gRDP.otherMode.blender>>12) & 0x3;
275 uint32 dwM1B_2 = (gRDP.otherMode.blender>>8) & 0x3;
276 uint32 dwM2A_2 = (gRDP.otherMode.blender>>4) & 0x3;
277 uint32 dwM2B_2 = (gRDP.otherMode.blender ) & 0x3;
278
279 TRACE0("Unknown Blender Mode: 2 cycle");
280 DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t%04x - Cycle2:\t%s * %s + %s * %s", blendmode_1,
281 sc_szBlClr[dwM1A_1], sc_szBlA1[dwM1B_1], sc_szBlClr[dwM2A_1], sc_szBlA2[dwM2B_1], blendmode_2,
282 sc_szBlClr[dwM1A_2], sc_szBlA1[dwM1B_2], sc_szBlClr[dwM2A_2], sc_szBlA2[dwM2B_2]);
283
284 }
285#endif
286 if( blendmode_2 == (BLEND_PASS>>2) )
287 {
288 BlendFunc(BLEND_ONE, BLEND_ZERO);
289 }
290 else
291 {
292 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
293 }
294 Enable();
295 break;
296 }
297 break;
298 default: // 1/2 Cycle or Copy
299 if( gRDP.otherMode.force_bl && gRDP.otherMode.z_cmp && blendmode_1 != BLEND_FOG_ASHADE )
300 {
301 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
302 Enable();
303 break;
304 }
305 if( gRDP.otherMode.force_bl && options.enableHackForGames == HACK_FOR_COMMANDCONQUER )
306 {
307 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
308 Enable();
309 break;
310 }
311
312#ifdef DEBUGGER
313 //if( (blendmode_1>>2) != blendmode_2 )
314 //{
315 // DebuggerAppendMsg("Warning: in 1 cycle mode, blend1!=blend2");
316 //}
317#endif
318
319 switch ( blendmode_1 )
320 //switch ( blendmode_2<<2 )
321 {
322 case BLEND_XLU: // IN * A_IN + MEM * (1-A_IN)
323 case BLEND_BI_AIN: // Bl * AIn + Mem * 1-A
324 case BLEND_FOG_MEM: // c440 - Cycle1: Fog * AFog + Mem * 1-A
325 case BLEND_FOG_MEM_IN_MEM: // c440 - Cycle1: In * AFog + Mem * 1-A
326 case BLEND_BLENDCOLOR: //Bl * 0 + Bl * 1
327 case 0x00c0: //In * AIn + Fog * 1-A
328 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
329 Enable();
330 break;
331 case BLEND_MEM_ALPHA_IN: // Mem * AIn + Mem * AMem
332 BlendFunc(BLEND_ZERO, BLEND_DESTALPHA);
333 Enable();
334 break;
335 case BLEND_PASS: // IN * 0 + IN * 1
336 BlendFunc(BLEND_ONE, BLEND_ZERO);
337 if( gRDP.otherMode.alpha_cvg_sel )
338 {
339 Enable();
340 }
341 else
342 {
343 Disable();
344 }
345 break;
346 case BLEND_OPA: // IN * A_IN + MEM * A_MEM
347 if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
348 {
349 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
350 }
351 else
352 {
353 BlendFunc(BLEND_ONE, BLEND_ZERO);
354 }
355 Enable();
356 break;
357 case BLEND_NOOP: // IN * A_IN + IN * (1 - A_IN)
358 case BLEND_FOG_ASHADE: // Fog * AShade + In * 1-A
359 case BLEND_FOG_MEM_3: // Mem * AFog + Fog * 1-A
360 case BLEND_BI_AFOG: // Bl * AFog + In * 1-A
361 BlendFunc(BLEND_ONE, BLEND_ZERO);
362 Enable();
363 break;
364 case BLEND_FOG_APRIM: // Fog * AFog + In * 1-A
365 BlendFunc(BLEND_INVSRCALPHA, BLEND_ZERO);
366 Enable();
367 break;
368 case BLEND_NOOP3: // In * 0 + Mem * 1
369 case BLEND_NOOP5: // Fog * 0 + Mem * 1
370 BlendFunc(BLEND_ZERO, BLEND_ONE);
371 Enable();
372 break;
373 case BLEND_MEM: // Mem * 0 + Mem * 1-A
374 // WaveRace
375 BlendFunc(BLEND_ZERO, BLEND_ONE);
376 Enable();
377 break;
378 default:
379#ifdef DEBUGGER
380 if( pauseAtNext )
381 {
382 uint32 dwM1A_1 = (gRDP.otherMode.blender>>14) & 0x3;
383 uint32 dwM1B_1 = (gRDP.otherMode.blender>>10) & 0x3;
384 uint32 dwM2A_1 = (gRDP.otherMode.blender>>6) & 0x3;
385 uint32 dwM2B_1 = (gRDP.otherMode.blender>>2) & 0x3;
386
387 uint32 dwM1A_2 = (gRDP.otherMode.blender>>12) & 0x3;
388 uint32 dwM1B_2 = (gRDP.otherMode.blender>>8) & 0x3;
389 uint32 dwM2A_2 = (gRDP.otherMode.blender>>4) & 0x3;
390 uint32 dwM2B_2 = (gRDP.otherMode.blender ) & 0x3;
391
392 TRACE0("Unknown Blender Mode: 1 cycle");
393 DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t\tCycle2:\t%s * %s + %s * %s", blendmode_1,
394 sc_szBlClr[dwM1A_1], sc_szBlA1[dwM1B_1], sc_szBlClr[dwM2A_1], sc_szBlA2[dwM2B_1],
395 sc_szBlClr[dwM1A_2], sc_szBlA1[dwM1B_2], sc_szBlClr[dwM2A_2], sc_szBlA2[dwM2B_2]);
396 }
397#endif
398 BlendFunc(BLEND_SRCALPHA, BLEND_INVSRCALPHA);
399 Enable();
400 render->SetAlphaTestEnable(TRUE);
401 break;
402 }
403 }
404}
405