1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tg-clr-persp.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 #include <demo.h>
15 
16 /*---------------------------------------------------------------------------*
17   Global Data
18  *---------------------------------------------------------------------------*/
19 // view matrix
20 Mtx g_viewMtx;
21 // Draw mode
22 u8 g_mode = 0;
23 // What texture maps to use
24 u8 g_map = 0;
25 // Base texture?
26 u8 g_base = 0;
27 // Alpha texture?
28 u8 g_alpha = 1;
29 // Vectors to keep track of the camera's coordinate system orientation
30 Vec g_camX = {1.0F, 0.0F, 0.0F};
31 Vec g_camY = {0.0F, 1.0F, 0.0F};
32 Vec g_camZ = {0.0F, 0.0F, 1.0F};
33 // Distance (Z) of Cam (one for each mode)
34 f32 g_dist[3] = {800.0F, 800.0F, 800.0F};
35 #define MAX_DIST 2500.0F
36 #define MIN_DIST 10.0F
37 // Texture maps
38 #define NUM_TEXTURES 15
39 GXTexObj g_texMap[NUM_TEXTURES];
40 
41 /*---------------------------------------------------------------------------*
42   Macros
43  *---------------------------------------------------------------------------*/
44 #define COLOR_ADJUST(color, size) \
45     (u8)(((size) / (size - 1)) * color + (((size) / (size - 1)) * 128))
46 
47 /*---------------------------------------------------------------------------*
48   CubeModelData
49  *---------------------------------------------------------------------------*/
50 // Vertices
51 static f32 cube_vrt_f32[] ATTRIBUTE_ALIGN(32) = {
52     -128.0F,  128.0F,  128.0F,
53     128.0F,  128.0F,  128.0F,
54     128.0F, -128.0F,  128.0F,
55     -128.0F, -128.0F,  128.0F,
56     -128.0F,  128.0F, -128.0F,
57     128.0F,  128.0F, -128.0F,
58     128.0F, -128.0F, -128.0F,
59     -128.0F, -128.0F, -128.0F,
60 };
61 // Colors
62 static u32 cube_clr_u32[] ATTRIBUTE_ALIGN(32) = {
63     0xff0000ff,
64     0x00ff00ff,
65     0x0000ffff,
66     0xff00ffff,
67     0xff000010,
68     0x00ff0010,
69     0x0000ff10,
70     0xffffff10,
71 };
72 // Colors (RG)
73 static u32 cube_clr0_u32[] ATTRIBUTE_ALIGN(32) = {
74     0xff000000,
75     0x00ff0000,
76     0x00000000,
77     0xff000000,
78     0xff000000,
79     0x00ff0000,
80     0x00000000,
81     0xffff0000,
82 };
83 // Colors (BA) Channels moved into (RG) Channels
84 static u32 cube_clr1_u32[] ATTRIBUTE_ALIGN(32) = {
85     0x00ff0000,
86     0x00ff0000,
87     0xffff0000,
88     0xffff0000,
89     0x00100000,
90     0x00100000,
91     0xff100000,
92     0xff100000,
93 };
94 // Texture
95 static f32 cube_txt_f32[] ATTRIBUTE_ALIGN(32) =
96 {
97     0.0F, 0.0F,
98     1.0F, 0.0F,
99     1.0F, 1.0F,
100     0.0F, 1.0F,
101 };
102 // Face Info
103 static u32 cube_quad_order[6][4] = {
104     // Front
105     {0, 1, 2, 3},
106     // Right
107     {1, 5, 6, 2},
108     // Back
109     {5, 4, 7, 6},
110     // Left
111     {4, 0, 3, 7},
112     // Top
113     {4, 5, 1, 0},
114     // Bottom
115     {3, 2, 6, 7},
116 };
117 static u32 cube_tri_order[12][3] = {
118     // Front
119     {0, 1, 3}, {1, 2, 3},
120     // Right
121     {1, 5, 2}, {5, 6, 2},
122     // Back
123     {5, 4, 6}, {4, 7, 6},
124     // Left
125     {4, 0, 7}, {0, 3, 7},
126     // Top
127     {4, 5, 0}, {5, 1, 0},
128     // Bottom
129     {3, 2, 7}, {2, 6, 7},
130 };
131 static u32 cube_tex_order[12] = {0, 1, 3, 1, 2, 3, 0};
132 
133 /*---------------------------------------------------------------------------*
134   WallData
135  *---------------------------------------------------------------------------*/
136 #define WALL_SIZE 64
137 
138 /*---------------------------------------------------------------------------*
139   LightData
140  *---------------------------------------------------------------------------*/
141 // Number of Lights
142 u8 g_numHwLights = 4;
143 GXLightObj g_lightObj[8];
144 // Vertices
145 static Vec light_vtx_vec[] ATTRIBUTE_ALIGN(32) = {
146     {-128.0F, 128.0F, 30.0F},
147     {-128.0F, -128.0F, 30.0F},
148     {128.0F, 128.0F, 30.0F},
149     {128.0F, -128.0F, 30.0F},
150 };
151 // Colors
152 static GXColor light_clr_clr[] ATTRIBUTE_ALIGN(32) = {
153     {0xc0, 0x00, 0x00, 0xff},  // burgundy
154     {0x70, 0xc0, 0x40, 0xff},  // olive green
155     {0xc0, 0xa0, 0x70, 0xff},  // beige
156     {0x40, 0x00, 0xc0, 0xff},  // indigo
157 };
158 GXColor g_ambClr = {0x00, 0x00, 0x00, 0x00};
159 GXColor g_matClr = {0xFF, 0xFF, 0xFF, 0xFF};
160 
161 /*---------------------------------------------------------------------------*
162   PlaneData
163  *---------------------------------------------------------------------------*/
164 // Colors
165 static u32 plane_clr0_u32[] ATTRIBUTE_ALIGN(32) = {
166     0xff0000ff,
167     0x00ff00ff,
168     0x0000ffff,
169     0xff00ffff,
170 };
171 // Colors (BA)
172 static u32 plane_clr1_u32[] ATTRIBUTE_ALIGN(32) = {
173     0x00ff0000,
174     0x00ff0000,
175     0xffff0000,
176     0xffff0000,
177 };
178 
179 /*---------------------------------------------------------------------------*
180    Forward references
181  *---------------------------------------------------------------------------*/
182 static void CameraInit(Mtx v);
183 static void MakeModelMtx(Vec xAxis, Vec yAxis, Vec zAxis, Mtx m);
184 static void DrawCube(u32 * cube_clr0_u32, u32 * cube_clr1_u32,
185         f32 * cube_tex_f32);
186 static void AnimTick(u8 * mode);
187 static void DrawTick(u8 mode);
188 static void DrawInit(void);
189 static void DrawState(u8 mode);
190 static void DrawWall(u16 size);
191 static void DrawZPlane(u32 * wall_clr0_u32, u32 * wall_clr1_u32);
192 static void PrintIntro( void );
193 
194 
195 /*---------------------------------------------------------------------------*
196    Application main loop
197  *---------------------------------------------------------------------------*/
main(void)198 void main ( void )
199 {
200     DEMOInit(NULL);    // Init os, pad, gx, vi
201 
202     PrintIntro();
203 
204     CameraInit(g_viewMtx);
205 
206     DrawInit();
207 
208     OSReport("********************************\n");
209     while (1)
210     {
211         AnimTick(&g_mode);
212         DEMOBeforeRender();
213         DrawTick(g_mode);
214         DEMODoneRender();
215         DEMOPadRead();
216     }
217     OSHalt("End of demo");
218 }
219 
220 /*---------------------------------------------------------------------------*
221    Functions
222  *---------------------------------------------------------------------------*/
223 
224 /*---------------------------------------------------------------------------*
225     Name:           CameraInit
226 
227     Description:    Initialize the projection matrix and load into hardware.
228                     Initialize the view matrix
229 
230     Arguments:      v    view matrix
231 
232     Returns:        none
233  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)234 static void CameraInit ( Mtx v )
235 {
236     Mtx44 p;
237     Vec   camPt = {0.0F, 0.0F, 800.0F};
238     Vec   at    = {0.0F, 0.0F, -100.0F};
239     Vec   up    = {0.0F, 1.0F, 0.0F};
240 
241     MTXFrustum(p, 240.0F,-240.0F,-320.0F, 320.0F, 400, 2000);
242     MTXPerspective(p, 90.0F, 4.0F/3.0F, 5.0F, 10000);
243     GXSetProjection(p, GX_PERSPECTIVE);
244     MTXLookAt(v, &camPt, &up, &at);
245 }
246 
247 /*---------------------------------------------------------------------------*
248     Name:           MakeModelMtx
249 
250     Description:    computes a model matrix from 3 vectors representing an
251                     object's coordinate system.
252 
253     Arguments:      xAxis   vector for the object's X axis
254                     yAxis   vector for the object's Y axis
255                     zAxis   vector for the object's Z axis
256 
257     Returns:        none
258  *---------------------------------------------------------------------------*/
MakeModelMtx(Vec xAxis,Vec yAxis,Vec zAxis,Mtx m)259 static void MakeModelMtx ( Vec xAxis, Vec yAxis, Vec zAxis, Mtx m )
260 {
261     VECNormalize(&xAxis,&xAxis);
262     VECNormalize(&yAxis,&yAxis);
263     VECNormalize(&zAxis, &zAxis);
264 
265     m[0][0] = xAxis.x;
266     m[1][0] = xAxis.y;
267     m[2][0] = xAxis.z;
268 
269     m[0][1] = yAxis.x;
270     m[1][1] = yAxis.y;
271     m[2][1] = yAxis.z;
272 
273     m[0][2] = zAxis.x;
274     m[1][2] = zAxis.y;
275     m[2][2] = zAxis.z;
276 
277     m[0][3] = 0.0F;
278     m[1][3] = 0.0F;
279     m[2][3] = 0.0F;
280 }
281 
282 /*---------------------------------------------------------------------------*
283     Name:           DrawCube
284 
285     Description:    Draws a Cube.
286 
287     Arguments:
288                     cube_clr0_u32  if not Null the color0 vtx data
289                                    (must be an array of 8 u32s)
290                     cube_clr1_u32  if not Null the color1 vtx data
291                                    (must be an array of 8 u32s)
292                     cube_tex_f32   if not NULL the texture coords
293                                    (must be an array of 4 f32s);
294 
295     Returns:        none
296  *---------------------------------------------------------------------------*/
DrawCube(u32 * cube_clr0_u32,u32 * cube_clr1_u32,f32 * cube_tex_f32)297 static void DrawCube(u32 * cube_clr0_u32, u32 * cube_clr1_u32,
298         f32 * cube_tex_f32)
299 {
300     // Face Info
301     u32 i, j;
302 
303     // Setup
304     GXClearVtxDesc();
305 
306     // Vertices
307     GXSetVtxDesc(GX_VA_POS,  GX_INDEX8);
308     GXSetArray(GX_VA_POS,  cube_vrt_f32, 3*sizeof(f32));
309     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS,  GX_POS_XYZ,  GX_F32, 0);
310 
311     // Colors
312     if (cube_clr0_u32 != NULL)
313     {
314         GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
315         GXSetArray(GX_VA_CLR0, cube_clr0_u32, 1*sizeof(u32));
316         GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
317     }
318 
319     // Colors
320     if (cube_clr1_u32 != NULL)
321     {
322         GXSetVtxDesc(GX_VA_CLR1, GX_INDEX8);
323         GXSetArray(GX_VA_CLR1, cube_clr1_u32, 1*sizeof(u32));
324         GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0);
325     }
326 
327     // Textures
328     if (cube_txt_f32 != NULL)
329     {
330         GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
331         GXSetArray(GX_VA_TEX0, cube_txt_f32, 2*sizeof(f32));
332         GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
333     }
334 
335     // Draw a cube
336     for (i = 0; i < 6; i++)
337     {
338         GXBegin(GX_QUADS, GX_VTXFMT0, 4);
339         for (j = 0; j < 4; j++)
340         {
341             GXPosition1x8((u8)cube_quad_order[i][j]);
342             if (cube_clr0_u32) GXColor1x8((u8)cube_quad_order[i][j]);
343             if (cube_clr1_u32) GXColor1x8((u8)cube_quad_order[i][j]);
344             if (cube_tex_f32) GXTexCoord1x8((u8)j);
345         }
346         GXEnd();
347     }
348 }
349 
350 /*---------------------------------------------------------------------------*
351     Name:           DrawWall
352 
353     Description:    Draws a tessellated wall
354 
355     Arguments:      size of the wall. The wall will be sizeXsize
356 
357     Returns:        none
358  *---------------------------------------------------------------------------*/
DrawWall(u16 size)359 static void DrawWall(u16 size)
360 {
361     s32 x, y, i;
362     f32 xx, yy0, yy1;
363     f32 half;
364 #define STEP 10
365 
366     half = size / 2;
367 
368     // Setup
369     GXClearVtxDesc();
370 
371     // Vertices
372     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
373     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
374 
375     // Normal
376     GXSetVtxDesc(GX_VA_NRM,  GX_DIRECT);
377     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
378 
379     for (y = 0; y < size - 1; ++y)
380     {
381         i = y * size;
382         GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (u16)(size * 2));
383         for (x = 0; x < size; ++x)
384         {
385             xx = (f32)(x * STEP - half * STEP);
386             yy0 = (f32)(y * STEP - half * STEP);
387             yy1 = (f32)((y + 1) * STEP - half * STEP);
388             GXPosition3f32(xx, yy0, 0.0F);
389             GXNormal3f32(0.0F, 0.0F, 1.0F);
390             GXPosition3f32(xx, yy1, 0.0F);
391             GXNormal3f32(0.0F, 0.0F, 1.0F);
392         }
393         GXEnd();
394     }
395 }
396 
397 /*---------------------------------------------------------------------------*
398     Name:           DrawZPlane
399 
400     Description:    Draws a quad in the X-Y axis
401 
402     Arguments:
403                     cube_clr0_u32  the color0 vtx data (will be written)
404                                    (must be an array of 4 u32s)
405                     cube_clr1_u32  the color1 vtx data (will be written)
406                                    (must be an array of 4 u32s)
407 
408     Returns:        none
409  *---------------------------------------------------------------------------*/
DrawZPlane(u32 * wall_clr0_u32,u32 * wall_clr1_u32)410 static void DrawZPlane(u32 * wall_clr0_u32, u32 * wall_clr1_u32)
411 {
412 
413     // Setup
414     GXClearVtxDesc();
415 
416     // Vertices
417     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
418     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
419 
420     // Colors
421     if (wall_clr0_u32)
422     {
423         GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16);
424         GXSetArray(GX_VA_CLR0, wall_clr0_u32, 1*sizeof(u32));
425         GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
426     }
427 
428     // Colors
429     if (wall_clr1_u32)
430     {
431         GXSetVtxDesc(GX_VA_CLR1, GX_INDEX16);
432         GXSetArray(GX_VA_CLR1, wall_clr1_u32, 1*sizeof(u32));
433         GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0);
434     }
435 
436     GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
437     GXPosition3f32(0.0F, -64.0F,  1500.0F);
438     if (wall_clr0_u32) GXColor1x16(0);
439     if (wall_clr1_u32) GXColor1x16(0);
440     GXPosition3f32(0.0F,  64.0F,  1500.0F);
441     if (wall_clr0_u32) GXColor1x16(1);
442     if (wall_clr1_u32) GXColor1x16(1);
443     GXPosition3f32(0.0F, -64.0F, -1500.0F);
444     if (wall_clr0_u32) GXColor1x16(2);
445     if (wall_clr1_u32) GXColor1x16(2);
446     GXPosition3f32(0.0F,  64.0F, -1500.0F);
447     if (wall_clr0_u32) GXColor1x16(3);
448     if (wall_clr1_u32) GXColor1x16(3);
449     GXEnd();
450 }
451 
452 /*---------------------------------------------------------------------------*
453     Name:           DrawTick
454 
455     Description:
456 
457     Arguments:      mode   current draw mode
458 
459     Returns:        none
460  *---------------------------------------------------------------------------*/
DrawTick(u8 mode)461 static void DrawTick(u8 mode)
462 {
463     switch (mode)
464     {
465         case 0:
466             if (!g_base)
467             {
468                 DrawState(0);
469                 GXSetCurrentMtx(GX_PNMTX0);
470                 // Note: Drawing twice for cheap z-sort
471                 GXSetCullMode(GX_CULL_FRONT);
472                 DrawCube(cube_clr_u32, NULL, cube_txt_f32);
473                 GXSetCullMode(GX_CULL_BACK);
474                 DrawCube(cube_clr_u32, NULL, cube_txt_f32);
475 
476                 DrawState(1);
477                 GXSetCurrentMtx(GX_PNMTX1);
478                 // Note: Drawing twice for cheap z-sort
479                 GXSetCullMode(GX_CULL_FRONT);
480                 DrawCube(cube_clr0_u32, cube_clr1_u32, cube_txt_f32);
481                 GXSetCullMode(GX_CULL_BACK);
482                 DrawCube(cube_clr0_u32, cube_clr1_u32, cube_txt_f32);
483             }
484             else
485             {
486                 DrawState(2);
487                 GXSetCurrentMtx(GX_PNMTX0);
488                 // Note: Drawing twice for cheap z-sort
489                 GXSetCullMode(GX_CULL_FRONT);
490                 DrawCube(cube_clr_u32, NULL, cube_txt_f32);
491                 GXSetCullMode(GX_CULL_BACK);
492                 DrawCube(cube_clr_u32, NULL, cube_txt_f32);
493 
494                 DrawState(3);
495                 GXSetCurrentMtx(GX_PNMTX1);
496                 // Note: Drawing twice for cheap z-sort
497                 GXSetCullMode(GX_CULL_FRONT);
498                 DrawCube(cube_clr0_u32, cube_clr1_u32, cube_txt_f32);
499                 GXSetCullMode(GX_CULL_BACK);
500                 DrawCube(cube_clr0_u32, cube_clr1_u32, cube_txt_f32);
501             }
502             break;
503         case 1:
504             GXSetCurrentMtx(GX_PNMTX7);
505             DrawState(4);
506             GXSetCullMode(GX_CULL_NONE);
507             DrawWall(WALL_SIZE);
508             break;
509         case 2:
510             GXSetCullMode(GX_CULL_NONE);
511 
512             DrawState(0);
513             GXSetCurrentMtx(GX_PNMTX0);
514             DrawZPlane(plane_clr0_u32, NULL);
515 
516             DrawState(1);
517             GXSetCurrentMtx(GX_PNMTX1);
518             DrawZPlane(plane_clr0_u32, cube_clr1_u32);
519             break;
520     }
521 }
522 
523 /*---------------------------------------------------------------------------*
524     Name:           AnimTick
525 
526     Description:
527 
528     Arguments:      mode   pointer to current draw mode
529 
530     Returns:        none
531  *---------------------------------------------------------------------------*/
AnimTick(u8 * mode)532 static void AnimTick(u8 * mode)
533 {
534     static f32 rotX = 0, rotY = 0;
535     static f32 lrotZ = 0;
536     static u8 rotate = 1;
537     s8 stickX, stickY;
538     s8 substickX, substickY;
539     Mtx temp;
540     Mtx mtx0;
541     Mtx mtx1;
542     f32 ddist;
543     u16 button;
544     u16 i;
545     u16 w, h;
546 
547     button = DEMOPadGetButtonDown(0);
548     stickX = DEMOPadGetStickX(0);
549     stickY = DEMOPadGetStickY(0);
550     substickX = DEMOPadGetSubStickX(0);
551     substickY = DEMOPadGetSubStickY(0);
552 
553     // Global Button Controls
554     switch (button)
555     {
556         // Swap Texture!
557         case PAD_BUTTON_X:
558             g_map = (u8)((g_map + 1) % 7);
559             GXLoadTexObj(&g_texMap[2 * g_map], GX_TEXMAP0);
560             GXLoadTexObj(&g_texMap[2 * g_map + 1], GX_TEXMAP1);
561             w = GXGetTexObjWidth(&g_texMap[2 * g_map]);
562             h = GXGetTexObjHeight(&g_texMap[2 * g_map]);
563             OSReport("Rasterization Lookup Texture: %d (%dx%d)\n",
564                     g_map, w, h);
565             break;
566         case PAD_BUTTON_A:
567             *mode = (u8)((*mode + 1) % 3);
568             break;
569         case PAD_BUTTON_B:
570             rotate ^= 1;
571             break;
572     }
573 
574     // Mode Controls
575     switch (*mode)
576     {
577         case 0:
578             // Cube Rotation
579             if (rotate)
580             {
581                 rotX += 0.33F;
582                 rotY += 0.32F;
583             }
584             rotX += (f32)stickX / 3.0F;
585             rotY -= (f32)stickY / 3.0F;
586 
587             // Button Controls
588             switch (button)
589             {
590                 case PAD_BUTTON_UP:
591                     g_base ^= 1;
592                     break;
593                 case PAD_BUTTON_LEFT:
594                     g_alpha ^= 1;
595                     break;
596             }
597 
598             // Stick Controls
599             if (substickX || substickY)
600             {
601                 if (substickX)
602                 {
603                     if (stickX > 0)
604                         MTXRotAxisDeg(temp, &g_camY, 3.0F);
605                     else
606                         MTXRotAxisDeg(temp, &g_camY, -3.0F);
607 
608                     MTXMultVec(temp, &g_camX, &g_camX);
609                     MTXMultVec(temp, &g_camZ, &g_camZ);
610                 }
611 
612                 if (substickY)
613                 {
614                     if (stickY > 0)
615                         MTXRotAxisDeg(temp, &g_camX, 3.0F);
616                     else
617                         MTXRotAxisDeg(temp, &g_camX, -3.0F);
618 
619                     MTXMultVec(temp, &g_camY, &g_camY);
620                     MTXMultVec(temp, &g_camZ, &g_camZ);
621                 }
622             }
623             ddist = DEMOPadGetTriggerL(0) / 3.0F;
624             if (g_dist[0] - ddist > MIN_DIST) g_dist[0] -= ddist;
625             ddist = DEMOPadGetTriggerR(0) / 3.0F;
626             if (g_dist[0] + ddist < MAX_DIST) g_dist[0] += ddist;
627 
628             // Create View Matrix
629             MakeModelMtx(g_camX, g_camY, g_camZ, g_viewMtx);
630             MTXTranspose(g_viewMtx, g_viewMtx);
631             MTXTrans(temp, 0.0F, 0.0F, -g_dist[0]);
632             MTXConcat(temp, g_viewMtx, g_viewMtx);
633 
634             // Cube 0
635             MTXTrans(mtx0, -200.0F, 0.0F, 0.0F);
636             MTXRotDeg(temp, 'x', rotX);
637             MTXConcat(mtx0, temp, mtx0);
638             MTXRotDeg(temp, 'y', rotY);
639             MTXConcat(mtx0, temp, mtx0);
640             MTXConcat(g_viewMtx, mtx0, mtx0);
641 
642             // Cube 1
643             MTXTrans(mtx1, 200.0F, 0.0F, 0.0F);
644             MTXRotDeg(temp, 'x', rotX);
645             MTXConcat(mtx1, temp, mtx1);
646             MTXRotDeg(temp, 'y', rotY);
647             MTXConcat(mtx1, temp, mtx1);
648             MTXConcat(g_viewMtx, mtx1, mtx1);
649 
650             GXLoadPosMtxImm(mtx0, GX_PNMTX0);
651             GXLoadPosMtxImm(mtx1, GX_PNMTX1);
652             break;
653         case 1:
654             // Camera Control
655             ddist = (f32)substickY / 5.0F;
656             if (g_dist[1] - ddist < MAX_DIST && g_dist[1] - ddist > MIN_DIST)
657             {
658                 g_dist[1] -= ddist;
659             }
660             MTXIdentity(g_viewMtx);
661             MTXTrans(temp, 0.0F, 0.0F, -g_dist[1]);
662             MTXConcat(temp, g_viewMtx, g_viewMtx);
663 
664             // Model Control
665             GXLoadPosMtxImm(g_viewMtx, GX_PNMTX7);
666 
667             // Normal
668             MTXInverse(g_viewMtx, temp);
669             MTXTranspose(temp, temp);
670             GXLoadNrmMtxImm(temp, GX_PNMTX7);
671 
672             // Rotate Lights
673             if (rotate)
674             {
675                 lrotZ = 0.32F;
676             }
677             else
678             {
679                 lrotZ = 0.0F;
680             }
681             MTXRotDeg(temp, 'z', lrotZ);
682             for (i = 0; i < g_numHwLights; ++i)
683             {
684                 MTXMultVec(temp, &light_vtx_vec[i], &light_vtx_vec[i]);
685             }
686 
687             break;
688         case 2:
689             // Camera Control
690             ddist = (f32)substickY / 5.0F;
691             if (g_dist[2] - ddist < MAX_DIST && g_dist[2] - ddist > MIN_DIST)
692             {
693                 g_dist[2] -= ddist;
694             }
695             MTXIdentity(g_viewMtx);
696             MTXTrans(temp, 0.0F, 0.0F, -g_dist[2]);
697             MTXConcat(temp, g_viewMtx, g_viewMtx);
698 
699             // Model Control
700             MTXTrans(mtx0, -200.0F, 0.0F, 0.0F);
701             MTXConcat(g_viewMtx, mtx0, mtx0);
702             MTXTrans(mtx1, 200.0F, 0.0F, 0.0F);
703             MTXConcat(g_viewMtx, mtx1, mtx1);
704             GXLoadPosMtxImm(mtx0, GX_PNMTX0);
705             GXLoadPosMtxImm(mtx1, GX_PNMTX1);
706             break;
707     }
708 }
709 
710 /*---------------------------------------------------------------------------*
711     Name:           DrawInit
712 
713     Description:    Initializes Drawing state
714 
715     Arguments:      none
716 
717     Returns:        none
718  *---------------------------------------------------------------------------*/
DrawInit(void)719 static void DrawInit(void)
720 {
721     TPLDescriptorPtr tdp;
722     TPLPalettePtr tpl = 0;
723     GXColor black = {0, 0, 0, 0};
724     u32 i;
725 
726     // Setup Textures
727     TPLGetPalette(&tpl, "gxTests/tg-pc.tpl");
728     // First
729     for (i = 0; i < NUM_TEXTURES; i++)
730     {
731         tdp = TPLGet(tpl, i);
732         GXInitTexObj(&g_texMap[i],
733                 tdp->textureHeader->data,
734                 tdp->textureHeader->width,
735                 tdp->textureHeader->height,
736                 (GXTexFmt)tdp->textureHeader->format,
737                 GX_CLAMP,
738                 GX_CLAMP,
739                 GX_FALSE);
740     }
741     GXLoadTexObj(&g_texMap[0], GX_TEXMAP0);
742     GXLoadTexObj(&g_texMap[1], GX_TEXMAP1);
743     GXLoadTexObj(&g_texMap[NUM_TEXTURES - 1], GX_TEXMAP2);
744 
745     // Global Modes
746     GXSetCullMode(GX_CULL_NONE);
747 
748     // Copy
749     GXSetDispCopyGamma(GX_GM_1_0);
750     GXSetCopyClear(black, GX_MAX_Z24);
751 }
752 
753 /*---------------------------------------------------------------------------*
754     Name:           DrawState
755 
756     Description:    Sets draw state
757 
758     Arguments:      mode    What mode to draw
759 
760     Returns:        none
761  *---------------------------------------------------------------------------*/
DrawState(u8 mode)762 static void DrawState(u8 mode)
763 {
764     u8 i;
765     Vec temp;
766     GXColor color;
767     u32 mask0 = 0;
768     u32 mask1 = 0;
769     int lookup[] = {
770         GX_LIGHT0, GX_LIGHT1, GX_LIGHT2, GX_LIGHT3,
771         GX_LIGHT4, GX_LIGHT5, GX_LIGHT6, GX_LIGHT7};
772 
773     if (g_alpha)
774     {
775         GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
776     }
777     else
778     {
779         GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
780     }
781 
782     switch (mode)
783     {
784         case 0:
785             /*-------------------------------------------------*
786               Rasterize Color State (vtx color => final color)
787               => Not Perspective Correct Interpolation
788              *-------------------------------------------------*/
789 
790             // Don't forget these!
791             GXSetNumChans(1);
792             GXSetNumTexGens(0);
793             GXSetNumTevStages(1);
794 
795             // Color Channel (Vertex Color)
796             GXSetChanCtrl(GX_COLOR0A0,
797                     GX_DISABLE,
798                     GX_SRC_VTX,
799                     GX_SRC_VTX,
800                     GX_LIGHT_NULL,
801                     GX_DF_NONE,
802                     GX_AF_NONE);
803 
804             // Tev 0
805             GXSetTevOrder(GX_TEVSTAGE0,
806                     GX_TEXCOORD_NULL,
807                     GX_TEXMAP_NULL,
808                     GX_COLOR0A0);
809             GXSetTevColorIn(GX_TEVSTAGE0,
810                     GX_CC_ZERO,
811                     GX_CC_ZERO,
812                     GX_CC_ZERO,
813                     GX_CC_RASC);
814             GXSetTevAlphaIn(GX_TEVSTAGE0,
815                     GX_CA_ZERO,
816                     GX_CA_ZERO,
817                     GX_CA_ZERO,
818                     GX_CA_RASA);
819             GXSetTevColorOp(GX_TEVSTAGE0,
820                     GX_TEV_ADD,
821                     GX_TB_ZERO,
822                     GX_CS_SCALE_1,
823                     GX_ENABLE,
824                     GX_TEVPREV);
825             GXSetTevAlphaOp(GX_TEVSTAGE0,
826                     GX_TEV_ADD,
827                     GX_TB_ZERO,
828                     GX_CS_SCALE_1,
829                     GX_ENABLE,
830                     GX_TEVPREV);
831 
832             break;
833         case 1:
834             /*-------------------------------------------------*
835               Rasterize Color => Texture Coords => Perspective
836                  Correct Texture Interpolation
837              *-------------------------------------------------*/
838 
839             // Don't forget these!
840             GXSetNumChans(2);
841             GXSetNumTexGens(2);
842             GXSetNumTevStages(2);
843 
844             // Color Channels
845             // Send vertex color data through the color channels
846             GXSetChanCtrl(GX_COLOR0A0,
847                     GX_DISABLE,
848                     GX_SRC_VTX,
849                     GX_SRC_VTX,
850                     GX_LIGHT_NULL,
851                     GX_DF_NONE,
852                     GX_AF_NONE);
853             GXSetChanCtrl(GX_COLOR1A1,
854                     GX_DISABLE,
855                     GX_SRC_VTX,
856                     GX_SRC_VTX,
857                     GX_LIGHT_NULL,
858                     GX_DF_NONE,
859                     GX_AF_NONE);
860 
861             // Convert color0 to s,t for 2-D texture lookup (RG)
862             GXSetTexCoordGen(GX_TEXCOORD0,
863                     GX_TG_SRTG,
864                     GX_TG_COLOR0,
865                     GX_IDENTITY);
866             // Convert color1 to s,t for 2-D texture lookup (BA)
867             GXSetTexCoordGen(GX_TEXCOORD1,
868                     GX_TG_SRTG,
869                     GX_TG_COLOR1,
870                     GX_IDENTITY);
871 
872             // Tev 0: Use rasterization lookup table (RG)
873             // Note: Blue = 0 and Alpha = 0;
874             GXSetTevOrder(GX_TEVSTAGE0,
875                     GX_TEXCOORD0,
876                     GX_TEXMAP0,
877                     GX_COLOR_NULL);
878             GXSetTevColorIn(GX_TEVSTAGE0,
879                     GX_CC_ZERO,
880                     GX_CC_ZERO,
881                     GX_CC_ZERO,
882                     GX_CC_TEXC);
883             GXSetTevAlphaIn(GX_TEVSTAGE0,
884                     GX_CA_ZERO,
885                     GX_CA_ZERO,
886                     GX_CA_ZERO,
887                     GX_CA_ZERO);
888             GXSetTevColorOp(GX_TEVSTAGE0,
889                     GX_TEV_ADD,
890                     GX_TB_ZERO,
891                     GX_CS_SCALE_1,
892                     GX_ENABLE,
893                     GX_TEVPREV);
894             GXSetTevAlphaOp(GX_TEVSTAGE0,
895                     GX_TEV_ADD,
896                     GX_TB_ZERO,
897                     GX_CS_SCALE_1,
898                     GX_ENABLE,
899                     GX_TEVPREV);
900 
901             // Tev 1: Use rasterization lookup table (BA),
902             // then add previous tev (RG + BA)
903             GXSetTevOrder(GX_TEVSTAGE1,
904                     GX_TEXCOORD1,
905                     GX_TEXMAP1,
906                     GX_COLOR_NULL);
907             GXSetTevColorIn(GX_TEVSTAGE1,
908                     GX_CC_ZERO,
909                     GX_CC_TEXC,
910                     GX_CC_ONE,
911                     GX_CC_CPREV);
912             GXSetTevAlphaIn(GX_TEVSTAGE1,
913                     GX_CA_ZERO,
914                     GX_CA_TEXA,
915                     GX_CA_ONE,
916                     GX_CA_APREV);
917             GXSetTevColorOp(GX_TEVSTAGE1,
918                     GX_TEV_ADD,
919                     GX_TB_ZERO,
920                     GX_CS_SCALE_1,
921                     GX_ENABLE,
922                     GX_TEVPREV);
923             GXSetTevAlphaOp(GX_TEVSTAGE1,
924                     GX_TEV_ADD,
925                     GX_TB_ZERO,
926                     GX_CS_SCALE_1,
927                     GX_ENABLE,
928                     GX_TEVPREV);
929             break;
930         case 2:
931             /*-------------------------------------------------*
932               Rasterize Color State (vtx color => final color)
933               => Not Perspective Correct Interpolation
934                  + Base Texture
935              *-------------------------------------------------*/
936 
937             // Don't forget these!
938             GXSetNumChans(1);
939             GXSetNumTexGens(1);
940             GXSetNumTevStages(1);
941 
942             // Color Channel (Vertex Color)
943             GXSetChanCtrl(GX_COLOR0A0,
944                     GX_DISABLE,
945                     GX_SRC_VTX,
946                     GX_SRC_VTX,
947                     GX_LIGHT_NULL,
948                     GX_DF_NONE,
949                     GX_AF_NONE);
950 
951             // Base Texture Coordinates
952             GXSetTexCoordGen(GX_TEXCOORD0,
953                     GX_TG_MTX2x4,
954                     GX_TG_TEX0,
955                     GX_IDENTITY);
956 
957             // Tev 0
958             GXSetTevOrder(GX_TEVSTAGE0,
959                     GX_TEXCOORD0,
960                     GX_TEXMAP2,
961                     GX_COLOR0A0);
962             GXSetTevColorIn(GX_TEVSTAGE0,
963                     GX_CC_ZERO,
964                     GX_CC_RASC,
965                     GX_CC_TEXC,
966                     GX_CC_ZERO);
967             GXSetTevAlphaIn(GX_TEVSTAGE0,
968                     GX_CA_ZERO,
969                     GX_CA_ZERO,
970                     GX_CA_ZERO,
971                     GX_CA_RASA);
972             GXSetTevColorOp(GX_TEVSTAGE0,
973                     GX_TEV_ADD,
974                     GX_TB_ZERO,
975                     GX_CS_SCALE_1,
976                     GX_ENABLE,
977                     GX_TEVPREV);
978             GXSetTevAlphaOp(GX_TEVSTAGE0,
979                     GX_TEV_ADD,
980                     GX_TB_ZERO,
981                     GX_CS_SCALE_1,
982                     GX_ENABLE,
983                     GX_TEVPREV);
984 
985             break;
986         case 3:
987             /*-------------------------------------------------*
988               Rasterize Color => Texture Coords => Perspective
989                  Correct Texture Interpolation
990                  + Base Texture
991              *-------------------------------------------------*/
992 
993             // Don't forget these!
994             GXSetNumChans(2);
995             GXSetNumTexGens(3);
996             GXSetNumTevStages(3);
997 
998             // Color Channels
999             // Send vertex color data through the color channels
1000             GXSetChanCtrl(GX_COLOR0A0,
1001                     GX_DISABLE,
1002                     GX_SRC_VTX,
1003                     GX_SRC_VTX,
1004                     GX_LIGHT_NULL,
1005                     GX_DF_NONE,
1006                     GX_AF_NONE);
1007             GXSetChanCtrl(GX_COLOR1A1,
1008                     GX_DISABLE,
1009                     GX_SRC_VTX,
1010                     GX_SRC_VTX,
1011                     GX_LIGHT_NULL,
1012                     GX_DF_NONE,
1013                     GX_AF_NONE);
1014 
1015             // Note: The following TexCoordGen order is important.
1016             // See "Functional Ordering Requirements" on man page.
1017 
1018             // Base Texture Coordinates
1019             GXSetTexCoordGen(GX_TEXCOORD0,
1020                     GX_TG_MTX2x4,
1021                     GX_TG_TEX0,
1022                     GX_IDENTITY);
1023             // Convert color0 to s,t for 2-D texture lookup (RG)
1024             GXSetTexCoordGen(GX_TEXCOORD1,
1025                     GX_TG_SRTG,
1026                     GX_TG_COLOR0,
1027                     GX_IDENTITY);
1028             // Convert color1 to s,t for 2-D texture lookup (BA)
1029             GXSetTexCoordGen(GX_TEXCOORD2,
1030                     GX_TG_SRTG,
1031                     GX_TG_COLOR1,
1032                     GX_IDENTITY);
1033 
1034             // Tev 0: Use rasterization lookup table (RG)
1035             // Note: Blue = 0 and Alpha = 0;
1036             GXSetTevOrder(GX_TEVSTAGE0,
1037                     GX_TEXCOORD1,
1038                     GX_TEXMAP0,
1039                     GX_COLOR_NULL);
1040             GXSetTevColorIn(GX_TEVSTAGE0,
1041                     GX_CC_ZERO,
1042                     GX_CC_ZERO,
1043                     GX_CC_ZERO,
1044                     GX_CC_TEXC);
1045             GXSetTevAlphaIn(GX_TEVSTAGE0,
1046                     GX_CA_ZERO,
1047                     GX_CA_ZERO,
1048                     GX_CA_ZERO,
1049                     GX_CA_ZERO);
1050             GXSetTevColorOp(GX_TEVSTAGE0,
1051                     GX_TEV_ADD,
1052                     GX_TB_ZERO,
1053                     GX_CS_SCALE_1,
1054                     GX_ENABLE,
1055                     GX_TEVPREV);
1056             GXSetTevAlphaOp(GX_TEVSTAGE0,
1057                     GX_TEV_ADD,
1058                     GX_TB_ZERO,
1059                     GX_CS_SCALE_1,
1060                     GX_ENABLE,
1061                     GX_TEVPREV);
1062 
1063             // Tev 1: Use rasterization lookup table (BA),
1064             // then add previous tev (RG + BA)
1065             GXSetTevOrder(GX_TEVSTAGE1,
1066                     GX_TEXCOORD2,
1067                     GX_TEXMAP1,
1068                     GX_COLOR_NULL);
1069             GXSetTevColorIn(GX_TEVSTAGE1,
1070                     GX_CC_ZERO,
1071                     GX_CC_TEXC,
1072                     GX_CC_ONE,
1073                     GX_CC_CPREV);
1074             GXSetTevAlphaIn(GX_TEVSTAGE1,
1075                     GX_CA_ZERO,
1076                     GX_CA_TEXA,
1077                     GX_CA_ONE,
1078                     GX_CA_APREV);
1079             GXSetTevColorOp(GX_TEVSTAGE1,
1080                     GX_TEV_ADD,
1081                     GX_TB_ZERO,
1082                     GX_CS_SCALE_1,
1083                     GX_ENABLE,
1084                     GX_TEVPREV);
1085             GXSetTevAlphaOp(GX_TEVSTAGE1,
1086                     GX_TEV_ADD,
1087                     GX_TB_ZERO,
1088                     GX_CS_SCALE_1,
1089                     GX_ENABLE,
1090                     GX_TEVPREV);
1091 
1092             // Tev 2: Modulate Base Texture
1093             // No alpha in base texture, so we just pass previous alpha
1094             GXSetTevOrder(GX_TEVSTAGE2,
1095                     GX_TEXCOORD0,
1096                     GX_TEXMAP2,
1097                     GX_COLOR_NULL);
1098             GXSetTevColorIn(GX_TEVSTAGE2,
1099                     GX_CC_ZERO,
1100                     GX_CC_TEXC,
1101                     GX_CC_CPREV,
1102                     GX_CC_ZERO);
1103             GXSetTevAlphaIn(GX_TEVSTAGE2,
1104                     GX_CA_ZERO,
1105                     GX_CA_ZERO,
1106                     GX_CA_ZERO,
1107                     GX_CA_APREV);
1108             GXSetTevColorOp(GX_TEVSTAGE2,
1109                     GX_TEV_ADD,
1110                     GX_TB_ZERO,
1111                     GX_CS_SCALE_1,
1112                     GX_ENABLE,
1113                     GX_TEVPREV);
1114             GXSetTevAlphaOp(GX_TEVSTAGE2,
1115                     GX_TEV_ADD,
1116                     GX_TB_ZERO,
1117                     GX_CS_SCALE_1,
1118                     GX_ENABLE,
1119                     GX_TEVPREV);
1120             break;
1121         case 4:
1122             /*-------------------------------------------------*
1123                 Rasterize Color w/ Lighting => Texture Coords
1124                 => Perspective Correct Texture interpolation
1125              *-------------------------------------------------*/
1126 
1127             // Turn on lights. Note that 2 lights are needed for a full
1128             // RGBA light, unless you only need a monochromatic light
1129             for (i = 0 ; i < g_numHwLights ; ++i)
1130             {
1131                 // Convert light position into view space
1132                 MTXMultVec(g_viewMtx,
1133                         &light_vtx_vec[i],
1134                         &temp);
1135 
1136                 // RG
1137                 GXInitLightPos(&g_lightObj[2 * i],
1138                         temp.x,
1139                         temp.y,
1140                         temp.z);
1141                 GXInitLightColor(&g_lightObj[2 * i],
1142                         light_clr_clr[i]);
1143                 // BA
1144                 GXInitLightPos(&g_lightObj[2 * i + 1],
1145                         temp.x,
1146                         temp.y,
1147                         temp.z);
1148                 color.r = light_clr_clr[i].b;
1149                 color.g = light_clr_clr[i].a;
1150                 color.b = 0;
1151                 color.a = 0;
1152                 GXInitLightColor(&g_lightObj[2 * i + 1],
1153                         color);
1154 
1155                 // Load light object into hardware
1156                 GXLoadLightObjImm(&g_lightObj[2 * i],
1157                         (GXLightID)lookup[2 * i]);
1158                 GXLoadLightObjImm(&g_lightObj[2 * i + 1],
1159                         (GXLightID)lookup[2 * i + 1]);
1160 
1161                 // Compute Mask
1162                 mask0 |= lookup[2 * i];
1163                 mask1 |= lookup[2 * i + 1];
1164             }
1165 
1166             // Don't forget these!
1167             GXSetNumChans(2);
1168             GXSetNumTexGens(2);
1169             GXSetNumTevStages(2);
1170 
1171             // Color Channels
1172             GXSetChanCtrl(GX_COLOR0,
1173                     GX_ENABLE,
1174                     GX_SRC_REG,
1175                     GX_SRC_REG,
1176                     mask0,
1177                     GX_DF_CLAMP,
1178                     GX_AF_NONE);
1179             GXSetChanCtrl(GX_COLOR1,
1180                     GX_ENABLE,
1181                     GX_SRC_REG,
1182                     GX_SRC_REG,
1183                     mask1,
1184                     GX_DF_CLAMP,
1185                     GX_AF_NONE);
1186             // Since we only us RG in texgen, alpha can be turned off.
1187             // Actually, you have to if you want to use 4 full color lights
1188             // (8 hardware lights total)
1189             GXSetChanCtrl (GX_ALPHA0,
1190                     GX_DISABLE,
1191                     GX_SRC_REG,
1192                     GX_SRC_REG,
1193                     GX_LIGHT_NULL,
1194                     GX_DF_NONE,
1195                     GX_AF_NONE);
1196             GXSetChanCtrl(GX_ALPHA1,
1197                     GX_DISABLE,
1198                     GX_SRC_REG,
1199                     GX_SRC_REG,
1200                     GX_LIGHT_NULL,
1201                     GX_DF_NONE,
1202                     GX_AF_NONE);
1203 
1204             // set up ambient color
1205             GXSetChanAmbColor(GX_COLOR0A0,
1206                     g_ambClr);
1207             GXSetChanAmbColor(GX_COLOR1A1,
1208                     g_ambClr);
1209             // set up material color
1210             GXSetChanMatColor(GX_COLOR0A0,
1211                     g_matClr);
1212             GXSetChanMatColor(GX_COLOR1A1,
1213                     g_matClr);
1214 
1215             // Tev 0: Use rasterization lookup table (RG)
1216             GXSetTevOrder(GX_TEVSTAGE0,
1217                     GX_TEXCOORD_NULL,
1218                     GX_TEXMAP_NULL,
1219                     GX_COLOR0A0);
1220             GXSetTevColorIn(GX_TEVSTAGE0,
1221                     GX_CC_ZERO,
1222                     GX_CC_ZERO,
1223                     GX_CC_ZERO,
1224                     GX_CC_RASC);
1225             GXSetTevAlphaIn(GX_TEVSTAGE0,
1226                     GX_CA_ZERO,
1227                     GX_CA_ZERO,
1228                     GX_CA_ZERO,
1229                     GX_CA_RASA);
1230             GXSetTevColorOp(GX_TEVSTAGE0,
1231                     GX_TEV_ADD,
1232                     GX_TB_ZERO,
1233                     GX_CS_SCALE_1,
1234                     GX_ENABLE,
1235                     GX_TEVPREV);
1236             GXSetTevAlphaOp(GX_TEVSTAGE0,
1237                     GX_TEV_ADD,
1238                     GX_TB_ZERO,
1239                     GX_CS_SCALE_1,
1240                     GX_ENABLE,
1241                     GX_TEVPREV);
1242 
1243             // Tev 1: Use rasterization lookup table (BA),
1244 
1245             // then add previous tev (RG + BA)
1246             GXSetTevOrder(GX_TEVSTAGE1,
1247                     GX_TEXCOORD1,
1248                     GX_TEXMAP1,
1249                     GX_COLOR1A1);
1250             GXSetTevColorIn(GX_TEVSTAGE1,
1251                     GX_CC_ZERO,
1252                     GX_CC_TEXC,
1253                     GX_CC_ONE,
1254                     GX_CC_CPREV);
1255             GXSetTevAlphaIn(GX_TEVSTAGE1,
1256                     GX_CA_ZERO,
1257                     GX_CA_TEXA,
1258                     GX_CA_ONE,
1259                     GX_CA_APREV);
1260             GXSetTevColorOp(GX_TEVSTAGE1,
1261                     GX_TEV_ADD,
1262                     GX_TB_ZERO,
1263                     GX_CS_SCALE_1,
1264                     GX_ENABLE,
1265                     GX_TEVPREV);
1266             GXSetTevAlphaOp(GX_TEVSTAGE1,
1267                     GX_TEV_ADD,
1268                     GX_TB_ZERO,
1269                     GX_CS_SCALE_1,
1270                     GX_ENABLE,
1271                     GX_TEVPREV);
1272 
1273             // convert color0 to s,t for 2-D texture lookup (RG)
1274             GXSetTexCoordGen(GX_TEXCOORD0,
1275                     GX_TG_SRTG,
1276                     GX_TG_COLOR0,
1277                     GX_IDENTITY);
1278             // convert color1 to s,t for 2-D texture lookup (BA)
1279             GXSetTexCoordGen(GX_TEXCOORD1,
1280                     GX_TG_SRTG,
1281                     GX_TG_COLOR1,
1282                     GX_IDENTITY);
1283             break;
1284     }
1285 }
1286 
1287 /*---------------------------------------------------------------------------*
1288     Name:           PrintIntro
1289     Description:    Prints the directions on how to use this demo.
1290  *---------------------------------------------------------------------------*/
PrintIntro(void)1291 static void PrintIntro( void )
1292 {
1293     OSReport("\n\n");
1294     OSReport("************************************************\n");
1295     OSReport("tg-clr-persp: perspective correct color demo\n");
1296     OSReport("************************************************\n");
1297     OSReport("to quit hit the start button\n");
1298     OSReport("\n");
1299     OSReport("A button : change mode\n");
1300     OSReport("X button : change size of look-up textures\n");
1301     OSReport("B button : toggle rotation\n");
1302     OSReport("C-stick  : control camera\n");
1303     OSReport(" [ Followings: Mode 1 only ]\n");
1304     OSReport("Stick    : control models\n");
1305     OSReport("L/R      : zoom-in/out\n");
1306     OSReport("D-Up     : toggle base texture\n");
1307     OSReport("D-Left   : toggle alpha modes\n");
1308     OSReport("************************************************\n\n");
1309 }
1310