1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin GD library
3   File:     GDTev.c
4 
5   Copyright 2001 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: GDTev.c,v $
14   Revision 1.2  2006/02/20 04:24:39  mitu
15   Changed include path from dolphin/ to revolution/.
16 
17   Revision 1.1.1.1  2005/05/12 02:15:49  yasuh-to
18   Ported from dolphin source tree.
19 
20 
21     5     2001/11/07 6:44p Hirose
22     Fixed GDSetTevColorS10 negative value bug.
23 
24     4     2001/09/28 4:37p Hirose
25     Fixed GDSetTevColorS10 and GDSetTevKColor as well.
26 
27     3     2001/09/28 3:19a Hirose
28     Fixed a bug in GDSetTevColor.
29 
30     2     2001/09/21 1:46p Carl
31     Changed order of args for GDSetKonstantSel.
32 
33 
34     1     2001/09/12 1:52p Carl
35     Initial revision of GD: Graphics Display List Library.
36 
37   $NoKeywords: $
38  *---------------------------------------------------------------------------*/
39 
40 #include <revolution/gd.h>
41 #include <revolution/os.h>
42 
43 /*---------------------------------------------------------------------------*/
44 
45 
46 /*---------------------------------------------------------------------------*/
47 //  Name:         GDSetTevOp
48 //
49 //  Description:  Sets up various TEV configurations in a simplified way.
50 //                Note: the ras & tex swap parameters are set to TEV_SWAP0.
51 //
52 //  Arguments:    stage:  	which TEV stage will be set
53 //                mode:   	which simplified TEV mode
54 //
55 //  Returns:      none
56 //
57 /*---------------------------------------------------------------------------*/
58 
GDSetTevOp(GXTevStageID stage,GXTevMode mode)59 void GDSetTevOp(GXTevStageID stage, GXTevMode mode)
60 {
61     GXTevColorArg carg = GX_CC_RASC;
62     GXTevAlphaArg aarg = GX_CA_RASA;
63 
64     if (stage != GX_TEVSTAGE0) {
65         carg = GX_CC_CPREV;
66         aarg = GX_CA_APREV;
67     }
68 
69     switch (mode) {
70       case GX_MODULATE:
71         GDSetTevColorCalc( stage,
72             GX_CC_ZERO, GX_CC_TEXC, carg, GX_CC_ZERO,
73             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV );
74         GDSetTevAlphaCalcAndSwap( stage,
75             GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO,
76             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV,
77             GX_TEV_SWAP0, GX_TEV_SWAP0 );
78         break;
79       case GX_DECAL:
80         GDSetTevColorCalc( stage,
81             carg, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO,
82             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV );
83         GDSetTevAlphaCalcAndSwap( stage,
84             GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg,
85             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV,
86             GX_TEV_SWAP0, GX_TEV_SWAP0 );
87         break;
88       case GX_BLEND:
89         GDSetTevColorCalc( stage,
90             carg, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO,
91             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV );
92         GDSetTevAlphaCalcAndSwap( stage,
93             GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO,
94             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV,
95             GX_TEV_SWAP0, GX_TEV_SWAP0 );
96         break;
97       case GX_REPLACE:
98         GDSetTevColorCalc(stage,
99             GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC,
100             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV );
101         GDSetTevAlphaCalcAndSwap( stage,
102             GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA,
103             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV,
104             GX_TEV_SWAP0, GX_TEV_SWAP0 );
105         break;
106       case GX_PASSCLR:
107         GDSetTevColorCalc( stage,
108             GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, carg,
109             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV );
110         GDSetTevAlphaCalcAndSwap( stage,
111             GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg,
112             GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV,
113             GX_TEV_SWAP0, GX_TEV_SWAP0 );
114         break;
115       default:
116         ASSERTMSG(0, "GDSetTevOp: Invalid Tev Mode");
117         break;
118     }
119 }
120 
121 /*---------------------------------------------------------------------------*/
122 //  Name:         GDSetTevColorCalc
123 //
124 //  Description:  Sets up the RGB part of a TEV calculation
125 //
126 //  Arguments:    stage:  	which TEV stage will be set
127 //                ...:    	parameters to set, as indicated by name
128 //
129 //  Returns:      none
130 //
131 /*---------------------------------------------------------------------------*/
132 
GDSetTevColorCalc(GXTevStageID stage,GXTevColorArg a,GXTevColorArg b,GXTevColorArg c,GXTevColorArg d,GXTevOp op,GXTevBias bias,GXTevScale scale,GXBool clamp,GXTevRegID out_reg)133 void GDSetTevColorCalc(
134     GXTevStageID    stage,
135     GXTevColorArg   a,
136     GXTevColorArg   b,
137     GXTevColorArg   c,
138     GXTevColorArg   d,
139     GXTevOp         op,
140     GXTevBias       bias,
141     GXTevScale      scale,
142     GXBool          clamp,
143     GXTevRegID      out_reg )
144 {
145     if (op <= GX_TEV_SUB)
146     {
147         GDWriteBPCmd( TEV_COLOR_ENV( d, c, b, a,
148                                      bias, (op & 1), clamp, scale,
149                                      out_reg,
150                                      TEV_COLOR_ENV_0_ID + 2 * (u32) stage ));
151     } else {
152         GDWriteBPCmd( TEV_COLOR_ENV( d, c, b, a,
153                                      GX_MAX_TEVBIAS, (op&1), clamp, ((op>>1)&3),
154                                      out_reg,
155                                      TEV_COLOR_ENV_0_ID + 2 * (u32) stage ));
156     }
157 }
158 
159 /*---------------------------------------------------------------------------*/
160 //  Name:         GDSetTevAlphaCalcAndSwap
161 //
162 //  Description:  Sets up the alpha part of a TEV calculation, as well as
163 //                selecting the raster and texture color swap modes
164 //
165 //  Arguments:    stage:  	which TEV stage will be set
166 //                ...:    	parameters to set, as indicated by name
167 //
168 //  Returns:      none
169 //
170 /*---------------------------------------------------------------------------*/
171 
GDSetTevAlphaCalcAndSwap(GXTevStageID stage,GXTevAlphaArg a,GXTevAlphaArg b,GXTevAlphaArg c,GXTevAlphaArg d,GXTevOp op,GXTevBias bias,GXTevScale scale,GXBool clamp,GXTevRegID out_reg,GXTevSwapSel ras_sel,GXTevSwapSel tex_sel)172 void GDSetTevAlphaCalcAndSwap(
173     GXTevStageID    stage,
174     GXTevAlphaArg   a,
175     GXTevAlphaArg   b,
176     GXTevAlphaArg   c,
177     GXTevAlphaArg   d,
178     GXTevOp         op,
179     GXTevBias       bias,
180     GXTevScale      scale,
181     GXBool          clamp,
182     GXTevRegID      out_reg,
183     GXTevSwapSel    ras_sel,
184     GXTevSwapSel    tex_sel )
185 {
186     if (op <= GX_TEV_SUB)
187     {
188         GDWriteBPCmd( TEV_ALPHA_ENV( ras_sel, tex_sel,
189                                      d, c, b, a,
190                                      bias, (op & 1), clamp, scale,
191                                      out_reg,
192                                      TEV_ALPHA_ENV_0_ID + 2 * (u32) stage ));
193     } else {
194         GDWriteBPCmd( TEV_ALPHA_ENV( ras_sel, tex_sel,
195                                      d, c, b, a,
196                                      GX_MAX_TEVBIAS, (op&1), clamp, ((op>>1)&3),
197                                      out_reg,
198                                      TEV_ALPHA_ENV_0_ID + 2 * (u32) stage ));
199     }
200 }
201 
202 /*---------------------------------------------------------------------------*/
203 //  Name:         GDSetTevColor
204 //
205 //  Description:  Set one of the dynamic TEV color registers.
206 //                This versions lets you input RGBA8 colors.
207 //
208 //  Arguments:    reg:    	which dynamic TEV color register will be set
209 //                color:  	RGBA8 color value to write to register
210 //
211 //  Returns:      none
212 //
213 /*---------------------------------------------------------------------------*/
214 
GDSetTevColor(GXTevRegID reg,GXColor color)215 void GDSetTevColor   ( GXTevRegID reg, GXColor color )
216 {
217     u32 regRA, regBG;
218 
219     regRA = TEV_REGISTERL( color.r, color.a, TEV_COLOR_REG,
220                            TEV_REGISTERL_0_ID + reg * 2 );
221     regBG = TEV_REGISTERH( color.b, color.g, TEV_COLOR_REG,
222                            TEV_REGISTERH_0_ID + reg * 2 );
223     GDWriteBPCmd( regRA );
224     GDWriteBPCmd( regBG );
225     // Due to color load delay bug, must put two more BP commands here...
226     GDWriteBPCmd( regBG );
227     GDWriteBPCmd( regBG );
228 }
229 
230 /*---------------------------------------------------------------------------*/
231 //  Name:         GDSetTevColorS10
232 //
233 //  Description:  Set one of the dynamic TEV color registers.
234 //                This versions lets you input RGBA10 colors.
235 //
236 //  Arguments:    reg:    	which dynamic TEV color register will be set
237 //                color:  	RGBA8 color value to write to register
238 //
239 //  Returns:      none
240 //
241 /*---------------------------------------------------------------------------*/
242 
243 #define TEV_REGISTER_VAL_SIZE   11
244 #define TEV_REGISTER_VAL_MASK   ((1<<TEV_REGISTER_VAL_SIZE)-1)
245 
GDSetTevColorS10(GXTevRegID reg,GXColorS10 color)246 void GDSetTevColorS10( GXTevRegID reg, GXColorS10 color )
247 {
248     u32 regRA, regBG;
249 
250     regRA = TEV_REGISTERL( (color.r & TEV_REGISTER_VAL_MASK),
251                            (color.a & TEV_REGISTER_VAL_MASK),
252                            TEV_COLOR_REG,
253                            TEV_REGISTERL_0_ID + reg * 2 );
254     regBG = TEV_REGISTERH( (color.b & TEV_REGISTER_VAL_MASK),
255                            (color.g & TEV_REGISTER_VAL_MASK),
256                            TEV_COLOR_REG,
257                            TEV_REGISTERH_0_ID + reg * 2 );
258     GDWriteBPCmd( regRA );
259     GDWriteBPCmd( regBG );
260     // Due to color load delay bug, must put two more BP commands here...
261     GDWriteBPCmd( regBG );
262     GDWriteBPCmd( regBG );
263 }
264 
265 /*---------------------------------------------------------------------------*/
266 //  Name:         GXSetTevKColor
267 //
268 //  Description:  Sets one of four constant TEV color registers.
269 //
270 //  Arguments:    id:            	register name.
271 //                color:         	color value.
272 //
273 //  Returns:      None
274 //
275 /*---------------------------------------------------------------------------*/
276 
GDSetTevKColor(GXTevKColorID reg,GXColor color)277 void GDSetTevKColor  ( GXTevKColorID reg, GXColor color )
278 {
279     u32 regRA, regBG;
280 
281     regRA = TEV_REGISTERL( color.r, color.a, TEV_KONSTANT_REG,
282                            TEV_REGISTERL_0_ID + reg * 2 );
283     regBG = TEV_REGISTERH( color.b, color.g, TEV_KONSTANT_REG,
284                            TEV_REGISTERH_0_ID + reg * 2 );
285     GDWriteBPCmd( regRA );
286     GDWriteBPCmd( regBG );
287     // The KColor registers do not have the load delay bug.
288 }
289 
290 /*---------------------------------------------------------------------------*/
291 //  Name:         GDSetTevKColorSel
292 //
293 //  Description:  Selects form of Konstant color to use for a given pair
294 //                of TEV stages.
295 //
296 //  Arguments:    evenStage:    	tev stage id (must be even)
297 //                kcsel0:       	selection for Konstant color for evenStage
298 //                kasel0:       	selection for Konstant alpha for evenStage
299 //                kcsel1:       	selection for Konstant color for evenStage+1
300 //                kasel1:       	selection for Konstant alpha for evenStage+1
301 //
302 //  Returns:      None
303 //
304 /*---------------------------------------------------------------------------*/
305 
306 #define TEV_KSEL_MASK_KCSEL \
307     (( 0x00001F << TEV_KSEL_KCSEL0_SHIFT ) | \
308      ( 0x00001F << TEV_KSEL_KASEL0_SHIFT ) | \
309      ( 0x00001F << TEV_KSEL_KCSEL1_SHIFT ) | \
310      ( 0x00001F << TEV_KSEL_KASEL1_SHIFT ))
311 
GDSetTevKonstantSel(GXTevStageID evenStage,GXTevKColorSel kcsel0,GXTevKAlphaSel kasel0,GXTevKColorSel kcsel1,GXTevKAlphaSel kasel1)312 void GDSetTevKonstantSel( GXTevStageID evenStage,
313                           GXTevKColorSel kcsel0, GXTevKAlphaSel kasel0,
314                           GXTevKColorSel kcsel1, GXTevKAlphaSel kasel1 )
315 {
316     // Mask to avoid touching the swap-select tables
317     GDWriteBPCmd( SS_MASK( TEV_KSEL_MASK_KCSEL ) );
318     GDWriteBPCmd( TEV_KSEL( 0, 0, kcsel0, kasel0, kcsel1, kasel1,
319                             TEV_KSEL_0_ID + (evenStage/2) ));
320 }
321 
322 /*---------------------------------------------------------------------------*/
323 //  Name:         GXSetTevSwapModeTable
324 //
325 //  Description:  Sets the table of 4 different swap mode possibilities.
326 //
327 //  Arguments:    table:         	which swap table to set
328 //
329 //                red, green:	    which channel to output for each input
330 //                blue, alpha
331 //
332 //  Returns:      None
333 //
334 /*---------------------------------------------------------------------------*/
335 
336 #define TEV_KSEL_MASK_SWAPMODETABLE \
337     (( 0x000003 << TEV_KSEL_XRB_SHIFT ) | \
338      ( 0x000003 << TEV_KSEL_XGA_SHIFT ))
339 
GDSetTevSwapModeTable(GXTevSwapSel table,GXTevColorChan red,GXTevColorChan green,GXTevColorChan blue,GXTevColorChan alpha)340 void GDSetTevSwapModeTable(
341     GXTevSwapSel    table,
342     GXTevColorChan  red,
343     GXTevColorChan  green,
344     GXTevColorChan  blue,
345     GXTevColorChan  alpha )
346 {
347     // Mask to avoid touching the konstant-color selects
348     GDWriteBPCmd( SS_MASK( TEV_KSEL_MASK_SWAPMODETABLE ) );
349     GDWriteBPCmd( TEV_KSEL( red, green, 0, 0, 0, 0,
350                             TEV_KSEL_0_ID + (table * 2) ));
351     GDWriteBPCmd( SS_MASK( TEV_KSEL_MASK_SWAPMODETABLE ) );
352     GDWriteBPCmd( TEV_KSEL( blue, alpha, 0, 0, 0, 0,
353                             TEV_KSEL_0_ID + (table * 2) + 1 ));
354 }
355 
356 /*---------------------------------------------------------------------------*/
357 //  Name:         GDSetAlphaCompare
358 //
359 //  Description:  Sets alpha value comparison function and parameters.
360 //
361 //  Arguments:    comp0:       	compare function 0.
362 //                ref0:        	reference value 0.
363 //                op:          	logical op to combine the two comparison results.
364 //                comp1:       	compare function 0.
365 //                ref1:        	reference value 1.
366 //
367 //  Returns:      None
368 //
369 /*---------------------------------------------------------------------------*/
370 
GDSetAlphaCompare(GXCompare comp0,u8 ref0,GXAlphaOp op,GXCompare comp1,u8 ref1)371 void GDSetAlphaCompare(
372     GXCompare       comp0,
373     u8              ref0,
374     GXAlphaOp       op,
375     GXCompare       comp1,
376     u8              ref1 )
377 {
378     GDWriteBPCmd( TEV_ALPHAFUNC( ref0, ref1, comp0, comp1, op,
379                                  TEV_ALPHAFUNC_ID ));
380 }
381 
382 /*---------------------------------------------------------------------------*/
383 //  Name:         GDSetZTexture
384 //
385 //  Description:  Sets parameters for controlling z textures in the last
386 //                tev stage.
387 //
388 //  Arguments:    op:    	Z Texture operation
389 //                fmt:   	Format of z texels.
390 //                bias:  	bias to add to the z values.
391 //
392 //  Returns:      None
393 //
394 /*---------------------------------------------------------------------------*/
395 
GDSetZTexture(GXZTexOp op,GXTexFmt fmt,u32 bias)396 void GDSetZTexture ( GXZTexOp op, GXTexFmt fmt, u32 bias )
397 {
398     u32 zfmt;
399 
400     switch(fmt) {
401       case GX_TF_Z8:    zfmt = TEV_Z_TYPE_U8;   break;
402       case GX_TF_Z16:   zfmt = TEV_Z_TYPE_U16;  break;
403       case GX_TF_Z24X8: zfmt = TEV_Z_TYPE_U24;  break;
404       default:
405         ASSERTMSG(0, "GDSetZTexture: Invalid format");
406         zfmt = TEV_Z_TYPE_U24; break;
407     }
408 
409     GDWriteBPCmd( TEV_Z_ENV_0( bias, TEV_Z_ENV_0_ID ));
410     GDWriteBPCmd( TEV_Z_ENV_1( zfmt, op, TEV_Z_ENV_1_ID ));
411 }
412 
413 /*---------------------------------------------------------------------------*/
414 //  Name:         GXSetTevOrder
415 //
416 //  Description:  Sets texture map id, texture coordinate id, and color id
417 //                for the given pair of texture stages.
418 //
419 //  Arguments:    evenStage:    	tev stage id (must be even)
420 //                ...:          	parameters to set, as indicated by name
421 //
422 //  Returns:
423 //
424 /*---------------------------------------------------------------------------*/
425 
GDSetTevOrder(GXTevStageID evenStage,GXTexCoordID coord0,GXTexMapID map0,GXChannelID color0,GXTexCoordID coord1,GXTexMapID map1,GXChannelID color1)426 void GDSetTevOrder(
427     GXTevStageID    evenStage,
428     GXTexCoordID    coord0,
429     GXTexMapID      map0,
430     GXChannelID     color0,
431     GXTexCoordID    coord1,
432     GXTexMapID      map1,
433     GXChannelID     color1 )
434 {
435     static u8 c2r[] = {         // Convert enums to HW values
436         RAS1_CC_0,              // GX_COLOR0
437         RAS1_CC_1,              // GX_COLOR1
438         RAS1_CC_0,              // GX_ALPHA0
439         RAS1_CC_1,              // GX_ALPHA1
440         RAS1_CC_0,              // GX_COLOR0A0
441         RAS1_CC_1,              // GX_COLOR1A1
442         RAS1_CC_Z,              // GX_COLOR_ZERO
443         RAS1_CC_B,              // GX_COLOR_BUMP
444         RAS1_CC_BN,             // GX_COLOR_BUMPN
445         0,                      // 9
446         0,                      // 10
447         0,                      // 11
448         0,                      // 12
449         0,                      // 13
450         0,                      // 14
451         RAS1_CC_Z               // 15: GX_COLOR_NULL gets mapped here
452     };
453 
454     GDWriteBPCmd( RAS1_TREF(
455         (map0 & 7),                                             // map 0
456         (coord0 & 7),                                           // tc 0
457         ((map0 != GX_TEXMAP_NULL) && !(map0 & GX_TEX_DISABLE)), // enable 0
458         c2r[ color0 & 0xf ],                                    // color 0
459         (map1 & 7),                                             // map 1
460         (coord1 & 7),                                           // tc 1
461         ((map1 != GX_TEXMAP_NULL) && !(map1 & GX_TEX_DISABLE)), // enable 1
462         c2r[ color1 & 0xf ],                                    // color 1
463         (RAS1_TREF0_ID + (evenStage/2)) ));
464 }
465 
466