1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tev-swap.c
4 
5   Copyright 1998-2006 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 /*---------------------------------------------------------------------------*
14     tev-swap
15         TEV swap mode table capability demo
16  *---------------------------------------------------------------------------*/
17 
18 
19 /*---------------------------------------------------------------------------*
20    Header files
21  *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24 
25 /*---------------------------------------------------------------------------*
26    Macro definitions
27  *---------------------------------------------------------------------------*/
28 #define NUM_MENU        5
29 
30 #define NUM_PATTERNS    2
31 #define NUM_DONUTS      12
32 
33 #define Clamp(val,min,max) \
34     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
35 
36 /*---------------------------------------------------------------------------*
37    Structure definitions
38  *---------------------------------------------------------------------------*/
39 // for entire scene control
40 typedef struct
41 {
42     u32         patternNo;
43     u32         cursor;
44     u32         tblIdx;
45     BOOL        blend;
46     u16         screen_width;
47     u16         screen_height;
48 } MySceneCtrlObj;
49 
50 /*---------------------------------------------------------------------------*
51    Forward references
52  *---------------------------------------------------------------------------*/
53 void        main                ( void );
54 static void DrawInit            ( MySceneCtrlObj* sc );
55 static void DrawTick            ( MySceneCtrlObj* sc );
56 static void AnimTick            ( MySceneCtrlObj* sc );
57 static void DrawSampleTex       ( MySceneCtrlObj* sc );
58 static void DrawDonuts          ( MySceneCtrlObj* sc );
59 static void LoadTevSwapTable    ( void );
60 static void PrintIntro          ( void );
61 
62 /*---------------------------------------------------------------------------*
63   Model and texture data
64  *---------------------------------------------------------------------------*/
65 #define NUM_COLORS  12
66 static GXColor MyColorArray[] ATTRIBUTE_ALIGN(32) =
67 {
68     { 0xFF, 0xFF, 0xFF, 0xFF }, // White
69     { 0x00, 0xFF, 0xFF, 0x80 }, // Cyan
70     { 0x00, 0xFF, 0x00, 0xC0 }, // Green
71     { 0xFF, 0xFF, 0x00, 0xA0 }, // Yellow
72     { 0xFF, 0x00, 0x00, 0xE0 }, // Red
73     { 0xFF, 0x00, 0xFF, 0x60 }, // Magenta
74     { 0x00, 0x00, 0xFF, 0x80 }, // Blue
75     { 0x80, 0x80, 0x80, 0x40 }, // Gray
76     { 0xFF, 0x80, 0x80, 0xC0 }, //
77     { 0x80, 0xFF, 0x80, 0x80 }, //
78     { 0x80, 0x80, 0xFF, 0x20 }, //
79     { 0x00, 0x00, 0x00, 0xFF }  //
80 };
81 
82 /*---------------------------------------------------------------------------*
83    Swap mode table
84  *---------------------------------------------------------------------------*/
85 static u8 MySwapModeTable[4][4] =
86 {
87     { 0, 1, 2, 3 }, // RGBA
88     { 0, 0, 0, 3 }, // RRRA
89     { 1, 1, 1, 3 }, // GGGA
90     { 2, 2, 2, 3 }, // BBBA
91 };
92 
93 static char* MySwCompMsg[4] =
94 {
95     "RED  ", "GREEN", "BLUE ", "ALPHA"
96 };
97 
98 
99 static GXTevSwapSel MySwSelTable[4] =
100 {
101     GX_TEV_SWAP0, GX_TEV_SWAP1, GX_TEV_SWAP2, GX_TEV_SWAP3
102 };
103 
104 static GXTevColorChan MyChCompTable[4] =
105 {
106     GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA
107 };
108 
109 /*---------------------------------------------------------------------------*
110    Global variables
111  *---------------------------------------------------------------------------*/
112 static MySceneCtrlObj   SceneCtrl;          // scene control parameters
113 static TPLPalettePtr    MyTplObj = NULL;    // for TPL file
114 
115 /*---------------------------------------------------------------------------*
116    Application main loop
117  *---------------------------------------------------------------------------*/
main(void)118 void main ( void )
119 {
120     DEMOInit(NULL);       // Init the OS, game pad, graphics and video.
121 
122     DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
123                           // and default scene settings.
124 
125     PrintIntro();    // Print demo directions
126 
127     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
128     {
129         DEMOBeforeRender();
130         DrawTick(&SceneCtrl);    // Draw the model.
131         DEMODoneRender();
132         DEMOPadRead();           // Read controller
133         AnimTick(&SceneCtrl);    // Do animation
134     }
135 
136     OSHalt("End of demo");
137 }
138 
139 /*---------------------------------------------------------------------------*
140    Functions
141  *---------------------------------------------------------------------------*/
142 /*---------------------------------------------------------------------------*
143     Name:           DrawInit
144 
145     Description:    Initializes the vertex attribute format and sets up
146                     the array pointer for the indexed data.
147                     This function also initializes scene control parameters.
148 
149     Arguments:      sc : pointer to the structure of scene control parameters
150 
151     Returns:        none
152  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)153 static void DrawInit( MySceneCtrlObj* sc )
154 {
155     GXRenderModeObj *rmp;
156 
157     // Get framebuffer size of current rendering mode
158     rmp = DEMOGetRenderModeObj();
159     sc->screen_width  = rmp->fbWidth;
160     sc->screen_height = rmp->efbHeight;
161 
162     // Vertex Attribute (VTXFMT0 is used by DEMOPuts library)
163     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
164     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_S16, 8);
165     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
166 
167     // load tpl file
168     TPLGetPalette(&MyTplObj, "gxTests/tex-02/rgba8_1.tpl");
169 
170     // Default scene control parameter settings
171     sc->patternNo = 0;
172     sc->cursor    = 0;
173     sc->tblIdx    = 0;
174     sc->blend     = FALSE;
175 }
176 
177 /*---------------------------------------------------------------------------*
178     Name:           DrawTick
179 
180     Description:    Draw the model by using given scene parameters
181 
182     Arguments:      sc : pointer to the structure of scene control parameters
183 
184     Returns:        none
185  *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)186 static void DrawTick( MySceneCtrlObj* sc )
187 {
188     Mtx44  proj;
189 
190     // Initialize screen space projection
191     MTXOrtho(proj, 0, sc->screen_height, 0, sc->screen_width, 0.0F, 10000.0F);
192     GXSetProjection(proj, GX_ORTHOGRAPHIC);
193 
194     // Load TEV swap mode table setting into the hardware
195     LoadTevSwapTable();
196 
197     // Alpha blending mode
198     if ( sc->blend )
199     {
200         GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
201     }
202     else
203     {
204         GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET);
205     }
206 
207     // Draw models
208     if ( sc->patternNo == 0 )
209     {
210         DrawSampleTex(sc);
211     }
212     else
213     {
214         DrawDonuts(sc);
215     }
216 
217     // Caption
218     DEMOInitCaption(DM_FT_OPQ, (s16)(sc->screen_width/2), (s16)(sc->screen_height/2));
219     DEMOPrintf(24, 16, 0, "Swap Mode Table : %d", sc->tblIdx);
220     DEMOPrintf(24, 24, 0, "%s -> RED",   MySwCompMsg[MySwapModeTable[sc->tblIdx][0]]);
221     DEMOPrintf(24, 32, 0, "%s -> GREEN", MySwCompMsg[MySwapModeTable[sc->tblIdx][1]]);
222     DEMOPrintf(24, 40, 0, "%s -> BLUE",  MySwCompMsg[MySwapModeTable[sc->tblIdx][2]]);
223     DEMOPrintf(24, 48, 0, "%s -> ALPHA", MySwCompMsg[MySwapModeTable[sc->tblIdx][3]]);
224     // Cursor
225     DEMOPrintf(12, (s16)(sc->cursor*8+16), 0, "%c", 0x7F);
226 }
227 
228 /*---------------------------------------------------------------------------*
229     Name:           AnimTick
230 
231     Description:    Changes scene parameters according to the pad status.
232 
233     Arguments:      sc : pointer to the structure of scene control parameters
234 
235     Returns:        none
236  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)237 static void AnimTick( MySceneCtrlObj* sc )
238 {
239     // Move cursor
240     if ( DEMOPadGetDirsNew(0) & DEMO_STICK_UP )
241     {
242         sc->cursor += NUM_MENU - 1;
243     }
244     if ( DEMOPadGetDirsNew(0) & DEMO_STICK_DOWN )
245     {
246         sc->cursor++;
247     }
248     sc->cursor %= NUM_MENU;
249 
250 
251     // Change swap mode parameters
252     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
253     {
254         switch(sc->cursor)
255         {
256           case 0 :
257             sc->tblIdx = ( sc->tblIdx + 1 ) % 4;
258             break;
259           case 1 :
260           case 2 :
261           case 3 :
262           case 4 :
263             MySwapModeTable[sc->tblIdx][sc->cursor - 1]++;
264             MySwapModeTable[sc->tblIdx][sc->cursor - 1] %= 4;
265             break;
266         }
267     }
268 
269     // Change the display pattern
270     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_B )
271     {
272         sc->patternNo = ++sc->patternNo % NUM_PATTERNS;
273     }
274 
275     // Alpha blend mode
276     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_Y )
277     {
278         sc->blend = sc->blend ? FALSE : TRUE;
279     }
280 }
281 
282 /*---------------------------------------------------------------------------*
283     Name:           DrawSampleTex
284 
285     Description:    Draw a sample texture
286                     which shows TEX component swap results
287 
288     Arguments:      none
289 
290     Returns:        none
291  *---------------------------------------------------------------------------*/
DrawSampleTex(MySceneCtrlObj * sc)292 static void DrawSampleTex( MySceneCtrlObj* sc )
293 {
294     GXTexObj    tx;
295     Mtx         mv;
296 
297     // Transform matrix
298     MTXIdentity(mv);
299     GXLoadPosMtxImm(mv, GX_PNMTX0);
300     GXSetCurrentMtx(GX_PNMTX0);
301 
302     // No color channel
303     GXSetNumChans(0);
304 
305     // Texture coord generation
306     GXSetNumTexGens(1);
307     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
308 
309     // Set up texture
310     TPLGetGXTexObjFromPalette(MyTplObj, &tx, 0);
311     GXLoadTexObj(&tx, GX_TEXMAP0);
312 
313     // Set TEV operation for one texture
314     GXSetNumTevStages(1);
315     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
316     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
317 
318     // TEV swap mode setting
319     // Note that these features don't work on the emulator
320 
321     // swap mode table select
322     GXSetTevSwapMode(
323         GX_TEVSTAGE0,
324         MySwSelTable[sc->tblIdx],   // ras_sel (actually not used here)
325         MySwSelTable[sc->tblIdx] ); // tex_sel
326 
327     // Vertex descriptor
328     GXClearVtxDesc();
329     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
330     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
331 
332     // Draw a large quad
333     GXBegin(GX_QUADS, GX_VTXFMT1, 4);
334         GXPosition3s16( 64,  120, 0);
335         GXTexCoord2s16(0x0000, 0x0000);
336         GXPosition3s16(576,  120, 0);
337         GXTexCoord2s16(0x0100, 0x0000);
338         GXPosition3s16(576, 376, 0);
339         GXTexCoord2s16(0x0100, 0x0100);
340         GXPosition3s16( 64, 376, 0);
341         GXTexCoord2s16(0x0000, 0x0100);
342     GXEnd();
343 }
344 
345 /*---------------------------------------------------------------------------*
346     Name:           DrawDonuts
347 
348     Description:    Draw lit colored doughnuts
349                     that show RAS component swap results
350 
351     Arguments:      none
352 
353     Returns:        none
354  *---------------------------------------------------------------------------*/
DrawDonuts(MySceneCtrlObj * sc)355 static void DrawDonuts( MySceneCtrlObj* sc )
356 {
357     static u32  rot = 0;
358     GXLightObj  lo;
359     u32         i;
360     Mtx         m0, m1, ms;
361     GXColor     ambCol = { 64, 64, 64, 64 };
362     GXColor     litCol = { 192, 192, 192, 192 };
363 
364     // Lighting on
365     GXSetNumChans(1);
366     GXSetChanCtrl(GX_COLOR0A0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG,
367                   GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE);
368     GXSetChanAmbColor(GX_COLOR0A0, ambCol);
369 
370     GXInitLightColor(&lo, litCol);
371     GXInitLightPos(&lo, 10000.0F, -10000.0F, 5000.0F);
372     GXLoadLightObjImm(&lo, GX_LIGHT0);
373 
374     // No texgen
375     GXSetNumTexGens(0);
376 
377     // Set TEV operation to use vertex color
378     GXSetNumTevStages(1);
379     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
380     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
381 
382     // TEV swap mode
383     // Note that this feature doesn't work on the emulator
384     GXSetTevSwapMode(
385         GX_TEVSTAGE0,
386         MySwSelTable[sc->tblIdx],   // ras_sel
387         MySwSelTable[sc->tblIdx] ); // tex_sel (actually not used here)
388 
389     // Transform matrix
390     GXSetCurrentMtx(GX_PNMTX0);
391 
392     // Draw each torus
393     MTXScale(ms, 40, -40, 40);
394     for ( i = 0 ; i < NUM_DONUTS ; ++i )
395     {
396         MTXRotDeg(m0, 'y', (rot+i*60));
397         MTXConcat(ms, m0, m1);
398         MTXTrans(m0, ((i%4)+1)*128, (i/4)*96+160, -256);
399         MTXConcat(m0, m1, m1);
400         GXLoadPosMtxImm(m1, GX_PNMTX0);
401 
402         GXSetChanMatColor(GX_COLOR0A0, MyColorArray[i]);
403         GXDrawTorus(0.3F, 12, 16);
404     }
405 
406     // Rotation counter
407     rot = ++rot % 360;
408 }
409 
410 /*---------------------------------------------------------------------------*
411     Name:           LoadTevSwapTable
412 
413     Description:    Load TEV swap mode table setting into hardware
414 
415     Arguments:      sc : scene control object
416 
417     Returns:        none
418  *---------------------------------------------------------------------------*/
LoadTevSwapTable(void)419 static void LoadTevSwapTable( void )
420 {
421     u32  i;
422 
423     for ( i = 0 ; i < 4 ; ++i )
424     {
425         GXSetTevSwapModeTable(
426             MySwSelTable[i],
427             MyChCompTable[MySwapModeTable[i][0]],
428             MyChCompTable[MySwapModeTable[i][1]],
429             MyChCompTable[MySwapModeTable[i][2]],
430             MyChCompTable[MySwapModeTable[i][3]] );
431     }
432 }
433 
434 /*---------------------------------------------------------------------------*
435     Name:           PrintIntro
436 
437     Description:    Prints the directions on how to use this demo.
438 
439     Arguments:      none
440 
441     Returns:        none
442  *---------------------------------------------------------------------------*/
PrintIntro(void)443 static void PrintIntro( void )
444 {
445     OSReport("\n\n");
446     OSReport("************************************************\n");
447     OSReport("tev-swap: TEV swap mode table demo\n");
448     OSReport("************************************************\n");
449     OSReport("to quit hit the start/pause button\n");
450     OSReport("\n");
451     OSReport("Stick Up/Down : Move the cursor\n");
452     OSReport("A Button      : Change the value\n");
453     OSReport("B Button      : Change the test pattern\n");
454     OSReport("Y Button      : Turn on/off alpha blending\n");
455     OSReport("************************************************\n\n");
456 }
457 
458 /*============================================================================*/
459