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