1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tex-invalid.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 tex-invalid
15 texture cache region invalidation test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <string.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 #define NUM_REGIONS 8
29 #define NUM_TEXOBJS NUM_REGIONS
30 #define NUM_ROWS 5
31 #define NUM_TEXTURES NUM_ROWS
32
33 // for display position
34 #define ALI_ROW(y) (y * 80 + 56)
35 #define ALI_COL(x) (x * 68 + 48)
36
37 /*---------------------------------------------------------------------------*
38 Structure definitions
39 *---------------------------------------------------------------------------*/
40 // for entire scene control
41 typedef struct
42 {
43 u32 curX;
44 u32 curY;
45 u8 invalidateSw[NUM_ROWS-2][NUM_REGIONS];
46 GXTexObj texture[NUM_TEXOBJS];
47 u32 dataSize;
48 u8* dataBuffer[NUM_TEXOBJS];
49 u8* dataSource[NUM_TEXTURES];
50 u16 screenWd;
51 u16 screenHt;
52 } MySceneCtrlObj;
53
54 /*---------------------------------------------------------------------------*
55 Forward references
56 *---------------------------------------------------------------------------*/
57 void main ( void );
58 static void DrawInit ( MySceneCtrlObj* sc );
59 static void DrawTick ( MySceneCtrlObj* sc );
60 static void AnimTick ( MySceneCtrlObj* sc );
61 static void DrawQuad ( void );
62 static void DrawLines ( void );
63 static void MyDrawCaption ( MySceneCtrlObj* sc );
64 static void MyMemCopy ( u8* src, u8* dst, u32 size );
65 static GXTexRegion*
66 MyTexRegionCallback( const GXTexObj* texObj, GXTexMapID mapID );
67
68 static void PrintIntro ( void );
69
70
71 /*---------------------------------------------------------------------------*
72 Model Data
73 *---------------------------------------------------------------------------*/
74 static s16 QuadVertices[3*8] ATTRIBUTE_ALIGN(32) =
75 {
76 0, 0, 0, // 0
77 64, 0, 0, // 1
78 64, 64, 0, // 2
79 0, 64, 0 // 3
80 };
81
82 static s8 QuadTexCoords[2*4] ATTRIBUTE_ALIGN(32) =
83 {
84 0, 0,
85 1, 0,
86 1, 1,
87 0, 1
88 };
89
90 /*---------------------------------------------------------------------------*
91 String data for messages
92 *---------------------------------------------------------------------------*/
93 static char* InvSwStr[2] =
94 {
95 "-------",
96 "INVALID"
97 };
98
99 static char* InvTexAllStr = "******* GXInvalidateTexAll *******";
100
101 /*---------------------------------------------------------------------------*
102 Global variables
103 *---------------------------------------------------------------------------*/
104 static MySceneCtrlObj SceneCtrl; // scene control parameters
105 static TPLPalettePtr MyTplObj = NULL; // texture palette
106 static GXTexRegion MyTexRegions[NUM_REGIONS]; // cache regions
107
108 /*---------------------------------------------------------------------------*
109 Application main loop
110 *---------------------------------------------------------------------------*/
main(void)111 void main ( void )
112 {
113 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
114
115 DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
116 // and default scene settings.
117
118 PrintIntro(); // Print demo directions
119
120 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
121 {
122 DEMOBeforeRender();
123 DrawTick(&SceneCtrl); // Draw the model.
124 DEMODoneRender();
125 DEMOPadRead(); // Read controller
126 AnimTick(&SceneCtrl); // Do animation
127 }
128
129 OSHalt("End of demo");
130 }
131
132 /*---------------------------------------------------------------------------*
133 Functions
134 *---------------------------------------------------------------------------*/
135 /*---------------------------------------------------------------------------*
136 Name: DrawInit
137
138 Description: Initializes the vertex attribute format and sets up
139 the array pointer for the indexed data.
140 This function also initializes scene control parameters.
141
142 Arguments: sc : pointer to the structure of scene control parameters
143
144 Returns: none
145 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)146 static void DrawInit( MySceneCtrlObj* sc )
147 {
148 TPLDescriptorPtr tdp;
149 GXRenderModeObj* rmode;
150 u32 i, j;
151
152 // Vertex Attribute (VTXFMT0 is used by DEMOPuts library)
153 GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
154 GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA4, 0);
155 GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0);
156
157 // Array pointers
158 GXSetArray(GX_VA_POS, QuadVertices, 3 * sizeof(s16));
159 GXSetArray(GX_VA_TEX0, QuadTexCoords, 2 * sizeof(s8));
160
161 // Get Screen Information defined in DEMOInit()
162 // This test is supposing height=480 (or near.)
163 rmode = DEMOGetRenderModeObj();
164 sc->screenWd = rmode->fbWidth; // Screen Width
165 sc->screenHt = rmode->efbHeight; // Screen Height
166
167 // TMEM configuration
168 for ( i = 0 ; i < NUM_REGIONS ; ++i )
169 {
170 // The region is used as a 32K cache.
171 GXInitTexCacheRegion(
172 &MyTexRegions[i],
173 GX_FALSE, // 32b mipmap
174 0x00000 + i * 0x08000, // tmem_even
175 GX_TEXCACHE_32K, // size_even
176 0x80000 + i * 0x08000, // tmem_odd
177 GX_TEXCACHE_32K ); // size_odd
178 }
179 // User-defined tex region Callback
180 GXSetTexRegionCallback(MyTexRegionCallback);
181
182 // Load TPL file
183 TPLGetPalette(&MyTplObj, "gxTests/tex-07.tpl");
184
185 // This test doesn't use tpl data directly.
186 // Just keeping pointers for image data and
187 // copies them into buffers when used.
188 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
189 {
190 tdp = TPLGet(MyTplObj, i);
191 sc->dataSource[i] = (u8*)tdp->textureHeader->data;
192 }
193
194 // Same parameter is used in every texture in tex-07.tpl.
195 tdp = TPLGet(MyTplObj, 0);
196 sc->dataSize = GXGetTexBufferSize(
197 tdp->textureHeader->width,
198 tdp->textureHeader->height,
199 tdp->textureHeader->format,
200 GX_FALSE,
201 0 );
202
203 // Initialize texture objects
204 for ( i = 0 ; i < NUM_TEXOBJS ; ++i )
205 {
206 sc->dataBuffer[i] = MEMAllocFromAllocator(&DemoAllocator1, sc->dataSize);
207
208 GXInitTexObj(
209 &sc->texture[i],
210 (void*)sc->dataBuffer[i], // allocated buffer
211 tdp->textureHeader->width,
212 tdp->textureHeader->height,
213 (GXTexFmt)tdp->textureHeader->format,
214 tdp->textureHeader->wrapS, // s
215 tdp->textureHeader->wrapT, // t
216 GX_FALSE ); // Mipmap is turned off.
217
218 // UserData field keeps ID number.
219 GXInitTexObjUserData(&sc->texture[i], (void*)i);
220 }
221
222
223 // Default scene control parameter settings
224
225 // region invalidation switches
226 for ( i = 0 ; i < NUM_ROWS - 2 ; ++i )
227 {
228 for ( j = 0 ; j < NUM_REGIONS ; ++j )
229 {
230 sc->invalidateSw[i][j] = 1;
231 }
232 }
233
234 // cursor
235 sc->curX = 0;
236 sc->curY = 0;
237 }
238
239 /*---------------------------------------------------------------------------*
240 Name: DrawTick
241
242 Description: Draw the model by using given scene parameters
243
244 Arguments: sc : pointer to the structure of scene control parameters
245
246 Returns: none
247 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)248 static void DrawTick( MySceneCtrlObj* sc )
249 {
250 Mtx mt, mv;
251 s32 x, y;
252 u16 token;
253
254 // set projection to match screen space coordinate system
255 DEMOSetupScrnSpc(sc->screenWd, sc->screenHt, 100.0F);
256
257 // set up Zmode
258 GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
259
260 // set up Tev for simple colored objects
261 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
262 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
263 GXSetNumChans(1);
264 GXSetNumTexGens(0);
265
266 // draw lines
267 MTXIdentity(mv);
268 GXLoadPosMtxImm(mv, GX_PNMTX0);
269 DrawLines();
270
271 // set up Tev for textured objects
272 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
273 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
274 GXSetNumChans(0);
275 GXSetNumTexGens(1);
276 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
277
278 // reset token for synchronization
279 token = 0;
280 GXSetDrawSync(token);
281
282 for ( y = 0 ; y < NUM_ROWS ; ++y )
283 {
284 // Sync is necessary because CPU modifies main
285 // memory area for textures in run-time.
286 while ( token != GXReadDrawSync() )
287 {}
288
289 // Copy source image into each buffer
290 for ( x = 0 ; x < NUM_TEXOBJS ; ++x )
291 {
292 MyMemCopy(sc->dataSource[y], sc->dataBuffer[x], sc->dataSize);
293 }
294
295 // Invalidate cache regions
296 if ( y == 0 || y == NUM_ROWS - 1 )
297 {
298 GXInvalidateTexAll();
299 }
300 else
301 {
302 for ( x = 0 ; x < NUM_REGIONS ; ++x )
303 {
304 if ( sc->invalidateSw[y-1][x] )
305 {
306 GXInvalidateTexRegion(&MyTexRegions[x]);
307 }
308 }
309 }
310
311 // Draw textured quads for a row
312 for ( x = 0 ; x < NUM_TEXOBJS ; ++x )
313 {
314 // modelview matrix
315 MTXTrans(
316 mt,
317 (f32)ALI_COL(x),
318 (f32)ALI_ROW(y),
319 0.0F );
320 GXLoadPosMtxImm(mt, GX_PNMTX0);
321
322 GXLoadTexObj(&sc->texture[x], GX_TEXMAP0);
323 DrawQuad();
324 }
325
326 // Send the next sync token
327 GXSetDrawSync(++token);
328 }
329
330 // Captions
331 MyDrawCaption(sc);
332 }
333
334 /*---------------------------------------------------------------------------*
335 Name: AnimTick
336
337 Description: Changes scene parameters according to the pad status.
338
339 Arguments: sc : pointer to the structure of scene control parameters
340
341 Returns: none
342 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)343 static void AnimTick( MySceneCtrlObj* sc )
344 {
345 u16 down, dirs;
346
347 // PAD
348 down = DEMOPadGetButtonDown(0);
349 dirs = DEMOPadGetDirsNew(0);
350
351 // move cursor
352 if ( dirs & DEMO_STICK_RIGHT )
353 {
354 sc->curX += 1;
355 }
356 if ( dirs & DEMO_STICK_LEFT )
357 {
358 sc->curX += NUM_REGIONS - 1;
359 }
360 if ( dirs & DEMO_STICK_DOWN )
361 {
362 sc->curY += 1;
363 }
364 if ( dirs & DEMO_STICK_UP )
365 {
366 sc->curY += NUM_ROWS - 3;
367 }
368 sc->curX %= NUM_REGIONS;
369 sc->curY %= NUM_ROWS - 2;
370
371 // toggle invalidation switch
372 if ( down & PAD_BUTTON_A )
373 {
374 ++(sc->invalidateSw[sc->curY][sc->curX]);
375 sc->invalidateSw[sc->curY][sc->curX] %= 2;
376 }
377 }
378
379 /*---------------------------------------------------------------------------*
380 Name: DrawQuad
381
382 Description: Draw a textured Quad. Each face can have different texture
383 which is specified by given texture number list.
384
385 Arguments: texNoList : a pointer to texture number list
386
387 Returns: none
388 *---------------------------------------------------------------------------*/
DrawQuad(void)389 static void DrawQuad( void )
390 {
391 u8 i;
392
393 // set vertex descriptor
394 GXClearVtxDesc();
395 GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
396 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
397
398 // draw the quad
399 GXBegin(GX_QUADS, GX_VTXFMT1, 4);
400 for ( i = 0 ; i < 4 ; ++i )
401 {
402 GXPosition1x8(i);
403 GXTexCoord1x8(i);
404 }
405 GXEnd();
406 }
407
408 /*---------------------------------------------------------------------------*
409 Name: DrawLines
410
411 Description: Draw lines
412
413 Arguments: none
414
415 Returns: none
416 *---------------------------------------------------------------------------*/
DrawLines(void)417 static void DrawLines( void )
418 {
419 u8 i;
420
421 // set vertex descriptor
422 GXClearVtxDesc();
423 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
424 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
425
426 // draw lines
427 GXBegin(GX_LINES, GX_VTXFMT1, NUM_REGIONS * 2);
428 for ( i = 0 ; i < NUM_REGIONS ; ++i )
429 {
430 GXPosition3s16((s16)(i*72+64), 112, 0);
431 GXColor1u16(0xFFFF); // White
432 GXPosition3s16((s16)(i*72+64), 368, 0);
433 GXColor1u16(0xFFFF); // White
434 }
435 GXEnd();
436 }
437
438 /*---------------------------------------------------------------------------*
439 Name: MyDrawCaption
440
441 Description: Draw captions
442
443 Arguments: sc : pointer to the structure of scene control parameters
444
445 Returns: none
446 *---------------------------------------------------------------------------*/
MyDrawCaption(MySceneCtrlObj * sc)447 static void MyDrawCaption( MySceneCtrlObj* sc )
448 {
449 u32 i, j;
450
451 DEMOInitCaption(DM_FT_OPQ, sc->screenWd, sc->screenHt);
452
453 for ( i = 0 ; i < NUM_REGIONS ; ++i )
454 {
455 DEMOPrintf((s16)ALI_COL(i), (s16)(ALI_ROW(0)-16), 0, "[CACHE%d]", i);
456
457 for ( j = 0 ; j < NUM_ROWS - 2 ; ++j )
458 {
459 DEMOPuts(
460 (s16)(ALI_COL(i)+8),
461 (s16)(ALI_ROW(j)+68),
462 0,
463 InvSwStr[sc->invalidateSw[j][i]]);
464 }
465 }
466
467 // Cursor
468 DEMOPrintf((s16)ALI_COL(sc->curX), (s16)(ALI_ROW(sc->curY)+68), 0, "%c", 0x7F);
469
470 // "GXInvalidateTexAll"
471 DEMOPrintf(ALI_COL(0), (s16)(ALI_ROW(3)+68), 0, "%s%s", InvTexAllStr, InvTexAllStr);
472 }
473
474 /*---------------------------------------------------------------------------*
475 Name: MyMemCopy
476
477 Description: Copy specified memory block and flush related cache.
478
479 Arguments: src : start address of source data
480 dst : start address of destination
481 size : data size
482
483 Returns: none
484 *---------------------------------------------------------------------------*/
MyMemCopy(u8 * src,u8 * dst,u32 size)485 static void MyMemCopy( u8* src, u8* dst, u32 size )
486 {
487 memcpy(dst, src, size);
488 DCFlushRange(dst, size);
489 }
490
491 /*---------------------------------------------------------------------------*
492 Name: MyTexRegionCallback
493
494 Description: Tex cache allocator using simple round algorithm
495
496 Arguments: texObj : a pointer to texture object to be loaded
497 mapID : destination texmap ID (just same as GXLoadTexObj)
498
499 Returns: appropriate tex cache region for loading texture.
500 *---------------------------------------------------------------------------*/
MyTexRegionCallback(const GXTexObj * texObj,GXTexMapID mapID)501 static GXTexRegion* MyTexRegionCallback(const GXTexObj* texObj, GXTexMapID mapID)
502 {
503 #pragma unused(mapID)
504
505 u32 texID, regionNum;
506
507 texID = (u32)GXGetTexObjUserData(texObj);
508 regionNum = texID % NUM_REGIONS;
509
510 return &MyTexRegions[regionNum];
511 }
512
513 /*---------------------------------------------------------------------------*
514 Name: PrintIntro
515
516 Description: Prints the directions on how to use this demo.
517
518 Arguments: none
519
520 Returns: none
521 *---------------------------------------------------------------------------*/
PrintIntro(void)522 static void PrintIntro( void )
523 {
524 OSReport("\n\n");
525 OSReport("************************************************\n");
526 OSReport("tex-invalid: tex cache region allocator test\n");
527 OSReport("************************************************\n");
528 OSReport("to quit hit the start button\n");
529 OSReport("\n");
530 OSReport("Main Stick : move the cursor\n");
531 OSReport("A button : toggle on/off invalidation switch\n");
532 OSReport("************************************************\n\n");
533 }
534
535 /*============================================================================*/
536