1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin GD demo
3   File:     gd-tev-create.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: gd-tev-create.c,v $
14   Revision 1.1  02/08/2006 11:19:43  mitu
15   1st version.
16 
17 
18     2     10/13/01 2:29a Hirose
19     Fixes due to GDSetTexCoordGen API change.
20 
21     1     10/04/01 2:48p Hirose
22     Initial check in.
23 
24   $NoKeywords: $
25  *---------------------------------------------------------------------------*/
26 /*---------------------------------------------------------------------------*
27    gd-tev
28      Displaylist demo with multi-texture shader commands
29      [Displaylist creation function for both off-line/runtime]
30  *---------------------------------------------------------------------------*/
31 
32 
33 /*---------------------------------------------------------------------------*
34    Header files
35  *---------------------------------------------------------------------------*/
36 #include "gd-tev.h"
37 
38 /*---------------------------------------------------------------------------*
39     Name:           CreateModelDL
40 
41     Description:    Creates a display list for drawing model
42 
43     Arguments:      dlPtr  : pointer to display list buffer memory
44                     dlSize : actual display list size will be set
45 
46     Returns:        none
47  *---------------------------------------------------------------------------*/
48 static GXVtxDescList VcdSetting[] =
49 {
50     { GX_VA_POS,  GX_INDEX16 },
51     { GX_VA_NBT,  GX_INDEX16 },
52     { GX_VA_TEX0, GX_INDEX16 },
53     { GX_VA_NULL, GX_NONE    }  // NULL Terminator
54 };
55 
CreateModelDL(void * dlPtr,u32 * dlSize)56 void CreateModelDL( void* dlPtr, u32* dlSize )
57 {
58     GDLObj  dlObj;
59     u32     i, j, k;
60     u16     idx;
61 
62     GDInitGDLObj(&dlObj, dlPtr, MDL_SIZE_MAX);
63     GDSetCurrent(&dlObj);
64 
65     // set up vertex descriptor
66     GDSetVtxDescv(VcdSetting);
67 
68     // send primitives
69     for ( i = 0 ; i < MODEL_MESHY - 1 ; i++ )
70     {
71         GDBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (u16)(MODEL_MESHX*2));
72             for ( j = 0 ; j < MODEL_MESHX ; j++ )
73             {
74                 for ( k = 0 ; k <= 1 ; k++ )
75                 {
76                     idx = (u16)((i+k)*MODEL_MESHX + j);
77                     GDPosition1x16(idx);
78                     GDNormal1x16(idx);
79                     GDTexCoord1x16(idx);
80                 }
81             }
82         GDEnd();
83     }
84 
85     // close the DL creation (padding + flushing)
86     GDPadCurr32();
87     GDFlushCurrToMem();
88 
89     // get actual DL size
90     *dlSize = GDGetCurrOffset();
91 
92     // release GD object
93     GDSetCurrent(NULL);
94 }
95 
96 /*---------------------------------------------------------------------------*
97     Name:           CreateShader?DL
98 
99     Description:    Creates display list which contains shader settings
100                     such as TEV and TexGen.
101 
102     Arguments:      dlPtr  : pointer to display list buffer memory
103                     dlSize : actual display list size will be set
104                     plPtr  : pointer to patch list buffer memory
105                     plSize : actual patch list size will be set
106 
107     Returns:        none
108  *---------------------------------------------------------------------------*/
109 /*---------------------------------------------------------------------------*
110     These shader display lists expect the environment as following:
111 
112     These texture map are obtained from a tpl file and should be loaded
113     appropriately before you call these shader display lists.
114 
115         GX_TEXMAP0 : Emboss bump map texture
116         GX_TEXMAP1 : Base texture
117         GX_TEXMAP2 : Reflection map texture
118         GX_TEXMAP3 : Gloss map texture
119 
120     Color channels are reserved for each of diffuse/specular lighting.
121 
122         GX_COLOR0A0 : Diffuse lighting channel
123         GX_COLOR1A1 : Specular lighting channel
124 
125     Also, these texgen matrices will be composed in run-time.
126 
127         GX_TEXMTX0   : Texgen matrix for bump map
128         GX_TEXMTX1   : Texgen matrix for base texture
129         GX_TEXMTX2   : Texgen matrix for spherical reflection map (1st.)
130         GX_TEXMTX3   : Texgen matrix for gloss map
131         GX_PTTEXMTX0 : Texgen matrix for spherical reflection map (2nd.)
132 
133 
134  *---------------------------------------------------------------------------*/
135 
136 /*---------------------------------------------------------------------------*
137     Shader0DL: (1 TEV stage)
138         Base texture * Diffuse light
139  *---------------------------------------------------------------------------*/
CreateShader0DL(void * dlPtr,u32 * dlSize,u32 * plPtr,u32 * plSize)140 void CreateShader0DL( void* dlPtr, u32* dlSize, u32* plPtr, u32* plSize )
141 {
142     GDLObj  dlObj;
143     u32     plIndex = 0;
144 
145     GDInitGDLObj(&dlObj, dlPtr, SDL_SIZE_MAX);
146     GDSetCurrent(&dlObj);
147 
148     // ------------------------ TEV Order -------------------------
149     GDSetTevOrder(
150         GX_TEVSTAGE0,
151         GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR0A0,              // stage 0
152         GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);   // stage 1
153 
154 
155     // ---------------------- TEXCOORD Scale ----------------------
156     // We don't know the actual size of textures at this time
157     // because textures are provided from a TPL file in the
158     // application. Therefore, the code stuffs dummy data for now
159     // and patch them later.
160     //
161     // For patching, keep connection infomation between each
162     // TEXCOORDs and TEXMAPs in the patch list.
163 
164     // GX_TEXCOORD0 - scaled by GX_TEXMAP1
165     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
166     plPtr[plIndex++] = GX_TEXCOORD0;                // target info (TEXCOORD0)
167     plPtr[plIndex++] = 1;                           // source info (TEXMAP1)
168     GDSetTexCoordScale2(GX_TEXCOORD0,               // dummy
169                         1, GX_DISABLE, GX_DISABLE,
170                         1, GX_DISABLE, GX_DISABLE);
171 
172 
173     // ------------------------ TEVSTAGE 0 ------------------------
174     // REGPREV(C) = diffuse lit color * base texture
175 
176     // Color operation
177     GDSetTevColorCalc(
178         GX_TEVSTAGE0,
179         GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO,
180         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV);
181     // Alpha operation + swap mode
182     GDSetTevAlphaCalcAndSwap(
183         GX_TEVSTAGE0,
184         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
185         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
186         GX_TEV_SWAP0, GX_TEV_SWAP0);
187 
188 
189     // ------------- Texture coordinate generation ---------------
190     GDSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0,
191                      GX_FALSE, GX_PTIDENTITY);
192 
193     // All texgen matrix should be set simultaneously (also with PN current matrix.)
194     GDSetCurrentMtx(
195         GX_PNMTX0,      // Position/Normal current matrix index
196         GX_TEXMTX1,     // TEXCOORD0
197         GX_IDENTITY,    // TEXCOORD1 (Not used)
198         GX_IDENTITY,    // TEXCOORD2 (Not used)
199         GX_IDENTITY,    // TEXCOORD3 (Not used)
200         GX_IDENTITY,    // TEXCOORD4 (Not used)
201         GX_IDENTITY,    // TEXCOORD5 (Not used)
202         GX_IDENTITY,    // TEXCOORD6 (Not used)
203         GX_IDENTITY);   // TEXCOORD7 (Not used)
204 
205 
206     // ------- General graphics pipe configuration setting -------
207     GDSetGenMode(1, 1, 1); // NumTexGens, NumChans, NumTevStages
208 
209 
210     // close the DL creation (padding + flushing)
211     GDPadCurr32();
212     GDFlushCurrToMem();
213 
214     // get actual DL size and PL size
215     *dlSize = GDGetCurrOffset();
216     *plSize = plIndex * sizeof(u32);
217 
218     // release GD object
219     GDSetCurrent(NULL);
220 }
221 
222 /*---------------------------------------------------------------------------*
223     Shader1DL: (2 TEV stages)
224           Base texture * Diffuse light
225         + Reflection map * REFLEX_SCALE
226         + Specular light
227  *---------------------------------------------------------------------------*/
CreateShader1DL(void * dlPtr,u32 * dlSize,u32 * plPtr,u32 * plSize)228 void CreateShader1DL( void* dlPtr, u32* dlSize, u32* plPtr, u32* plSize )
229 {
230     GDLObj      dlObj;
231     GXColor     reg0Col = { 0, 0, 0, REFLEX_SCALE };
232     u32         plIndex = 0;
233 
234     GDInitGDLObj(&dlObj, dlPtr, SDL_SIZE_MAX);
235     GDSetCurrent(&dlObj);
236 
237     // ------------------- TEV Color Registers --------------------
238     GDSetTevColor(GX_TEVREG0, reg0Col);
239 
240     // ------------------------ TEV Order -------------------------
241     GDSetTevOrder(
242         GX_TEVSTAGE0,
243         GX_TEXCOORD0, GX_TEXMAP2, GX_COLOR1A1,      // stage 0
244         GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);     // stage 1
245 
246 
247     // ---------------------- TEXCOORD Scale ----------------------
248     // We don't know the actual size of textures at this time
249     // because textures are provided from a TPL file in the
250     // application. Therefore, the code stuffs dummy data for now
251     // and patch them later.
252     //
253     // For patching, keep connection infomation between each
254     // TEXCOORDs and TEXMAPs in the patch list.
255 
256     // GX_TEXCOORD0 - scaled by GX_TEXMAP2
257     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
258     plPtr[plIndex++] = GX_TEXCOORD0;                // target info (TEXCOORD0)
259     plPtr[plIndex++] = 2;                           // source info (TEXMAP2)
260     GDSetTexCoordScale2(GX_TEXCOORD0,               // dummy
261                         1, GX_DISABLE, GX_DISABLE,
262                         1, GX_DISABLE, GX_DISABLE);
263     // GX_TEXCOORD1 - scaled by GX_TEXMAP1
264     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
265     plPtr[plIndex++] = GX_TEXCOORD1;                // target info (TEXCOORD1)
266     plPtr[plIndex++] = 1;                           // source info (TEXMAP1)
267     GDSetTexCoordScale2(GX_TEXCOORD1,               // dummy
268                         1, GX_DISABLE, GX_DISABLE,
269                         1, GX_DISABLE, GX_DISABLE);
270 
271 
272     // ------------------------ TEVSTAGE 0 ------------------------
273     // REGPREV(C) = specular lit color + reflection map * REG0(A)
274 
275     // Color operation
276     GDSetTevColorCalc(
277         GX_TEVSTAGE0,
278         GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_RASC,
279         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV);
280     // Alpha operation + swap mode
281     GDSetTevAlphaCalcAndSwap(
282         GX_TEVSTAGE0,
283         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
284         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
285         GX_TEV_SWAP0, GX_TEV_SWAP0);
286 
287     // ------------------------ TEVSTAGE 1 ------------------------
288     // REGPREV(C) = REGPREV(C) + diffuse lit color * base texture
289 
290     // Color operation
291     GDSetTevColorCalc(
292         GX_TEVSTAGE1,
293         GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_CPREV,
294         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
295     // Alpha operation + swap mode
296     GDSetTevAlphaCalcAndSwap(
297         GX_TEVSTAGE1,
298         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
299         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
300         GX_TEV_SWAP0, GX_TEV_SWAP0);
301 
302 
303     // ------------- Texture coordinate generation ---------------
304     GDSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_NRM,
305                      GX_TRUE, GX_PTTEXMTX0);
306     GDSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0,
307                      GX_FALSE, GX_PTIDENTITY);
308 
309     // All texgen matrix should be set simultaneously (also with PN current matrix.)
310     GDSetCurrentMtx(
311         GX_PNMTX0,      // Position/Normal current matrix index
312         GX_TEXMTX2,     // TEXCOORD0
313         GX_TEXMTX1,     // TEXCOORD1
314         GX_IDENTITY,    // TEXCOORD2 (Not used)
315         GX_IDENTITY,    // TEXCOORD3 (Not used)
316         GX_IDENTITY,    // TEXCOORD4 (Not used)
317         GX_IDENTITY,    // TEXCOORD5 (Not used)
318         GX_IDENTITY,    // TEXCOORD6 (Not used)
319         GX_IDENTITY);   // TEXCOORD7 (Not used)
320 
321 
322     // ------- General graphics pipe configuration setting -------
323     GDSetGenMode(2, 2, 2); // NumTexGens, NumChans, NumTevStages
324 
325 
326     // close the DL creation (padding + flushing)
327     GDPadCurr32();
328     GDFlushCurrToMem();
329 
330     // get actual DL size and PL size
331     *dlSize = GDGetCurrOffset();
332     *plSize = plIndex * sizeof(u32);
333 
334     // release GD object
335     GDSetCurrent(NULL);
336 }
337 
338 /*---------------------------------------------------------------------------*
339     Shader2DL: (3 TEV stages)
340         (Diffuse light + Emboss bump map * BUMP_SCALE) * constant color
341  *---------------------------------------------------------------------------*/
CreateShader2DL(void * dlPtr,u32 * dlSize,u32 * plPtr,u32 * plSize)342 void CreateShader2DL( void* dlPtr, u32* dlSize, u32* plPtr, u32* plSize )
343 {
344     GDLObj      dlObj;
345     GXColor     reg0Col = { 0xFF, 0xE0, 0xC0, BUMP_SCALE };
346     u32         plIndex = 0;
347 
348     GDInitGDLObj(&dlObj, dlPtr, SDL_SIZE_MAX);
349     GDSetCurrent(&dlObj);
350 
351     // ------------------- TEV Color Registers --------------------
352     GDSetTevColor(GX_TEVREG0, reg0Col);
353 
354     // ------------------------ TEV Order -------------------------
355     GDSetTevOrder(
356         GX_TEVSTAGE0,
357         GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0,              // stage 0
358         GX_TEXCOORD1, GX_TEXMAP0, GX_COLOR_NULL);           // stage 1
359     GDSetTevOrder(
360         GX_TEVSTAGE2,
361         GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL,    // stage 2
362         GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);   // stage 3
363 
364 
365     // ---------------------- TEXCOORD Scale ----------------------
366     // We don't know the actual size of textures at this time
367     // because textures are provided from a TPL file in the
368     // application. Therefore, the code stuffs dummy data for now
369     // and patch them later.
370     //
371     // For patching, keep connection infomation between each
372     // TEXCOORDs and TEXMAPs in the patch list.
373 
374     // GX_TEXCOORD0 - scaled by GX_TEXMAP0
375     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
376     plPtr[plIndex++] = GX_TEXCOORD0;                // target info (TEXCOORD0)
377     plPtr[plIndex++] = 0;                           // source info (TEXMAP0)
378     GDSetTexCoordScale2(GX_TEXCOORD0,               // dummy
379                         1, GX_DISABLE, GX_DISABLE,
380                         1, GX_DISABLE, GX_DISABLE);
381     // GX_TEXCOORD1 - scaled by GX_TEXMAP0
382     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
383     plPtr[plIndex++] = GX_TEXCOORD1;                // target info (TEXCOORD1)
384     plPtr[plIndex++] = 0;                           // source info (TEXMAP0)
385     GDSetTexCoordScale2(GX_TEXCOORD1,               // dummy
386                         1, GX_DISABLE, GX_DISABLE,
387                         1, GX_DISABLE, GX_DISABLE);
388 
389 
390     // ------------------------ TEVSTAGE 0 ------------------------
391     // REGPREV(C) = diffuse lit color + bump texture * bump scale(REG0(A))
392 
393     // Color operation
394     GDSetTevColorCalc(
395         GX_TEVSTAGE0,
396         GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_RASC,
397         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV);
398     // Alpha operation + swap mode
399     GDSetTevAlphaCalcAndSwap(
400         GX_TEVSTAGE0,
401         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
402         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
403         GX_TEV_SWAP0, GX_TEV_SWAP0);
404 
405     // ------------------------ TEVSTAGE 1 ------------------------
406     // REGPREV(C) = REGPREV(C) - bump texture * bump scale(REG0(A))
407 
408     // Color operation
409     GDSetTevColorCalc(
410         GX_TEVSTAGE1,
411         GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_CPREV,
412         GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
413     // Alpha operation + swap mode
414     GDSetTevAlphaCalcAndSwap(
415         GX_TEVSTAGE1,
416         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
417         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
418         GX_TEV_SWAP0, GX_TEV_SWAP0);
419 
420     // ------------------------ TEVSTAGE 2 ------------------------
421     // REGPREV(C) = REGPREV(C) * constant color (REG0(C))
422 
423     // Color operation
424     GDSetTevColorCalc(
425         GX_TEVSTAGE2,
426         GX_CC_ZERO, GX_CC_CPREV, GX_CC_C0, GX_CC_ZERO,
427         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
428     // Alpha operation + swap mode
429     GDSetTevAlphaCalcAndSwap(
430         GX_TEVSTAGE2,
431         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
432         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
433         GX_TEV_SWAP0, GX_TEV_SWAP0);
434 
435 
436     // ------------- Texture coordinate generation ---------------
437     GDSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0,
438                      GX_FALSE, GX_PTIDENTITY);
439     GDSetTexCoordGen(GX_TEXCOORD1, GX_TG_BUMP0, GX_TG_TEXCOORD0,
440                      GX_FALSE, GX_PTIDENTITY);
441 
442     // All texgen matrix should be set simultaneously (also with PN current matrix.)
443     GDSetCurrentMtx(
444         GX_PNMTX0,      // Position/Normal current matrix index
445         GX_TEXMTX0,     // TEXCOORD0
446         GX_IDENTITY,    // TEXCOORD1
447         GX_IDENTITY,    // TEXCOORD2 (Not used)
448         GX_IDENTITY,    // TEXCOORD3 (Not used)
449         GX_IDENTITY,    // TEXCOORD4 (Not used)
450         GX_IDENTITY,    // TEXCOORD5 (Not used)
451         GX_IDENTITY,    // TEXCOORD6 (Not used)
452         GX_IDENTITY);   // TEXCOORD7 (Not used)
453 
454 
455     // ------- General graphics pipe configuration setting -------
456     GDSetGenMode(2, 1, 3); // NumTexGens, NumChans, NumTevStages
457 
458 
459     // close the DL creation (padding + flushing)
460     GDPadCurr32();
461     GDFlushCurrToMem();
462 
463     // get actual DL size and PL size
464     *dlSize = GDGetCurrOffset();
465     *plSize = plIndex * sizeof(u32);
466 
467     // release GD object
468     GDSetCurrent(NULL);
469 }
470 
471 /*---------------------------------------------------------------------------*
472     Shader3DL: (5 TEV stages)
473           (Diffuse light + Emboss bump map * BUMP_SCALE)
474           * Base texture * gloss map
475         + (Specular light + Reflection map * REFLEX_SCALE)
476           * (1 - gloss map)
477  *---------------------------------------------------------------------------*/
CreateShader3DL(void * dlPtr,u32 * dlSize,u32 * plPtr,u32 * plSize)478 void CreateShader3DL( void* dlPtr, u32* dlSize, u32* plPtr, u32* plSize )
479 {
480     GDLObj      dlObj;
481     GXColor     reg0Col = { 0, 0, 0, BUMP_SCALE };
482     GXColor     reg1Col = { 0, 0, 0, REFLEX_SCALE };
483     u32         plIndex = 0;
484 
485     GDInitGDLObj(&dlObj, dlPtr, SDL_SIZE_MAX);
486     GDSetCurrent(&dlObj);
487 
488     // ------------------- TEV Color Registers --------------------
489     GDSetTevColor(GX_TEVREG0, reg0Col);
490     GDSetTevColor(GX_TEVREG1, reg1Col);
491 
492     // ------------------------ TEV Order -------------------------
493     GDSetTevOrder(
494         GX_TEVSTAGE0,
495         GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0,              // stage 0
496         GX_TEXCOORD4, GX_TEXMAP0, GX_COLOR_NULL);           // stage 1
497     GDSetTevOrder(
498         GX_TEVSTAGE2,
499         GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL,            // stage 2
500         GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR1A1);             // stage 3
501     GDSetTevOrder(
502         GX_TEVSTAGE4,
503         GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR_NULL,            // stage 4
504         GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);   // stage 5
505 
506 
507     // ---------------------- TEXCOORD Scale ----------------------
508     // We don't know the actual size of textures at this time
509     // because textures are provided from a TPL file in the
510     // application. Therefore, the code stuffs dummy data for now
511     // and patch them later.
512     //
513     // For patching, keep connection infomation between each
514     // TEXCOORDs and TEXMAPs in the patch list.
515 
516     // GX_TEXCOORD0 - scaled by GX_TEXMAP0
517     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
518     plPtr[plIndex++] = GX_TEXCOORD0;                // target info (TEXCOORD0)
519     plPtr[plIndex++] = 0;                           // source info (TEXMAP0)
520     GDSetTexCoordScale2(GX_TEXCOORD0,               // dummy
521                         1, GX_DISABLE, GX_DISABLE,
522                         1, GX_DISABLE, GX_DISABLE);
523     // GX_TEXCOORD1 - scaled by GX_TEXMAP1
524     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
525     plPtr[plIndex++] = GX_TEXCOORD1;                // target info (TEXCOORD1)
526     plPtr[plIndex++] = 1;                           // source info (TEXMAP1)
527     GDSetTexCoordScale2(GX_TEXCOORD1,               // dummy
528                         1, GX_DISABLE, GX_DISABLE,
529                         1, GX_DISABLE, GX_DISABLE);
530     // GX_TEXCOORD2 - scaled by GX_TEXMAP2
531     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
532     plPtr[plIndex++] = GX_TEXCOORD2;                // target info (TEXCOORD2)
533     plPtr[plIndex++] = 2;                           // source info (TEXMAP2)
534     GDSetTexCoordScale2(GX_TEXCOORD2,               // dummy
535                         1, GX_DISABLE, GX_DISABLE,
536                         1, GX_DISABLE, GX_DISABLE);
537     // GX_TEXCOORD3 - scaled by GX_TEXMAP3
538     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
539     plPtr[plIndex++] = GX_TEXCOORD3;                // target info (TEXCOORD3)
540     plPtr[plIndex++] = 3;                           // source info (TEXMAP3)
541     GDSetTexCoordScale2(GX_TEXCOORD0,               // dummy
542                         1, GX_DISABLE, GX_DISABLE,
543                         1, GX_DISABLE, GX_DISABLE);
544     // GX_TEXCOORD4 - scaled by GX_TEXMAP0
545     plPtr[plIndex++] = GDGetCurrOffset();           // patch pointer
546     plPtr[plIndex++] = GX_TEXCOORD4;                // target info (TEXCOORD4)
547     plPtr[plIndex++] = 0;                           // source info (TEXMAP0)
548     GDSetTexCoordScale2(GX_TEXCOORD4,               // dummy
549                         1, GX_DISABLE, GX_DISABLE,
550                         1, GX_DISABLE, GX_DISABLE);
551 
552 
553     // ------------------------ TEVSTAGE 0 ------------------------
554     // REGPREV(C) = diffuse lit color + bump texture * bump scale(REG0(A))
555 
556     // Color operation
557     GDSetTevColorCalc(
558         GX_TEVSTAGE0,
559         GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_RASC,
560         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV);
561     // Alpha operation + swap mode
562     GDSetTevAlphaCalcAndSwap(
563         GX_TEVSTAGE0,
564         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
565         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
566         GX_TEV_SWAP0, GX_TEV_SWAP0);
567 
568     // ------------------------ TEVSTAGE 1 ------------------------
569     // REGPREV(C) = REGPREV(C) - bump texture * bump scale(REG0(A))
570 
571     // Color operation
572     GDSetTevColorCalc(
573         GX_TEVSTAGE1,
574         GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_CPREV,
575         GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
576     // Alpha operation + swap mode
577     GDSetTevAlphaCalcAndSwap(
578         GX_TEVSTAGE1,
579         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
580         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
581         GX_TEV_SWAP0, GX_TEV_SWAP0);
582 
583     // ------------------------ TEVSTAGE 2 ------------------------
584     // REG2(C) = REGPREV(C) * base texture
585 
586     // Color operation
587     GDSetTevColorCalc(
588         GX_TEVSTAGE2,
589         GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO,
590         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2);
591     // Alpha operation + swap mode
592     GDSetTevAlphaCalcAndSwap(
593         GX_TEVSTAGE2,
594         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
595         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVREG2,
596         GX_TEV_SWAP0, GX_TEV_SWAP0);
597 
598     // ------------------------ TEVSTAGE 3 ------------------------
599     // REGPREV(C) = specular lit color + reflection map * reflection scale(REG1(A))
600 
601     // Color operation
602     GDSetTevColorCalc(
603         GX_TEVSTAGE3,
604         GX_CC_ZERO, GX_CC_A1, GX_CC_TEXC, GX_CC_RASC,
605         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
606     // Alpha operation + swap mode
607     GDSetTevAlphaCalcAndSwap(
608         GX_TEVSTAGE3,
609         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
610         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
611         GX_TEV_SWAP0, GX_TEV_SWAP0);
612 
613     // ------------------------ TEVSTAGE 4 ------------------------
614     // REGPREV(C) = gloss map * REG2(C) + (1 - gloss map) * REGPREV(C)
615 
616     // Color operation
617     GDSetTevColorCalc(
618         GX_TEVSTAGE4,
619         GX_CC_CPREV, GX_CC_C2, GX_CC_TEXC, GX_CC_ZERO,
620         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
621     // Alpha operation + swap mode
622     GDSetTevAlphaCalcAndSwap(
623         GX_TEVSTAGE4,
624         GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
625         GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
626         GX_TEV_SWAP0, GX_TEV_SWAP0);
627 
628 
629     // ------------- Texture coordinate generation ---------------
630     GDSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0,
631                      GX_FALSE, GX_PTIDENTITY);
632     GDSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0,
633                      GX_FALSE, GX_PTIDENTITY);
634     GDSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX3x4, GX_TG_NRM,
635                      GX_TRUE, GX_PTTEXMTX0);
636     GDSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX0,
637                      GX_FALSE, GX_PTIDENTITY);
638     GDSetTexCoordGen(GX_TEXCOORD4, GX_TG_BUMP0, GX_TG_TEXCOORD0,
639                      GX_FALSE, GX_PTIDENTITY);
640 
641     // All texgen matrix should be set simultaneously (also with PN current matrix.)
642     GDSetCurrentMtx(
643         GX_PNMTX0,      // Position/Normal current matrix index
644         GX_TEXMTX0,     // TEXCOORD0
645         GX_TEXMTX1,     // TEXCOORD1
646         GX_TEXMTX2,     // TEXCOORD2
647         GX_TEXMTX3,     // TEXCOORD3
648         GX_IDENTITY,    // TEXCOORD4
649         GX_IDENTITY,    // TEXCOORD5 (Not used)
650         GX_IDENTITY,    // TEXCOORD6 (Not used)
651         GX_IDENTITY);   // TEXCOORD7 (Not used)
652 
653 
654     // ------- General graphics pipe configuration setting -------
655     GDSetGenMode(5, 2, 5); // NumTexGens, NumChans, NumTevStages
656 
657 
658     // close the DL creation (padding + flushing)
659     GDPadCurr32();
660     GDFlushCurrToMem();
661 
662     // get actual DL size and PL size
663     *dlSize = GDGetCurrOffset();
664     *plSize = plIndex * sizeof(u32);
665 
666     // release GD object
667     GDSetCurrent(NULL);
668 }
669 
670 /*============================================================================*/
671