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