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