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