1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     frb-vfilter.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 #include <demo.h>
15 
16 #define MAX_NUM_NTSC_RM             6
17 #define MAX_NUM_NTSC_RM_NONPROG     4
18 #define MAX_NUM_PAL_RM              4
19 #define MAX_NUM_PAL_RM_NONPROG      4
20 #define MAX_NUM_MPAL_RM             4
21 #define MAX_NUM_MPAL_RM_NONPROG     4
22 #define MAX_NUM_EURGB_RM            4
23 #define MAX_NUM_EURGB_RM_NONPROG    4
24 
25 
26 enum{
27     CTRL_BRIGHTNESS  = 0,
28     CTRL_RATIO       = 1,
29     CTRL_RENDERMODE  = 2,
30     CTRL_PROGRESSIVE = 3
31 };
32 
33 
34 typedef struct _GXRMObjPtrStr
35 {
36     GXRenderModeObj*    GXRMObjPtr;
37     char*               GXRMObjString;
38 }GXRMObjPtrStr;
39 
40 GXRMObjPtrStr GXRMObjPtrStrTblNtsc[MAX_NUM_NTSC_RM] =
41 {
42     {&GXNtsc240Ds,      "GXNtsc240Ds\n"},
43 //  {&GXNtsc240DsAa,    "GXNtsc240DsAa\n"},
44     {&GXNtsc240Int,     "GXNtsc240Int\n"},
45 //  {&GXNtsc240IntAa,   "GXNtsc240IntAa\n"},
46     {&GXNtsc480IntDf,   "GXNtsc480IntDf\n"},
47     {&GXNtsc480Int,     "GXNtsc480Int\n"},
48 //  {&GXNtsc480IntAa,   "GXNtsc480IntAa\n"},
49     {&GXNtsc480Prog,    "GXNtsc480Prog\n"},
50 //  {&GXNtsc480ProgAa,  "GXNtsc480ProgAa\n"},
51     {&GXNtsc480ProgSoft,"GXNtsc480ProgSoft\n"},
52 };
53 
54 GXRMObjPtrStr GXRMObjPtrStrTblPal[MAX_NUM_PAL_RM] =
55 {
56     {&GXPal264Ds,       "GXPal264Ds\n"},
57 //  {&GXPal264DsAa,     "GXPal264DsAa\n"},
58     {&GXPal264Int,      "GXPal264Int\n"},
59 //  {&GXPal264IntAa,    "GXPal264IntAa\n"},
60     {&GXPal528IntDf,    "GXPal528IntDf\n"},
61     {&GXPal528Int,      "GXPal528Int\n"},
62 //  {&GXPal524IntAa,    "GXPal524IntAa\n"},
63 };
64 
65 GXRMObjPtrStr GXRMObjPtrStrTblMPal[MAX_NUM_MPAL_RM] =
66 {
67     {&GXMpal240Ds,          "GXMpal240Ds\n"},
68 //  {&GXMpal240DsAa,        "GXMpal240DsAa\n"},
69     {&GXMpal240Int,         "GXMpal240Int\n"},
70 //  {&GXMpal240IntAa,       "GXMpal240IntAa\n"},
71     {&GXMpal480IntDf,       "GXMpal480IntDf\n"},
72     {&GXMpal480Int,         "GXMpal480Int\n"},
73 //  {&GXMpal480IntAa,       "GXMpal480IntAa\n"},
74 };
75 
76 GXRMObjPtrStr GXRMObjPtrStrTblEURGB[MAX_NUM_EURGB_RM] =
77 {
78     {&GXEurgb60Hz240Ds,     "GXEurgb60Hz240Ds\n"},
79 //  {&GXEurgb60Hz240DsAa,   "GXEurgb60Hz240DsAa\n"},
80     {&GXEurgb60Hz240Int,    "GXEurgb60Hz240Int\n"},
81 //  {&GXEurgb60Hz240IntAa,  "GXEurgb60Hz240IntAa\n"},
82     {&GXEurgb60Hz480IntDf,  "GXEurgb60Hz480IntDf\n"},
83     {&GXEurgb60Hz480Int,    "GXEurgb60Hz480Int\n"},
84 //  {&GXEurgb60Hz480IntAa,  "GXEurgb60Hz480IntAa\n"}
85 };
86 
87 /*---------------------------------------------------------------------------*
88    The macro ATTRIBUTE_ALIGN provides a convenient way to align initialized
89    arrays.  Alignment of vertex arrays to 32B IS NOT required, but may result
90    in a slight performance improvement.
91  *---------------------------------------------------------------------------*/
92 f32 Verts_f32[] ATTRIBUTE_ALIGN(32) =
93 {
94 //      x, y, z
95     0.0f, 0.0f, 1.0f,    // 0:0
96     0.0f, 1.0f, 0.0f,    // 0:1
97     1.0f, 0.0f, 0.0f,    // 0:2
98     0.0f, 0.0f, 1.0f,    // 1:0
99     -1.0f, 0.0f, 0.0f,   // 1:1
100     0.0f, 1.0f, 0.0f,    // 1:2
101     0.0f, 0.0f, 1.0f,    // 2:0
102     0.0f, -1.0f, 0.0f,   // 2:1
103     -1.0f, 0.0f, 0.0f,   // 2:2
104     0.0f, 0.0f, 1.0f,    // 3:0
105     1.0f, 0.0f, 0.0f,    // 3:1
106     0.0f, -1.0f, 0.0f,   // 3:2
107     0.0f, 0.0f, -1.0f,   // 4:0
108     1.0f, 0.0f, 0.0f,    // 4:1
109     0.0f, 1.0f, 0.0f,    // 4:2
110     0.0f, 0.0f, -1.0f,   // 5:0
111     0.0f, 1.0f, 0.0f,    // 5:1
112     -1.0f, 0.0f, 0.0f,   // 5:2
113     0.0f, 0.0f, -1.0f,   // 6:0
114     -1.0f, 0.0f, 0.0f,   // 6:1
115     0.0f, -1.0f, 0.0f,   // 6:2
116     0.0f, 0.0f, -1.0f,   // 7:0
117     0.0f, -1.0f, 0.0f,   // 7:1
118     1.0f, 0.0f, 0.0f     // 7:2
119 };
120 
121 f32 Tex_f32[] ATTRIBUTE_ALIGN(32) =
122 {
123     1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f,
124     0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f,
125     1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f,
126     0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f,
127     0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f,
128     1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f,
129     0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f,
130     1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f,
131 
132 };
133 
134 u32    ticks = 0;     // time counter
135 
136 typedef struct{
137     s32    control;   // mode
138     BOOL   flug_prog; // progressive ON/OFF
139 } myControlParam;
140 
141 typedef struct{
142     u8 newFilter[7];
143     f32 brightness;
144     f32 ratio;
145     GXBool flug;
146     u16 df_a, df_b;
147     u32 RMIndex;
148 } myCopyFilter;
149 
150 static u32  MaxNumRM;
151 static u32  MaxNumRMNonProg;
152 
153 static GXRMObjPtrStr* GXRMObjPtrStrTbl;
154 
155 /*---------------------------------------------------------------------------*
156    Forward references
157  *---------------------------------------------------------------------------*/
158 
159 void        main                ( void );
160 static void myDrawCaptionTick   ( myCopyFilter, myControlParam * );
161 static void CameraInit          ( Mtx );
162 static void DrawInit            ( void );
163 static void DrawTick            ( Mtx );
164 static void DrawBackgroundTick  ( Mtx, GXTexObj * );
165 static void AnimTick            ( void );
166 static void PrintIntro          ( void );
167 static void myInitCopyFilter    ( myCopyFilter *);
168 static void myCopyFilterTick    ( myCopyFilter *, myControlParam *);
169 
170 /*---------------------------------------------------------------------------*
171    Application main loop
172  *---------------------------------------------------------------------------*/
173 
main(void)174 void main ( void )
175 {
176     Mtx         v;
177     PADStatus   pad[PAD_MAX_CONTROLLERS];
178     GXTexObj    texObj,texObj_zebra_1, texObj_zebra_2, texObj_zebra_4;
179     TPLPalettePtr tpl = (TPLPalettePtr)NULL;
180     myCopyFilter cf;
181     myControlParam cp;
182     GXRenderModeObj * rmode;
183 
184     VIInit();
185     switch( VIGetTvFormat() )
186     {
187       case VI_NTSC:
188         MaxNumRM         = MAX_NUM_NTSC_RM;
189         MaxNumRMNonProg  = MAX_NUM_NTSC_RM_NONPROG;
190         GXRMObjPtrStrTbl = GXRMObjPtrStrTblNtsc;
191         OSReport("NTSC\n");
192         break;
193       case VI_PAL:
194         MaxNumRM         = MAX_NUM_PAL_RM;
195         MaxNumRMNonProg  = MAX_NUM_PAL_RM_NONPROG;
196         GXRMObjPtrStrTbl = GXRMObjPtrStrTblPal;
197         OSReport("PAL\n");
198         break;
199       case VI_MPAL:
200         MaxNumRM         = MAX_NUM_MPAL_RM;
201         MaxNumRMNonProg  = MAX_NUM_MPAL_RM_NONPROG;
202         GXRMObjPtrStrTbl = GXRMObjPtrStrTblMPal;
203         OSReport("M/PAL\n");
204         break;
205       case VI_EURGB60:
206         MaxNumRM         = MAX_NUM_EURGB_RM;
207         MaxNumRMNonProg  = MAX_NUM_EURGB_RM_NONPROG;
208         GXRMObjPtrStrTbl = GXRMObjPtrStrTblEURGB;
209         OSReport("EU RGB 60\n");
210         break;
211       default:
212         OSHalt("Unknown TV Format\n");
213     }
214 
215     cf.RMIndex = 3; // GXNtsc480Int
216 
217     myInitCopyFilter( &cf );
218 
219     cp.control = 0;       // BRIGHTNESS
220     cp.flug_prog = FALSE; // PROGRESSIVE OFF
221 
222     rmode = GXRMObjPtrStrTbl[cf.RMIndex].GXRMObjPtr;
223 
224     DEMOInit(rmode);
225 
226     TPLGetPalette(&tpl, "gxTests/vfilter01.tpl");
227     TPLGetGXTexObjFromPalette(tpl, &texObj, 0);
228     TPLGetGXTexObjFromPalette(tpl, &texObj_zebra_1, 1);
229     TPLGetGXTexObjFromPalette(tpl, &texObj_zebra_2, 2);
230     TPLGetGXTexObjFromPalette(tpl, &texObj_zebra_4, 3);
231 
232     pad[0].button = 0;
233 
234     PrintIntro();
235 
236     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
237     {
238 
239         DEMOPadRead();
240         myCopyFilterTick( &cf, &cp );
241 
242         rmode = GXRMObjPtrStrTbl[cf.RMIndex].GXRMObjPtr;
243         GXSetCopyFilter( rmode->aa, rmode->sample_pattern, GX_TRUE, cf.newFilter );
244 
245         DEMOBeforeRender();
246 
247         myDrawCaptionTick(cf, &cp);
248         CameraInit(v);
249         DrawBackgroundTick(v, &texObj);
250 
251         GXLoadTexObj(&texObj_zebra_1, GX_TEXMAP1); // zebra : width 1
252         GXLoadTexObj(&texObj_zebra_2, GX_TEXMAP2); // zebra : width 2
253         GXLoadTexObj(&texObj_zebra_4, GX_TEXMAP3); // zebra : width 4
254 
255         DrawInit();
256         DrawTick(v);
257 
258         DEMODoneRender();
259 
260 
261         AnimTick();        // Update animation.
262 
263     }
264 
265     OSHalt("End of demo.");
266 
267 }
268 
269 /*---------------------------------------------------------------------------*
270    Functions
271  *---------------------------------------------------------------------------*/
272 
273 /*---------------------------------------------------------------------------*
274     Name:           myDrawCaptionTick
275 
276     Description:    Indicate current status on a screen
277 
278     Arguments:      cf          pointer of myCopyFilter
279                     cp          pointer of myControlparam
280 
281     Returns:        none
282  *---------------------------------------------------------------------------*/
283 
myDrawCaptionTick(myCopyFilter cf,myControlParam * cp)284 static void myDrawCaptionTick( myCopyFilter cf, myControlParam * cp ){
285 
286     s16 i;
287     s16 pos_x = 15;
288     s16 pos_y = 30;
289     s16 pos_z = 1;
290     char * indent[4];
291 
292     DEMOInitCaption(DM_FT_XLU, 320, 240);
293 
294     DEMOPrintf(pos_x, 20, pos_z, "frb-vfilter");
295     DEMOPrintf(pos_x, 25, pos_z, "-----------");
296 
297     for (i = 0; i < 7; ++i){
298         DEMOPrintf((s16)(pos_x+10), (s16)(i*10+10+pos_y), pos_z, "%d", cf.newFilter[i]);
299     }
300 
301     for (i = 0;i < 4;i++){
302         if(i == cp->control)
303             indent[i]=">";
304         else
305             indent[i]=" ";
306     }
307 
308     DEMOPrintf(pos_x, (s16)(90  + pos_y), pos_z, "%sBRIGHTNESS",indent[0]);
309     DEMOPrintf(pos_x, (s16)(100 + pos_y), pos_z, " %f", cf.brightness/64.0F);
310 
311     DEMOPrintf(pos_x, (s16)(115 + pos_y), pos_z, "%sRATIO",indent[1]);
312     DEMOPrintf(pos_x, (s16)(125 + pos_y), pos_z, " %f%%", cf.ratio*100.0F);
313 
314     DEMOPrintf(pos_x, (s16)(140 + pos_y), pos_z, "%sRENDER MODE",indent[2]);
315     DEMOPrintf(pos_x, (s16)(150 + pos_y), pos_z, " %s", GXRMObjPtrStrTbl[cf.RMIndex].GXRMObjString);
316 
317     DEMOPrintf(pos_x, (s16)(165 + pos_y), pos_z, "%sPROGRESSIVE",indent[3]);
318     if(cp->flug_prog)
319         DEMOPrintf(pos_x, (s16)(175 + pos_y), pos_z, " ON");
320     else
321         DEMOPrintf(pos_x, (s16)(175 + pos_y), pos_z, " OFF");
322 
323 }
324 
325 
326 /*---------------------------------------------------------------------------*
327     Name:           myInitCopyFilter
328 
329     Description:    Initialize the struct " myCopyFilter ".
330 
331     Arguments:      cf          pointer of myCopyFilter
332 
333     Returns:        none
334  *---------------------------------------------------------------------------*/
335 
myInitCopyFilter(myCopyFilter * cf)336 static void myInitCopyFilter( myCopyFilter * cf ){
337 
338     u32 i;
339     GXRenderModeObj * rmode;
340     f32 tmp_center = 0.0f;
341 
342     rmode = GXRMObjPtrStrTbl[cf->RMIndex].GXRMObjPtr;
343 
344     cf->brightness = 0;
345 
346     for(i = 0;i < 7; i++){
347         cf->brightness += rmode->vfilter[i];
348         cf->newFilter[i] = rmode->vfilter[i];
349         if(i > 1 && i < 5)
350             tmp_center += rmode->vfilter[i];
351     }
352     cf->ratio = tmp_center / cf->brightness;
353     cf->df_b = (u16)(cf->brightness * cf->ratio);
354     cf->df_a = (u16)(cf->brightness - cf->df_b);
355 
356 }
357 
358 /*---------------------------------------------------------------------------*
359     Name:           myCopyFilterTick
360 
361     Description:    Calculates the parameter of myCopyFilter once
362                         with input from PAD.
363 
364     Arguments:      cf          pointer of myCopyFilter
365                     cp          pointer of myControlParam
366 
367     Returns:        none
368  *---------------------------------------------------------------------------*/
369 
myCopyFilterTick(myCopyFilter * cf,myControlParam * cp)370 static void myCopyFilterTick( myCopyFilter * cf, myControlParam * cp){
371         s16 i;
372         u8 temp_a[4], temp_b[3];
373 
374         u16 button;
375         u16 buttonDown;
376         GXRenderModeObj * rmode;
377         u32 max_rm;
378         BOOL pad_r = FALSE;
379         BOOL pad_l = FALSE;
380         BOOL flug_change_rm = FALSE;
381         BOOL flug_change_param = FALSE;
382         BOOL flug_bad_param = FALSE;
383 
384         button = DEMOPadGetButton(PAD_CHAN0);
385         buttonDown = DEMOPadGetButtonDown(PAD_CHAN0);
386 
387         if( buttonDown & ( PAD_BUTTON_RIGHT | PAD_BUTTON_A )){
388             pad_r = TRUE;
389         }
390         else if( buttonDown & ( PAD_BUTTON_LEFT | PAD_BUTTON_B )){
391             pad_l = TRUE;
392         }
393         else{
394             if(buttonDown & PAD_BUTTON_DOWN){
395                 cp->control = (cp->control + 1) % 4;
396             }
397             else if(buttonDown & PAD_BUTTON_UP){
398                 cp->control = (cp->control + 3) % 4;
399             }
400         }
401 
402         if(cp->control == CTRL_BRIGHTNESS){
403             // increase brightness
404             if((button & (PAD_BUTTON_RIGHT | PAD_BUTTON_A))&&
405                 cf->df_b < 64*3 && cf->df_a < 64*4){
406                     cf->brightness++;
407                     cf->df_b = (u16)(cf->brightness * cf->ratio);
408                     cf->df_a = (u16)(cf->brightness - cf->df_b);
409                     flug_change_param = TRUE;
410 
411             }
412             // decrease brightness
413             else if(button & (PAD_BUTTON_LEFT | PAD_BUTTON_B)){
414                 if(cf->brightness > 0){
415                     cf->brightness--;
416                     cf->df_b = (u16)(cf->brightness * cf->ratio);
417                     cf->df_a = (u16)(cf->brightness - cf->df_b);
418                     flug_change_param = TRUE;
419                 }
420             }
421         }
422         else if(cp->control == CTRL_RATIO){
423             // increase a ratio of center line
424             if(button & (PAD_BUTTON_RIGHT | PAD_BUTTON_A)){
425                 if(cf->df_a > 0 && cf->df_b < 63*3){
426 
427                     cf->df_b++;
428                     cf->df_a--;
429 
430                     cf->ratio = (f32)cf->df_b / cf->brightness;
431                     flug_change_param = TRUE;
432                 }
433             }
434             // decrease a ratio of center line
435             else if(button & (PAD_BUTTON_LEFT | PAD_BUTTON_B)){
436                 if(cf->df_b > 0 && cf->df_a < 63*4){
437 
438                     cf->df_b--;
439                     cf->df_a++;
440 
441                     cf->ratio = (f32)cf->df_b / cf->brightness;
442                     flug_change_param = TRUE;
443                 }
444             }
445         }
446         else if(cp->control == CTRL_RENDERMODE){
447             // increase RenderModeIndex
448             if(pad_l){
449 
450                 if(cp->flug_prog)
451                     max_rm = MaxNumRM;
452                 else
453                     max_rm = MaxNumRMNonProg;
454 
455                 cf->RMIndex++;
456                 cf->RMIndex %= max_rm;
457 
458                 rmode = GXRMObjPtrStrTbl[cf->RMIndex].GXRMObjPtr;
459                 DEMOReInit(rmode);
460 
461                 flug_change_rm = TRUE;
462 
463             }
464             // decrease RenderModeIndex
465             else if(pad_r){
466 
467                 if(cp->flug_prog)
468                     max_rm = MaxNumRM;
469                 else
470                     max_rm = MaxNumRMNonProg;
471 
472                 if(cf->RMIndex==0){
473                     cf->RMIndex = max_rm;
474                 }
475                 cf->RMIndex--;
476 
477                 rmode = GXRMObjPtrStrTbl[cf->RMIndex].GXRMObjPtr;
478                 DEMOReInit(rmode);
479 
480                 flug_change_rm = TRUE;
481 
482             }
483         }
484         else if(cp->control == CTRL_PROGRESSIVE){
485 
486             if(pad_r || pad_l)
487                 cp->flug_prog = !cp->flug_prog;
488 
489             if((cp->flug_prog == FALSE) && cf->RMIndex >= MaxNumRMNonProg){
490                 cf->RMIndex = 0;
491                 rmode = GXRMObjPtrStrTbl[cf->RMIndex].GXRMObjPtr;
492                 DEMOReInit(rmode);
493 
494                 flug_change_rm = TRUE;
495 
496             }
497 
498         }
499 
500         // get back to initial condition
501         if((button & PAD_TRIGGER_Z) || flug_change_rm){
502             myInitCopyFilter( cf );
503         }
504 
505         // calculate BRIGHTNESS and RATIO
506         else if(flug_change_param){
507 
508             flug_bad_param = FALSE;
509 
510             // calculate each 7 points' value
511             for(i=0; i<4; i++){
512                 if(i < cf->df_a % 4)
513                     temp_a[i]=(u8)((f32)cf->df_a / 4.0F + 1);
514                 else
515                     temp_a[i]=(u8)((f32)cf->df_a / 4.0F);
516                 if(temp_a[i]>63)
517                     flug_bad_param = TRUE;
518             }
519             for(i=0; i<3; i++){
520                 if(i < cf->df_b % 3)
521                     temp_b[i]=(u8)((f32)cf->df_b / 3.0F + 1);
522                 else
523                     temp_b[i]=(u8)((f32)cf->df_b / 3.0F);
524                 if(temp_b[i]>63)
525                     flug_bad_param = TRUE;
526             }
527 
528             if(!flug_bad_param){
529                 cf->newFilter[0] = temp_a[0];
530                 cf->newFilter[1] = temp_a[2];
531                 cf->newFilter[2] = temp_b[0];
532                 cf->newFilter[3] = temp_b[1];
533                 cf->newFilter[4] = temp_b[2];
534                 cf->newFilter[5] = temp_a[1];
535                 cf->newFilter[6] = temp_a[3];
536             }
537         }
538 }
539 
540 
541 /*---------------------------------------------------------------------------*
542     Name:           CameraInit
543 
544     Description:    Initialize the projection matrix and load into hardware.
545                     Initialize the view matrix.
546 
547     Arguments:      v       view matrix
548 
549     Returns:        none
550  *---------------------------------------------------------------------------*/
551 
CameraInit(Mtx v)552 static void CameraInit ( Mtx v )
553 {
554     Mtx44   p;      // projection matrix
555     Vec     up      = {0.0F, 1.0F, 0.0F};
556     Vec     camLoc  = {0.5F, 1.0F, -3.0F};
557     Vec     objPt   = {0.5F, 0.0F, 0.0F};
558     f32     top     = 0.0375F;
559     f32     left    = -0.050F;
560     f32     znear   = 0.1F;
561     f32     zfar    = 10.0F;
562 
563     MTXFrustum(p, top, -top, left, -left, znear, zfar);
564     GXSetProjection(p, GX_PERSPECTIVE);
565 
566     MTXLookAt(v, &camLoc, &up, &objPt);
567 }
568 
569 /*---------------------------------------------------------------------------*
570     Name:           DrawBackTick
571 
572     Description:    Draw the background once.
573 
574     Arguments:      v       view matrix
575                     texObj      pointer of GXTexObj
576 
577     Returns:        none
578  *---------------------------------------------------------------------------*/
579 
DrawBackgroundTick(Mtx v,GXTexObj * texObj)580 static void DrawBackgroundTick( Mtx v , GXTexObj * texObj){
581 
582     Mtx    m;    // Model matrix.
583     Mtx    mv;   // Modelview matrix.
584 
585     GXSetNumTexGens(1);
586     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
587     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
588     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
589 
590     MTXIdentity( m );
591     MTXConcat(v, m, mv);
592     GXLoadPosMtxImm(mv, GX_PNMTX0);
593 
594     GXClearVtxDesc();
595     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
596     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
597 
598     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS,  GX_POS_XYZ,  GX_F32,    0);
599     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST,   GX_F32,    0);
600 
601     GXLoadTexObj(texObj, GX_TEXMAP0);
602 
603     GXBegin(GX_QUADS, GX_VTXFMT0, 4);
604 
605         GXPosition3f32( 3.0f, 1.0f, 1.0f );
606         GXTexCoord2f32( 0.0f, 0.0f );
607         GXPosition3f32( -1.5f, 1.0f, 1.0f );
608         GXTexCoord2f32( 1.0f, 0.0f );
609         GXPosition3f32( -1.7f, -2.2f, 1.0f );
610         GXTexCoord2f32( 1.0f, 1.0f );
611         GXPosition3f32( 3.1f, -2.2f, 1.0f );
612         GXTexCoord2f32( 0.0f, 1.0f );
613 
614     GXEnd();
615 
616 }
617 
618 /*---------------------------------------------------------------------------*
619     Name:           DrawInit
620 
621     Description:    Initializes the vertex attribute format 0, and sets
622                     the array pointers and strides for the indexed data.
623 
624     Arguments:      none
625 
626     Returns:        none
627  *---------------------------------------------------------------------------*/
628 
DrawInit(void)629 static void DrawInit( void )
630 {
631     GXColor black = {0, 0, 0, 0};
632 
633     GXSetCopyClear(black, 0x00ffffff);
634 
635     GXSetNumTexGens(1);
636     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
637     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
638 
639     // change zebra texture at regular time intervals
640     switch ((u32)(ticks / 180) % 3)
641     {
642         case 0:
643             GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL);
644             break;
645         case 1:
646             GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP2, GX_COLOR_NULL);
647             break;
648         case 2:
649             GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP3, GX_COLOR_NULL);
650             break;
651         default:
652             GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL);
653             break;
654     }
655 
656     // Set current vertex descriptor to enable position and color0.
657     // Both use 8b index to access their data arrays.
658     GXClearVtxDesc();
659     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
660     GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
661 
662     // Position has 3 elements (x,y,z), each of type f32.
663     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
664 
665     // Texture Chood 0 has 2 elements (s,t), each of type f32.
666     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
667 
668     // stride = 3 elements (x,y,z) each of type f32
669     GXSetArray(GX_VA_POS, Verts_f32, 3*sizeof(f32));
670     // stride = 2 elements (s,t) each of type f32
671     GXSetArray(GX_VA_TEX0, Tex_f32, 2*sizeof(f32));
672 
673     GXSetNumChans(0);
674 
675 }
676 
677 /*---------------------------------------------------------------------------*
678     Name:           Vertex
679 
680     Description:    Create my vertex format
681 
682     Arguments:      t        8-bit triangle index
683                     v        8-bit vertex index
684 
685     Returns:        none
686  *---------------------------------------------------------------------------*/
687 
Vertex(u8 t,u8 v)688 static inline void Vertex( u8 t, u8 v )
689 {
690     u8 tv3 = (u8) (3 * t + v);
691     GXPosition1x8(tv3);
692     GXTexCoord1x8(tv3);
693 }
694 
695 /*---------------------------------------------------------------------------*
696     Name:           DrawTick
697 
698     Description:    Draw the model once.
699 
700     Arguments:      v       view matrix
701 
702     Returns:        none
703  *---------------------------------------------------------------------------*/
704 
DrawTick(Mtx v)705 static void DrawTick( Mtx v )
706 {
707     Mtx    m;        // Model matrix.
708     Mtx    mv;       // Modelview matrix.
709     u8     iTri;     // index of triangle
710     u8     iVert;    // index of vertex
711 
712     // model has a rotation about z axis
713     MTXRotDeg(m, 'y', 1 * ticks);
714     MTXConcat(v, m, mv);
715     GXLoadPosMtxImm(mv, GX_PNMTX0);
716 
717     GXBegin(GX_TRIANGLES, GX_VTXFMT0, 24);
718 
719     // for all triangles of octahedron, ...
720     for (iTri = 0; iTri < 8; ++iTri)
721     {
722         // for all vertices of triangle, ...
723         for (iVert = 0; iVert < 3; ++iVert)
724         {
725             Vertex(iTri, iVert);
726         }
727     }
728 
729     GXEnd();
730 }
731 
732 /*---------------------------------------------------------------------------*
733     Name:           AnimTick
734 
735     Description:    Computes next time step.
736 
737     Arguments:      none
738 
739     Returns:        none
740  *---------------------------------------------------------------------------*/
741 
AnimTick(void)742 static void AnimTick( void )
743 {
744     ticks++;
745 }
746 
747 /*---------------------------------------------------------------------------*
748     Name:            PrintIntro
749 
750     Description:     Prints the directions on how to use this demo.
751 
752     Arguments:       none
753 
754     Returns:         none
755  *---------------------------------------------------------------------------*/
756 
PrintIntro(void)757 static void PrintIntro( void )
758 {
759     OSReport("\n\n********************************\n");
760     OSReport("to change item:\n");
761     OSReport("     + UP/DOWN\n");
762     OSReport("to change BRIGHTNESS/RATIO\n");
763     OSReport("     + RIGHT or Button A : increase parameter\n");
764     OSReport("     + LEFT  or Button B : decrease parameter\n");
765     OSReport("to change RENDERMODE/PROGRESSIVE\n");
766     OSReport("     + RIGHT, + LEFT, Button A and B : change parameter\n");
767     OSReport("     (if you choose PROGRESSIVE OFF,\n");
768     OSReport("      progressive mode are excluded from RENDERMODE)\n");
769     OSReport("to return default parameters\n");
770     OSReport("     Button Z\n");
771     OSReport("to quit:\n");
772     OSReport("     START : quit the program.\n");
773     OSReport("********************************\n");
774 }
775 
776 /*============================================================================*/
777