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