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