1 /*---------------------------------------------------------------------------*
2 Project: Dolphin
3 File: gc-matrix-gc.c
4
5 Copyright 2000 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 $Log: gd-matrix-gc.c,v $
14 Revision 1.3.64.1 2009/12/08 02:44:59 abe_takehiro
15 Erased warning message
16
17 Revision 1.3 2006/08/18 21:50:58 carlmu
18 Added explanatory output.
19
20 Revision 1.2 2006/02/20 04:13:09 mitu
21 changed include path from dolphin/ to revolution/.
22
23 Revision 1.1 2006/02/08 11:19:43 mitu
24 1st version.
25
26
27 3 02/09/06 11:26 Hirose
28 Resolved future time stamp problem.
29
30 3 10/19/02 6:53p Hirose
31 Changed location of data file.
32
33 2 9/24/01 2:23p Hirose
34 Changed flag definition.
35
36 1 9/19/01 5:49p Carl
37 Source files for GD matrix demo.
38
39 $NoKeywords: $
40 *---------------------------------------------------------------------------*/
41
42 #include <demo.h>
43 #include <math.h>
44
45 #include <revolution/gd.h>
46
47 /*---------------------------------------------------------------------------*
48 Defines
49 *---------------------------------------------------------------------------*/
50
51 // This macro is used to copy a 3x4 matrix into a 3x3 matrix
52 #define COPY3x3(ms, md) \
53 { md[0][0]=ms[0][0]; md[0][1]=ms[0][1]; md[0][2]=ms[0][2]; \
54 md[1][0]=ms[1][0]; md[1][1]=ms[1][1]; md[1][2]=ms[1][2]; \
55 md[2][0]=ms[2][0]; md[2][1]=ms[2][1]; md[2][2]=ms[2][2]; }
56
57 /*---------------------------------------------------------------------------*
58 Forward references
59 *---------------------------------------------------------------------------*/
60
61 void main ( void );
62
63 static void CameraInit ( void );
64 static void DrawInit ( void );
65 static void DrawTick ( void );
66
67 static void AnimTick ( void );
68
69 static void ParameterInit ( void );
70
71 #ifdef LOAD_DL_FROM_FILE
72 static void LoadDLs ( void );
73 #else
74 extern void CreateDLs ( void );
75 #endif
76
77 /*---------------------------------------------------------------------------*
78 Global variables
79 *---------------------------------------------------------------------------*/
80
81 // Display lists *************************************************************
82
83 // This set of display lists will each load an indexed position matrix
84 // and an indexed normal matrix, then draw one face of the cube.
85
86 GDLObj DrawDLOs[6];
87
88 /*---------------------------------------------------------------------------*/
89
90 // Actual primitive data follows
91
92 #define SIDE 30
93 #define NORM (sqrt(3.0))/3.0
94
95 // Remember: Alignment of vertex arrays to 32B IS NOT required, but it
96 // may result in a slight performance improvement.
97
98 float FloatVert[] ATTRIBUTE_ALIGN(32) =
99 {
100 -SIDE, SIDE, -SIDE,
101 -SIDE, SIDE, SIDE,
102 -SIDE, -SIDE, SIDE,
103 -SIDE, -SIDE, -SIDE,
104 SIDE, SIDE, -SIDE,
105 SIDE, -SIDE, -SIDE,
106 SIDE, -SIDE, SIDE,
107 SIDE, SIDE, SIDE,
108 };
109
110 float FloatNorm[] ATTRIBUTE_ALIGN(32) =
111 {
112 -1, 1, -1,
113 -1, 1, 1,
114 -1, -1, 1,
115 -1, -1, -1,
116 1, 1, -1,
117 1, -1, -1,
118 1, -1, 1,
119 1, 1, 1,
120 };
121
122 float FloatTex[] ATTRIBUTE_ALIGN(32) =
123 {
124 0.0F, 0.0F,
125 1.0F, 0.0F,
126 1.0F, 1.0F,
127 0.0F, 1.0F,
128 };
129
130 // This array is used to animate the Draw DL's.
131 // Since it is CPU-only data, no special treatment is needed.
132
133 float AnimData[6][3] =
134 {
135 -1.0f, 0.0f, 0.0f,
136 1.0f, 0.0f, 0.0f,
137 0.0f, -1.0f, 0.0f,
138 0.0f, 1.0f, 0.0f,
139 0.0f, 0.0f, -1.0f,
140 0.0f, 0.0f, 1.0f
141 };
142
143 // These matrices will be referenced by the GP from the Draw DL's.
144 // They could be ALIGNed, but they don't have to be.
145
146 Mtx posMats[6];
147 f32 nrmMats[6][3][3];
148
149 // Misc data...
150
151 Mtx v; // view matrix
152 u32 rot; // current cube rotation
153
154 /*---------------------------------------------------------------------------*
155 Application main loop
156 *---------------------------------------------------------------------------*/
157
main(void)158 void main ( void )
159 {
160 DEMOInit(NULL);
161
162 OSReport("\n\n");
163 OSReport("**********************************************\n");
164 OSReport("gd-matrix-gc: Matrix-loading display list demo\n");
165 OSReport("**********************************************\n");
166 OSReport("To quit hit the start button.\n");
167 OSReport("\n");
168 OSReport("A button toggles animation.\n");
169 OSReport("**********************************************\n");
170 OSReport("\n\n");
171
172 DrawInit(); // Prepare the display lists and such
173
174 ParameterInit();
175
176 DEMOPadRead(); // Read the joystick for this frame
177
178 // While the quit button is not pressed
179 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
180 {
181 DEMOPadRead(); // Read the joystick for this frame
182
183 AnimTick(); // Do animation based on input
184
185 DEMOBeforeRender();
186
187 DrawTick(); // Draw the model.
188
189 DEMODoneRender();
190 }
191
192 OSHalt("End of test");
193 }
194
195 /*---------------------------------------------------------------------------*
196 Functions
197 *---------------------------------------------------------------------------*/
198
199 /*---------------------------------------------------------------------------*
200 Name: CameraInit
201
202 Description: Initialize the projection matrix and load into hardware.
203
204 Arguments: v view matrix to be passed to ViewInit
205 cameraLocScale scale for the camera's distance from the
206 object - to be passed to ViewInit
207
208 Returns: none
209 *---------------------------------------------------------------------------*/
CameraInit(void)210 static void CameraInit ( void )
211 {
212 Mtx44 p;
213 Vec camPt = {0.0F, 0.0F, 650.0F};
214 Vec up = {0.0F, 1.0F, 0.0F};
215 Vec origin = {0.0F, 0.0F, 0.0F};
216
217 MTXFrustum(p, 112, -112, -160, 160, 500, 2000);
218
219 GXSetProjection(p, GX_PERSPECTIVE);
220
221 MTXLookAt(v, &camPt, &up, &origin);
222 }
223
224
225 /*---------------------------------------------------------------------------*
226 Name: LoadDLs
227
228 Description: Loads the display lists used by the program from a file.
229 This routine is only called if LOAD_DL_FROM_FILE is defined.
230
231 Arguments: none
232
233 Returns: none
234 *---------------------------------------------------------------------------*/
235 #ifdef LOAD_DL_FROM_FILE
LoadDLs(void)236 static void LoadDLs ( void )
237 {
238 s32 err;
239 GDGList *DLDescArray;
240 GDGList *PLDescArray;
241 u32 numDLs, numPLs;
242 u32 i;
243
244 err = GDReadDLFile("gddemo/gdMatrix.gdl", &numDLs, &numPLs,
245 &DLDescArray, &PLDescArray);
246
247 OSReport("(%d) Read %d DLs, %d PLs\n", err, numDLs, numPLs);
248
249 ASSERTMSG(!err, "Error reading GDL file.\n");
250
251 ASSERTMSG(numDLs >= 6 && numPLs >= 0, "Too little data in GDL file.\n");
252
253 // Note: We put the DL length into the "offset" field, since that's
254 // where the run-time code expects it. We do this since the CreateDLs
255 // function uses an oversize "length" field, and the actual valid data
256 // length is saved in the "offset" field in that case. Thus we do the
257 // same thing here for consistency.
258
259 for(i=0; i<6; i++)
260 {
261 GDInitGDLObj( &DrawDLOs[i],
262 DLDescArray[i].ptr,
263 DLDescArray[i].byteLength );
264 GDSetCurrent( &DrawDLOs[i] );
265 GDSetCurrOffset( DLDescArray[i].byteLength );
266 }
267
268 GDSetCurrent( NULL );
269 }
270 #endif
271
272
273 /*---------------------------------------------------------------------------*
274 Name: DrawInit
275
276 Description: Calls the correct initialization function for the current
277 model.
278
279 Arguments: none
280
281 Returns: none
282 *---------------------------------------------------------------------------*/
DrawInit(void)283 static void DrawInit( void )
284 {
285 u32 i;
286 GXLightObj MyLight;
287 GXColor White = {255, 255, 255, 255};
288
289 // Create all the display lists.
290 // In this demo, this is done at run-time.
291 // We can also just load the DL's from a file created by a DL tool.
292 #ifdef LOAD_DL_FROM_FILE
293 LoadDLs();
294 #else
295 CreateDLs();
296 #endif
297
298 CameraInit(); // Initialize the camera.
299
300 GXClearVtxDesc(); // Set up VCD/VAT.
301
302 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
303 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
304 GXSetArray(GX_VA_TEX0, FloatTex, 8);
305
306 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
307 GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
308 GXSetArray(GX_VA_NRM, FloatNorm, 12);
309
310 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
311 GXSetVtxDesc (GX_VA_POS, GX_INDEX8);
312 GXSetArray(GX_VA_POS, FloatVert, 12);
313
314 // Set up a light
315 GXInitLightPos(&MyLight, 0.0F, 0.0F, 0.0F);
316 GXInitLightColor(&MyLight, White);
317 GXLoadLightObjImm(&MyLight, GX_LIGHT0);
318 GXSetChanCtrl(
319 GX_COLOR0,
320 GX_ENABLE, // enable channel
321 GX_SRC_REG, // amb source
322 GX_SRC_REG, // mat source
323 GX_LIGHT0, // light mask
324 GX_DF_CLAMP, // diffuse function
325 GX_AF_NONE);
326
327 // Set up TEV
328 GXSetNumChans(1);
329 GXSetNumTevStages(1);
330 GXSetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
331 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
332
333 // We'll send the face color in through TEVREG0
334 GXSetTevColorIn(GX_TEVSTAGE0,
335 GX_CC_ZERO, GX_CC_RASC, GX_CC_C0, GX_CC_ZERO);
336
337 // Fix up normals
338 for(i = 0; i < 24; i++)
339 {
340 FloatNorm[i] *= NORM;
341 }
342
343 // Flush to memory
344 DCFlushRange((void *)FloatNorm, sizeof(FloatNorm));
345
346 // These matrices will be set up in DrawTick, below
347 GXSetArray(GX_POS_MTX_ARRAY, posMats, sizeof(Mtx));
348 GXSetArray(GX_NRM_MTX_ARRAY, nrmMats, sizeof(f32 [3][3]));
349 }
350
351 /*---------------------------------------------------------------------------*
352 Name: DrawTick
353
354 Description: Draw the current model once.
355
356 Arguments: v view matrix
357 m model matrix
358
359 Returns: none
360 *---------------------------------------------------------------------------*/
DrawTick(void)361 static void DrawTick( void )
362 {
363 u32 i;
364 static GXColor color[6] = {
365 { 255, 0, 0, 255 },
366 { 0, 255, 0, 255 },
367 { 0, 0, 255, 255 },
368 { 0, 255, 255, 255 },
369 { 255, 0, 255, 255 },
370 { 255, 255, 0, 255 }
371 };
372
373 // Draw the moving faces
374
375 GXSetCullMode(GX_CULL_NONE);
376
377 // Set the color, then call the DL to draw the geometry.
378 for(i=0; i<6; i++)
379 {
380 GXSetTevColor(GX_TEVREG0, color[i]);
381 GXCallDisplayList(GDGetGDLObjStart(&DrawDLOs[i]),
382 GDGetGDLObjOffset(&DrawDLOs[i]));
383 }
384 }
385
386 /*---------------------------------------------------------------------------*
387 Name: AnimTick
388
389 Description: Animates the camera and object based on the joystick's
390 state.
391
392 Arguments: none
393
394 Returns: none
395 *---------------------------------------------------------------------------*/
AnimTick(void)396 static void AnimTick ( void )
397 {
398 u32 i;
399 Mtx ry, rz, mv, tm, mn;
400 f32 tx, ty, tr;
401 u16 buttons = DEMOPadGetButton(0);
402
403 // Just simple controls right now...
404
405 if(buttons & PAD_BUTTON_A)
406 {
407 // suspend animation
408 } else {
409
410 rot ++;
411 if(rot > 2159)
412 rot = 0;
413 }
414
415 // Set up our transformations...
416
417 tx = 0.0f;
418 ty = 0.0f;
419
420 MTXRotDeg(ry, 'X', (float)rot);
421 MTXRotDeg(rz, 'Y', (float)rot / 3.0F);
422 MTXTrans(tm, tx, ty, 0);
423
424 MTXConcat(rz, ry, mv);
425 MTXConcat(tm, mv, mv);
426 MTXConcat(v, mv, mv);
427
428 MTXInverse(mv, mn);
429 MTXTranspose(mn, mn);
430
431 // Need to set up and flush all matrices for the AltDrawList's.
432 if (rot % 120 < 60)
433 {
434 tr = (float)(rot % 60);
435 } else {
436 tr = (float)(60 - (rot % 60));
437 }
438
439 // We recalculate and reload all the normal matrices, even though
440 // they're actually the same for all faces. This is just example
441 // code to illustrate the various steps.
442 for(i=0; i<6; i++)
443 {
444 MTXTrans(tm, AnimData[i][0]*(tr),
445 AnimData[i][1]*(tr),
446 AnimData[i][2]*(tr));
447 MTXConcat(mv, tm, posMats[i]);
448 COPY3x3(mn, nrmMats[i]);
449 }
450
451 // If you had a large number of matrices, you should flush them
452 // as you calculate them. Since we have just a few here, it's okay
453 // to flush them all at once like this.
454 DCFlushRange((void*) posMats, sizeof(posMats));
455 DCFlushRange((void*) nrmMats, sizeof(nrmMats));
456 }
457
458 /*---------------------------------------------------------------------------*
459 Name: ParameterInit
460
461 Description: Initialize parameters for single frame display
462
463 Arguments: none
464
465 Returns: none
466 *---------------------------------------------------------------------------*/
ParameterInit(void)467 static void ParameterInit ( void )
468 {
469 rot = 45;
470 }
471
472 /****************************************************************************/
473
474
475