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