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