1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     lit-dist-atn.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-dist-atn
15      Distance attenuation 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 typedef struct
33 {
34     Vec    location;
35     Vec    up;
36     Vec    target;
37     f32    left;
38     f32    top;
39     f32    znear;
40     f32    zfar;
41 } CameraConfig;
42 
43 typedef struct
44 {
45     CameraConfig  cfg;
46     Mtx           view;
47     Mtx44         proj;
48     s32           theta;
49     s32           zoom;
50 } MyCameraObj;
51 
52 typedef struct
53 {
54     f32    k0;
55     f32    k1;
56     f32    k2;
57 } DistAttn;
58 
59 typedef struct
60 {
61     GXLightObj    lobj;
62     u32           attnType;
63 } MyLightObj;
64 
65 typedef struct
66 {
67     MyCameraObj   cam;
68     MyLightObj    light;
69 } MySceneCtrlObj;
70 
71 /*---------------------------------------------------------------------------*
72    Forward references
73  *---------------------------------------------------------------------------*/
74 void        main            ( void );
75 static void DrawInit        ( MySceneCtrlObj* sc );
76 static void DrawTick        ( MySceneCtrlObj* sc );
77 static void AnimTick        ( MySceneCtrlObj* sc );
78 static void DrawTessPanel   ( void );
79 static void SetCamera       ( MyCameraObj* cam );
80 static void SetLight        ( MyLightObj* light, Mtx v );
81 static void DisableLight    ( void );
82 static void PrintIntro      ( void );
83 static void StatusMessage   ( u32 index );
84 
85 /*---------------------------------------------------------------------------*
86    Lighting parameters
87  *---------------------------------------------------------------------------*/
88 #define BLACK   MyColors[2]
89 #define WHITE   MyColors[3]
90 
91 static GXColor MyColors[] ATTRIBUTE_ALIGN(32) =
92 {
93     {0x00, 0x00, 0x40, 0xff},  // blue
94     {0x40, 0x00, 0x00, 0xff},  // red
95     {0x00, 0x00, 0x00, 0xff},  // black
96     {0xff, 0xff, 0xff, 0xff},  // white
97 };
98 
99 // fixed normal vector
100 static f32 FixedNormal[] ATTRIBUTE_ALIGN(32) =
101 {
102     0.0F, 0.0F, 1.0F
103 };
104 
105 #define NUM_OF_ATTNS    14
106 static DistAttn LightAttnSamples[NUM_OF_ATTNS] =
107 {
108     { 1.0F,  0.1F,   0.0F   },
109     { 1.0F,  0.02F,  0.0F   },
110     { 1.0F,  0.01F,  0.0F   },
111     { 1.0F,  0.005F, 0.0F   },
112     { 1.0F,  0.002F, 0.0F   },
113     { 1.0F,  0.001F, 0.0F   },
114     { 1.0F,  0.0F,   0.0F   },
115     { 2.0F,  0.0F,   0.0F   },
116     { 2.0F,  0.001F, 0.0F   },
117     { 1.0F,  0.0F,   0.0001F },
118     { 1.0F, -0.01F,  0.0001F },
119     { 1.0F, -0.05F,  0.0005F },
120     { 1.0F, -0.005F, 0.000025F },
121     { 4.0F, -0.002F, 0.0F  }
122 };
123 
124 /*---------------------------------------------------------------------------*
125    Camera configuration
126  *---------------------------------------------------------------------------*/
127 static CameraConfig DefaultCamera =
128 {
129     { 0.0F, 0.0F, 0.1F }, // location
130     { 0.0F, 1.0F, 0.0F }, // up
131     { 0.0F, 0.0F, 0.0F }, // target
132     -320.0F,  // left
133     240.0F,   // top
134     400.0F,   // near
135     1800.0F   // far
136 };
137 
138 /*---------------------------------------------------------------------------*
139    Global Variables
140  *---------------------------------------------------------------------------*/
141 static MySceneCtrlObj  SceneCtrl;    // scene control parameters
142 
143 /*---------------------------------------------------------------------------*
144    Application main loop
145  *---------------------------------------------------------------------------*/
main(void)146 void main ( void )
147 {
148     DEMOInit(NULL);    // Init the OS, game pad, graphics and video.
149 
150     DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters etc.
151 
152     PrintIntro();  // Print demo directions
153 
154     StatusMessage(SceneCtrl.light.attnType);
155     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
156     {
157         DEMOBeforeRender();
158         DrawTick(&SceneCtrl);    // Draw the model.
159         DEMODoneRender();
160         DEMOPadRead();           // Update pad status.
161         AnimTick(&SceneCtrl);    // Update animation.
162     }
163 
164     OSHalt("End of demo");
165 }
166 
167 /*---------------------------------------------------------------------------*
168    Functions
169  *---------------------------------------------------------------------------*/
170 /*---------------------------------------------------------------------------*
171     Name:           DrawInit
172 
173     Description:    Initializes the vertex attribute format, texture and
174                     default scene parameters.
175 
176     Arguments:      sc : pointer to the structure of scene control parameters
177 
178     Returns:        none
179  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)180 static void DrawInit( MySceneCtrlObj* sc )
181 {
182     // set up a vertex attribute
183     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S8, 0);
184     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
185 
186     // culling off
187     GXSetCullMode(GX_CULL_NONE);
188 
189 
190     // Default scene parameter settings
191 
192     // camera
193     sc->cam.cfg   = DefaultCamera;
194     sc->cam.theta = 45;
195     sc->cam.zoom  = 1000;
196 
197     // light parameters
198     sc->light.attnType = 0;
199 }
200 
201 /*---------------------------------------------------------------------------*
202     Name:           DrawTick
203 
204     Description:    Draw the model by using given scene parameters
205 
206     Arguments:      sc : pointer to the structure of scene control parameters
207 
208     Returns:        none
209  *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)210 static void DrawTick( MySceneCtrlObj* sc )
211 {
212     Mtx  ms;  // Scale matrix.
213     Mtx  mt;  // Translation matrix
214     Mtx  mv;  // Modelview matrix.
215     Mtx  mvi; // Modelview matrix.
216     s32  iz;
217 
218     // render mode = one color / no texture
219     GXSetNumTexGens(0);
220     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
221     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
222 
223     // Set camera
224     SetCamera(&sc->cam);
225 
226     // Set light
227     SetLight(&sc->light, sc->cam.view);
228 
229     // Draw panels
230     for ( iz = 0 ; iz < 10 ; ++iz )
231     {
232         f32 width = 10.0F - iz * 0.6F;
233         MTXScale(ms, width * 2.0F, width * 2.0F, 1.0F);
234         MTXTrans(mt, -7.5F, -7.5F, iz * 100.0F - 500.0F );
235         MTXConcat(sc->cam.view, ms, mv);
236         MTXConcat(mv, mt, mv);
237 
238         GXLoadPosMtxImm(mv, GX_PNMTX0);
239         MTXInverse(mv, mvi);
240         MTXTranspose(mvi, mv);
241         GXLoadNrmMtxImm(mv, GX_PNMTX0);
242 
243         GXSetChanAmbColor(GX_COLOR0A0, MyColors[iz%2]);
244         DrawTessPanel();
245     }
246 
247     // Disable light
248     DisableLight();
249     // use ambient color for drawing
250     GXSetChanAmbColor(GX_COLOR0A0, WHITE);
251 
252     // Draw ball light object
253     MTXTrans(mt, 0.0F, 0.0F, 500.0F);
254     MTXConcat(sc->cam.view, mt, mv);
255     MTXScale(ms, 20.0F, 20.0F, 20.0F);
256     MTXConcat(mv, ms, mv);
257     GXLoadPosMtxImm(mv, GX_PNMTX0);
258     MTXInverse(mv, mvi);
259     MTXTranspose(mvi, mv);
260     GXLoadNrmMtxImm(mv, GX_PNMTX0);
261     GXSetChanMatColor(GX_COLOR0A0, WHITE);
262     GXDrawSphere(12, 24);
263 
264 }
265 
266 /*---------------------------------------------------------------------------*
267     Name:           AnimTick
268 
269     Description:    Changes scene parameters according to the pad status.
270 
271     Arguments:      sc : pointer to the structure of scene control parameters
272 
273     Returns:        none
274  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)275 static void AnimTick( MySceneCtrlObj* sc )
276 {
277     u16  down = DEMOPadGetButtonDown(0);
278 
279     // Camera Position Calculation
280     sc->cam.theta -= ( DEMOPadGetStickX(0) / 24 );
281     if ( sc->cam.theta < 0 )
282         sc->cam.theta = 0;
283     if ( sc->cam.theta > 180 )
284         sc->cam.theta = 180;
285 
286     sc->cam.zoom -= DEMOPadGetStickY(0);
287     if ( sc->cam.zoom < 600 )
288         sc->cam.zoom = 600;
289     if ( sc->cam.zoom > 1200 )
290         sc->cam.zoom = 1200;
291 
292     // Light Attenuation change
293     if ( down & PAD_TRIGGER_R )
294     {
295         sc->light.attnType = ( sc->light.attnType + 1 ) % NUM_OF_ATTNS;
296         StatusMessage(sc->light.attnType);
297     }
298     if ( down & PAD_TRIGGER_L )
299     {
300         sc->light.attnType = ( sc->light.attnType + NUM_OF_ATTNS - 1 ) % NUM_OF_ATTNS;
301         StatusMessage(sc->light.attnType);
302     }
303 }
304 
305 /*---------------------------------------------------------------------------*
306     Name:           DrawTessPanel
307 
308     Description:    Draws 16x16 vertices panel
309 
310     Arguments:      none
311 
312     Returns:        none
313  *---------------------------------------------------------------------------*/
DrawTessPanel(void)314 static void DrawTessPanel( void )
315 {
316     s8 x, y;
317 
318     // set up vertex descriptors
319     GXClearVtxDesc();
320     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
321     GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
322 
323     // normal array (actually contains only one item)
324     GXSetArray(GX_VA_NRM, FixedNormal, 3 * sizeof(f32));
325 
326     for ( y = 0 ; y < 15 ; ++y )
327     {
328         GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 32);
329             for ( x = 0 ; x < 16 ; ++x )
330             {
331                 GXPosition3s8(x, y, 0);
332                 GXNormal1x8(0);
333                 GXPosition3s8(x, (s8)(y+1), 0);
334                 GXNormal1x8(0);
335             }
336         GXEnd();
337     }
338 }
339 
340 /*---------------------------------------------------------------------------*
341     Name:           SetCamera
342 
343     Description:    set view matrix and load projection matrix into hardware
344 
345     Arguments:      cam : pointer to the MyCameraObj structure
346 
347     Returns:        none
348  *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)349 static void SetCamera( MyCameraObj* cam )
350 {
351     cam->cfg.location.x =
352         (f32)cam->zoom * cosf((f32)cam->theta * PI / 180.0F);
353     cam->cfg.location.y =
354         (f32)cam->zoom * 0.2F;
355     cam->cfg.location.z =
356         (f32)cam->zoom * sinf((f32)cam->theta * PI / 180.0F);
357 
358     MTXLookAt(
359         cam->view,
360         &cam->cfg.location,
361         &cam->cfg.up,
362         &cam->cfg.target );
363 
364     MTXFrustum(
365         cam->proj,
366         cam->cfg.top,
367         - (cam->cfg.top),
368         cam->cfg.left,
369         - (cam->cfg.left),
370         cam->cfg.znear,
371         cam->cfg.zfar );
372     GXSetProjection(cam->proj, GX_PERSPECTIVE);
373 }
374 
375 /*---------------------------------------------------------------------------*
376     Name:           SetLight
377 
378     Description:    Set up lights and lighting channel parameters
379 
380     Arguments:      light : pointer to a MyLightObj structure
381                     v     : view matrix
382 
383     Returns:        none
384  *---------------------------------------------------------------------------*/
SetLight(MyLightObj * light,Mtx v)385 void SetLight( MyLightObj* light, Mtx v )
386 {
387     Vec lpos = { 0.0F, 0.0F, 500.0F };
388 
389     DistAttn attn = LightAttnSamples[light->attnType];
390 
391     // Multiplied by view matrix
392     MTXMultVec(v, &lpos, &lpos);
393 
394     GXInitLightPos(&light->lobj, lpos.x, lpos.y, lpos.z);
395     GXInitLightAttn(
396         &light->lobj,
397         1.0F,
398         0.0F,
399         0.0F,
400         attn.k0,
401         attn.k1,
402         attn.k2 );
403     GXInitLightColor(&light->lobj, WHITE);
404     GXLoadLightObjImm(&light->lobj, GX_LIGHT0);
405 
406     GXSetNumChans(1); // number of active color channels
407     GXSetChanCtrl(
408         GX_COLOR0A0,
409         GX_ENABLE,   // enable channel
410         GX_SRC_REG,  // amb source
411         GX_SRC_REG,  // mat source
412         GX_LIGHT0,   // light mask
413         GX_DF_CLAMP, // diffuse function
414         GX_AF_SPOT);
415     // set up material color
416     GXSetChanMatColor(GX_COLOR0A0, WHITE);
417 }
418 
419 /*---------------------------------------------------------------------------*
420     Name:           DisableLight
421 
422     Description:    Disables lighting
423 
424     Arguments:      none
425 
426     Returns:        none
427  *---------------------------------------------------------------------------*/
DisableLight(void)428 void DisableLight( void )
429 {
430     GXSetNumChans(1);
431     GXSetChanCtrl(
432         GX_COLOR0A0,
433         GX_DISABLE,  // disable channel
434         GX_SRC_REG,  // amb source
435         GX_SRC_REG,  // mat source
436         0,           // light mask
437         GX_DF_NONE,  // diffuse function
438         GX_AF_NONE);
439 }
440 
441 /*---------------------------------------------------------------------------*
442     Name:           PrintIntro
443 
444     Description:    Prints the directions on how to use this demo.
445 
446     Arguments:      none
447 
448     Returns:        none
449  *---------------------------------------------------------------------------*/
PrintIntro(void)450 static void PrintIntro( void )
451 {
452     OSReport("\n\n");
453     OSReport("******************************************************\n");
454     OSReport("lit-dist-atn: distance attenuation test\n");
455     OSReport("******************************************************\n");
456     OSReport("to quit hit the start button\n");
457     OSReport("\n");
458     OSReport("Stick        : Move camera position\n");
459     OSReport("L/R Triggers : Change the distance attenuation value set\n");
460     OSReport("******************************************************\n");
461     OSReport("\n\n");
462 }
463 
464 /*---------------------------------------------------------------------------*
465     Name:           StatusMessage
466 
467     Description:    Prints the current status.
468  *---------------------------------------------------------------------------*/
StatusMessage(u32 index)469 static void StatusMessage( u32 index )
470 {
471     OSReport(" k0 = %f ", LightAttnSamples[index].k0);
472     OSReport(" k1 = %f ", LightAttnSamples[index].k1);
473     OSReport(" k2 = %f ", LightAttnSamples[index].k2);
474 
475     OSReport("\n");
476 }
477 
478 /*============================================================================*/
479