1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     cmn-model.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 #include <demo.h>
14 #include <stdlib.h>     // for rand()
15 #include <math.h>       // for cosf(), sinf()
16 #include "cmn-model.h"
17 
18 #define PAI     3.1415926535898f
19 
20 static  void    cmModel0_Draw( Camera* );
21 static  void    cmModel1_Anim( Model*, DEMOPadStatus*, Camera* );
22 static  void    cmModel1_Draw( Camera* );
23 static  void    cmModel2_Anim( Model*, DEMOPadStatus*, Camera* );
24 static  void    cmModel2_Draw( Camera* );
25 static  void    cmModel3_Anim( Model*, DEMOPadStatus*, Camera* );
26 static  void    cmModel3_Draw( Camera* );
27 static  void    cmModel4_Anim( Model*, DEMOPadStatus*, Camera* );
28 static  void    cmModel4_Draw( Camera* );
29 
30 Model   cmModel[] = {
31     { cmModel0_Draw, 0,             0 },
32     { cmModel1_Draw, cmModel1_Anim, 0 },
33     { cmModel2_Draw, cmModel2_Anim, 0 },
34     { cmModel3_Draw, cmModel3_Anim, 0 },
35     { cmModel4_Draw, cmModel4_Anim, 0 },
36 };
37 
38 //============================================================================
39 //  Model
40 //============================================================================
41 
42 /*---------------------------------------------------------------------------*
43     Name:           ModelAnim
44     Description:    Animate all models
45     Arguments:      Scene* s
46     Returns:        none
47  *---------------------------------------------------------------------------*/
cmModelAnime(DEMOPadStatus * pad,Camera * c)48 void    cmModelAnime( DEMOPadStatus* pad, Camera* c )
49 {
50     int  i;
51 
52     // walk through all models
53     for ( i = 0; i < sizeof(cmModel)/sizeof(Model); i ++ )
54     {
55         // if valid model, do animation
56         if ( cmModel[i].anim )
57         {
58             (*cmModel[i].anim)( &cmModel[i], pad, c );
59         }
60     }
61     return;
62 }
63 
64 //============================================================================
65 //  Model 0
66 //  Static grid stage
67 //============================================================================
68 
69 /*---------------------------------------------------------------------------*
70     Name:           cmModel0_Draw
71     Description:    Draw mesh grid
72     Arguments:      Camera*
73     Returns:        none
74  *---------------------------------------------------------------------------*/
cmModel0_Draw(Camera * c)75 static  void    cmModel0_Draw( Camera* c )
76 {
77     s32     i;
78     GXColor red = {255, 0, 0, 255};
79 
80     // Set modelview matrix
81     GXSetCurrentMtx( GX_PNMTX0 );
82     GXLoadPosMtxImm( c->viewMtx, GX_PNMTX0 );
83 
84     // Use constant material color
85     GXSetChanCtrl( GX_COLOR0,
86                    GX_FALSE,            // enable Channel
87                    GX_SRC_REG,          // amb source           (Don't care)
88                    GX_SRC_REG,          // mat source
89                    GX_LIGHT0,           // light mask           (Don't care)
90                    GX_DF_NONE,          // diffuse function     (Don't care)
91                    GX_AF_NONE );        // atten   function     (Don't care)
92     GXSetChanCtrl( GX_ALPHA0,
93                    GX_FALSE,            // enable Channel
94                    GX_SRC_REG,          // amb source           (Don't care)
95                    GX_SRC_REG,          // mat source
96                    GX_LIGHT0,           // light mask           (Don't care)
97                    GX_DF_NONE,          // diffuse function     (Don't care)
98                    GX_AF_NONE );        // atten   function     (Don't care)
99     GXSetChanMatColor( GX_COLOR0A0, red );
100     GXSetNumChans(1);
101 
102     // Set TEV parameters
103     GXSetNumTexGens( 0 );               // # of Tex Gens
104     GXSetNumTevStages( 1 );             // # of Tev Stages
105     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL,GX_COLOR0A0);
106     GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
107 
108     // Set vertex descriptor
109     GXClearVtxDesc( );
110     GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
111     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0 );
112 
113 #define GRIDX             11
114 #define GRIDY             11
115 #define STEP             100
116 #define ORGX            -500
117 #define ORGY               0
118 
119     // Send vertex data for grid
120     GXBegin( GX_LINES, GX_VTXFMT0, (GRIDX+GRIDY)*2 );
121 
122         // Vertical lines
123         for ( i = 0; i < GRIDX; i ++ )
124         {
125             GXPosition2s16( (s16)(i*STEP+ORGX), (s16)(               ORGY) );
126             GXPosition2s16( (s16)(i*STEP+ORGX), (s16)((GRIDY-1)*STEP+ORGY) );
127         }
128 
129         // Horizontal lines
130         for ( i = 0; i < GRIDY; i ++ )
131         {
132             GXPosition2s16( (s16)(               ORGX), (s16)(i*STEP+ORGY) );
133             GXPosition2s16( (s16)((GRIDX-1)*STEP+ORGX), (s16)(i*STEP+ORGY) );
134         }
135 
136     GXEnd( );
137 
138     return;
139 }
140 
141 //============================================================================
142 //  Model 1
143 //  Flying depth tags
144 //============================================================================
145 
146 // Data area
147 typedef struct {                // for z coord tag data
148   f32     x, y, z, dir;
149   GXColor color;
150 } Obj1;
151 
152 Obj1 obj1_data[10] = {
153   {  6.0f,   4.0f,  100.0f, -1.0f, {255,255,255,255} },
154   {-20.0f,  10.0f,  200.0f,  0.5f, {255,255,  0,255} },
155   {-20.0f,   0.0f,  300.0f, -0.6f, {255,  0,255,255} },
156   {-20.0f, -30.0f,  400.0f,  1.0f, {  0,255,255,255} },
157   { 10.0f, -30.0f,  500.0f,  0.9f, {255,  0,  0,255} },
158   { 40.0f, -30.0f,  600.0f, -0.2f, {  0,  0,255,255} },
159   { 40.0f,   0.0f,  700.0f,  0.4f, {  0,255,  0,255} },
160   { 40.0f,  50.0f,  800.0f, -0.6f, {255,255,128,255} },
161   {  0.0f,  54.0f,  900.0f, -0.7f, {255,128,255,255} },
162   {-60.0f,  60.0f, 1000.0f,  0.3f, {128,255,255,255} },
163 };
164 
165 Obj1 *obj1 = obj1_data;
166 
167 /*---------------------------------------------------------------------------*
168     Name:           cmModel1_Anim
169     Description:    Move z coord tags
170     Arguments:      Model*, DEMOPadStatus*, Camera*
171     Returns:        none
172  *---------------------------------------------------------------------------*/
cmModel1_Anim(Model * m,DEMOPadStatus * pad,Camera * c)173 static  void    cmModel1_Anim( Model* m, DEMOPadStatus* pad, Camera* c )
174 {
175     s32         i;
176     Obj1*       p;
177     static  u32 anim = 1;
178 
179     // do animation only if referred
180     if ( !(m->flag & MODEL_REFERRED) ) return;
181 
182     // control animation flag
183     if ( pad->buttonDown & PAD_TRIGGER_R ) anim ^= 1;
184     if ( anim == 0 ) return;
185 
186     p = obj1;
187     for ( i = 0; i < 10; i ++ )
188     {
189         // Move object
190         if ( (int)(p->y) & 1 )
191         {
192             f32 ang, dx, dz, dist;
193             ang = (i * 44.4f/10.0f - 44.4f*9.0f/20.0f) * 3.1415926535f/180.0f;
194             dx =  sinf(ang);
195             dz =  cosf(ang);
196             p->x += dx * p->dir;
197             p->z += dz * p->dir;
198             dist = (p->x * p->x + p->z * p->z);
199             if (dist > c->zfar*c->zfar || dist < c->zfar*c->zfar/9)
200             {
201                 p->dir = -p->dir;
202             }
203         }
204         else if ( (int)(p->x) & 1 )
205         {
206             p->z += p->dir;
207 
208             if ( p->z > c->zfar || p->z < c->zfar / 3 )
209             {
210                 p->dir = -p->dir;
211             }
212         }
213         else
214         {
215             p->z += p->dir;
216 
217             // Check if near/far plane
218             if ( p->z > c->zfar || p->z < c->znear )
219             {
220                 // Set new x,y coordinates
221                 p->x += 16.0f;
222                 p->y -= 12.0f;
223                 if ( p->x >  48.0f ) p->x -= 96.0f;
224                 if ( p->y < -48.0f ) p->y += 96.0f;
225 
226                 // Reset z coordinate
227                 p->z = ( p->z > c->zfar ) ? c->znear : c->zfar;
228             }
229         }
230 
231         p ++;
232     }
233     return;
234 }
235 
236 /*---------------------------------------------------------------------------*
237     Name:           cmModel1_Draw
238     Description:    Draw the tags of z coordinate
239     Arguments:      Camera*
240     Returns:        none
241  *---------------------------------------------------------------------------*/
cmModel1_Draw(Camera * c)242 static  void    cmModel1_Draw( Camera* c )
243 {
244     s32         i, j;
245     Mtx         mmtx;
246     Mtx         vmtx;
247     Mtx         fmtx;
248 
249     // Draw grid
250     cmModel0_Draw( c );
251 
252     // Compute model matrix
253     for ( i = 0; i < 3; i ++ )
254     {
255         for ( j = 0; j < 4; j ++ )
256         {
257             mmtx[i][j] = 0.0f;
258         }
259     }
260     mmtx[0][0] =  1.0f;
261     mmtx[1][2] =  1.0f;
262     mmtx[2][1] = -1.0f;
263 
264     // Set modelview matrix
265     MTXConcat( c->viewMtx, mmtx, vmtx );
266     GXSetCurrentMtx( GX_PNMTX0 );
267 
268     // use constant material for color
269     GXSetChanCtrl( GX_COLOR0,
270                    GX_FALSE,            // enable Channel
271                    GX_SRC_REG,          // amb source           (Don't care)
272                    GX_SRC_REG,          // mat source
273                    GX_LIGHT0,           // light mask           (Don't care)
274                    GX_DF_NONE,          // diffuse function     (Don't care)
275                    GX_AF_NONE );        // atten   function     (Don't care)
276     GXSetChanCtrl( GX_ALPHA0,
277                    GX_FALSE,            // enable Channel
278                    GX_SRC_REG,          // amb source           (Don't care)
279                    GX_SRC_REG,          // mat source
280                    GX_LIGHT0,           // light mask           (Don't care)
281                    GX_DF_NONE,          // diffuse function     (Don't care)
282                    GX_AF_NONE );        // atten   function     (Don't care)
283     GXSetNumChans(1);
284 
285     // set several mode
286     GXSetCullMode( GX_CULL_BACK );              // Cull mode
287     GXSetNumTevStages( 1 );             // # of Tev Stage
288     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
289     GXSetTevOp( GX_TEVSTAGE0, GX_MODULATE );
290 
291     // Draw tags
292     DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_BILERP );
293     for ( i = 0; i < 10; i ++ )
294     {
295         // okay, this is very inefficient, but it works!
296         MTXTrans( mmtx, obj1[i].x-12.0f, obj1[i].y-4.0f, obj1[i].z);
297         MTXConcat( vmtx, mmtx, fmtx );
298         MTXScale( mmtx, 2.0f, 2.0f, 1.0f );
299         MTXConcat( fmtx, mmtx, fmtx );
300         GXLoadPosMtxImm( fmtx, GX_PNMTX0 );
301 
302         GXSetChanMatColor( GX_COLOR0A0, obj1[i].color );
303         DEMOPrintf( 0, 0, 0, "%3d", (s32)obj1[i].z );
304     }
305 
306     return;
307 }
308 
309 //============================================================================
310 //  Model 2
311 //  Fly on the hill
312 //============================================================================
313 
314 // Data area
315 static  s16     obj2_height[11][12] = { 0 };
316 static  s32     obj2_ybase = 0;
317 static  s32     obj2_yofst = 0;
318 #define MESHSTEP        100
319 
320 /*---------------------------------------------------------------------------*
321     Name:           cmModel2_Anim
322     Description:    Generate new map and move camera.
323     Arguments:      Model*, DEMOPadStatus*, Camera*
324     Returns:        none
325  *---------------------------------------------------------------------------*/
cmModel2_Anim(Model * m,DEMOPadStatus * pad,Camera * c)326 static  void    cmModel2_Anim( Model* m, DEMOPadStatus* pad, Camera* c )
327 {
328     s32         i, y, h;
329     f32         z, z0, z1, t;
330     static  u32 anim = 1;
331 
332     // do animation only when referred
333     if ( !(m->flag & MODEL_REFERRED) ) return;
334 
335     // control animation flag
336     if ( pad->buttonDown & PAD_TRIGGER_R ) anim ^= 1;
337     if ( anim == 0 ) return;
338 
339     obj2_yofst ++;
340     if ( obj2_yofst >= MESHSTEP )
341     {
342         // update mesh sub-strip
343         y = ( obj2_ybase + 11 ) % 12;
344         for ( i = 0; i < 11; i ++ )
345         {
346             h = obj2_height[i][y] + ((signed)(rand() & 63)) - 32;
347             if ( h > 100 ) h -= 48;
348             if ( h <   0 ) h = -h;
349             obj2_height[i][obj2_ybase] = (s16)h;
350         }
351 
352         // update y coordinate
353         obj2_yofst -= MESHSTEP;
354         obj2_ybase  = ( obj2_ybase + 1 ) % 12;
355     }
356 
357     // camera does trail on middle of 4th and 5th column of the mesh
358     // compute Z coordinate at that point
359     y = ( obj2_ybase + 1 ) % 12;
360     t = (float)obj2_yofst / (float)MESHSTEP;
361     z0 = (float)( obj2_height[4][obj2_ybase] + obj2_height[5][obj2_ybase] );
362     z1 = (float)( obj2_height[4][y         ] + obj2_height[5][y         ] );
363     z  = ( z0 * (1.0f - t) + z1 * t ) / 2.0f + 30.0f;
364 
365     // change height of camera
366     c->position.z = ( z > 30.0f ) ? z : 30.0f;
367 
368     return;
369 }
370 
371 /*---------------------------------------------------------------------------*
372     Name:           cmModel2_Draw
373     Description:    Draw ground
374     Arguments:      Camera* c
375     Returns:        none
376  *---------------------------------------------------------------------------*/
377 // Intensity of diffuse/ambient light
378 #define ITN_DIF         0.60f
379 #define ITN_AMB         0.40f
380 
cmModel2_Draw(Camera * c)381 static  void    cmModel2_Draw( Camera* c )
382 {
383     s32         i, j, y0, y1, sx, sy;
384     Vec         n0, n1;
385     f32         itn0, itn1;
386     u8          r0, g0, b0, r1, g1, b1;
387     static Vec  lightDir = { 0.577f, -0.577f, 0.577f };
388     GXColor     black = { 0, 0, 0, 255 };
389 
390     // set modelview matrix
391     GXSetCurrentMtx( GX_PNMTX0 );
392     GXLoadPosMtxImm( c->viewMtx, GX_PNMTX0 );
393 
394     // use constant material color
395     GXSetChanCtrl( GX_COLOR0,
396                    GX_FALSE,            // enable Channel
397                    GX_SRC_REG,          // amb source
398                    GX_SRC_VTX,          // mat source
399                    GX_LIGHT0,           // light mask
400                    GX_DF_NONE,          // diffuse function
401                    GX_AF_NONE );
402     GXSetChanCtrl( GX_ALPHA0,
403                    GX_FALSE,            // enable Channel
404                    GX_SRC_REG,          // amb source           (Don't care)
405                    GX_SRC_REG,          // mat source
406                    GX_LIGHT0,           // light mask           (Don't care)
407                    GX_DF_NONE,          // diffuse function     (Don't care)
408                    GX_AF_NONE );        // atten   function     (Don't care)
409     GXSetChanMatColor( GX_ALPHA0, black );
410     GXSetNumChans(1);
411 
412     // set several mode
413     GXSetCullMode( GX_CULL_BACK );      // Cull mode
414     GXSetNumTexGens( 0 );               // # of Tex Gens
415     GXSetNumTevStages( 1 );             // # of Tev Stage
416     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL,GX_TEXMAP_NULL,GX_COLOR0A0 );
417     GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );     // Stage 0
418 
419     // set vertex descriptor
420     GXClearVtxDesc();
421     GXSetVtxDesc( GX_VA_POS,  GX_DIRECT );
422     GXSetVtxDesc( GX_VA_CLR0, GX_DIRECT );
423     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS,  GX_POS_XYZ, GX_S16,  0 );
424     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0 );
425 
426     // draw the ground
427     y0 = obj2_ybase;
428     for ( j = 0; j < 11; j ++ )
429     {
430         y1 = ( y0 + 1 ) % 12;
431         GXBegin( GX_TRIANGLES, GX_VTXFMT0, 3*2*10 );
432         for ( i = 0; i < 10; i ++ )
433         {
434             // get vertex
435             sx = (i-5)*MESHSTEP+MESHSTEP/2;
436             sy = (j  )*MESHSTEP-obj2_yofst;
437 
438             // compute intensity of light, then get color
439             n0.x = (float)( obj2_height[i  ][y0] - obj2_height[i-1][y0] );
440             n0.y = (float)( obj2_height[i-1][y1] - obj2_height[i-1][y0] );
441             n0.z = (float)MESHSTEP;
442             VECNormalize( &n0, &n0 );
443             itn0 = VECDotProduct( &n0, &lightDir );
444             itn0 = ( itn0 < 0.0f ? 0.0f : itn0 ) * ITN_DIF + ITN_AMB;
445             r0 = (u8)(itn0 * 64.0f );
446             g0 = (u8)(itn0 * 255.0f);
447             b0 = (u8)(itn0 * 128.0f);
448 
449             // send vertex of triangle 0
450             GXPosition3s16( (s16)(sx), (s16)(sy),
451                             (s16)obj2_height[i][y0] );
452             GXColor3u8( r0, g0, b0 );
453             GXPosition3s16( (s16)(sx), (s16)(sy+MESHSTEP),
454                             (s16)obj2_height[i][y1] );
455             GXColor3u8( r0, g0, b0 );
456             GXPosition3s16( (s16)(sx+MESHSTEP), (s16)(sy),
457                             (s16)obj2_height[i+1][y0] );
458             GXColor3u8( r0, g0, b0 );
459 
460             // compute intensity of light, then get color
461             n1.x = (float)( obj2_height[i-1][y1] - obj2_height[i][y1] );
462             n1.y = (float)( obj2_height[i  ][y0] - obj2_height[i][y1] );
463             n1.z = (float)MESHSTEP;
464             VECNormalize( &n1, &n1 );
465             itn1 = VECDotProduct( &n1, &lightDir );
466             itn1 = ( itn1 < 0.0f ? 0.0f : itn1 ) * ITN_DIF + ITN_AMB;
467             r1 = (u8)(itn1 * 255.0f);
468             g1 = (u8)(itn1 *  92.0f);
469             b1 = (u8)(itn1 *  32.0f);
470 
471             // send vertex of triangle 1
472             GXPosition3s16( (s16)(sx), (s16)(sy+MESHSTEP),
473                             (s16)obj2_height[i][y1] );
474             GXColor3u8( r1, g1, b1 );
475             GXPosition3s16( (s16)(sx+MESHSTEP), (s16)(sy+MESHSTEP),
476                             (s16)obj2_height[i+1][y1] );
477             GXColor3u8( r1, g1, b1 );
478             GXPosition3s16( (s16)(sx+MESHSTEP), (s16)(sy),
479                             (s16)obj2_height[i+1][y0] );
480             GXColor3u8( r1, g1, b1 );
481         }
482         GXEnd( );
483         y0 = y1;
484     }
485     return;
486 }
487 
488 //============================================================================
489 //  Model 3
490 //  Rotating polygons
491 //============================================================================
492 
493 // Data area
494 typedef struct {
495   f32       x, y, z;
496   f32       w, h;
497   f32       ang, avel;  // rotation anime parameter
498   f32       r, dr;      // deform   anime parameter
499   GXColor   color;
500 } Obj3;
501 
502 Obj3    obj3[] = {
503 //  x    y    z   w    h  ang  avel  r     dr   color
504 {  50, 500,  30, 10,  80,   0,  1,   0,  0.1f, {255,  0,  0,255} },
505 {-100, 502,  20, 30,  60,  30,  1,  90, -1.5f, {  0,255,  0,255} },
506 {  50, 504, -50, 20,  80, 120,  1,  72,  3.0f, {  0,  0,255,255} },
507 {  10, 501,  75, 25, 120,  90,  2,   0,  1.0f, {255,128,128, 64} },
508 { -20, 505, -15, 30,  30,  20,  1, 180,  0.2f, {128,255,128,128} },
509 {  40, 503,   0,  5,  80, 150,  3,   0, -0.1f, {128,128,255,192} },
510 };
511 
512 /*---------------------------------------------------------------------------*
513     Name:           cmModel3_Anim
514     Description:    Rotate quadrangles
515     Arguments:      Model*, DEMOPadStatus*, Camera*
516     Returns:        none
517  *---------------------------------------------------------------------------*/
cmModel3_Anim(Model * m,DEMOPadStatus * pad,Camera * c)518 static  void    cmModel3_Anim( Model* m, DEMOPadStatus* pad, Camera* c )
519 {
520     #pragma     unused(c)
521     s32         i;
522     static  u32 anim = 1;
523 
524     // do animation only if referred
525     if ( !(m->flag & MODEL_REFERRED) ) return;
526 
527     // control animation flag
528     if ( pad->buttonDown & PAD_TRIGGER_R ) anim ^= 1;
529     if ( anim == 0 ) return;
530 
531     for ( i = 0; i < sizeof(obj3)/sizeof(Obj3); i ++ )
532     {
533         // Animation of the object
534         obj3[i].r += obj3[i].dr;
535 
536         // Rotation
537         obj3[i].ang += obj3[i].avel * cosf( obj3[i].r * PAI / 180.0f );
538     }
539     return;
540 }
541 
542 /*---------------------------------------------------------------------------*
543     Name:           cmModel3_Draw
544     Description:    Draw the rotating polygons
545     Arguments:      Camera* c
546     Returns:        none
547  *---------------------------------------------------------------------------*/
cmModel3_Draw(Camera * c)548 static  void    cmModel3_Draw( Camera* c )
549 {
550     s32   i;
551     f32   cs, sn, wcos, wsin, hcos, hsin;
552 
553     // Draw grid
554     cmModel0_Draw( c );
555 
556     // Set modelview matrix
557     GXSetCurrentMtx( GX_PNMTX0 );
558     GXLoadPosMtxImm( c->viewMtx, GX_PNMTX0 );
559 
560     // use constant material color
561     GXSetChanCtrl( GX_COLOR0,
562                    GX_FALSE,            // enable Channel
563                    GX_SRC_REG,          // amb source           (Don't care)
564                    GX_SRC_REG,          // mat source
565                    GX_LIGHT0,           // light mask           (Don't care)
566                    GX_DF_NONE,          // diffuse function     (Don't care)
567                    GX_AF_NONE );        // atten   function     (Don't care)
568     GXSetChanCtrl( GX_ALPHA0,
569                    GX_FALSE,            // enable Channel
570                    GX_SRC_REG,          // amb source           (Don't care)
571                    GX_SRC_REG,          // mat source
572                    GX_LIGHT0,           // light mask           (Don't care)
573                    GX_DF_NONE,          // diffuse function     (Don't care)
574                    GX_AF_NONE );        // atten   function     (Don't care)
575     GXSetNumChans(1);
576 
577     // set several mode
578     GXSetCullMode( GX_CULL_BACK );      // Cull mode
579     GXSetNumTexGens( 0 );               // # of Tex Gens
580     GXSetNumTevStages( 1 );             // # of Tev Stage
581     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL,GX_TEXMAP_NULL,GX_COLOR0A0 );
582     GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );     // Stage 0
583 
584     // set vertex descriptor
585     GXClearVtxDesc();
586     GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
587     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS,  GX_POS_XYZ, GX_F32, 0 );
588 
589     // Draw parameters to the window and turn on bilerp filtering
590     for ( i = 0; i < sizeof(obj3)/sizeof(Obj3); i ++ )
591     {
592         cs = cosf( obj3[i].ang * PAI / 180.0f );
593         sn = sinf( obj3[i].ang * PAI / 180.0f );
594         wcos = obj3[i].w * cs;
595         wsin = obj3[i].w * sn;
596         hcos = obj3[i].h * cs;
597         hsin = obj3[i].h * sn;
598         GXSetChanMatColor( GX_COLOR0A0, obj3[i].color );
599         GXBegin( GX_QUADS, GX_VTXFMT0, 4 );
600             GXPosition3f32( obj3[i].x + wcos + hsin, obj3[i].y,
601                             obj3[i].z - wsin + hcos );
602             GXPosition3f32( obj3[i].x + wcos - hsin, obj3[i].y,
603                             obj3[i].z - wsin - hcos );
604             GXPosition3f32( obj3[i].x - wcos - hsin, obj3[i].y,
605                             obj3[i].z + wsin - hcos );
606             GXPosition3f32( obj3[i].x - wcos + hsin, obj3[i].y,
607                             obj3[i].z + wsin + hcos );
608         GXEnd();
609     }
610 
611     return;
612 }
613 
614 //============================================================================
615 //  Model 4
616 //  Wondering depth tags
617 //============================================================================
618 
619 // Data area
620 typedef struct {                // for z coord tag data
621   f32     x,  y,  z;
622   f32     dx, dy, dz;
623   GXColor color;
624 } Obj4;
625 
626 Obj4    obj4[10] = {
627   {  6.0f,   3.0f,  400.0f,  0.00f,-0.01f, 0.00f, {255,255,255,255} },
628   {-20.0f,  10.0f,  400.0f,  0.00f, 0.05f, 0.00f, {255,255,  0,255} },
629   {-20.0f,   0.0f,  400.0f,  0.00f,-0.02f, 0.00f, {255,  0,255,255} },
630   {-20.0f, -30.0f,  401.0f,  0.00f, 0.04f, 0.00f, {  0,255,255,255} },
631   { 10.0f, -30.0f,  399.0f,  0.00f, 0.09f, 0.00f, {255,  0,  0,255} },
632   { 40.0f, -30.0f,  500.0f, -0.02f, 0.00f, 0.00f, {  0,  0,255,255} },
633   { 40.0f,   0.0f,  300.0f,  0.04f, 0.00f, 0.00f, {  0,255,  0,255} },
634   { 40.0f,  50.0f,  402.0f, -0.06f, 0.00f, 0.00f, {255,255,128,255} },
635   {  0.0f,  55.0f,  398.0f, -0.07f, 0.00f, 0.00f, {255,128,255,255} },
636   {-60.0f,  60.0f,  400.0f,  0.03f, 0.00f, 0.00f, {128,255,255,255} },
637 };
638 
639 /*---------------------------------------------------------------------------*
640     Name:           cmModel4_Anim
641     Description:    Move depth tags
642     Arguments:      Model*, DEMOPadStatus*, Camera*
643     Returns:        none
644  *---------------------------------------------------------------------------*/
cmModel4_Anim(Model * m,DEMOPadStatus * pad,Camera * c)645 static  void    cmModel4_Anim( Model* m, DEMOPadStatus* pad, Camera* c )
646 {
647     #pragma     unused(c)
648     s32         i;
649     static  u32 anim = 1;
650 
651     // do animation only if referred
652     if ( !(m->flag & MODEL_REFERRED) ) return;
653 
654     // control animation flag
655     if ( pad->buttonDown & PAD_TRIGGER_R ) anim ^= 1;
656     if ( anim == 0 ) return;
657 
658     for ( i = 0; i < sizeof(obj4)/sizeof(Obj4); i ++ )
659     {
660         obj4[i].x += obj4[i].dx;
661         obj4[i].y += obj4[i].dy;
662         obj4[i].z += obj4[i].dz;
663         if ( obj4[i].x >  300.0f ) obj4[i].x -= 600.0f;
664         if ( obj4[i].x < -300.0f ) obj4[i].x += 600.0f;
665         if ( obj4[i].y >  300.0f ) obj4[i].y -= 600.0f;
666         if ( obj4[i].y < -300.0f ) obj4[i].y += 600.0f;
667     }
668     return;
669 }
670 
671 /*---------------------------------------------------------------------------*
672     Name:           cmModel4_Draw
673     Description:    Draw the wondering depth tags
674     Arguments:      Camera* c
675     Returns:        none
676  *---------------------------------------------------------------------------*/
cmModel4_Draw(Camera * c)677 static  void    cmModel4_Draw( Camera* c )
678 {
679     s32         i, j;
680     Mtx         mmtx;
681 
682     // Draw grid
683     cmModel0_Draw( c );
684 
685     // Compute model matrix
686     for ( i = 0; i < 3; i ++ )
687     {
688         for ( j = 0; j < 4; j ++ )
689         {
690             mmtx[i][j] = 0.0f;
691         }
692     }
693     mmtx[0][0] =  2.0f;
694     mmtx[1][2] =  1.0f;
695     mmtx[2][1] = -2.0f;
696 
697     // Set modelview matrix
698     MTXConcat( c->viewMtx, mmtx, mmtx );
699     GXLoadPosMtxImm( mmtx, GX_PNMTX0 );
700     GXSetCurrentMtx( GX_PNMTX0 );
701 
702     // Draw parameters to the window and turn on bilerp filtering
703     DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_BILERP );
704     for ( i = 0; i < 10; i ++ )
705     {
706         DEMOPrintf( (s16)(obj4[i].x-12.0f),
707                     (s16)(obj4[i].y- 4.0f),
708                     (s16)(obj4[i].z), "%3d", (s32)obj4[i].z );
709     }
710 
711     return;
712 }
713 
714 /*======== End of cmn-model.c ========*/
715