1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tex-2-tex.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 #include <math.h>
16 
17 /*---------------------------------------------------------------------------*
18    Forward references
19  *---------------------------------------------------------------------------*/
20 
21 void        main            ( void );
22 
23 static void CameraInit      ( void );
24 static void DrawInit        ( void );
25 static void DrawTick        ( void );
26 
27 static void AnimTick        ( void );
28 
29 static void DrawSmoothCube  ( float tx, float ty );
30 static void SendVertex      ( u16 posIndex, u16 texCoordIndex );
31 
32 static void PrintIntro      ( void );
33 
34 
35 #define SIDE 30
36 #define NORM (sqrt(3.0))/3.0
37 
38 /*---------------------------------------------------------------------------*
39    Global variables
40  *---------------------------------------------------------------------------*/
41 Mtx v;
42 u32 rot;
43 
44 u8 CurrentControl;
45 u8 DoInvalidate = 0;
46 
47 GXTexObj to0, to1, to2, to3, to4, to5, to6, to7, to8;
48 
49 float FloatVert[] ATTRIBUTE_ALIGN(32) =
50                     {   -SIDE, SIDE, -SIDE,
51                         -SIDE, SIDE, SIDE,
52                         -SIDE, -SIDE, SIDE,
53                         -SIDE, -SIDE, -SIDE,
54                         SIDE, SIDE, -SIDE,
55                         SIDE, -SIDE, -SIDE,
56                         SIDE, -SIDE, SIDE,
57                         SIDE, SIDE, SIDE
58                     };
59 
60 float FloatNorm[] ATTRIBUTE_ALIGN(32) =
61                     {   -1, 1, -1,
62                         -1, 1, 1,
63                         -1, -1, 1,
64                         -1, -1, -1,
65                         1, 1, -1,
66                         1, -1, -1,
67                         1, -1, 1,
68                         1, 1, 1
69                     };
70 
71 float FloatTex[] ATTRIBUTE_ALIGN(32) =
72                     {   0.0F, 0.0F,
73                         1.0F, 0.0F,
74                         1.0F, 1.0F,
75                         0.0F, 1.0F
76                     };
77 
78 u8  ColorRGBA8[] ATTRIBUTE_ALIGN(32) = {255, 255, 255, 255}; //GX_RGBA8
79 
80 TPLPalettePtr tpl = 0;
81 /*---------------------------------------------------------------------------*
82    Application main loop
83  *---------------------------------------------------------------------------*/
main(void)84 void main ( void )
85 {
86     DEMOInit(NULL);
87 
88     DrawInit();         // Define my vertex formats and set array pointers.
89 
90     PrintIntro();
91 
92     DEMOPadRead();      // Read the joystick for this frame
93 
94     // While the quit button is not pressed
95     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
96     {
97         DEMOPadRead();  // Read the joystick for this frame
98 
99         // Do animation based on input
100         AnimTick();
101         DEMOBeforeRender();
102 
103         DrawTick();     // Draw the model.
104 
105         DEMODoneRender();
106     }
107     OSHalt("End of demo.\n");
108 }
109 
110 /*---------------------------------------------------------------------------*
111    Functions
112  *---------------------------------------------------------------------------*/
113 
114 
115 /*---------------------------------------------------------------------------*
116     Name:           CameraInit
117 
118     Description:    Initialize the projection matrix and load into hardware.
119 
120     Arguments:      v   view matrix to be passed to ViewInit
121                     cameraLocScale  scale for the camera's distance from the
122                                     object - to be passed to ViewInit
123 
124     Returns:        none
125  *---------------------------------------------------------------------------*/
CameraInit(void)126 static void CameraInit      ( void )
127 {
128     Mtx44 p;
129     Vec camPt = {0.0F, 0.0F, 650.0F};
130     Vec up = {0.0F, 1.0F, 0.0F};
131     Vec origin = {0.0F, 0.0F, 0.0F};
132 
133     MTXFrustum(p, 240, -240, -320, 320, 500, 2000);
134 
135     GXSetProjection(p, GX_PERSPECTIVE);
136 
137     MTXLookAt(v, &camPt, &up, &origin);
138 }
139 
140 /*---------------------------------------------------------------------------*
141     Name:           DrawInit
142 
143     Description:    Calls the correct initialization function for the current
144                     model.
145 
146     Arguments:      none
147 
148     Returns:        none
149  *---------------------------------------------------------------------------*/
DrawInit(void)150 static void DrawInit( void )
151 {
152     Mtx rz;
153     u32 i;
154 
155     CameraInit();   // Initialize the camera.
156 
157     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
158     GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16);
159     GXSetArray(GX_VA_TEX0, FloatTex, 8);
160 
161     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0);
162     GXSetVtxDesc(GX_VA_TEX1, GX_INDEX16);
163     GXSetArray(GX_VA_TEX1, FloatTex, 8);
164 
165     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
166     GXSetVtxDesc(GX_VA_NRM, GX_INDEX16);
167     GXSetArray(GX_VA_NRM, FloatNorm, 12);
168 
169     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
170     GXSetVtxDesc (GX_VA_POS, GX_INDEX16);
171     GXSetArray(GX_VA_POS, FloatVert, 12);
172 
173     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
174     GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16);
175     GXSetArray(GX_VA_CLR0, ColorRGBA8, 4);
176 
177     TPLGetPalette(&tpl, "gxTests/tex-06.tpl");
178 
179     GXSetNumChans(1);
180     GXSetNumTevStages(2);
181     GXSetTevOp   (GX_TEVSTAGE0, GX_REPLACE);
182     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
183     GXSetTevOp   (GX_TEVSTAGE1, GX_MODULATE);
184     GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0  );
185 
186     for(i = 0; i < 24; i++)
187     {
188         FloatNorm[i] *= NORM;
189     }
190 
191     MTXScale(rz, 3.0F, 3.0F, 3.0F);
192     GXLoadTexMtxImm(rz, GX_TEXMTX0, GX_MTX2x4);
193     GXSetNumTexGens(2);
194     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
195     GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
196 
197     OSReport("\n\nDon't invalidate texture cache");
198     OSReport("\nTev Mode - modulate\n\n");
199 }
200 
201 /*---------------------------------------------------------------------------*
202     Name:           DrawTick
203 
204     Description:    Draw the current model once.
205 
206     Arguments:      v       view matrix
207                     m       model matrix
208 
209     Returns:        none
210  *---------------------------------------------------------------------------*/
DrawTick(void)211 static void DrawTick( void )
212 {
213     u32 i, j;
214     TPLDescriptorPtr temp;
215     GXTlutObj tlo1;
216 
217     if(DoInvalidate == 1)
218         GXInvalidateTexAll();
219 
220     for(i = 0; i < 7; i++)
221     {
222         for(j = 0; j < 7; j ++)
223         {
224             if(DoInvalidate == 2)
225                 GXInvalidateTexAll();
226 
227             temp = TPLGet(tpl, i);
228             if(temp->CLUTHeader)
229             {
230                 TPLGetGXTexObjFromPaletteCI(tpl, &to0, &tlo1, GX_TLUT0, i);
231                 GXLoadTlut(&tlo1, 0);
232                 GXLoadTexObj(&to0, GX_TEXMAP0);
233             }
234             else
235             {
236                 TPLGetGXTexObjFromPalette(tpl, &to0, i);
237                 GXLoadTexObj(&to0, GX_TEXMAP0);
238             }
239 
240             temp = TPLGet(tpl, j + 7);
241             if(temp->CLUTHeader)
242             {
243                 TPLGetGXTexObjFromPaletteCI(tpl, &to1, &tlo1, GX_TLUT0, j + 7);
244                 GXLoadTlut(&tlo1, 0);
245                 GXLoadTexObj(&to1, GX_TEXMAP1);
246             }
247             else
248             {
249                 TPLGetGXTexObjFromPalette(tpl, &to1, j + 7);
250                 GXLoadTexObj(&to1, GX_TEXMAP1);
251             }
252 
253             DrawSmoothCube(-300.0F + ((float)(i * 100)), -300.0F + ((float)(j * 100)));
254         }
255     }
256 }
257 
258 /*---------------------------------------------------------------------------*
259     Name:           AnimTick
260 
261     Description:    Animates the camera and object based on the joystick's
262                     state.
263 
264     Arguments:      none
265 
266     Returns:        none
267  *---------------------------------------------------------------------------*/
AnimTick(void)268 static void AnimTick ( void )
269 {
270     u16 buttons = DEMOPadGetButtonDown(0);
271 
272     if(buttons & PAD_BUTTON_X)
273     {
274         CurrentControl ++;
275         if(CurrentControl > 2)
276             CurrentControl = 0;
277 
278         switch(CurrentControl)
279         {
280             case 0:
281                 GXSetTevOp   (GX_TEVSTAGE1, GX_MODULATE);
282                 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1,
283                               GX_TEXMAP1,   GX_COLOR0A0 );
284                 OSReport("\n\nTev Mode - modulate\n\n");
285                 break;
286 
287             case 1:
288                 GXSetTevOp   (GX_TEVSTAGE1, GX_DECAL);
289                 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1,
290                               GX_TEXMAP1,   GX_COLOR0A0 );
291                 OSReport("\n\nTev Mode - decal\n\n");
292                 break;
293 
294             case 2:
295                 GXSetTevOp   (GX_TEVSTAGE1, GX_PASSCLR);
296                 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL,
297                               GX_TEXMAP_NULL, GX_COLOR0A0 );
298                 OSReport("\n\nTexture 2 off\n\n");
299                 break;
300         }
301     }
302 
303     if(buttons & PAD_BUTTON_B)
304     {
305         DoInvalidate ++;
306         if(DoInvalidate > 2)
307             DoInvalidate = 0;
308 
309         switch(DoInvalidate)
310         {
311             case 0:
312                 OSReport("\n\nDon't invalidate texture cache\n\n");
313                 break;
314 
315             case 1:
316                 OSReport("\n\nInvalidate texture cache every frame (SLOW)\n\n");
317                 break;
318 
319             case 2:
320                 OSReport("\n\nInvalidate texture cache every cube (SLOWEST)\n\n");
321                 break;
322         }
323     }
324 
325     rot ++;
326     if(rot > 1439)
327         rot = 0;
328 }
329 
330 /*---------------------------------------------------------------------------*/
DrawSmoothCube(float tx,float ty)331 static void DrawSmoothCube ( float tx, float ty )
332 {
333     Mtx ry, rz, mv, t;
334 
335     MTXRotDeg(ry, 'Y', (float)rot);
336     MTXRotDeg(rz, 'Z', (float)rot / 2.0F);
337     MTXTrans(t, tx, ty, 0);
338 
339     MTXConcat(rz, ry, mv);
340     MTXConcat(t, mv, mv);
341     MTXConcat(v, mv, mv);
342     GXLoadPosMtxImm(mv, GX_PNMTX0);
343     MTXInverse(mv, mv);
344     MTXTranspose(mv, mv);
345     GXLoadNrmMtxImm(mv, GX_PNMTX0);
346 
347     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
348 
349         SendVertex(0, 0);
350         SendVertex(1, 1);
351         SendVertex(2, 2);
352         SendVertex(3, 3);
353 
354         SendVertex(4, 0);
355         SendVertex(5, 1);
356         SendVertex(6, 2);
357         SendVertex(7, 3);
358 
359         SendVertex(2, 0);
360         SendVertex(6, 1);
361         SendVertex(5, 2);
362         SendVertex(3, 3);
363 
364         SendVertex(1, 0);
365         SendVertex(0, 1);
366         SendVertex(4, 2);
367         SendVertex(7, 3);
368 
369         SendVertex(5, 0);
370         SendVertex(4, 1);
371         SendVertex(0, 2);
372         SendVertex(3, 3);
373 
374         SendVertex(6, 0);
375         SendVertex(2, 1);
376         SendVertex(1, 2);
377         SendVertex(7, 3);
378 
379     GXEnd();
380 }
381 
382 /*---------------------------------------------------------------------------*/
SendVertex(u16 posIndex,u16 texCoordIndex)383 static void SendVertex ( u16 posIndex, u16 texCoordIndex )
384 {
385     GXPosition1x16(posIndex);
386     GXNormal1x16(posIndex);
387     GXColor1x16(0);
388     GXTexCoord1x16(texCoordIndex);
389     GXTexCoord1x16(texCoordIndex);
390 }
391 
392 /*---------------------------------------------------------------------------*
393     Name:           PrintIntro
394     Description:    Prints the directions on how to use this demo.
395  *---------------------------------------------------------------------------*/
PrintIntro(void)396 static void PrintIntro( void )
397 {
398     OSReport("\n\n");
399     OSReport("************************************************\n");
400     OSReport("tex-2-tex: multitexture / cache invalidation\n");
401     OSReport("************************************************\n");
402     OSReport("to quit hit the start button\n");
403     OSReport("\n");
404     OSReport("X button : toggle combine mode.\n");
405     OSReport("B button : change texture cache flush frequency.\n");
406     OSReport("************************************************\n\n");
407 }
408 
409 /*===========================================================================*/
410