1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     pix-logic.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_ZNEAR    0.0f    // near plane Z in screen coordinates
19 #define SCREEN_ZFAR     1.0f    // far  plane Z in screen coordinates
20 #define ZBUFFER_MAX     0x00ffffff
21 
22 /*---------------------------------------------------------------------------*
23    Typedefs
24  *---------------------------------------------------------------------------*/
25 typedef struct
26 {
27     char*               title;
28     GXBlendMode type;
29     GXBlendFactor               sfactor;
30     GXBlendFactor               dfactor;
31     GXLogicOp           logic;
32 }   Blend;
33 
34 typedef struct
35 {
36     Model*      model;
37     Camera*     camera;
38     ViewPort*   viewport;
39     Blend*      blend;
40     u32         flag;
41 }   Scene;
42 
43 #define SCENE_DRAWN     (1<<0)
44 #define SCENE_CURSOR    (1<<1)
45 
46 /*---------------------------------------------------------------------------*
47    Forward references
48  *---------------------------------------------------------------------------*/
49 void    SceneDraw( Scene* );
50 void    SceneDrawInfo( Scene* );
51 void    SceneControl( DEMOPadStatus* );
52 static  void PrintIntro( void );
53 
54 /*---------------------------------------------------------------------------*
55    Rendering parameters
56  *---------------------------------------------------------------------------*/
57 Camera  myCamera =
58 {
59     { 0.0f,   0.0f, 30.0f },    // position
60     { 0.0f,1000.0f,  0.0f },    // target
61     { 0.0f,   0.0f,  1.0f },    // upVec
62        33.3f,                   // fovy
63        16.0f,                   // near plane Z in camera coordinates
64      1024.0f,                   // far  plane Z in camera coordinates
65 };
66 
67 ViewPort myViewPort[] =
68 {
69     // full size (these are adjusted in main)
70     { 0,         0,         SCREEN_WD*2, SCREEN_HT*2 },
71     // half size
72     { 0,         0,         SCREEN_WD,   SCREEN_HT },
73     { 0,         SCREEN_HT, SCREEN_WD,   SCREEN_HT },
74     { SCREEN_WD, 0,         SCREEN_WD,   SCREEN_HT },
75     { SCREEN_WD, SCREEN_HT, SCREEN_WD,   SCREEN_HT },
76 };
77 
78 Blend   myBlend[] =
79 {
80  { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_COPY    },
81  { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_INVCOPY },
82  { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_XOR     },
83  { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_AND     },
84 };
85 
86 GXColor sceneBgColor = { 32, 32, 128,255};
87 
88 Scene   myScene[] =
89 {
90     { &cmModel[3], &myCamera, &myViewPort[0], &myBlend[0], 0 },
91     { &cmModel[3], &myCamera, &myViewPort[1], &myBlend[0], 0 },
92     { &cmModel[3], &myCamera, &myViewPort[2], &myBlend[1], 0 },
93     { &cmModel[3], &myCamera, &myViewPort[3], &myBlend[2], 0 },
94     { &cmModel[3], &myCamera, &myViewPort[4], &myBlend[3], 0 },
95 };
96 
97 #define NUMSCENE        (sizeof(myScene)/sizeof(Scene))
98 
99 /*---------------------------------------------------------------------------*
100    Application main loop
101  *---------------------------------------------------------------------------*/
main(void)102 void    main ( void )
103 {
104     GXRenderModeObj *rmp;
105     u32     i;
106 
107     // initialize render settings and set clear color for first frame
108     DEMOInit( NULL );  // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
109     GXInvalidateTexAll( );
110     GXSetCopyClear( sceneBgColor, ZBUFFER_MAX );
111 
112     // Perform dummy copy operation to clear eFB by specified color
113     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
114 
115     rmp = DEMOGetRenderModeObj();
116 
117     for(i = 0; i < 5; i++)
118     {
119         myViewPort[i].xorg   *= rmp->fbWidth/2;
120         myViewPort[i].yorg   *= rmp->efbHeight/2;
121         myViewPort[i].width  *= rmp->fbWidth/2;
122         myViewPort[i].height *= rmp->efbHeight/2;
123     }
124 
125     PrintIntro();
126 
127     while( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
128     {
129         // get pad status
130         DEMOPadRead( );
131         // General control & model animation
132         SceneControl( &DemoPad[0] );
133         cmModelAnime( &DemoPad[0], &myCamera );
134 
135         // Draw scene
136         DEMOBeforeRender( );
137         for ( i = 0; i < NUMSCENE; i ++ )
138         {
139             SceneDraw( &myScene[i] );
140         }
141         DEMODoneRender( );
142     }
143 
144     OSHalt("End of test");
145 }
146 
147 /*---------------------------------------------------------------------------*
148    Functions
149  *---------------------------------------------------------------------------*/
150 
151 //============================================================================
152 //  Scene
153 //============================================================================
154 typedef struct
155 {
156     GXLogicOp   ops;
157     char*       name;
158 }   Logic;
159 
160 // Bogus id number to test non-logic (subtract) mode
161 #define GX_LO_XXX   (GXLogicOp)0xFFFFFFFF
162 
163 Logic   myLogic[] = {
164  { GX_LO_CLEAR,   "CLEAR    0"            },
165  { GX_LO_SET,     "SET      1"            },
166  { GX_LO_COPY,    "COPY     Src"          },
167  { GX_LO_INVCOPY, "INVCOPY  ~Src"         },
168  { GX_LO_NOOP,    "NOOP     Dst"          },
169  { GX_LO_INV,     "INV      ~Dst"         },
170  { GX_LO_AND,     "AND      Src & Dst"    },
171  { GX_LO_NAND,    "NAND     ~(Src & Dst)" },
172  { GX_LO_OR,      "OR       Src | Dst"    },
173  { GX_LO_NOR,     "NOR      ~(Src & Dst)" },
174  { GX_LO_XOR,     "XOR      Src ^ Dst"    },
175  { GX_LO_EQUIV,   "EQUIV    ~(Src ^ Dst)" },
176  { GX_LO_REVAND,  "REVAND   Src & ~Dst"   },
177  { GX_LO_INVAND,  "INVAND   ~Src ^ Dst"   },
178  { GX_LO_REVOR,   "REVOR    Src | ~Dst"   },
179  { GX_LO_INVOR,   "INVOR    ~Src | Dst"   },
180  { GX_LO_XXX,     "SUB      Dst - Src"    },    // subtract mode test
181 };
182 
183 #define NUMLOGICS       (sizeof(myLogic)/sizeof(Logic))
184 
185 /*---------------------------------------------------------------------------*
186     Name:           SceneDrawBegin
187     Description:    Update the perspective and view matrices.
188     Arguments:      Scene* s
189     Returns:        none
190  *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)191 void    SceneDraw( Scene* s )
192 {
193     Camera*     c = s->camera;
194     ViewPort*   v = s->viewport;
195     Blend*      b = s->blend;
196     float       aspect = (float) (4.0 / 3.0);
197     GXColor     black = {0, 0, 0, 0};
198 
199     // Check if drawn flag
200     if ( !(s->flag & SCENE_DRAWN) ) return;
201 
202     // Set Perspective Viewing frustum
203     MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar );
204     GXSetProjection( c->projMtx, GX_PERSPECTIVE );
205 
206     // Set CameraView matrix
207     MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
208 
209     // Set Viewport
210     GXSetViewport( v->xorg, v->yorg, v->width, v->height,
211                    SCREEN_ZNEAR, SCREEN_ZFAR );
212     GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height );
213 
214     // Set Pixel Processing Mode
215     GXSetFog( GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, black );
216     GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE );
217 
218     // Set blend
219     if ( b->logic >= GX_LO_CLEAR && b->logic <= GX_LO_SET )
220         GXSetBlendMode( b->type, b->sfactor, b->dfactor, b->logic );
221     else
222         GXSetBlendMode( b->type, b->sfactor, b->dfactor, GX_LO_CLEAR );
223 
224     // Draw model
225     if ( s->model->draw ) (*s->model->draw)( c );
226 
227     // draw information
228     SceneDrawInfo( s );
229     return;
230 }
231 
232 /*---------------------------------------------------------------------------*
233     Name:           SceneDrawInfo
234     Description:    Draw scene information
235     Arguments:
236     Returns:        none
237  *---------------------------------------------------------------------------*/
SceneDrawInfo(Scene * s)238 void    SceneDrawInfo( Scene* s )
239 {
240     Camera*     c = s->camera;
241     ViewPort*   v = s->viewport;
242     Blend*      b = s->blend;
243     s32         lid;
244 
245     // Draw parameters to the window
246     DEMOInitCaption( DM_FT_OPQ, v->width, v->height );
247     if ( b->title )
248     {
249         DEMOPuts( 20, 12, 0, b->title );
250     }
251     else
252     {
253         // get logic id
254         for ( lid = NUMLOGICS-1; lid > 0; lid -- )
255         {
256             if ( b->logic == myLogic[lid].ops ) break;
257         }
258         DEMOPuts( 20, 12, 0, myLogic[lid].name );
259     }
260 
261     // Draw cursor
262     if ( s->flag & SCENE_CURSOR ) DEMOPuts( 12, 12,0, "\x7f" );
263 
264     return;
265 }
266 
267 /*---------------------------------------------------------------------------*
268     Name:           SceneControl
269     Description:    user interface for parameter control
270     Arguments:
271     Returns:        none
272  *---------------------------------------------------------------------------*/
SceneControl(DEMOPadStatus * pad)273 void    SceneControl( DEMOPadStatus* pad )
274 {
275     static  s32 zoomMode = 0;
276     static  s32 cursor   = 0;
277     static  u32 modelId  = 3;
278 
279     s32     i, lid;
280     Scene*  s;
281     Blend*  b;
282 
283     //  Validate animation
284     cmModel[modelId].flag = MODEL_REFERRED;
285 
286     // zoom mode
287     if ( pad->buttonDown & PAD_BUTTON_A ) zoomMode ^= 1;
288 
289     if ( zoomMode )
290     {
291         //
292         // *** zoom mode
293         //
294 
295         // show specified scene in full screen and put cursor
296         s = &myScene[cursor+1];
297         b = s->blend;
298         myScene[0].blend = b;
299         myScene[0].flag  = SCENE_DRAWN | SCENE_CURSOR;
300 
301         // turn off another window
302         for ( i = 1; i < NUMSCENE; i ++ )
303         {
304             myScene[i].flag = 0;
305         }
306 
307         // get logic id
308         for ( lid = NUMLOGICS-1; lid > 0; lid -- )
309         {
310             if ( b->logic == myLogic[lid].ops ) break;
311         }
312 
313         // change blend parameter
314         if ( pad->dirsNew & ( DEMO_STICK_LEFT  | DEMO_STICK_UP   ) )
315         {
316             if ( lid > 0 ) lid --;
317         }
318         if ( pad->dirsNew & ( DEMO_STICK_RIGHT | DEMO_STICK_DOWN ) )
319         {
320             if ( lid < NUMLOGICS-1 ) lid ++;
321         }
322 
323         // set parameter
324         b->logic = myLogic[lid].ops;
325 
326         // the last bogus id is used for testing subtract mode
327         if ( b->logic == GX_LO_XXX )
328         {
329             b->type = GX_BM_SUBTRACT;
330         }
331         else
332         {
333             b->type = GX_BM_LOGIC;
334         }
335     }
336     else
337     {
338         //
339         // *** catalog mode
340         //
341 
342         // choose a scene.
343         if ( pad->dirsNew & DEMO_STICK_LEFT  ) cursor &= ~2; // left
344         if ( pad->dirsNew & DEMO_STICK_RIGHT ) cursor |=  2; // right
345         if ( pad->dirsNew & DEMO_STICK_UP    ) cursor &= ~1; // up
346         if ( pad->dirsNew & DEMO_STICK_DOWN  ) cursor |=  1; // down
347 
348         // show 4 small windows
349         for ( i = 1; i < 5; i ++ )
350         {
351             myScene[i].flag = SCENE_DRAWN;
352         }
353 
354         // turn off large window
355         myScene[0].flag = 0;
356 
357         // set cursor
358         s = &myScene[cursor+1];
359         s->flag |= SCENE_CURSOR;
360     }
361     return;
362 }
363 
364 /*---------------------------------------------------------------------------*
365     Name:           PrintIntro
366 
367     Description:    Prints the directions on how to use this demo.
368 
369     Arguments:      none
370 
371     Returns:        none
372  *---------------------------------------------------------------------------*/
PrintIntro(void)373 static void PrintIntro( void )
374 {
375     OSReport("\n\n");
376     OSReport("************************************************\n");
377     OSReport("pix-logic: logic-ops test\n");
378     OSReport("************************************************\n");
379     OSReport("to quit hit the menu button\n");
380     OSReport("\n");
381     OSReport("  Stick X/Y    : move cursor, change option\n");
382     OSReport("  A button     : toggle zoom mode\n");
383     OSReport("************************************************\n\n");
384 }
385 
386 
387 /*======== End of pix-logic.c ========*/
388