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