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