1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     ind-tile-test.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 #define PI 3.1415926535f
17 
18 // If these two are defined simultaneously, the image will not appear correct.
19 #define USE_PRELOADED_TEXTURE
20 
21 // Level 1
22 
23 void MapInit( TPLPalettePtr *tpl );
24 
25 extern GXTexObj toTilesRGB_1;
26 
27 extern GXTexObj toTileMap_1;
28 
29 /*---------------------------------------------------------------------------*
30   Defines
31  *---------------------------------------------------------------------------*/
32 
33 typedef struct
34 {
35     f32 x, y, z;
36     f32 s, t;
37 } Coord;
38 
39 typedef struct
40 {
41     f32 rPosX;  // Position vector X component (measured in tile coordinates)
42     f32 rPosY;  // Position vector Y component (measured in tile coordinates)
43     f32 rOriX;  // Normalized orientation vector X component
44     f32 rOriY;  // Normalized orientation vector Y component
45 } G2DPosOri;    // 2D Position and Orientation
46 
47 /*---------------------------------------------------------------------------*
48    Forward references
49  *---------------------------------------------------------------------------*/
50 
51 void        main                ( void );
52 
53 static void ParameterInit       ( void );
54 
55 static void TexInit             ( void );
56 static void DrawInit            ( void );
57 static void DrawTick            ( void );
58 static void AnimTick            ( void );
59 static void sendVertex          (Coord *d);
60 static void PrintIntro          ( void );
61 
62  /*---------------------------------------------------------------------------*
63    Global variables
64  *---------------------------------------------------------------------------*/
65 
66 G2DPosOri poCam;
67 G2DPosOri poShip;
68 f32 rAng = 0.0f;
69 f32 scale = 1.5f;
70 
71 static TPLPalettePtr tpl = NULL;
72 
73 static GXTexRegion texRegTiles, texRegMap;
74 
75 /*---------------------------------------------------------------------------*
76    Application main loop
77  *---------------------------------------------------------------------------*/
main(void)78 void main ( void )
79 {
80     DEMOInit(NULL);
81 
82     TexInit();
83 
84     PrintIntro();    // Print demo directions
85 
86     ParameterInit();
87 
88     DEMOPadRead();      // Read the joystick for this frame
89 
90     // While the quit button is not pressed
91     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
92     {
93         DrawInit();
94 
95         DEMOPadRead();  // Read the joystick for this frame
96 
97         AnimTick();     // Do animation based on input
98 
99         DEMOBeforeRender();
100 
101         DrawTick();     // Draw the model.
102 
103         DEMODoneRender();
104     }
105 
106     OSHalt("End of demo");
107 }
108 
109 /*---------------------------------------------------------------------------*
110    Functions
111  *---------------------------------------------------------------------------*/
112 
113 /*---------------------------------------------------------------------------*
114     Name:           ParameterInit
115 
116     Description:    Initialize parameters for single frame display
117 
118     Arguments:      none
119 
120     Returns:        none
121  *---------------------------------------------------------------------------*/
ParameterInit(void)122 static void ParameterInit( void )
123 {
124     rAng = 0.0F;
125     poShip.rPosX = 0.0F;
126     poShip.rPosY = 0.0F;
127 }
128 
129 /*---------------------------------------------------------------------------*
130     Name:           DrawInit
131 
132     Description:    Calls the correct initialization function for the current
133                     model.
134 
135     Arguments:      none
136 
137     Returns:        none
138  *---------------------------------------------------------------------------*/
TexInit(void)139 static void TexInit( void )
140 {
141 #ifdef USE_PRELOADED_TEXTURE
142     u32 size;
143 #endif
144     // Get/Create textures
145 
146     TPLGetPalette(&tpl, "gxTests/G2D-00.tpl");
147 
148     MapInit( &tpl );
149 #ifdef USE_PRELOADED_TEXTURE
150     // Preload the textures
151 
152     // Note that we don't set up a region allocator callback.
153     // This is okay if these are the only textures we use.
154     // See the comment in tex-preload if this is not clear.
155 
156     size = GXGetTexBufferSize(
157         GXGetTexObjWidth(&toTilesRGB_1),
158         GXGetTexObjHeight(&toTilesRGB_1),
159         GXGetTexObjFmt(&toTilesRGB_1),
160         GX_FALSE, 0);
161 
162     GXInitTexPreLoadRegion(
163         &texRegTiles,
164         0x00000,         // tmem_even
165         size/2,          // size_even
166         0x80000,         // tmem_odd
167         size/2 );        // size_odd
168 
169     GXPreLoadEntireTexture(&toTilesRGB_1, &texRegTiles);
170 
171     // Note that the above texture occupies the entire
172     // texture cache.  However, there are some unused tiles
173     // towards the end.  The texture below is loaded over
174     // those unused tiles.
175 
176     size = GXGetTexBufferSize(
177         GXGetTexObjWidth(&toTileMap_1),
178         GXGetTexObjHeight(&toTileMap_1),
179         GXGetTexObjFmt(&toTileMap_1),
180         GX_FALSE, 0);
181 
182     GXInitTexPreLoadRegion(
183         &texRegMap,
184         0x100000 - size, // tmem_even
185         size,            // size_even
186         0x00000,         // tmem_odd (not used)
187         0 );             // size_odd (not used)
188 
189     GXPreLoadEntireTexture(&toTileMap_1, &texRegMap);
190 #endif
191 }
192 
DrawInit(void)193 static void DrawInit( void )
194 {
195     Mtx   idtMtx;
196     Mtx44 prjMtx;
197 
198     // Misc setup
199     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
200 
201     // Set up textures
202 #ifdef USE_PRELOADED_TEXTURE
203     GXLoadTexObjPreLoaded(&toTilesRGB_1, &texRegTiles, GX_TEXMAP0);
204     GXLoadTexObjPreLoaded(&toTileMap_1, &texRegMap, GX_TEXMAP1);
205 #else
206     GXLoadTexObj(&toTilesRGB_1, GX_TEXMAP0);
207     GXLoadTexObj(&toTileMap_1, GX_TEXMAP1);
208 #endif
209     // Set up texgen
210     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
211     GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 128*32, 64*32);
212 
213     // Set up TEV and such...
214     GXSetNumTevStages(1);
215     GXSetNumIndStages(1);
216 
217     // One texture coordinate, no colors.
218     GXSetNumTexGens(1);
219     GXSetNumChans(0);
220 
221     // Indirect Stage 0 -- Lookup tile map
222     GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP1);
223     GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_32, GX_ITS_32);
224 
225     // Stage 0 -- Output texture color
226     //
227     // TEVPREV = TEXC/TEXA
228 
229     // This function also takes care of setting the indirect matrix
230     GXSetTevIndTile(GX_TEVSTAGE0,       // tev stage
231                     GX_INDTEXSTAGE0,    // indirect stage
232                     32,                 // tile size S
233                     32,                 // tile size T
234                     32,                 // tile spacing S
235                     32,                 // tile spacing T
236                     GX_ITF_4,           // ind tex format
237                     GX_ITM_0,           // ind matrix select
238                     GX_ITB_NONE,        // bias select
239                     GX_ITBA_OFF);       // bump alpha select
240 
241     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
242     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
243 
244     GXClearVtxDesc();
245     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
246     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
247     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
248     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
249 
250     MTXIdentity(idtMtx);
251     GXLoadPosMtxImm(idtMtx, GX_PNMTX0);
252     GXLoadTexMtxImm(idtMtx, GX_TEXMTX0, GX_MTX2x4);
253 
254 #define ASP (10.0f/7.0f)
255     MTXOrtho(prjMtx, -1.5f, 1.5f, -1.5f*ASP, 1.5f*ASP, 1.0f, 15.0f);
256     GXSetProjection(prjMtx, GX_ORTHOGRAPHIC);
257 }
258 
259 /*---------------------------------------------------------------------------*
260     Name:           DrawTick
261 
262     Description:    Draw the current model once.
263 
264     Arguments:      none
265     Returns:        none
266  *---------------------------------------------------------------------------*/
DrawTick(void)267 static void DrawTick( void )
268 {
269     Coord c;
270 
271     GXBegin(GX_QUADS, GX_VTXFMT0, 4);
272 #if 0
273     // Draw one copy of the board
274     c.x = -1.0f;
275     c.y = -0.5f;
276     c.z = -5.0f;
277     c.s =  0.0f;
278     c.t =  0.0f;
279     sendVertex(&c);
280     c.x =  1.0f;
281     c.s =  1.0f;
282     sendVertex(&c);
283     c.y =  0.5f;
284     c.t =  1.0f;
285     sendVertex(&c);
286     c.x = -1.0f;
287     c.s =  0.0f;
288     sendVertex(&c);
289 #else
290     // Draw nine copies of the board
291     c.x = -3.0f;
292     c.y = -1.5f;
293     c.z = -5.0f;
294     c.s = -1.0f;
295     c.t = -1.0f;
296     sendVertex(&c);
297     c.x =  3.0f;
298     c.s =  2.0f;
299     sendVertex(&c);
300     c.y =  1.5f;
301     c.t =  2.0f;
302     sendVertex(&c);
303     c.x = -3.0f;
304     c.s = -1.0f;
305     sendVertex(&c);
306 #endif
307     GXEnd();
308 }
309 
sendVertex(Coord * d)310 void sendVertex(Coord *d)
311 {
312     GXPosition3f32(d->x, d->y, d->z);
313     GXTexCoord2f32(d->s, d->t);
314 }
315 
316 /*---------------------------------------------------------------------------*
317     Name:           AnimTick
318 
319     Description:    Animate the scene.
320 
321     Arguments:      none
322     Returns:        none
323  *---------------------------------------------------------------------------*/
AnimTick(void)324 static void AnimTick( void )
325 {
326     Mtx tmpMtx;
327     Mtx posMtx;
328     f32 dx, dy;
329     u16 stick = DEMOPadGetDirs(0);
330     u16 press = DEMOPadGetButton(0);
331     u16 down = DEMOPadGetButtonDown(0);
332 
333     if (press & PAD_TRIGGER_L)
334     rAng += 1.5f;
335 
336     if (press & PAD_TRIGGER_R)
337     rAng -= 1.5f;
338 
339     if (down & PAD_BUTTON_A)
340     scale *= 1.25f;
341 
342     if (down & PAD_BUTTON_B)
343     scale *= 0.8f;
344 
345     dx = sinf(rAng / 180.0f * PI) * 0.01f;
346     dy = cosf(rAng / 180.0f * PI) * 0.01f;
347 
348     if (stick & DEMO_STICK_RIGHT)
349     {
350         poShip.rPosX -= dy;
351         poShip.rPosY += dx;
352     }
353 
354     if (stick & DEMO_STICK_LEFT)
355     {
356         poShip.rPosX += dy;
357         poShip.rPosY -= dx;
358     }
359 
360     if (stick & DEMO_STICK_DOWN)
361     {
362         poShip.rPosX -= dx;
363         poShip.rPosY -= dy;
364     }
365 
366     if (stick & DEMO_STICK_UP)
367     {
368         poShip.rPosX += dx;
369         poShip.rPosY += dy;
370     }
371 
372     if (poShip.rPosX >  1.0f) poShip.rPosX -= 2.0f;
373     if (poShip.rPosX < -1.0f) poShip.rPosX += 2.0f;
374     if (poShip.rPosY >  0.5f) poShip.rPosY -= 1.0f;
375     if (poShip.rPosY < -0.5f) poShip.rPosY += 1.0f;
376 
377     MTXRotDeg(posMtx, 'z', rAng);
378     MTXTrans(tmpMtx, poShip.rPosX, poShip.rPosY, 0.0f);
379     MTXConcat(posMtx, tmpMtx, posMtx);
380     MTXScale(tmpMtx, scale, scale, 1.0f);
381     MTXConcat(tmpMtx, posMtx, posMtx);
382 
383     GXLoadPosMtxImm(posMtx, GX_PNMTX0);
384 }
385 
386 /*---------------------------------------------------------------------------*
387     Name:           PrintIntro
388 
389     Description:    Prints the directions on how to use this demo.
390 
391     Arguments:      none
392 
393     Returns:        none
394  *---------------------------------------------------------------------------*/
PrintIntro(void)395 static void PrintIntro( void )
396 {
397     OSReport("\n\n");
398     OSReport("************************************************\n");
399     OSReport("ind-tile-test: tiled texture map using indirect textures\n");
400     OSReport("************************************************\n");
401     OSReport("to quit hit the start button\n");
402     OSReport("main stick   : moves position\n");
403     OSReport("A button     : expand\n");
404     OSReport("B button     : reduce\n");
405     OSReport("l/r triggers : rotates position\n");
406     OSReport("\n");
407     OSReport("************************************************\n\n");
408 }
409