1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: pix-a-comp.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 "cmn-model.h"
15
16 #define SCREEN_WD 1 // Dummy - actual value filled at runtime
17 #define SCREEN_HT 1 // Dummy - actual value filled at runtime
18 #define SCREEN_DEPTH 128.0f
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 /*---------------------------------------------------------------------------*
24 Typedefs
25 *---------------------------------------------------------------------------*/
26 typedef struct
27 {
28 char* title;
29 // GXSetAlphaCompare
30 GXCompare comp0;
31 u8 ref0;
32 GXAlphaOp op;
33 GXCompare comp1;
34 u8 ref1;
35 // GXSetAlphaUpdate
36 GXBool update_enable;
37 } AlphaMode;
38
39 typedef struct
40 {
41 // Model* model;
42 Camera* camera;
43 ViewPort* viewport;
44 AlphaMode* alphamode;
45 u32 flag;
46 } Scene;
47
48 #define SCENE_DRAWN (1<<0)
49 #define SCENE_CURSOR (1<<1)
50 #define SCENE_LCURSOR0 (1<<2)
51 #define SCENE_LCURSOR1 (1<<3)
52 #define SCENE_LCURSOR2 (1<<4)
53 #define SCENE_LCURSOR3 (1<<5)
54 #define SCENE_LCURSOR4 (1<<6)
55
56 /*---------------------------------------------------------------------------*
57 Forward references
58 *---------------------------------------------------------------------------*/
59 void SceneDraw( Scene* );
60 void SceneDrawInfo( Scene* );
61 void SceneControl( void );
62 void myDrawModel( AlphaMode*, s32, s32 );
63 static void PrintIntro( void );
64
65 /*---------------------------------------------------------------------------*
66 Rendering parameters
67 *---------------------------------------------------------------------------*/
68 Camera myCamera =
69 {
70 { 0.0f, 0.0f, 30.0f }, // position (ignored in this demo)
71 { 0.0f,1000.0f, 0.0f }, // target (ignored in this demo)
72 { 0.0f, 0.0f, 1.0f }, // upVec (ignored in this demo)
73 33.3f, // fovy (ignored in this demo)
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 AlphaMode myAlphaMode[] =
90 {
91 // Title comp0 ref0 op comp1 ref1 update_enable
92 { NULL, GX_ALWAYS, 60, GX_AOP_AND, GX_ALWAYS, 40, GX_TRUE },
93 { NULL, GX_LESS, 60, GX_AOP_AND, GX_ALWAYS, 40, GX_TRUE },
94 { NULL, GX_GREATER, 60, GX_AOP_AND, GX_ALWAYS, 40, GX_TRUE },
95 { NULL, GX_EQUAL, 60, GX_AOP_AND, GX_ALWAYS, 40, GX_TRUE },
96 };
97
98 GXColor sceneBgColor = { 32, 32, 128,255};
99
100 Scene myScene[] =
101 {
102 { /*&cmModel[1],*/ &myCamera, &myViewPort[0], &myAlphaMode[0], 0 },
103 { /*&cmModel[1],*/ &myCamera, &myViewPort[1], &myAlphaMode[0], 0 },
104 { /*&cmModel[1],*/ &myCamera, &myViewPort[2], &myAlphaMode[1], 0 },
105 { /*&cmModel[1],*/ &myCamera, &myViewPort[3], &myAlphaMode[2], 0 },
106 { /*&cmModel[1],*/ &myCamera, &myViewPort[4], &myAlphaMode[3], 0 },
107 };
108
109 #define NUMSCENE (sizeof(myScene)/sizeof(Scene))
110
111 /*---------------------------------------------------------------------------*
112 Application main loop
113 *---------------------------------------------------------------------------*/
main(void)114 void main ( void )
115 {
116 GXRenderModeObj *rmp;
117 u32 i;
118
119 // initialize render settings and set clear color for first frame
120 DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
121 GXInvalidateTexAll( );
122 GXSetCopyClear( sceneBgColor, GX_MAX_Z24 );
123
124 // Perform dummy copy operation to clear eFB by specified color
125 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
126
127 rmp = DEMOGetRenderModeObj();
128
129 for(i = 0; i < 5; i++)
130 {
131 myViewPort[i].xorg *= rmp->fbWidth/2;
132 myViewPort[i].yorg *= rmp->efbHeight/2;
133 myViewPort[i].width *= rmp->fbWidth/2;
134 myViewPort[i].height *= rmp->efbHeight/2;
135 }
136
137 PrintIntro();
138
139 while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
140 {
141 // get pad status
142 DEMOPadRead( );
143 // General control & model animation
144 SceneControl( );
145 // No animation for this model.
146
147 // Draw scene
148 DEMOBeforeRender( );
149 for ( i = 0; i < NUMSCENE; i ++ )
150 {
151 SceneDraw( &myScene[i] );
152 }
153 DEMODoneRender( );
154 }
155
156 OSHalt("End of test");
157 }
158
159 /*---------------------------------------------------------------------------*
160 Functions
161 *---------------------------------------------------------------------------*/
162
163 //============================================================================
164 // Scene
165 //============================================================================
166 typedef struct
167 {
168 GXCompare comp;
169 char* fmt;
170 } AlphaComp;
171
172 AlphaComp myAlphaComp[] =
173 {
174 { GX_NEVER, "A:NEVER" },
175 { GX_LESS, "A < %3d" },
176 { GX_LEQUAL, "A <=%3d" },
177 { GX_EQUAL, "A ==%3d" },
178 { GX_NEQUAL, "A !=%3d" },
179 { GX_GEQUAL, "A >=%3d" },
180 { GX_GREATER, "A > %3d" },
181 { GX_ALWAYS, "A:ALWYS" },
182 };
183
184 typedef struct
185 {
186 GXAlphaOp op;
187 char* name;
188 } AlphaOps;
189
190 AlphaOps myAlphaOps[] =
191 {
192 { GX_AOP_AND, "AND " },
193 { GX_AOP_OR, "OR " },
194 { GX_AOP_XOR, "XOR " },
195 { GX_AOP_XNOR, "XNOR" },
196 };
197
198 #define NUMALPHACOMPS (sizeof(myAlphaComp)/sizeof(AlphaComp))
199 #define NUMALPHAOPS (sizeof(myAlphaOps )/sizeof(AlphaOps ))
200
201 /*---------------------------------------------------------------------------*
202 Name: SceneDraw
203 Description: Draw model
204 Arguments: Scene* s
205 Returns: none
206 *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)207 void SceneDraw( Scene* s )
208 {
209 ViewPort* v = s->viewport;
210 AlphaMode* a = s->alphamode;
211 GXColor black = {0, 0, 0, 0};
212
213 // Check if drawn flag
214 if ( !(s->flag & SCENE_DRAWN) ) return;
215
216 // Set Viewport
217 GXSetViewport( v->xorg, v->yorg, v->width, v->height,
218 SCREEN_ZNEAR, SCREEN_ZFAR );
219 GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height );
220
221 // Pixel processing mode
222 GXSetFog( GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, black );
223 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
224
225 // Set Z Comp Location (after Alpha compare)
226 GXSetZCompLoc( GX_FALSE );
227
228 // Set Alpha Mode
229 GXSetAlphaCompare( a->comp0, a->ref0, a->op, a->comp1, a->ref1 );
230 GXSetAlphaUpdate( a->update_enable );
231
232 // Draw objects
233 myDrawModel(a, (s32)v->width, (s32)v->height );
234
235 // draw information
236 SceneDrawInfo( s );
237 return;
238 }
239
240 /*---------------------------------------------------------------------------*
241 Name: SceneDrawInfo
242 Description: Draw scene information
243 Arguments:
244 Returns: none
245 *---------------------------------------------------------------------------*/
SceneDrawInfo(Scene * s)246 void SceneDrawInfo( Scene* s )
247 {
248 Camera* c = s->camera;
249 ViewPort* v = s->viewport;
250 AlphaMode* a = s->alphamode;
251 s32 lid0, lid1, oid;
252
253 // Temporary settings for drawing captions
254 GXSetAlphaCompare( GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0 );
255
256 // Draw parameters to the window
257 DEMOInitCaption( DM_FT_XLU, v->width, v->height );
258 if ( a->title )
259 {
260 DEMOPuts( 10, 2, 0, a->title );
261 }
262 else
263 {
264 // get alpha comp id and alpha op id
265 for ( lid0 = NUMALPHACOMPS-1; lid0 > 0; lid0 -- )
266 {
267 if ( a->comp0 == myAlphaComp[lid0].comp ) break;
268 }
269 for ( lid1 = NUMALPHACOMPS-1; lid1 > 0; lid1 -- )
270 {
271 if ( a->comp1 == myAlphaComp[lid1].comp ) break;
272 }
273 for ( oid = NUMALPHAOPS-1; oid > 0; oid -- )
274 {
275 if ( a->op == myAlphaOps[oid].op ) break;
276 }
277 DEMOPrintf( 10, 12, 0, myAlphaComp[lid0].fmt, a->ref0 );
278 DEMOPuts ( 74, 12, 0, myAlphaOps[oid].name );
279 DEMOPrintf(114, 12, 0, myAlphaComp[lid1].fmt, a->ref1 );
280 }
281
282 // Draw cursor
283 if ( s->flag & SCENE_CURSOR ) DEMOPuts( 2, 12, 0, "\x7f" );
284 if ( s->flag & SCENE_LCURSOR0 ) DEMOPuts( 26, 20, 0, "^" );
285 if ( s->flag & SCENE_LCURSOR1 ) DEMOPuts( 58, 20, 0, "^" );
286 if ( s->flag & SCENE_LCURSOR2 ) DEMOPuts( 74, 20, 0, "^" );
287 if ( s->flag & SCENE_LCURSOR3 ) DEMOPuts( 130, 20, 0, "^" );
288 if ( s->flag & SCENE_LCURSOR4 ) DEMOPuts( 170, 20, 0, "^" );
289
290 return;
291 }
292
293 /*---------------------------------------------------------------------------*
294 Name: SceneControl
295 Description: user interface for parameter control
296 Arguments:
297 Returns: none
298 *---------------------------------------------------------------------------*/
SceneControl(void)299 void SceneControl( void )
300 {
301 static s32 zoomMode = 0;
302 static s32 cursor = 0;
303 static s32 cursorL = 0;
304 s32 i, lid;
305 Scene* s;
306 AlphaMode* a;
307 GXCompare* comp;
308 u8* ref;
309 u16 buttons, stickDirs;
310
311 buttons = DEMOPadGetButtonDown(0);
312 stickDirs = DEMOPadGetDirsNew(0);
313
314 // zoom mode
315 if ( buttons & PAD_BUTTON_A ) zoomMode ^= 1;
316
317 if ( zoomMode )
318 {
319 //
320 // *** zoom mode
321 //
322
323 // show specified scene in full screen
324 s = &myScene[cursor+1];
325 a = s->alphamode;
326 myScene[0].alphamode = a;
327 myScene[0].flag = SCENE_DRAWN;
328
329 // turn off another window
330 for ( i = 1; i < NUMSCENE; i ++ )
331 {
332 myScene[i].flag = 0;
333 }
334
335 // move cursor
336 if ( stickDirs & DEMO_STICK_LEFT )
337 {
338 if ( cursorL > 0 )
339 {
340 cursorL --;
341 // If ALWAYS or NEVER, skip reference setting 0
342 if ( cursorL == 1 )
343 {
344 if ( a->comp0 == GX_NEVER || a->comp0 == GX_ALWAYS )
345 {
346 cursorL = 0;
347 }
348 }
349 }
350 }
351 if ( stickDirs & DEMO_STICK_RIGHT )
352 {
353 if ( cursorL < 4 )
354 {
355 cursorL ++;
356 // If ALWAYS or NEVER, cannot go reference setting 1
357 if ( cursorL == 4 )
358 {
359 if ( a->comp1 == GX_NEVER || a->comp1 == GX_ALWAYS )
360 {
361 cursorL = 3;
362 }
363 }
364 // If ALWAYS or NEVER, skip reference setting 0
365 else if ( cursorL == 1 )
366 {
367 if ( a->comp0 == GX_NEVER || a->comp0 == GX_ALWAYS )
368 {
369 cursorL = 2;
370 }
371 }
372 }
373 }
374 myScene[0].flag |= (SCENE_LCURSOR0 << cursorL);
375
376 // get alpha mode id and ops id
377 switch ( cursorL )
378 {
379 case 0:
380 case 3:
381 // comp0 or comp1
382 comp = ( cursorL == 0 ) ? &(a->comp0) : &(a->comp1);
383 for ( lid = NUMALPHACOMPS-1; lid > 0; lid -- )
384 {
385 if ( *comp == myAlphaComp[lid].comp ) break;
386 }
387 if ( stickDirs & DEMO_STICK_UP )
388 {
389 if ( lid > 0 ) lid --;
390 }
391 if ( stickDirs & DEMO_STICK_DOWN )
392 {
393 if ( lid < NUMALPHACOMPS-1 ) lid ++;
394 }
395 (*comp) = myAlphaComp[lid].comp;
396 break;
397
398 case 1:
399 case 4:
400 // ref0 or ref1
401 ref = ( cursorL == 1 ) ? &(a->ref0) : &(a->ref1);
402 if ( stickDirs & DEMO_STICK_UP )
403 {
404 if ( (*ref) <= 250 ) (*ref) += 5;
405 }
406 if ( stickDirs & DEMO_STICK_DOWN )
407 {
408 if ( (*ref) >= 5 ) (*ref) -= 5;
409 }
410 break;
411
412 case 2:
413 // op
414 for ( lid = NUMALPHAOPS-1; lid > 0; lid -- )
415 {
416 if ( a->op == myAlphaOps[lid].op ) break;
417 }
418 if ( stickDirs & DEMO_STICK_UP )
419 {
420 if ( lid > 0 ) lid --;
421 }
422 if ( stickDirs & DEMO_STICK_DOWN )
423 {
424 if ( lid < NUMALPHAOPS-1 ) lid ++;
425 }
426 a->op = myAlphaOps[lid].op;
427 break;
428
429 default:
430 // Never reached here
431 break;
432 }
433 }
434 else
435 {
436 //
437 // *** catalog mode
438 //
439
440 // choose a scene.
441 if ( stickDirs & DEMO_STICK_LEFT ) cursor &= ~2; // left
442 if ( stickDirs & DEMO_STICK_RIGHT ) cursor |= 2; // right
443 if ( stickDirs & DEMO_STICK_UP ) cursor &= ~1; // up
444 if ( stickDirs & DEMO_STICK_DOWN ) cursor |= 1; // down
445
446 // show 4 small windows
447 for ( i = 1; i < 5; i ++ )
448 {
449 myScene[i].flag = SCENE_DRAWN;
450 }
451
452 // turn off large window
453 myScene[0].flag = 0;
454
455 // set cursor
456 s = &myScene[cursor+1];
457 s->flag |= SCENE_CURSOR;
458 }
459 return;
460 }
461
462 //============================================================================
463 // Model
464 // Rectangles
465 //============================================================================
466 typedef struct
467 {
468 f32 x0, y0, x1, y1, z;
469 GXColor color;
470 } myModel;
471
472 myModel rect[] =
473 {
474 // x0 y0 x1 y1 z color
475 { 30, 20,170,180, 50, { 64, 64,255, 50 } },
476 { 10, 40,120, 90, 60, { 255, 64, 64, 60 } },
477 { 80,110,190,160, 25, { 64,255, 64, 25 } },
478 { 110, 10,160,120, 75, { 255,255, 64, 75 } },
479 { 40, 80, 90,190, 40, { 64,255,255, 40 } },
480 { 70, 70,130,130, 50, { 255,255,255, 50 } },
481 };
482
483 #define NUMRECTS (sizeof(rect)/sizeof(myModel))
484
485 /*---------------------------------------------------------------------------*
486 Name: myDrawModel
487 Description: draw model
488 Arguments: f32 width : width of viewport
489 f32 height: height of viewport
490 Returns: none
491 *---------------------------------------------------------------------------*/
myDrawModel(AlphaMode * a,s32 width,s32 height)492 void myDrawModel(AlphaMode *a, s32 width, s32 height )
493 {
494 Mtx mtx;
495 s32 i;
496
497 // use constant material color
498 GXSetChanCtrl( GX_COLOR0,
499 GX_FALSE, // enable Channel
500 GX_SRC_REG, // amb source (Don't care)
501 GX_SRC_REG, // mat source
502 GX_LIGHT0, // light mask (Don't care)
503 GX_DF_NONE, // diffuse function (Don't care)
504 GX_AF_NONE ); // atten function (Don't care)
505 GXSetChanCtrl( GX_ALPHA0,
506 GX_FALSE, // enable Channel
507 GX_SRC_REG, // amb source (Don't care)
508 GX_SRC_REG, // mat source
509 GX_LIGHT0, // light mask (Don't care)
510 GX_DF_NONE, // diffuse function (Don't care)
511 GX_AF_NONE ); // atten function (Don't care)
512
513 // set several mode
514 GXSetCullMode( GX_CULL_BACK ); // Cull mode
515
516 // Load tags in point sample mode
517 DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE );
518
519 // Here, use orthographic screen coordinates.
520 // Set normalized 0-200 screen coordinates and reduce z range in MTX0
521 // Set vertex descriptor on VTXFMT1
522 DEMOSetupScrnSpc( width, height, SCREEN_DEPTH );
523 MTXScale( mtx, ((float)width)/200.0f, ((float)height)/200.f, 1.0f );
524 GXLoadPosMtxImm( mtx, GX_PNMTX0 );
525 GXSetVtxAttrFmt( GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0 );
526
527 for ( i = 0; i < NUMRECTS; i ++ )
528 {
529 // Set material color to go through PE stage.
530 GXSetNumChans( 1 );
531 GXSetNumTexGens( 0 ); // # of Tex Gens
532 GXSetNumTevStages( 1 ); // # of Tev Stages
533 GXSetChanMatColor( GX_COLOR0A0, rect[i].color );
534 GXSetTevOrder( GX_TEVSTAGE0,
535 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
536 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
537 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
538
539 // Fill rectangle
540 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
541 GXClearVtxDesc( );
542 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
543 GXBegin( GX_QUADS, GX_VTXFMT1, 4 );
544 GXPosition3f32( rect[i].x0, rect[i].y0, rect[i].z );
545 GXPosition3f32( rect[i].x1, rect[i].y0, rect[i].z );
546 GXPosition3f32( rect[i].x1, rect[i].y1, rect[i].z );
547 GXPosition3f32( rect[i].x0, rect[i].y1, rect[i].z );
548 GXEnd( );
549
550 // Set texture color to go through PE stage and XOR'ed by blender.
551 GXSetNumTexGens( 1 );
552 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
553 GXSetTevOp( GX_TEVSTAGE0, GX_REPLACE );
554 GXSetBlendMode( GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_XOR );
555
556 // Draw tag to show z value as coplanar surface
557 GXSetCoPlanar( GX_TRUE );
558 GXSetAlphaCompare( GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0 );
559 GXSetZMode( GX_TRUE, GX_EQUAL, GX_TRUE );
560 DEMOPrintf( (s16)rect[i].x0, (s16)rect[i].y0,
561 (s16)rect[i].z, "%d", (s32)rect[i].z );
562 GXSetCoPlanar( GX_FALSE );
563 GXSetAlphaCompare( a->comp0, a->ref0, a->op, a->comp1, a->ref1 );
564 }
565 return;
566 }
567
568 /*---------------------------------------------------------------------------*
569 Name: PrintIntro
570
571 Description: Prints the directions on how to use this demo.
572
573 Arguments: none
574
575 Returns: none
576 *---------------------------------------------------------------------------*/
PrintIntro(void)577 static void PrintIntro( void )
578 {
579 OSReport("\n\n");
580 OSReport("************************************************\n");
581 OSReport("pix-a-comp: alpha compare test\n");
582 OSReport("************************************************\n");
583 OSReport("to quit hit the menu button\n");
584 OSReport("\n");
585 OSReport(" Stick X/Y : move cursor\n");
586 OSReport(" A button : toggle zoom mode\n");
587 OSReport("************************************************\n\n");
588 }
589
590
591 /*======== End of pix-a-comp.c ========*/
592