1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     perf-sync.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 
14 #include <demo.h>
15 #include <math.h>
16 
17 
18 /*---------------------------------------------------------------------------*
19    Forward references
20  *---------------------------------------------------------------------------*/
21 
22 void        main            ( void );
23 static void CameraInit      ( Mtx v );
24 static void DrawInit        ( void );
25 static void DrawTick        ( Mtx v );
26 static void AnimTick        ( void );
27 static void PrintIntro      ( void );
28 
29 static void myDrawSyncCallback( u16 token );
30 
31 /*---------------------------------------------------------------------------*
32   Model Data
33  *---------------------------------------------------------------------------*/
34 
35 #define Black   MyColors[0]
36 #define White   MyColors[1]
37 #define Red     MyColors[2]
38 #define Green   MyColors[3]
39 #define Blue    MyColors[4]
40 #define Gray    MyColors[5]
41 
42 GXColor MyColors[] = {
43     {0x00, 0x00, 0x00, 0x00},  // black
44     {0xff, 0xff, 0xff, 0xff},  // white
45     {0xff, 0x00, 0x00, 0xff},  // red
46     {0x00, 0xff, 0x00, 0xff},  // green
47     {0x00, 0x00, 0xff, 0xff},  // blue
48     {0x80, 0x80, 0x80, 0xff}}; // gray
49 
50 
51 typedef enum {
52     CYLINDER = 1,
53     TORUS,
54     CUBE,
55     SPHERE,
56     DODECA,
57     OCTA,
58     ICOSA,
59     SPHERE1,
60     MAX_MODELS
61 } MyModels;
62 
63 char *ModelOpt[] = {
64     "Cylinder",
65     "Torus",
66     "Cube",
67     "Sphere",
68     "Dodeca",
69     "Octa",
70     "Icosa",
71     "Sphere1" };
72 
73 
74 GXLightObj myLight;
75 u32        myCount[MAX_MODELS-1];
76 
77 /*---------------------------------------------------------------------------*
78    Application main loop
79  *---------------------------------------------------------------------------*/
80 
main(void)81 void main ( void )
82 {
83     Mtx         v;   // view matrix
84     u32         i;
85 
86     DEMOInit(NULL);
87 
88     GXSetDrawSyncCallback( myDrawSyncCallback );
89     GXSetGP0Metric(GX_PERF0_CLOCKS);
90 
91     for (i = 0; i < MAX_MODELS-1; i++)
92         myCount[i] = 0;
93 
94     PrintIntro();  // Print demo directions
95 
96     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
97     {
98         DEMOBeforeRender();
99         GXClearGP0Metric(); // clear perf counter
100 
101         CameraInit(v);      // Initialize the camera.
102         DrawInit();         // Define my vertex formats and set array pointers.
103         DrawTick(v);        // Draw the model.
104         DEMODoneRender();   // Wait until everything is drawn.
105 
106         DEMOPadRead();      // Update pad status.
107         AnimTick();         // Update animation.
108     }
109 
110     OSHalt("End of demo");
111 }
112 
113 
114 /*---------------------------------------------------------------------------*
115    Functions
116  *---------------------------------------------------------------------------*/
117 /*---------------------------------------------------------------------------*
118     Name:           CameraInit
119 
120     Description:    Initialize the projection matrix and load into hardware.
121                     Initialize the view matrix.
122 
123     Arguments:      v      view matrix
124 
125     Returns:        none
126  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)127 static void CameraInit ( Mtx v )
128 {
129     Mtx44   p;      // projection matrix
130     Vec     up      = {0.0F, 1.0F, 0.0F};
131     Vec     camLoc  = {0.0F, 0.0F, 800.0F};
132     Vec     objPt   = {0.0F, 0.0F, -100.0F};
133     f32     left    = 240.0F;
134     f32     top     = 320.0F;
135     f32     znear   = 500.0F;
136     f32     zfar    = 2000.0F;
137 
138     MTXFrustum(p, left, -left, -top, top, znear, zfar);
139     GXSetProjection(p, GX_PERSPECTIVE);
140 
141     MTXLookAt(v, &camLoc, &up, &objPt);
142 }
143 
144 /*---------------------------------------------------------------------------*
145     Name:           DrawInit
146 
147     Description:    Initializes the vertex attribute format 0, and sets
148                     the array pointers and strides for the indexed data.
149 
150     Arguments:      none
151 
152     Returns:        none
153  *---------------------------------------------------------------------------*/
DrawInit(void)154 static void DrawInit( void )
155 {
156     // for generated models
157     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
158     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
159     GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
160 
161     //
162     // set up light parameters
163     //
164 
165     GXInitLightPos(&myLight, 0.0F, 0.0F, 0.0F);
166     GXInitLightColor(&myLight, White);
167     GXLoadLightObjImm(&myLight, GX_LIGHT0);
168 }
169 
170 
171 /*---------------------------------------------------------------------------*
172     Name:           DrawModel
173 
174     Description:    Draw one of the available models
175 
176     Arguments:      none
177 
178     Returns:        none
179  *---------------------------------------------------------------------------*/
DrawModel(MyModels model)180 static void DrawModel(MyModels model)
181 {
182     GXClearVtxDesc();
183     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
184     GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
185 
186     if (model == CYLINDER)
187         GXDrawCylinder(16);
188     else if (model == TORUS)
189         GXDrawTorus(0.375F, 12, 16);
190     else if (model == SPHERE)
191         GXDrawSphere(8, 16);
192     else if (model == CUBE)
193         GXDrawCube();
194     else if (model == DODECA)
195         GXDrawDodeca();
196     else if (model == OCTA)
197         GXDrawOctahedron();
198     else if (model == ICOSA)
199         GXDrawIcosahedron();
200     else if (model == SPHERE1)
201         GXDrawSphere1(2);
202 }
203 
204 
205 /*---------------------------------------------------------------------------*
206     Name:           DrawTick
207 
208     Description:    Draw the model once.
209                     GXInit makes GX_PNMTX0 the default matrix.
210 
211     Arguments:      v        view matrix
212 
213     Returns:        none
214  *---------------------------------------------------------------------------*/
DrawTick(Mtx v)215 static void DrawTick( Mtx v )
216 {
217     static u32  rot = 60;
218     static u32  axisc = 0;
219     char axis[3] = {'x', 'y', 'z'};
220 
221     Mtx  ms;  // Model matrix. scale
222     Mtx  mr;  // Model matrix. rotate
223     Mtx  mt;  // Model matrix. translate
224     Mtx  mv;  // Modelview matrix.
225     Mtx  mvi; // Modelview matrix.
226 
227     // Enable Z compare.  Have to reset because DEMOPrintStats turns off
228     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
229 
230     // render mode = one color / no texture
231     GXSetNumTexGens(0);
232     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
233     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
234 
235     //
236     // set up channel control
237     //
238     GXSetNumChans(1); // number of color channels
239 
240     GXSetChanCtrl(
241         GX_COLOR0,
242         GX_TRUE,    // enable channel
243         GX_SRC_REG,  // amb source
244         GX_SRC_REG,  // mat source
245         GX_LIGHT0,   // light mask
246         GX_DF_CLAMP, // diffuse function
247         GX_AF_NONE);
248 
249     GXSetChanCtrl(
250         GX_ALPHA0,
251         FALSE,       // enable channel
252         GX_SRC_REG,  // amb source
253         GX_SRC_REG,  // mat source
254         GX_LIGHT0,   // light mask
255         GX_DF_NONE,  // diffuse function
256         GX_AF_NONE);
257 
258     // set up ambient color
259     GXSetChanAmbColor(GX_COLOR0, Black);
260     GXSetChanAmbColor(GX_ALPHA0, White);
261     // set up material color
262     GXSetChanMatColor(GX_COLOR0A0, Green);
263 
264     // Draw models
265     MTXScale(ms, 100.0F, 100.0F, 100.0F);
266     MTXConcat(v, ms, mv);
267     MTXRotDeg(mr, axis[(axisc)%3], (f32)rot);
268     MTXConcat(mv, mr, mv);
269     GXLoadPosMtxImm(mv, GX_PNMTX0);
270     MTXInverse(mv, mvi);
271     MTXTranspose(mvi, mv);
272     GXLoadNrmMtxImm(mv, GX_PNMTX0);
273 
274     DrawModel(CYLINDER);
275     GXSetDrawSync( CYLINDER );
276 
277     MTXTrans(mt, -300.0F, 0.0F, 0.0F);
278     MTXConcat(v, mt, mv);
279     MTXRotDeg(mr, axis[(axisc+1)%3], (f32)rot);
280     MTXConcat(mv, mr, mv);
281     MTXScale(ms, 100.0F, 100.0F, 100.0F);
282     MTXConcat(mv, ms, mv);
283     GXLoadPosMtxImm(mv, GX_PNMTX0);
284     MTXInverse(mv, mvi);
285     MTXTranspose(mvi, mv);
286     GXLoadNrmMtxImm(mv, GX_PNMTX0);
287 
288     DrawModel(CUBE);
289     GXSetDrawSync( CUBE );
290 
291     MTXTrans(mt, 300.0F, 0.0F, 0.0F);
292     MTXConcat(v, mt, mv);
293     MTXRotDeg(mr, axis[(axisc+2)%3], (f32)rot);
294     MTXConcat(mv, mr, mv);
295     MTXScale(ms, 100.0F, 100.0F, 100.0F);
296     MTXConcat(mv, ms, mv);
297     GXLoadPosMtxImm(mv, GX_PNMTX0);
298     MTXInverse(mv, mvi);
299     MTXTranspose(mvi, mv);
300     GXLoadNrmMtxImm(mv, GX_PNMTX0);
301 
302     DrawModel(TORUS);
303     GXSetDrawSync( TORUS );
304 
305     rot++;
306     if (rot == 360) {
307         rot = 0;
308         axisc++;
309     }
310 }
311 
312 /*---------------------------------------------------------------------------*
313     Name:           AnimTick
314 
315     Description:    Menu of test options
316 
317     Arguments:      none
318 
319     Returns:        none
320  *---------------------------------------------------------------------------*/
AnimTick(void)321 static void AnimTick( void )
322 {
323     u8   i;
324     u16  down = DEMOPadGetButtonDown(0);
325 
326     if (down & PAD_BUTTON_A)
327     {
328         for (i = 0; i < MAX_MODELS-1; i++)
329             OSReport("%s done at %d clocks\n", ModelOpt[i], myCount[i]);
330         OSReport("\n");
331     }
332 }
333 
334 /*---------------------------------------------------------------------------*
335     Name:           PrintIntro
336 
337     Description:    Prints the directions on how to use this demo.
338 
339     Arguments:      none
340 
341     Returns:        none
342  *---------------------------------------------------------------------------*/
PrintIntro(void)343 static void PrintIntro( void )
344 {
345     OSReport("\n\n");
346     OSReport("***********************************************\n");
347     OSReport("perf-sync - demonstrates sampling perf counters \n");
348     OSReport("            using the draw sync callback.       \n");
349     OSReport("***********************************************\n");
350     OSReport("to quit hit the start button\n");
351     OSReport("\n");
352     OSReport("BUTTON A, dump current stats\n");
353     OSReport("***********************************************\n");
354     OSReport("\n\n");
355 }
356 
357 
358 /*---------------------------------------------------------------------------*
359     Name:           myDrawSyncCallback
360 
361     Description:    This function is called for each drawsync interrupt
362                     It stores the current value of the GP0 counter in an
363                     array at the location specified by the token value.
364 
365     Arguments:      token, the value sent by GXSetDrawSync
366  *---------------------------------------------------------------------------*/
myDrawSyncCallback(u16 token)367 void myDrawSyncCallback( u16 token )
368 {
369     if (token >= MAX_MODELS) return;
370 
371     myCount[token-1] = GXReadGP0Metric();
372 }
373 
374 /*============================================================================*/
375