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