1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     pix-fog.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 #include <demo.h>
14 #include <math.h>       // for cosf(), sinf()
15 #include "cmn-model.h"
16 
17 #define SCREEN_WD       1       // Dummy - actual value filled at runtime
18 #define SCREEN_HT       1       // Dummy - actual value filled at runtime
19 #define SCREEN_ZNEAR    0.0f    // near plane Z in screen coordinates
20 #define SCREEN_ZFAR     1.0f    // far  plane Z in screen coordinates
21 #define ZBUFFER_MAX     0x00ffffff
22 
23 #define Clamp(val,min,max) \
24     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
25 
26 /*---------------------------------------------------------------------------*
27    Typedefs
28  *---------------------------------------------------------------------------*/
29 typedef struct
30 {
31     char*       title;
32     GXFogType   type;
33     f32         startz;
34     f32         endz;
35     GXColor     color;
36 }   Fog;
37 
38 typedef struct
39 {
40     Model*      model;
41     Camera*     camera;
42     ViewPort*   viewport;
43     Fog*        fog;
44     u32         flag;
45 }   Scene;
46 
47 #define SCENE_DRAWN     (1<<0)
48 #define SCENE_CURSOR    (1<<1)
49 #define SCENE_LCURSOR0  (1<<2)
50 #define SCENE_LCURSOR1  (1<<3)
51 
52 typedef struct {                // for z coord tag data
53   f32     x, y, z, dir;
54   GXColor color;
55 } Obj1;
56 
57 /*---------------------------------------------------------------------------*
58    Forward references
59  *---------------------------------------------------------------------------*/
60 void    SceneDraw( Scene* );
61 void    SceneDrawInfo( Scene* );
62 void    SceneControl( DEMOPadStatus* );
63 static  void PrintIntro( void );
64 
65 /*---------------------------------------------------------------------------*
66    Rendering parameters
67  *---------------------------------------------------------------------------*/
68 Camera  myCamera =
69 {
70     { 0.0f,   0.0f, 30.0f },    // position
71     { 0.0f,1000.0f,  0.0f },    // target
72     { 0.0f,   0.0f,  1.0f },    // upVec
73        33.3f,                   // fovy
74        16.0f,                   // near plane Z in camera coordinates
75      1024.0f,                   // far  plane Z in camera coordinates
76 };
77 
78 ViewPort myViewPort[] =
79 {
80     // full size (these are adjusted in main)
81     { 0,         0,         SCREEN_WD*2, SCREEN_HT*2 },
82     // half size
83     { 0,         0,         SCREEN_WD,   SCREEN_HT },
84     { 0,         SCREEN_HT, SCREEN_WD,   SCREEN_HT },
85     { SCREEN_WD, 0,         SCREEN_WD,   SCREEN_HT },
86     { SCREEN_WD, SCREEN_HT, SCREEN_WD,   SCREEN_HT },
87 };
88 
89 Fog     myFog[] =
90 {
91     // title      type            startz   endz    color
92     { "NONE",     GX_FOG_NONE,      0.0f,    0.0f, {128,128,128,255} },
93     { "LINEAR",   GX_FOG_LIN,      16.0f, 1024.0f, {128,128,128,255} },
94     { "EXP",      GX_FOG_EXP,      16.0f, 1024.0f, {128,128,128,255} },
95     { "EXP2",     GX_FOG_EXP2,     16.0f, 1024.0f, {128,128,128,255} },
96     { "REV-EXP",  GX_FOG_REVEXP,   16.0f, 1024.0f, {128,128,128,255} },
97     { "REV-EXP2", GX_FOG_REVEXP2,  16.0f, 1024.0f, {128,128,128,255} },
98 };
99 
100 GXColor sceneBgColor = {128,128,128,255};
101 
102 Scene   myScene[] =
103 {
104     { &cmModel[0], &myCamera, &myViewPort[0], &myFog[0], 0 },
105     { &cmModel[0], &myCamera, &myViewPort[1], &myFog[1], 0 },
106     { &cmModel[0], &myCamera, &myViewPort[2], &myFog[2], 0 },
107     { &cmModel[0], &myCamera, &myViewPort[3], &myFog[3], 0 },
108     { &cmModel[0], &myCamera, &myViewPort[4], &myFog[0], 0 },
109 };
110 
111 #define NUMSCENE        (sizeof(myScene)/sizeof(Scene))
112 
113 GXBool fogAdjust = GX_FALSE;
114 
115 extern Obj1 *obj1;
116 extern Obj1 obj1_data[10];
117 
118 Obj1 obj1_alt_data[10] = {
119   {-291.0f, -40.0f,  500.0f,  1.0f, {255,255,255,255} },
120   {-227.0f, -20.0f,  500.0f,  1.0f, {255,255,  0,255} },
121   {-163.0f, -40.0f,  500.0f,  1.0f, {255,  0,255,255} },
122   { -99.0f, -20.0f,  500.0f,  1.0f, {  0,255,255,255} },
123   { -35.0f, -40.0f,  500.0f,  1.0f, {255,  0,  0,255} },
124   {  33.0f, -20.0f,  500.0f,  1.0f, {  0,  0,255,255} },
125   {  97.0f, -40.0f,  500.0f,  1.0f, {  0,255,  0,255} },
126   { 161.0f, -20.0f,  500.0f,  1.0f, {255,255,128,255} },
127   { 225.0f, -40.0f,  500.0f,  1.0f, {255,128,255,255} },
128   { 289.0f, -20.0f,  500.0f,  1.0f, {128,255,255,255} },
129 };
130 
131 Obj1 obj1_cir_data[10] = {
132   { 0.0f, -41.0f, 0.0f,  1.0f, {255,255,255,255} },
133   { 0.0f, -21.0f, 0.0f,  1.0f, {255,255,  0,255} },
134   { 0.0f, -41.0f, 0.0f,  1.0f, {255,  0,255,255} },
135   { 0.0f, -21.0f, 0.0f,  1.0f, {  0,255,255,255} },
136   { 0.0f, -41.0f, 0.0f,  1.0f, {255,  0,  0,255} },
137   { 0.0f, -21.0f, 0.0f,  1.0f, {  0,  0,255,255} },
138   { 0.0f, -41.0f, 0.0f,  1.0f, {  0,255,  0,255} },
139   { 0.0f, -21.0f, 0.0f,  1.0f, {255,255,128,255} },
140   { 0.0f, -41.0f, 0.0f,  1.0f, {255,128,255,255} },
141   { 0.0f, -21.0f, 0.0f,  1.0f, {128,255,255,255} },
142 };
143 
144 /*---------------------------------------------------------------------------*
145    Application main loop
146  *---------------------------------------------------------------------------*/
main(void)147 void    main ( void )
148 {
149     GXRenderModeObj *rmp;
150     u32   i;
151     f32 ang;
152 
153     // initialize obj1 circle data
154     for(i=0; i<10; i++)
155     {
156         ang = (i * 44.4f/10.0f - 44.4f*9.0f/20.0f) * 3.1415926535f/180.0f;
157         obj1_cir_data[i].x = sinf(ang)*500.0f;
158         obj1_cir_data[i].z = cosf(ang)*500.0f;
159     }
160 
161     // initialize render settings and set clear color for first frame
162     DEMOInit(NULL);
163     GXInvalidateTexAll( );
164     GXSetCopyClear( sceneBgColor, ZBUFFER_MAX );
165 
166     // Perform dummy copy operation to clear eFB by specified color
167     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
168 
169     rmp = DEMOGetRenderModeObj();
170 
171     for(i = 0; i < 5; i++)
172     {
173         myViewPort[i].xorg   *= rmp->fbWidth/2;
174         myViewPort[i].yorg   *= rmp->efbHeight/2;
175         myViewPort[i].width  *= rmp->fbWidth/2;
176         myViewPort[i].height *= rmp->efbHeight/2;
177     }
178 
179     PrintIntro();
180 
181     while( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
182     {
183         // get pad status
184         DEMOPadRead( );
185         // General control & model animation
186         SceneControl( &DemoPad[0] );
187         cmModelAnime( &DemoPad[0], &myCamera );
188 
189         // Draw scene
190         DEMOBeforeRender( );
191         for ( i = 0; i < NUMSCENE; i ++ )
192         {
193             SceneDraw( &myScene[i] );
194         }
195         DEMODoneRender( );
196     }
197 
198     OSHalt("End of test");
199 }
200 
201 /*---------------------------------------------------------------------------*
202    Functions
203  *---------------------------------------------------------------------------*/
204 
205 //============================================================================
206 //  Scene
207 //============================================================================
208 /*---------------------------------------------------------------------------*
209     Name:           SceneDraw
210     Description:    Update the perspective and view matrices.
211     Arguments:      Scene* s
212     Returns:        none
213  *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)214 void    SceneDraw( Scene* s )
215 {
216     Camera*     c = s->camera;
217     ViewPort*   v = s->viewport;
218     Fog*        f = s->fog;
219     float       aspect = (float) (4.0 / 3.0);
220     GXFogAdjTable fogTable;
221 
222     // Check if drawn flag
223     if ( !(s->flag & SCENE_DRAWN) ) return;
224 
225     // Set Perspective Viewing frustum
226     MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar );
227     GXSetProjection( c->projMtx, GX_PERSPECTIVE );
228 
229     // Set CameraView matrix
230     MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
231 
232     // Set Viewport
233     GXSetViewport( v->xorg, v->yorg, v->width, v->height,
234                    SCREEN_ZNEAR, SCREEN_ZFAR );
235     GXSetScissor( (u32)v->xorg,  (u32)v->yorg, (u32)v->width, (u32)v->height );
236 
237     // Set Pixel Processing Mode
238     GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
239     GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE );
240 
241     // Set fog and clear color
242     GXSetFog( f->type, f->startz, f->endz, c->znear, c->zfar, f->color );
243     sceneBgColor = f->color;
244 
245     if (fogAdjust)
246     {
247         GXInitFogAdjTable(&fogTable, (u16) v->width, c->projMtx);
248         GXSetFogRangeAdj(GX_ENABLE, (u16) (v->xorg + (v->width/2)), &fogTable);
249     }
250     else
251     {
252         GXSetFogRangeAdj(GX_DISABLE, 0, NULL);
253     }
254 
255     // Draw model
256     if ( s->model->draw ) (*s->model->draw)( c );
257 
258     // draw information
259     SceneDrawInfo( s );
260 
261     return;
262 }
263 
264 /*---------------------------------------------------------------------------*
265     Name:           SceneDrawInfo
266     Description:    Draw scene information
267     Arguments:
268     Returns:        none
269  *---------------------------------------------------------------------------*/
SceneDrawInfo(Scene * s)270 void    SceneDrawInfo( Scene* s )
271 {
272     Camera*     c = s->camera;
273     ViewPort*   v = s->viewport;
274     Fog*        f = s->fog;
275     s16         ypos;
276 
277     // Draw parameters to the window
278     DEMOInitCaption( DM_FT_OPQ, v->width, v->height );
279     DEMOPuts( 20, 12, 0, f->title );
280 
281     if (fogAdjust)
282         DEMOPuts( 20, 20, 0, "Adjust" );
283 
284     ypos = 12;
285     if ( f->startz > 0.0f )
286     {
287         DEMOPrintf( 96, 12, 0, "STARTZ %7.2f", f->startz );
288         ypos += 8;
289     }
290     if ( f->endz   > 0.0f )
291     {
292          DEMOPrintf( 96, ypos, 0, "ENDZ   %7.2f", f->endz );
293     }
294 
295     // Draw cursor for full screen
296     if ( s->flag & SCENE_CURSOR   ) DEMOPuts(12,   12, 0, "\x7f" );
297     if ( s->flag & SCENE_LCURSOR0 ) DEMOPuts(88,   12, 0, "\x7f" );
298     if ( s->flag & SCENE_LCURSOR1 ) DEMOPuts(88, ypos, 0, "\x7f" );
299 
300     return;
301 }
302 
303 /*---------------------------------------------------------------------------*
304     Name:           SceneControl
305     Description:    user interface for parameter control
306     Arguments:
307     Returns:        none
308  *---------------------------------------------------------------------------*/
SceneControl(DEMOPadStatus * pad)309 void    SceneControl( DEMOPadStatus* pad )
310 {
311     static  s32 zoomMode = 0;
312     static  s32 cursor   = 0;
313     static  s32 range    = 0;
314     static  s32 cursorL  = 0;
315     static  f32 scale    = 1.0f;
316     static  s32 modelId  = 1;
317     s32     i;
318     Fog*    f;
319     Scene*  s;
320 
321     // clear flag
322     cmModel[modelId].flag = 0;
323 
324     // change model
325     if ( pad->buttonDown & PAD_BUTTON_B )
326     {
327         modelId = (modelId == 1) ? 2 : 1;
328     }
329 
330     // set flag
331     cmModel[modelId].flag = MODEL_REFERRED;
332     for ( i = 0; i < NUMSCENE; i ++ )
333     {
334         myScene[i].model = &cmModel[modelId];
335     }
336 
337     // object mode
338     if ( modelId == 1 && pad->buttonDown & PAD_BUTTON_X )
339     {
340         if (obj1 == obj1_data)
341         {
342             obj1 = obj1_alt_data;
343         }
344         else if (obj1 == obj1_alt_data)
345         {
346             obj1 = obj1_cir_data;
347         }
348         else
349         {
350             obj1 = obj1_data;
351         }
352     }
353 
354     // fog adjust mode
355     if ( pad->buttonDown & PAD_BUTTON_Y ) fogAdjust ^= 1;
356 
357     // zoom mode
358     if ( pad->buttonDown & PAD_BUTTON_A ) zoomMode ^= 1;
359 
360     if ( zoomMode )
361     {
362         //
363         // *** zoom mode
364         //
365 
366         // show specified scene in full screen
367         s = &myScene[cursor+1];
368         f = s->fog;
369         myScene[0].fog  = f;
370         myScene[0].flag = SCENE_DRAWN;
371 
372         // turn off another window
373         for ( i = 1; i < NUMSCENE; i ++ )
374         {
375             myScene[i].flag = 0;
376         }
377 
378         // choose a parameter
379         if ( pad->dirsNew & DEMO_STICK_UP )
380         {
381             if ( cursorL > 0 ) cursorL --;      // line cursor '>' move up
382         }
383         if ( pad->dirsNew & DEMO_STICK_DOWN )
384         {
385             if ( cursorL < 1 ) cursorL ++;      // line cursor '>' move down
386         }
387 
388         // skip if invalid item
389         if ( f->startz == 0.0f ) cursorL = 1;  // go to endz   if startz=0
390         if ( f->endz   == 0.0f ) cursorL = 0;  // go to startz if endz=0
391 
392         // set cursor position
393         if ( f->startz > 0.0f || f->endz > 0.0f )
394         {
395             myScene[0].flag |= (SCENE_LCURSOR0 << cursorL);
396 
397         } else {
398 
399 	    return;  // in "NONE" fog mode, no adjustment is possible
400 
401 	}
402 
403         // get scale parameter (velocity)
404         if      ( pad->dirs & DEMO_STICK_LEFT  ) scale *= 1.000002f;
405         else if ( pad->dirs & DEMO_STICK_RIGHT ) scale /= 1.000002f;
406         else                                     scale  = 1.0f;
407 
408         // scale clamping
409         Clamp(scale, 1.0F/1.5F, 1.5F);
410 
411         // multiply scale to the parameter which specified by cursor.
412         if ( cursorL == 0 )
413         {
414             f->startz *= scale;
415             Clamp(f->startz, 0.10F, f->endz);
416         }
417         else
418         {
419             f->endz *= scale;
420             Clamp(f->endz, f->startz, 8192.0F);
421         }
422     }
423     else
424     {
425         //
426         // *** catalog mode
427         //
428 
429         // choose a scene.
430         if ( pad->dirsNew & DEMO_STICK_LEFT )
431         {
432             if ( cursor <  2 ) range = 0;               // shift right
433             cursor &= ~2;                               // go to left
434         }
435         if ( pad->dirsNew & DEMO_STICK_RIGHT )
436         {
437             if ( cursor >= 2 ) range = 2;               // shift left
438             cursor |=  2;                               // go to right
439         }
440         if ( pad->dirsNew & DEMO_STICK_UP   ) cursor &= ~1; // up
441         if ( pad->dirsNew & DEMO_STICK_DOWN ) cursor |=  1; // down
442 
443         // show 4 small windows
444         for ( i = 1; i < 5; i ++ )
445         {
446             myScene[i].fog  = &myFog[i+range-1];
447             myScene[i].flag = SCENE_DRAWN;
448         }
449 
450         // turn off large window
451         myScene[0].flag = 0;
452 
453         // set cursor
454         s = &myScene[cursor+1];
455         s->flag |= SCENE_CURSOR;
456     }
457     return;
458 }
459 
460 /*---------------------------------------------------------------------------*
461     Name:           PrintIntro
462 
463     Description:    Prints the directions on how to use this demo.
464 
465     Arguments:      none
466 
467     Returns:        none
468  *---------------------------------------------------------------------------*/
PrintIntro(void)469 static void PrintIntro( void )
470 {
471     OSReport("\n\n");
472     OSReport("************************************************\n");
473     OSReport("pix-fog: fog test\n");
474     OSReport("************************************************\n");
475     OSReport("to quit hit the menu button\n");
476     OSReport("\n");
477     OSReport("  Stick X/Y    : move cursor, select option\n");
478     OSReport("  A button     : toggle zoom mode\n");
479     OSReport("  B button     : change model\n");
480     OSReport("  X button     : change tags\n");
481     OSReport("  Y button     : toggle range adjust\n");
482     OSReport("  R trigger    : toggle animation\n");
483     OSReport("************************************************\n\n");
484 }
485 
486 
487 /*======== End of pix-fog.c ========*/
488