Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / Blender.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 "Render.h"
20
21 const char * sc_szBlClr[4]      = { "In", "Mem", "Bl", "Fog" };
22 const char * sc_szBlA1[4]       = { "AIn", "AFog", "AShade", "0" };
23 const char * sc_szBlA2[4]       = { "1-A", "AMem", "1", "0" };
24
25 //========================================================================
26 void 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     /*
61 6. 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
68 7. 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
71 8. CVG_X_ALPHA      - Before output the color from color combiner, mod it with alpha
72
73 9. TEX_EDGE         - Ignore this
74
75 10.CLR_ON_CVG       - Used with XLU surfaces, ignore it
76
77 11.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
84 Possible Blending Inputs:
85
86     In  -   Input from color combiner
87     Mem -   Input from current frame buffer
88     Fog -   Fog generator
89     BL  -   Blender
90
91 Possible 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