1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     DL-tf-mtx.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     DL-tf-mtx
15         Display list which includes matrix load commands
16  *---------------------------------------------------------------------------*/
17 #include <demo.h>
18 #include <math.h>
19 
20 /*---------------------------------------------------------------------------*
21    Macro definitions
22  *---------------------------------------------------------------------------*/
23 #define ASPECT              ((float)640/(float)448)
24 
25 #define NUM_MTX_SLOTS       10
26 #define MTX_IDX_SPAN        3
27 
28 #define DL_BUFSIZE          16384
29 
30 #define NUM_CONTOUR         100     // (9*11+1) : should be (9n+1)
31 #define CONTOUR_SPAN        50.0F
32 #define VTX_PER_CONTOUR     12
33 
34 
35 /*---------------------------------------------------------------------------*
36    Rendering parameters
37  *---------------------------------------------------------------------------*/
38 typedef f32 Mtx33[3][3];
39 typedef f32 Mtx24[2][4];
40 
41 typedef struct
42 {
43     Point3d   position;
44     Point3d   target;
45     Vec       up;
46     f32       fovy;
47     f32       znear;
48     f32       zfar;
49     Mtx       viewMtx;
50 } MyCameraObj;
51 
52 typedef struct
53 {
54    s8  x,  y;
55    s8  nx, ny, nz;
56    s8  pad;
57 } MyVertex;
58 
59 
60 /*---------------------------------------------------------------------------*
61    Forward references
62  *---------------------------------------------------------------------------*/
63 static void     DrawInit        ( void );
64 static void     DrawTick        ( void );
65 static void     AnimTick        ( void );
66 static void     BuildModelDL    ( void );
67 static void     BuildMtxArray   ( void );
68 static void     CheckMissingObj ( void );
69 inline void     CopyMtxTo3x3    ( Mtx src, Mtx33 dst );
70 static void     PrintIntro      ( void );
71 
72 //---------------------------------------------------------------------------
73 //  Global variables
74 //---------------------------------------------------------------------------
75 // Camera
76 MyCameraObj DefaultCamera =
77 {
78     { 0.0f, -5000.0f, 0.0f },   // position
79     { 0.0f,     0.0f, 0.0f },   // target
80     { 0.0f,     0.0f, 1.0f },   // upVec
81        33.3f,                   // fovy
82      2000.0f,                   // near plane Z in camera coordinates
83     10000.0f,                   // far  plane Z in camera coordinates
84 };
85 
86 // For texture palette
87 static TPLPalettePtr   MyTplObj = 0;
88 
89 // For model display list
90 static void*    ModelDLBuffer = NULL;
91 static u32      ModelDLSize = 0;
92 // For model transform matrix array (double buffered)
93 static Mtx*     PosMtxArrayBuf[2];
94 static Mtx33*   NrmMtxArrayBuf[2];
95 static Mtx24*   TexMtxArrayBuf[2];
96 static u32      CurrentMtxBuffer;
97 
98 // For animation control
99 static Vec      AnimCtrlArray[NUM_CONTOUR];
100 static u32      AnimCtrlPtr = 0;
101 static s32      AnimCounter = 0;
102 static u32      AnimReset   = 0;
103 static u32      AnimPause   = 0;
104 static Mtx      AnimMtxOrigin;
105 static Mtx      AnimGlobalRot;
106 
107 //---------------------------------------------------------------------------
108 //  Model data
109 //---------------------------------------------------------------------------
110 static MyVertex VtxArray[VTX_PER_CONTOUR] ATTRIBUTE_ALIGN(32) =
111 {
112     {  50,   0,    64,   0,  0 }, /*   0 */
113     {  44,  25,    55,  32,  0 }, /*  30 */
114     {  25,  44,    32,  55,  0 }, /*  60 */
115     {   0,  50,     0,  64,  0 }, /*  90 */
116     { -25,  44,   -32,  55,  0 }, /* 120 */
117     { -44,  25,   -55,  32,  0 }, /* 150 */
118     { -50,   0,   -64,   0,  0 }, /* 180 */
119     { -44, -25,   -55, -32,  0 }, /* 210 */
120     { -25, -44,   -32, -55,  0 }, /* 240 */
121     {   0, -50,     0, -64,  0 }, /* 270 */
122     {  25, -44,    32, -55,  0 }, /* 300 */
123     {  44, -25,    55, -32,  0 }, /* 330 */
124 };
125 
126 /*---------------------------------------------------------------------------*
127    Application main loop
128  *---------------------------------------------------------------------------*/
main(void)129 void  main ( void )
130 {
131     // initialize render settings and set clear color for first frame
132     DEMOInit(NULL);
133     DrawInit();
134     PrintIntro();
135 
136     while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
137     {
138         DEMOBeforeRender();
139 
140         // Draw scene
141         DrawTick();
142 
143         // get pad status
144         DEMOPadRead();
145         // Control and Animation
146         AnimTick();
147 
148         CheckMissingObj();
149         DEMODoneRender();
150     }
151 
152     OSHalt("End of test");
153 }
154 
155 /*---------------------------------------------------------------------------*
156     Name:           DrawInit
157 
158     Description:    Initializes parameters and default graphics status.
159 
160     Arguments:      none
161 
162     Returns:        none
163  *---------------------------------------------------------------------------*/
DrawInit(void)164 void  DrawInit( void )
165 {
166     u32  i;
167 
168     // Reflection map texture
169     TPLGetPalette(&MyTplObj, "gxTests/tf-02.tpl");
170 
171     // Set background color
172     GXSetCopyClear((GXColor){ 64, 64, 64, 64}, GX_MAX_Z24);
173 
174     // Set pixel processing mode
175     GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
176     GXSetZMode(GX_TRUE, GX_LESS, GX_TRUE);
177 
178     GXSetZCompLoc(GX_FALSE); // Z after texturing
179     // NOTE: You should use Z after texuring to avoid
180     //       the bounding box bug in the easiest way.
181 
182     // Set culling mode
183     GXSetCullMode(GX_CULL_BACK);
184 
185     // Allocate matrix array buffers (double-buffer)
186     PosMtxArrayBuf[0] = (Mtx*)  MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx)   * NUM_CONTOUR);
187     PosMtxArrayBuf[1] = (Mtx*)  MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx)   * NUM_CONTOUR);
188     NrmMtxArrayBuf[0] = (Mtx33*)MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx33) * NUM_CONTOUR);
189     NrmMtxArrayBuf[1] = (Mtx33*)MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx33) * NUM_CONTOUR);
190     TexMtxArrayBuf[0] = (Mtx24*)MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx24) * NUM_CONTOUR);
191     TexMtxArrayBuf[1] = (Mtx24*)MEMAllocFromAllocator(&DemoAllocator1, sizeof(Mtx24) * NUM_CONTOUR);
192     CurrentMtxBuffer  = 0;
193 
194     // Animation setting
195     AnimReset   = 0;
196     AnimPause   = 0;
197     AnimCtrlPtr = 0;
198     AnimCounter = 0;
199     for ( i = 0; i < NUM_CONTOUR; i++ )
200     {
201         AnimCtrlArray[i] = (Vec){ 5.0F, 0.5F, 0.0F };
202     }
203     // Initial location of the object
204     MTXTrans(AnimMtxOrigin, -800.0F, 0.0F, -400.0F);
205     MTXIdentity(AnimGlobalRot);
206 
207     // Build matrix array for the first frame
208     // (for safety, initialize both of double-buffer)
209     BuildMtxArray();
210     BuildMtxArray();
211 
212     // Build a model display list
213     BuildModelDL();
214 
215     return;
216 }
217 
218 /*---------------------------------------------------------------------------*
219     Name:           DrawTick
220 
221     Description:    Draw the model
222 
223     Arguments:      none
224 
225     Returns:        none
226  *---------------------------------------------------------------------------*/
DrawTick(void)227 void  DrawTick( void )
228 {
229     Mtx*            posMtxArray = PosMtxArrayBuf[CurrentMtxBuffer];
230     Mtx33*          nrmMtxArray = NrmMtxArrayBuf[CurrentMtxBuffer];
231     Mtx24*          texMtxArray = TexMtxArrayBuf[CurrentMtxBuffer];
232     Mtx44           projMtx;
233     MyCameraObj*    c = &DefaultCamera;
234     GXTexObj        texObj;
235     GXLightObj      litObj;
236     Vec             lpos = { 10000.0F, -10000.0F, 10000.0F };
237 
238     // Set projection matrix
239     MTXPerspective(projMtx, c->fovy, ASPECT, c->znear, c->zfar);
240     GXSetProjection(projMtx, GX_PERSPECTIVE);
241 
242     // Lighting
243     GXSetNumChans(1);
244     GXSetChanCtrl(GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG,
245                   GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE);
246     GXSetChanCtrl(GX_ALPHA0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG,
247                   GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE);
248 
249     GXSetChanAmbColor(GX_COLOR0A0, (GXColor){ 48,  48,  48,  48 });
250     GXSetChanMatColor(GX_COLOR0A0, (GXColor){ 255, 255, 192, 255 });
251 
252     MTXMultVec(c->viewMtx, &lpos, &lpos);
253     GXInitLightPosv(&litObj, &lpos);
254     GXInitLightColor(&litObj, (GXColor){ 208, 208, 208, 208 });
255     GXLoadLightObjImm(&litObj, GX_LIGHT0);
256 
257     // TEV
258     GXSetNumTevStages(1);
259     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
260     GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
261     // Texture
262     TPLGetGXTexObjFromPalette(MyTplObj, &texObj, 1);
263     GXLoadTexObj(&texObj, GX_TEXMAP0);
264     // Texture coord gen
265     GXSetNumTexGens(1);
266     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX0);
267 
268     // Array base & stride setting
269     GXSetArray(GX_POS_MTX_ARRAY, posMtxArray,     sizeof(posMtxArray[0]));
270     GXSetArray(GX_NRM_MTX_ARRAY, nrmMtxArray,     sizeof(nrmMtxArray[0]));
271     GXSetArray(GX_TEX_MTX_ARRAY, texMtxArray,     sizeof(texMtxArray[0]));
272     GXSetArray(GX_VA_POS,        &VtxArray[0].x,  sizeof(VtxArray[0]));
273     GXSetArray(GX_VA_NRM,        &VtxArray[0].nx, sizeof(VtxArray[0]));
274 
275     // Vertex attribute/descriptor settings
276     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY,  GX_S8, 0);
277     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S8, 6);
278     GXClearVtxDesc();
279     GXSetVtxDesc(GX_VA_PNMTXIDX,   GX_DIRECT);
280     GXSetVtxDesc(GX_VA_TEX0MTXIDX, GX_DIRECT);
281     GXSetVtxDesc(GX_VA_POS,        GX_INDEX8);
282     GXSetVtxDesc(GX_VA_NRM,        GX_INDEX8);
283 
284     // Draw the model
285     GXCallDisplayList(ModelDLBuffer, ModelDLSize);
286 
287     return;
288 }
289 
290 /*---------------------------------------------------------------------------*
291     Name:           AnimTick
292 
293     Description:    Updates scene animation parameter by using PAD status.
294 
295     Arguments:      none
296 
297     Returns:        none
298  *---------------------------------------------------------------------------*/
AnimTick(void)299 void AnimTick( void )
300 {
301     Mtx     tmpMtx0, tmpMtx1, tmpMtx2;
302     f32     dir0, dir1;
303 
304     // Reset location
305     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
306     {
307         AnimReset = 1;
308     }
309 
310     // Pause
311     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_B )
312     {
313         AnimPause = 1 - AnimPause;
314     }
315 
316     // Global model rotation calculation
317     MTXRotDeg(tmpMtx1, 'Z', ( (f32)DEMOPadGetSubStickX(0) / 32 + 0.20F));
318     MTXRotDeg(tmpMtx0, 'X', (-(f32)DEMOPadGetSubStickY(0) / 32));
319     MTXConcat(tmpMtx1, AnimGlobalRot, AnimGlobalRot);
320     MTXConcat(tmpMtx0, AnimGlobalRot, AnimGlobalRot);
321 
322     // Increment animation counter
323     AnimCounter = ( AnimCounter + 1 ) % 180;
324 
325     // Reset location when the object goes somewhere outside the screen.
326     if ( AnimReset )
327     {
328         MTXIdentity(AnimMtxOrigin);
329         AnimReset = 0;
330     }
331 
332     // Update matrix for origin (end point) of the object.
333     if ( !AnimPause )
334     {
335         MTXTrans(tmpMtx0, 0.0F, 0.0F, CONTOUR_SPAN);
336         MTXRotDeg(tmpMtx1, 'Y', AnimCtrlArray[AnimCtrlPtr].x);
337         MTXConcat(tmpMtx1, tmpMtx0, tmpMtx2);
338         MTXRotDeg(tmpMtx1, 'Z', AnimCtrlArray[AnimCtrlPtr].y);
339         MTXConcat(tmpMtx1, tmpMtx2, tmpMtx0);
340         MTXConcat(AnimMtxOrigin, tmpMtx0, AnimMtxOrigin);
341 
342         // Get new parameter for the top point.
343         dir0 = 7.5F * sinf((f32)AnimCounter * 3.1415F / 90) + 2.5F;
344         dir1 = 1.0F * sinf((f32)AnimCounter * 3.1415F / 45);
345         AnimCtrlArray[AnimCtrlPtr].x = (f32)(DEMOPadGetStickX(0)/5) + dir0;
346         AnimCtrlArray[AnimCtrlPtr].y = (f32)(DEMOPadGetStickY(0)/5) + dir1;
347 
348         // Advance pointer of ring buffer.
349         AnimCtrlPtr = (AnimCtrlPtr + 1) % NUM_CONTOUR;
350     }
351 
352     // Build matrix array
353     BuildMtxArray();
354 }
355 
356 /*---------------------------------------------------------------------------*
357     Name:           BuildModelDL
358 
359     Description:    Build a display list for stitched pipe model.
360 
361     Arguments:      none
362 
363     Returns:        none
364  *---------------------------------------------------------------------------*
365     This function puts these three command APIs into the display list:
366 
367         GXLoadPosMtxIndx / GXLoadTexMtxIndx / GXLoadNrmMtxIndx3x3
368 
369     that are basically safe with using inside a display list. Since actual
370     matrix loads will occur when you call this display list, you can
371     animate this object by just updating matrix array on main memory.
372  *---------------------------------------------------------------------------*/
BuildModelDL(void)373 void BuildModelDL( void )
374 {
375     s32          i, j, k;
376     u8           vi;
377     GXPosNrmMtx  pm0, pm1;
378     GXTexMtx     tm0, tm1;
379 
380     //---- allocate buffer for the display list
381     if ( ModelDLBuffer == NULL )
382     {
383         ModelDLBuffer = MEMAllocFromAllocator(&DemoAllocator1, DL_BUFSIZE);
384         DCInvalidateRange(ModelDLBuffer, DL_BUFSIZE);
385     }
386 
387     //---- start generating display list
388     GXBeginDisplayList(ModelDLBuffer, DL_BUFSIZE);
389 
390 
391     //-------- Pipe lid
392     pm0 = GX_PNMTX0;
393     tm0 = GX_TEXMTX0;
394     GXLoadPosMtxIndx   (0, pm0);
395     GXLoadNrmMtxIndx3x3(0, pm0);
396     GXLoadTexMtxIndx   (0, tm0, GX_MTX2x4);
397 
398     GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, VTX_PER_CONTOUR );
399     for ( i = 0; i < VTX_PER_CONTOUR; i ++ )
400     {
401         GXMatrixIndex1x8((u8)pm0);
402         GXMatrixIndex1x8((u8)tm0);
403         GXPosition1x8   ((u8)i);
404         GXNormal1x8     ((u8)i);
405     }
406     GXEnd( );
407 
408     //-------- Pipe body
409     for ( i = 0; i < NUM_CONTOUR-1; i += (NUM_MTX_SLOTS-1) )
410     {
411         // Load 10 transform matrices into HW slots.
412         //
413         // It is better to load matrices as much as possible at one
414         // time to minimize the stall latency of graphics pipeline.
415         pm0 = GX_PNMTX0;
416         tm0 = GX_TEXMTX0;
417         for ( j = 0 ; j < NUM_MTX_SLOTS ; j++ )
418         {
419             GXLoadPosMtxIndx   ((u16)(i+j), pm0);
420             GXLoadNrmMtxIndx3x3((u16)(i+j), pm0);
421             GXLoadTexMtxIndx   ((u16)(i+j), tm0, GX_MTX2x4);
422             pm0 = (GXPosNrmMtx)(pm0 + MTX_IDX_SPAN);
423             tm0 = (GXTexMtx)(tm0 + MTX_IDX_SPAN);
424         }
425 
426         // Stich all transformed contour.
427         pm0 = GX_PNMTX0;
428         tm0 = GX_TEXMTX0;
429         for ( j = 0 ; j < (NUM_MTX_SLOTS-1) ; j++ )
430         {
431             pm1 = (GXPosNrmMtx)(pm0 + MTX_IDX_SPAN);
432             tm1 = (GXTexMtx)(tm0 + MTX_IDX_SPAN);
433 
434             GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (VTX_PER_CONTOUR+1)*2);
435             vi = VTX_PER_CONTOUR-1;
436             for ( k = -1; k < VTX_PER_CONTOUR; k++ )
437             {
438                 GXMatrixIndex1x8((u8)pm0);
439                 GXMatrixIndex1x8((u8)tm0);
440                 GXPosition1x8   (vi);
441                 GXNormal1x8     (vi);
442                 GXMatrixIndex1x8((u8)pm1);
443                 GXMatrixIndex1x8((u8)tm1);
444                 GXPosition1x8   (vi);
445                 GXNormal1x8     (vi);
446                 vi = (u8)(k + 1);
447             }
448             GXEnd();
449 
450             pm0 = pm1;
451             tm0 = tm1;
452         }
453     }
454 
455     //-------- Pipe lid 1
456     pm1 = GX_PNMTX9;
457     tm1 = GX_TEXMTX9;
458     GXBegin(GX_TRIANGLEFAN, GX_VTXFMT0, VTX_PER_CONTOUR);
459     for ( i = 0; i < VTX_PER_CONTOUR; i ++ )
460     {
461         GXMatrixIndex1x8((u8)pm1);
462         GXMatrixIndex1x8((u8)tm1);
463         GXPosition1x8   ((u8)(VTX_PER_CONTOUR-1-i));
464         GXNormal1x8     ((u8)(VTX_PER_CONTOUR-1-i));
465     }
466     GXEnd();
467 
468 
469     //---- end of the display list
470     ModelDLSize = GXEndDisplayList();
471     if ( !ModelDLSize )
472     {
473         OSHalt("Display list exceeds size of the buffer\n");
474     }
475     OSReport("Size = %d\n", ModelDLSize);
476 }
477 
478 /*---------------------------------------------------------------------------*
479     Name:           BuildMtxArray
480 
481     Description:    Build matrix array for animation.
482 
483     Arguments:      none
484 
485     Returns:        none
486  *---------------------------------------------------------------------------*/
BuildMtxArray(void)487 void BuildMtxArray( void )
488 {
489     MyCameraObj* c = &DefaultCamera;
490     Mtx*    posMtxArray;
491     Mtx33*  nrmMtxArray;
492     Mtx24*  texMtxArray;
493     Mtx     tmpMtx0, tmpMtx1, tmpMtx2;
494     u32     i, j;
495     Vec     angles;
496     f32     nfct;
497 
498     // Switch matrix array buffer
499     //
500     //    Using double-buffering is good to gain performance.
501     //    This function builds up matrix data for the next frame into
502     //    one buffer while the GP may be drawing object by using matrix
503     //    data from another buffer.
504     CurrentMtxBuffer = 1 - CurrentMtxBuffer;
505     posMtxArray = PosMtxArrayBuf[CurrentMtxBuffer];
506     nrmMtxArray = NrmMtxArrayBuf[CurrentMtxBuffer];
507     texMtxArray = TexMtxArrayBuf[CurrentMtxBuffer];
508 
509 
510     // Get View matrix
511     MTXLookAt(c->viewMtx, &c->position, &c->up, &c->target);
512 
513     // Build position matrix array
514     MTXConcat(c->viewMtx, AnimGlobalRot, tmpMtx0);
515     MTXConcat(tmpMtx0, AnimMtxOrigin, posMtxArray[0]);
516     for ( i = 1; i < NUM_CONTOUR; i++ )
517     {
518         angles = AnimCtrlArray[(i+AnimCtrlPtr-1)%NUM_CONTOUR];
519 
520         MTXTrans(tmpMtx0, 0.0F, 0.0F, 50.0F);
521         MTXRotDeg(tmpMtx1, 'Y', angles.x);
522         MTXConcat(tmpMtx1, tmpMtx0, tmpMtx2);
523         MTXRotDeg(tmpMtx1, 'Z', angles.y);
524         MTXConcat(tmpMtx1, tmpMtx2, tmpMtx0);
525         MTXConcat(posMtxArray[i-1], tmpMtx0, posMtxArray[i]);
526     }
527 
528     // Build normalmal matrix array
529     for ( i = 0; i < NUM_CONTOUR; i++ )
530     {
531         // No need to calculate inverse-transpose because these
532         // matrices don't contain anisotropic scale factor.
533 
534         // Copy 3x3 part to normal matrix arry.
535         CopyMtxTo3x3( posMtxArray[i], nrmMtxArray[i] );
536     }
537 
538     // Build texture matrix array for environment mapping
539     for ( i = 0; i < NUM_CONTOUR; i++ )
540     {
541         for ( j = 0; j < 2; j++ )
542         {
543             nfct = 0.5F / VECMag( (VecPtr)posMtxArray[i][0] );
544             if ( j == 1 ) nfct = -nfct;
545             texMtxArray[i][j][0] = posMtxArray[i][j][0] * nfct;
546             texMtxArray[i][j][1] = posMtxArray[i][j][1] * nfct;
547             texMtxArray[i][j][2] = posMtxArray[i][j][2] * nfct;
548             texMtxArray[i][j][3] = 0.5f;
549         }
550     }
551     DCFlushRange(posMtxArray, sizeof(Mtx)   * NUM_CONTOUR);
552     DCFlushRange(nrmMtxArray, sizeof(Mtx33) * NUM_CONTOUR);
553     DCFlushRange(texMtxArray, sizeof(Mtx24) * NUM_CONTOUR);
554 }
555 
556 /*---------------------------------------------------------------------------*
557     Name:           CopyMtxTo3x3
558 
559     Description:    Copy 3x3 portion from 3x4 matrix to another place
560                     in order to use GXLoadNrmMtxIndx3x3.
561 
562     Arguments:      src : source 3x4 matrix.
563                     dst : destination 3x3 matrix.
564 
565     Returns:        none
566  *---------------------------------------------------------------------------*/
CopyMtxTo3x3(Mtx src,Mtx33 dst)567 inline void CopyMtxTo3x3( Mtx src, Mtx33 dst )
568 {
569     dst[0][0] = src[0][0];  dst[0][1] = src[0][1];  dst[0][2] = src[0][2];
570     dst[1][0] = src[1][0];  dst[1][1] = src[1][1];  dst[1][2] = src[1][2];
571     dst[2][0] = src[2][0];  dst[2][1] = src[2][1];  dst[2][2] = src[2][2];
572 }
573 
574 /*---------------------------------------------------------------------------*
575     Name:           CheckMissingObj
576 
577     Description:    Check if the object is drawn on the screen.
578                     (The object has gone somewhere outside.)
579 
580     Arguments:      none
581 
582     Returns:        none
583  *---------------------------------------------------------------------------*/
CheckMissingObj(void)584 void CheckMissingObj( void )
585 {
586     u16  bt, bb, br, bl;
587 
588     // Synchronization
589     GXDrawDone();
590     // Get bounding box
591     GXReadBoundingBox(&bl, &bt, &br, &bb);
592 
593     if ( br <= 0 && bl >= 640 )
594     {
595         // Object lost. Need reset.
596         AnimReset = 1;
597     }
598 
599     // Clear bounding box (for next frame)
600     GXClearBoundingBox();
601 }
602 
603 /*---------------------------------------------------------------------------*
604     Name:           PrintIntro
605 
606     Description:    Prints the directions on how to use this demo.
607 
608     Arguments:      none
609 
610     Returns:        none
611  *---------------------------------------------------------------------------*/
PrintIntro(void)612 static void PrintIntro( void )
613 {
614     OSReport("\n\n");
615     OSReport("************************************************\n");
616     OSReport("DL-tf-mtx \n");
617     OSReport("************************************************\n");
618     OSReport("to quit hit the start button\n");
619     OSReport("\n");
620     OSReport("  sub stick    : rotation\n");
621     OSReport("  A button     : reset\n");
622     OSReport("  B button     : animation ON/OFF\n");
623     OSReport("************************************************\n\n");
624 }
625 
626 /****************************************************************************/