1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     lit-basic.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 #include <math.h>
16 
17 #define PI    3.14159265358979323846
18 
19 /*---------------------------------------------------------------------------*
20    Forward references
21  *---------------------------------------------------------------------------*/
22 void        main            ( void );
23 static void CameraInit      ( Mtx v );
24 static void DrawInit        ( void );
25 static void DrawTick        ( Mtx v );
26 static void AnimTick        ( void );
27 static void PrintIntro      ( void );
28 static void SetAmbClr       ( u8 cur );
29 static void SetMatClr       ( u8 cur );
30 static void SetModel        ( u8 cur);
31 static void SetChanEn       ( u8 cur );
32 static void DumpCurMenu     ( void );
33 
34 /*---------------------------------------------------------------------------*
35   Model Data
36  *---------------------------------------------------------------------------*/
37 
38 typedef struct
39 {
40     char *mode;
41     char **opt;
42     u8   cursel;
43     u8   maxsel; // n opts - 1
44     void (*f)(u8 cur);
45 } MenuOpt;
46 
47 
48 #define Black   MyColors[0]
49 #define White   MyColors[1]
50 #define Red     MyColors[2]
51 #define Green   MyColors[3]
52 #define Blue    MyColors[4]
53 #define Gray    MyColors[5]
54 
55 
56 GXColor MyColors[] = {
57     {0x00, 0x00, 0x00, 0x00},  // black
58     {0xff, 0xff, 0xff, 0xff},  // white
59     {0xff, 0x00, 0x00, 0xff},  // red
60     {0x00, 0xff, 0x00, 0xff},  // green
61     {0x00, 0x00, 0xff, 0xff},  // blue
62     {0x80, 0x80, 0x80, 0xff}}; // gray
63 
64 char *ColorOpt[] = {
65     "Black",
66     "White",
67     "Red",
68     "Green",
69     "Blue",
70     "Gray" };
71 
72 typedef enum {
73     CYLINDER,
74     TORUS,
75     CUBE,
76     SPHERE,
77     DODECA,
78     OCTA,
79     ICOSA,
80     SPHERE1} MyModels;
81 
82 char *ModelOpt[] = {
83     "Cylinder",
84     "Torus",
85     "Cube",
86     "Sphere",
87     "Dodeca",
88     "Octa",
89     "Icosa",
90     "Sphere1" };
91 
92 char *ChanEnOpt[] = {
93     "Disable",
94     "Enable" };
95 
96 MenuOpt Menu[] = {
97 { "chan en:    ", ChanEnOpt, 0, 1, SetChanEn },
98 { "amb color:  ", ColorOpt,  0, 5, SetAmbClr },
99 { "mat color:  ", ColorOpt,  2, 5, SetMatClr },
100 { "model:      ", ModelOpt,  0, 7, SetModel  }
101 };
102 
103 GXLightObj MyLight;
104 
105 u8       MyAmbClr = 0;
106 u8       MyMatClr = 2;
107 u8       MyChanEn = GX_DISABLE;
108 MyModels MyModel  = CYLINDER;
109 
110 /*---------------------------------------------------------------------------*
111    Application main loop
112  *---------------------------------------------------------------------------*/
main(void)113 void main ( void )
114 {
115     Mtx         v;   // view matrix
116 
117     DEMOInit(NULL);
118 
119     PrintIntro();  // Print demo directions
120 
121     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
122     {
123         DEMOBeforeRender(); // start stats counters
124 
125         CameraInit(v);      // Initialize the camera.
126         DrawInit();         // Define my vertex formats and set array pointers.
127         DrawTick(v);        // Draw the model.
128         DEMODoneRender();   // Wait until everything is drawn. read stats counters.
129 
130         DEMOPadRead();      // Update pad status.
131         AnimTick();         // Update animation.
132     }
133 
134     OSHalt("End of demo");
135 }
136 
137 
138 /*---------------------------------------------------------------------------*
139    Functions
140  *---------------------------------------------------------------------------*/
141 /*---------------------------------------------------------------------------*
142     Name:           CameraInit
143 
144     Description:    Initialize the projection matrix and load into hardware.
145                     Initialize the view matrix.
146 
147     Arguments:      v       view matrix
148 
149     Returns:        none
150  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)151 static void CameraInit ( Mtx v )
152 {
153     Mtx44   p;      // projection matrix
154     Vec     up      = {0.0F, 1.0F, 0.0F};
155     Vec     camLoc  = {0.0F, 0.0F, 800.0F};
156     Vec     objPt   = {0.0F, 0.0F, -100.0F};
157     f32     left    = 240.0F;
158     f32     top     = 320.0F;
159     f32     znear    = 500.0F;
160     f32     zfar     = 2000.0F;
161 
162     MTXFrustum(p, left, -left, -top, top, znear, zfar);
163     GXSetProjection(p, GX_PERSPECTIVE);
164 
165     MTXLookAt(v, &camLoc, &up, &objPt);
166 }
167 
168 /*---------------------------------------------------------------------------*
169     Name:           DrawInit
170 
171     Description:    Initializes the vertex attribute format 0, and sets
172                     the array pointers and strides for the indexed data.
173 
174     Arguments:      none
175 
176     Returns:        none
177  *---------------------------------------------------------------------------*/
DrawInit(void)178 static void DrawInit( void )
179 {
180     // for generated models
181     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
182     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
183     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
184 
185     //
186     // set up light parameters
187     //
188     GXInitLightPos(&MyLight, 0.0F, 0.0F, 0.0F);
189     GXInitLightColor(&MyLight, White);
190     GXLoadLightObjImm(&MyLight, GX_LIGHT0);
191 }
192 
DrawModel(MyModels model)193 static void DrawModel(MyModels model)
194 {
195     GXClearVtxDesc();
196     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
197     GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
198 
199     if (model == CYLINDER)
200         GXDrawCylinder(16);
201     else if (model == TORUS)
202         GXDrawTorus(0.375F, 12, 16);
203     else if (model == SPHERE)
204         GXDrawSphere(8, 16);
205     else if (model == CUBE)
206         GXDrawCube();
207     else if (model == DODECA)
208         GXDrawDodeca();
209     else if (model == OCTA)
210         GXDrawOctahedron();
211     else if (model == ICOSA)
212         GXDrawIcosahedron();
213     else if (model == SPHERE1)
214         GXDrawSphere1(2);
215 }
216 
217 
218 /*---------------------------------------------------------------------------*
219     Name:           DrawTick
220 
221     Description:    Draw the model once.
222                     GXInit makes GX_PNMTX0 the default matrix.
223 
224     Arguments:      v       view matrix
225 
226     Returns:        none
227  *---------------------------------------------------------------------------*/
DrawTick(Mtx v)228 static void DrawTick( Mtx v )
229 {
230     static u32  rot = 60;
231     static u32  axisc = 0;
232     char axis[3] = {'x', 'y', 'z'};
233 
234     Mtx  ms;  // Model matrix. scale
235     Mtx  mr;  // Model matrix. rotate
236     Mtx  mt;  // Model matrix. translate
237     Mtx  mv;  // Modelview matrix.
238     Mtx  mvi; // Modelview matrix.
239 
240     // Enable Z compare.  Have to reset because DEMOPrintStats turns off
241     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
242 
243     // render mode = one color / no texture
244     GXSetNumTexGens(0);
245     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
246     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
247 
248     //
249     // set up channel control
250     //
251     GXSetNumChans(1); // number of color channels
252     GXSetChanCtrl(
253         GX_COLOR0,
254         MyChanEn,    // enable channel
255         GX_SRC_REG,  // amb source
256         GX_SRC_REG,  // mat source
257         GX_LIGHT0,   // light mask
258         GX_DF_CLAMP, // diffuse function
259         GX_AF_NONE);
260     GXSetChanCtrl(
261         GX_ALPHA0,
262         FALSE,       // enable channel
263         GX_SRC_REG,  // amb source
264         GX_SRC_REG,  // mat source
265         GX_LIGHT0,   // light mask
266         GX_DF_NONE,  // diffuse function
267         GX_AF_NONE);
268     // set up ambient color
269     GXSetChanAmbColor(GX_COLOR0, MyColors[MyAmbClr]);
270     GXSetChanAmbColor(GX_ALPHA0, White);
271     // set up material color
272     GXSetChanMatColor(GX_COLOR0A0, MyColors[MyMatClr]);
273 
274     // Draw models
275     MTXScale(ms, 100.0F, 100.0F, 100.0F);
276     MTXConcat(v, ms, mv);
277     MTXRotDeg(mr, axis[axisc % 3], (f32)rot);
278     MTXConcat(mv, mr, mv);
279     GXLoadPosMtxImm(mv, GX_PNMTX0);
280     MTXInverse(mv, mvi);
281     MTXTranspose(mvi, mv);
282     GXLoadNrmMtxImm(mv, GX_PNMTX0);
283 
284     DrawModel(MyModel);
285 
286     MTXTrans(mt, -300.0F, 0.0F, 0.0F);
287     MTXConcat(v, mt, mv);
288     MTXRotDeg(mr, axis[(axisc+1)%3], (f32)rot);
289     MTXConcat(mv, mr, mv);
290     MTXScale(ms, 100.0F, 100.0F, 100.0F);
291     MTXConcat(mv, ms, mv);
292     GXLoadPosMtxImm(mv, GX_PNMTX0);
293     MTXInverse(mv, mvi);
294     MTXTranspose(mvi, mv);
295     GXLoadNrmMtxImm(mv, GX_PNMTX0);
296 
297     DrawModel(MyModel);
298 
299     MTXTrans(mt, 300.0F, 0.0F, 0.0F);
300     MTXConcat(v, mt, mv);
301     MTXRotDeg(mr, axis[(axisc+2)%3], (f32)rot);
302     MTXConcat(mv, mr, mv);
303     MTXScale(ms, 100.0F, 100.0F, 100.0F);
304     MTXConcat(mv, ms, mv);
305     GXLoadPosMtxImm(mv, GX_PNMTX0);
306     MTXInverse(mv, mvi);
307     MTXTranspose(mvi, mv);
308     GXLoadNrmMtxImm(mv, GX_PNMTX0);
309 
310     DrawModel(MyModel);
311 
312     rot++;
313     if (rot == 360)
314     {
315         rot = 0;
316         axisc++;
317     }
318 }
319 
320 /*---------------------------------------------------------------------------*
321     Name:           AnimTick
322 
323     Description:    Menu of test options
324 
325     Arguments:      none
326 
327     Returns:        none
328  *---------------------------------------------------------------------------*/
AnimTick(void)329 static void AnimTick( void )
330 {
331     static s32  curY   = 0;
332     static s32  curX   = 0;
333     static s32  oldX   = 0;
334     static s32  oldY   = 0;
335 
336     u32  maxY = sizeof(Menu)/sizeof(MenuOpt) - 1;
337     u16  down = DEMOPadGetButtonDown(0);
338     u8   sel;
339 
340     if (down & PAD_BUTTON_Y)
341         curY++;
342     if (down & PAD_BUTTON_X)
343         curY--;
344     if (down & PAD_TRIGGER_R)
345         curX++;
346     if (down & PAD_TRIGGER_L)
347         curX--;
348     if (down & PAD_BUTTON_A)
349         DumpCurMenu();
350 
351     // clamp Y (menu)
352     if (curY < 0) curY = (s32)maxY;
353     if (curY > maxY) curY = 0;
354 
355     // clamp X (choice)
356     if (curX < 0) curX = Menu[curY].maxsel;
357     if (curX > Menu[curY].maxsel) curX = 0;
358 
359     sel = Menu[curY].cursel;
360 
361     if (curY != oldY || curX != oldX)
362     {
363         if (curY != oldY)
364         {
365             curX = sel;
366         }
367         if (curX != oldX)
368         {
369             Menu[curY].cursel = (u8)curX;
370             Menu[curY].f((u8)curX);
371         }
372         OSReport("%s %s\n\n\n\n", Menu[curY].mode, Menu[curY].opt[curX]);
373     }
374 
375     oldX = curX;
376     oldY = curY;
377 }
378 
379 /*---------------------------------------------------------------------------*
380     Name:           DumpCurMenu
381 
382     Description:
383 
384     Arguments:      none
385 
386     Returns:        none
387  *---------------------------------------------------------------------------*/
DumpCurMenu(void)388 static void DumpCurMenu( void )
389 {
390     u32 i;
391     OSReport("Current settings\n");
392     for (i = 0; i < sizeof(Menu)/sizeof(MenuOpt); i++)
393     {
394         OSReport("%s %s\n", Menu[i].mode, Menu[i].opt[Menu[i].cursel]);
395     }
396     OSReport("\n\n");
397 }
398 
399 /*---------------------------------------------------------------------------*
400     Name:           PrintIntro
401 
402     Description:    Prints the directions on how to use this demo.
403 
404     Arguments:      none
405 
406     Returns:        none
407  *---------------------------------------------------------------------------*/
PrintIntro(void)408 static void PrintIntro( void )
409 {
410     OSReport("\n\n");
411     OSReport("***********************************************\n");
412     OSReport("lit-basic - demonstrate basic lighting controls\n");
413     OSReport("***********************************************\n");
414     OSReport("to quit hit the start button\n");
415     OSReport("\n");
416     OSReport("Dump current settings BUTTON A\n");
417     OSReport("Menu up/down BUTTON Y/X\n");
418     OSReport("Menu options TRIGGER L/R\n");
419     OSReport("***********************************************\n");
420     OSReport("\n\n");
421 
422     DumpCurMenu();
423 }
424 
SetAmbClr(u8 cur)425 static void SetAmbClr( u8 cur )
426 {
427     MyAmbClr = cur;
428 }
429 
SetMatClr(u8 cur)430 static void SetMatClr( u8 cur )
431 {
432     MyMatClr = cur;
433 }
434 
SetModel(u8 cur)435 static void SetModel( u8 cur )
436 {
437     MyModel = (MyModels)cur;
438 }
439 
440 
SetChanEn(u8 cur)441 static void SetChanEn( u8 cur )
442 {
443     if (cur)
444         MyChanEn = GX_ENABLE;
445     else
446         MyChanEn = GX_DISABLE;
447 }
448 
449 /*============================================================================*/
450