1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: lit-atn-func.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 lit-atn-func
15 Convenience attenuation function test
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 Header files
20 *---------------------------------------------------------------------------*/
21 #include <demo.h>
22 #include <math.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define PI 3.14159265358979323846F
28
29 /*---------------------------------------------------------------------------*
30 Structure definitions
31 *---------------------------------------------------------------------------*/
32 // for camera
33 typedef struct
34 {
35 Vec location;
36 Vec up;
37 Vec target;
38 f32 left;
39 f32 top;
40 f32 znear;
41 f32 zfar;
42 } CameraConfig;
43
44 typedef struct
45 {
46 CameraConfig cfg;
47 Mtx view;
48 Mtx44 proj;
49 } MyCameraObj;
50
51 // for entire scene control
52 typedef struct
53 {
54 MyCameraObj cam;
55 Mtx modelCtrl;
56 GXLightObj light;
57 GXTexObj texture;
58 u32 funcType;
59 s32 param0;
60 s32 param1;
61 } MySubSceneCtrlObj;
62
63 typedef struct
64 {
65 MySubSceneCtrlObj sub[2];
66 u32 mode;
67 } MySceneCtrlObj;
68
69 /*---------------------------------------------------------------------------*
70 Forward references
71 *---------------------------------------------------------------------------*/
72 void main ( void );
73 static void DrawInit ( MySceneCtrlObj* sc );
74 static void DrawTick ( MySceneCtrlObj* sc );
75 static void AnimTick ( MySceneCtrlObj* sc );
76 static void DrawModel0 ( void );
77 static void DrawModel1 ( void );
78 static void SetCamera ( MyCameraObj* cam );
79 static void SetLight ( GXLightObj* lobj );
80 static void PrintIntro ( void );
81 static void StatusMessage ( MySceneCtrlObj* sc );
82
83 /*---------------------------------------------------------------------------*
84 Lighting and model parameters
85 *---------------------------------------------------------------------------*/
86 #define LIGHT_COLOR MyColors[0]
87 #define REG_MATERIAL MyColors[1]
88 #define REG_AMBIENT MyColors[2]
89
90 static GXColor MyColors[] ATTRIBUTE_ALIGN(32) =
91 {
92 {0xff, 0xff, 0xff, 0xff}, // white
93 {0xff, 0xff, 0xff, 0xff}, // material
94 {0x00, 0x00, 0x00, 0x00} // ambient
95 };
96
97 #define NUM_SPFUNC 7
98 static GXSpotFn SpFnTable[NUM_SPFUNC] =
99 {
100 GX_SP_OFF,
101 GX_SP_FLAT,
102 GX_SP_COS,
103 GX_SP_COS2,
104 GX_SP_SHARP,
105 GX_SP_RING1,
106 GX_SP_RING2
107 };
108
109 #define NUM_DAFUNC 4
110 static GXDistAttnFn DaFnTable[NUM_DAFUNC] =
111 {
112 GX_DA_OFF,
113 GX_DA_GENTLE,
114 GX_DA_MEDIUM,
115 GX_DA_STEEP
116 };
117
118 /*---------------------------------------------------------------------------*
119 Strings for messages
120 *---------------------------------------------------------------------------*/
121 static char* SpFnStr[NUM_SPFUNC] =
122 {
123 "GX_SP_OFF",
124 "GX_SP_FLAT",
125 "GX_SP_COS",
126 "GX_SP_COS2",
127 "GX_SP_SHARP",
128 "GX_SP_RING1",
129 "GX_SP_RING2"
130 };
131
132 static char* DaFnStr[NUM_DAFUNC] =
133 {
134 "GX_DA_OFF",
135 "GX_DA_GENTLE",
136 "GX_DA_MEDIUM",
137 "GX_DA_STEEP"
138 };
139
140 /*---------------------------------------------------------------------------*
141 Camera configuration
142 *---------------------------------------------------------------------------*/
143 static CameraConfig DefaultCamera0 =
144 {
145 { 0.0F, 0.0F, 500.0F }, // location
146 { 0.0F, 1.0F, 0.0F }, // up
147 { 0.0F, 0.0F, 0.0F }, // target
148 -320.0F, // left
149 240.0F, // top
150 400.0F, // near
151 2000.0F // far
152 };
153
154 static CameraConfig DefaultCamera1 =
155 {
156 { 0.0F, 0.0F, 750.0F }, // location
157 { 0.0F, 1.0F, 0.0F }, // up
158 { 0.0F, 0.0F, 0.0F }, // target
159 -320.0F, // left
160 240.0F, // top
161 400.0F, // near
162 2000.0F // far
163 };
164
165 /*---------------------------------------------------------------------------*
166 Global variables
167 *---------------------------------------------------------------------------*/
168 static MySceneCtrlObj SceneCtrl; // scene control parameters
169 static TPLPalettePtr MyTplObj = 0; // external texture palette
170
171 /*---------------------------------------------------------------------------*
172 Application main loop
173 *---------------------------------------------------------------------------*/
main(void)174 void main( void )
175 {
176 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
177
178 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
179
180 PrintIntro(); // Print demo directions
181
182 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
183 {
184 DEMOBeforeRender();
185 DrawTick(&SceneCtrl); // Draw the model.
186 DEMODoneRender();
187 DEMOPadRead(); // Update controller status
188 AnimTick(&SceneCtrl); // Update animation.
189 }
190
191 OSHalt("End of demo");
192 }
193
194 /*---------------------------------------------------------------------------*
195 Functions
196 *---------------------------------------------------------------------------*/
197 /*---------------------------------------------------------------------------*
198 Name: DrawInit
199
200 Description: Initializes the vertex attribute format and textures.
201 This function also sets up default scene parameters.
202
203 Arguments: sc : pointer to the structure of scene control parameters
204
205 Returns: none
206 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)207 static void DrawInit( MySceneCtrlObj* sc )
208 {
209 Mtx ms;
210 Vec lpos;
211
212 // set up a vertex attribute.
213 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
214 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
215 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
216
217
218 // set up default scene settings
219
220 // camera
221 sc->sub[0].cam.cfg = DefaultCamera0;
222 SetCamera(&sc->sub[0].cam);
223 sc->sub[1].cam.cfg = DefaultCamera1;
224 SetCamera(&sc->sub[1].cam);
225
226 // lighting function parameters
227 sc->sub[0].funcType = 1;
228 sc->sub[0].param0 = 30; // cutoff
229 sc->sub[1].funcType = 1;
230 sc->sub[1].param0 = 500; // reference distance
231 sc->sub[1].param1 = 50; // reference brightness
232
233 // fixed parameters in light objects
234 lpos.x = lpos.y = lpos.z = 0.0F;
235 MTXMultVec(sc->sub[0].cam.view, &lpos, &lpos);
236 GXInitLightPos(&sc->sub[0].light, lpos.x, lpos.y, lpos.z);
237 GXInitLightDir(&sc->sub[0].light, 0.0F, 0.0F, -1.0F);
238 GXInitLightColor(&sc->sub[0].light, LIGHT_COLOR);
239 GXInitLightDistAttn(&sc->sub[0].light, 0.0F, 0.0F, GX_DA_OFF );
240
241 lpos.x = -500.0F;
242 lpos.y = lpos.z = 0.0F;
243 MTXMultVec(sc->sub[1].cam.view, &lpos, &lpos);
244 GXInitLightPos(&sc->sub[1].light, lpos.x, lpos.y, lpos.z);
245 GXInitLightDir(&sc->sub[1].light, 1.0F, 0.0F, 0.0F);
246 GXInitLightColor(&sc->sub[1].light, LIGHT_COLOR);
247 GXInitLightSpot(&sc->sub[1].light, 0.0F, GX_SP_OFF );
248
249 // model control matrix ( never changed in this test )
250 MTXScale(ms, 350.0F, 100.0F, 350.0F);
251 MTXConcat(sc->sub[0].cam.view, ms, sc->sub[0].modelCtrl);
252 MTXScale(ms, 1000.0F, 400.0F, 1.0F);
253 MTXConcat(sc->sub[1].cam.view, ms, sc->sub[1].modelCtrl);
254
255 // textures from tpl
256 TPLGetPalette(&MyTplObj, "gxTests/lit-10.tpl");
257 TPLGetGXTexObjFromPalette(MyTplObj, &sc->sub[0].texture, 0);
258 TPLGetGXTexObjFromPalette(MyTplObj, &sc->sub[1].texture, 1);
259 GXInvalidateTexAll();
260 }
261
262 /*---------------------------------------------------------------------------*
263 Name: DrawTick
264
265 Description: Draw the model by using given scene parameters
266
267 Arguments: sc : pointer to the structure of scene control parameters
268
269 Returns: none
270 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)271 static void DrawTick( MySceneCtrlObj* sc )
272 {
273 Mtx mv, mvi;
274
275 // reflects controllable parameters into light objects.
276 GXInitLightSpot(
277 &sc->sub[0].light,
278 (f32)(sc->sub[0].param0),
279 SpFnTable[sc->sub[0].funcType] );
280 GXInitLightDistAttn(
281 &sc->sub[1].light,
282 (f32)(sc->sub[1].param0),
283 (f32)(sc->sub[1].param1 * 0.01F),
284 DaFnTable[sc->sub[1].funcType] );
285
286 // set up Tev mode = one color / one texture
287 GXSetNumTexGens(1); // number of texture coord generators
288 GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
289
290 // load texture
291 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
292
293 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
294 GXSetNumTexGens(1);
295
296 GXLoadTexObj(&sc->sub[sc->mode].texture, GX_TEXMAP0);
297 // set up lights
298 SetLight(&sc->sub[sc->mode].light);
299
300 // set up modelview matrix
301 GXLoadPosMtxImm(sc->sub[sc->mode].modelCtrl, GX_PNMTX0);
302 MTXInverse(sc->sub[sc->mode].modelCtrl, mvi);
303 MTXTranspose(mvi, mv);
304 GXLoadNrmMtxImm(mv, GX_PNMTX0);
305
306 if ( sc->mode == 0 )
307 DrawModel0();
308 else
309 DrawModel1();
310 }
311
312 /*---------------------------------------------------------------------------*
313 Name: AnimTick
314
315 Description: Changes scene parameters according to the pad status.
316
317 Arguments: sc : pointer to the structure of scene control parameters
318
319 Returns: none
320 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)321 static void AnimTick( MySceneCtrlObj* sc )
322 {
323 u32 m = sc->mode;
324 s32 d, min, max;
325 u16 dirs = DEMOPadGetDirs(0);
326 u16 down = DEMOPadGetButtonDown(0);
327
328 // change parameter 0
329 d = ( m == 0 ) ? 1 : 10;
330 min = ( m == 0 ) ? 5 : 10;
331 max = ( m == 0 ) ? 90 : 1000;
332
333 if ( dirs & DEMO_STICK_LEFT )
334 {
335 sc->sub[m].param0 -= d;
336 if ( sc->sub[m].param0 < min )
337 {
338 sc->sub[m].param0 = min;
339 }
340 StatusMessage(sc);
341 }
342 if ( dirs & DEMO_STICK_RIGHT )
343 {
344 sc->sub[m].param0 += d;
345 if ( sc->sub[m].param0 > max )
346 {
347 sc->sub[m].param0 = max;
348 }
349 StatusMessage(sc);
350 }
351
352 // change parameter 1
353 d = ( m == 0 ) ? 0 : 5;
354 min = ( m == 0 ) ? 0 : 5;
355 max = ( m == 0 ) ? 1 : 95;
356
357 if ( dirs & DEMO_STICK_DOWN )
358 {
359 sc->sub[m].param1 -= d;
360 if ( sc->sub[m].param1 < min )
361 {
362 sc->sub[m].param1 = min;
363 }
364 StatusMessage(sc);
365 }
366 if ( dirs & DEMO_STICK_UP )
367 {
368 sc->sub[m].param1 += d;
369 if ( sc->sub[m].param1 > max )
370 {
371 sc->sub[m].param1 = max;
372 }
373 StatusMessage(sc);
374 }
375
376 // change function type
377 max = ( m == 0 ) ? NUM_SPFUNC : NUM_DAFUNC;
378
379 if ( down & PAD_BUTTON_Y )
380 {
381 sc->sub[m].funcType = ( sc->sub[m].funcType + 1 ) % max;
382 StatusMessage(sc);
383 }
384 if ( down & PAD_BUTTON_X )
385 {
386 sc->sub[m].funcType = ( sc->sub[m].funcType + max - 1 ) % max;
387 StatusMessage(sc);
388 }
389
390 // change sub scene (angle test/distance test)
391 if ( down & PAD_BUTTON_B )
392 {
393 sc->mode = 1 - sc->mode;
394 }
395 }
396
397 /*---------------------------------------------------------------------------*
398 Name: DrawModel0
399
400 Description: Draw the model for angular attenuation test
401
402 Arguments: none
403
404 Returns: none
405 *---------------------------------------------------------------------------*/
DrawModel0(void)406 static void DrawModel0( void )
407 {
408 s32 x, y;
409 f32 xp, yp, zp, s, t;
410
411 // set up vertex descriptors
412 GXClearVtxDesc();
413 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
414 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
415 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
416
417 // drawing loop
418 for ( y = 0 ; y < 4 ; ++y )
419 {
420 yp = 1.0F - (f32)y * 0.5F;
421 t = (f32)y * 0.25F;
422
423 GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 181*2);
424 for ( x = 0 ; x <= 180 ; ++x )
425 {
426 xp = - cosf((f32)x * PI / 180.0F);
427 zp = - sinf((f32)x * PI / 180.0F);
428 s = (f32)x/180.0F;
429
430 GXPosition3f32(xp, yp - 0.5F, zp);
431 GXNormal3f32(-xp, 0.0F, -zp);
432 GXTexCoord2f32(s, t + 0.25F);
433
434 GXPosition3f32(xp, yp, zp);
435 GXNormal3f32(-xp, 0.0F, -zp);
436 GXTexCoord2f32(s, t);
437 }
438 GXEnd();
439 }
440 }
441
442 /*---------------------------------------------------------------------------*
443 Name: DrawModel1
444
445 Description: Draw the model for distance attenuation test
446
447 Arguments: none
448
449 Returns: none
450 *---------------------------------------------------------------------------*/
DrawModel1(void)451 static void DrawModel1( void )
452 {
453 f32 xp, yp;
454
455 // set up vertex descriptors
456 GXClearVtxDesc();
457 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
458 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
459 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
460
461 // drawing loop
462 for ( yp = 0.0F ; yp < 1.0F ; yp += 0.25F )
463 {
464 GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 100*2);
465 for ( xp = 0.01F ; xp <= 1.0F ; xp += 0.01F )
466 {
467 GXPosition3f32(xp - 0.5F, yp - 0.5F, 0.0F);
468 GXNormal3f32(-xp, 0.5F - yp, 0.0F);
469 GXTexCoord2f32(xp, 1.0F - yp);
470
471 GXPosition3f32(xp - 0.5F, yp - 0.25F, 0.0F);
472 GXNormal3f32(-xp, 0.25F - yp, 0.0F);
473 GXTexCoord2f32(xp, 0.75F - yp);
474 }
475 GXEnd();
476 }
477 }
478
479 /*---------------------------------------------------------------------------*
480 Name: SetCamera
481
482 Description: set view matrix and load projection matrix into hardware
483
484 Arguments: cam : pointer to the MyCameraObj structure
485
486 Returns: none
487 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)488 static void SetCamera( MyCameraObj* cam )
489 {
490 MTXLookAt(
491 cam->view,
492 &cam->cfg.location,
493 &cam->cfg.up,
494 &cam->cfg.target );
495
496 MTXFrustum(
497 cam->proj,
498 cam->cfg.top,
499 - (cam->cfg.top),
500 cam->cfg.left,
501 - (cam->cfg.left),
502 cam->cfg.znear,
503 cam->cfg.zfar );
504 GXSetProjection(cam->proj, GX_PERSPECTIVE);
505 }
506
507 /*---------------------------------------------------------------------------*
508 Name: SetLight
509
510 Description: sets light objects and color channels
511
512 Arguments: lobj : pointer to GXLightObj structure to be used.
513
514 Returns: none
515 *---------------------------------------------------------------------------*/
SetLight(GXLightObj * lobj)516 static void SetLight( GXLightObj* lobj )
517 {
518 // loads given light object
519 GXLoadLightObjImm(lobj, GX_LIGHT0);
520
521 // channel setting
522 GXSetNumChans(1); // number of color channels
523 GXSetChanCtrl(
524 GX_COLOR0,
525 GX_ENABLE, // enable channel
526 GX_SRC_REG, // amb source
527 GX_SRC_REG, // mat source
528 GX_LIGHT0, // light mask
529 GX_DF_CLAMP, // diffuse function
530 GX_AF_SPOT);
531 GXSetChanCtrl(
532 GX_ALPHA0,
533 GX_DISABLE, // disable channel
534 GX_SRC_REG, // amb source
535 GX_SRC_REG, // mat source
536 0, // light mask
537 GX_DF_CLAMP, // diffuse function
538 GX_AF_SPOT);
539 // set up ambient color
540 GXSetChanAmbColor(GX_COLOR0A0, REG_AMBIENT);
541 // set up material color
542 GXSetChanMatColor(GX_COLOR0A0, REG_MATERIAL);
543 }
544
545 /*---------------------------------------------------------------------------*
546 Name: PrintIntro
547
548 Description: Prints the directions on how to use this demo.
549
550 Arguments: none
551
552 Returns: none
553 *---------------------------------------------------------------------------*/
PrintIntro(void)554 static void PrintIntro( void )
555 {
556 OSReport("\n\n");
557 OSReport("******************************************************\n");
558 OSReport("lit-atn-func: convienance light attn. function test\n");
559 OSReport("******************************************************\n");
560 OSReport("to quit hit the start button\n");
561 OSReport("\n");
562 OSReport("B Button : Switch Angle test/Distance test\n");
563 OSReport("X/Y Buttons : Select Attenuation Function type\n");
564 OSReport("Main Stick X : Change cutoff angle (angle test)\n");
565 OSReport(" : Change ref. distance (distance test)\n");
566 OSReport("Main Stick Y : Change ref. brightness (distance test)\n");
567 OSReport("******************************************************\n");
568 OSReport("\n");
569 }
570
571 /*---------------------------------------------------------------------------*
572 Name: StatusMessage
573
574 Description: Prints the current status.
575 *---------------------------------------------------------------------------*/
StatusMessage(MySceneCtrlObj * sc)576 static void StatusMessage( MySceneCtrlObj* sc )
577 {
578 if ( sc->mode == 0 )
579 {
580 OSReport("Cutoff=%d ", sc->sub[0].param0);
581 OSReport("Function=%s ", SpFnStr[sc->sub[0].funcType]);
582 OSReport("\n");
583 }
584 else
585 {
586 OSReport("Ref_Dist=%d ", sc->sub[1].param0);
587 OSReport("Ref_Br=%f ", (f32)sc->sub[1].param1 / 100.0);
588 OSReport("Function=%s ", DaFnStr[sc->sub[1].funcType]);
589 OSReport("\n");
590 }
591 }
592
593 /*============================================================================*/
594