1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tex-tlut.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-tlut
15 CI texture with arbitrary TLUT size test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define NUM_REGIONS 9
28
29 #define BG_TEXTURE_WIDTH 8
30 #define BG_TEXTURE_HEIGHT 8
31 #define BG_TEXTURE_FORMAT GX_TF_I4
32
33 #define SAMPLE_IMG_WIDTH 128
34 #define SAMPLE_IMG_HEIGHT 128
35
36 #define TEX_CMAP 0 // ID for color map texture
37 #define TEX_SIMG 1 // ID for quantized sample image texture
38 #define TEX_BG 2 // ID for background texture
39
40 /*---------------------------------------------------------------------------*
41 Structure definitions
42 *---------------------------------------------------------------------------*/
43 // for camera
44 typedef struct
45 {
46 Vec location;
47 Vec up;
48 Vec target;
49 f32 left;
50 f32 top;
51 f32 znear;
52 f32 zfar;
53 } CameraConfig;
54
55 typedef struct
56 {
57 CameraConfig cfg;
58 Mtx view;
59 Mtx44 proj;
60 } MyCameraObj;
61
62 // for TLUT size
63 typedef struct
64 {
65 GXTlutSize symbol;
66 u32 actualSize;
67 } MyTlutSize;
68
69 // for texture
70 typedef struct
71 {
72 GXTexObj tobj;
73 u8* data;
74 u16 width;
75 u16 height;
76 GXCITexFmt format;
77 } MyTextureObj;
78
79 // for color map
80 typedef struct
81 {
82 u32 tlutNumber;
83 GXTlutFmt tlutFormat;
84 u16* tlutBuffer;
85 u8 mapCtrl[4];
86 } MyColorMapObj;
87
88 // for entire scene control
89 typedef struct
90 {
91 MyCameraObj cam;
92 MyTextureObj texture[3];
93 MyColorMapObj cmap;
94 } MySceneCtrlObj;
95
96 /*---------------------------------------------------------------------------*
97 Forward references
98 *---------------------------------------------------------------------------*/
99 void main ( void );
100 static void DrawInit ( MySceneCtrlObj* sc );
101 static void DrawTick ( MySceneCtrlObj* sc );
102 static void AnimTick ( MySceneCtrlObj* sc );
103 static void SetScene ( MySceneCtrlObj* sc );
104 static void SetCamera ( MyCameraObj* cam );
105 static void DrawQuad ( void );
106
107 static void CreateColorMapTexture ( MyTextureObj* to, MyColorMapObj* cmo );
108 static void CreateSampleImgTexture ( MyTextureObj* to, MyColorMapObj* cmo );
109 static void InitColorMap ( MyColorMapObj* cmo );
110 static void ChangeColorMap ( MyColorMapObj* cmo, u32 cmp_id );
111 static void LoadColorMap ( MyColorMapObj* cmo );
112 static void PlotOnTexture ( MyTextureObj* to, u32 x, u32 y, u32 val );
113
114 static void MyTlutRegionInit ( void );
115 static GXTlutRegion* MyTlutRegionCallback ( u32 idx );
116
117 static void StatusMessage ( MyColorMapObj* cmo );
118 static void PrintIntro ( void );
119
120 /*---------------------------------------------------------------------------*
121 External data in tex-data04.c
122 *---------------------------------------------------------------------------*/
123 extern u8 BGTextureData[];
124 extern u8 SampleImageData[];
125
126 /*---------------------------------------------------------------------------*
127 Data for TLUT configuration
128 *---------------------------------------------------------------------------*/
129 static MyTlutSize TlutSizeTable[NUM_REGIONS] =
130 {
131 { GX_TLUT_16, 0x00200 },
132 { GX_TLUT_32, 0x00400 },
133 { GX_TLUT_64, 0x00800 },
134 { GX_TLUT_128, 0x01000 },
135 { GX_TLUT_256, 0x02000 },
136 { GX_TLUT_512, 0x04000 },
137 { GX_TLUT_1K, 0x08000 },
138 { GX_TLUT_2K, 0x10000 },
139 { GX_TLUT_4K, 0x20000 }
140 };
141
142 /*---------------------------------------------------------------------------*
143 Camera configuration
144 *---------------------------------------------------------------------------*/
145 static CameraConfig DefaultCamera =
146 {
147 { 0.0F, 0.0F, 100.0F }, // location
148 { 0.0F, 1.0F, 0.0F }, // up
149 { 0.0F, 0.0F, 0.0F }, // target
150 -320.0F, // left
151 224.0F, // top (note: was 240, now adjusted for over scan)
152 50.0F, // near
153 2000.0F // far
154 };
155
156 /*---------------------------------------------------------------------------*
157 Global variables
158 *---------------------------------------------------------------------------*/
159 static MySceneCtrlObj SceneCtrl; // scene control parameters
160 static GXTlutRegion MyTlutRegions[NUM_REGIONS]; // own tlut configuration
161
162 /*---------------------------------------------------------------------------*
163 Application main loop
164 *---------------------------------------------------------------------------*/
main(void)165 void main ( void )
166 {
167 DEMOInit(NULL);
168
169 DrawInit(&SceneCtrl); // Initialize vertex formats, tlut regions
170 // and default scene settings.
171
172 PrintIntro(); // Print demo directions
173
174 StatusMessage(&SceneCtrl.cmap);
175 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
176 {
177 DEMOBeforeRender();
178 DrawTick(&SceneCtrl); // Draw the model.
179 DEMODoneRender();
180 DEMOPadRead(); // Read controller
181 AnimTick(&SceneCtrl); // Do animation
182 }
183
184 OSHalt("End of demo");
185 }
186
187 /*---------------------------------------------------------------------------*
188 Functions
189 *---------------------------------------------------------------------------*/
190 /*---------------------------------------------------------------------------*
191 Name: DrawInit
192
193 Description: Initializes the vertex attribute format and sets up
194 tlut regions.
195 This function also initializes scene control parameters.
196
197 Arguments: sc : pointer to the structure of scene control parameters
198
199 Returns: none
200 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)201 static void DrawInit( MySceneCtrlObj* sc )
202 {
203 Mtx ms; // Scale matrix.
204 Mtx mt; // Translation matrix.
205 Mtx mv; // Modelview matrix.
206
207 // Vertex Attribute
208 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
209 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
210
211 // Texture and TLUT
212 MyTlutRegionInit();
213 GXInvalidateTexAll();
214
215 // Texture coord generation setting
216 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
217 GXSetNumTexGens(1);
218
219
220 // Default scene control parameter settings
221
222 // camera
223 sc->cam.cfg = DefaultCamera;
224 SetCamera(&sc->cam); // never changes in this test
225
226 // colormap information
227 sc->cmap.tlutNumber = 0;
228 sc->cmap.tlutFormat = GX_TL_IA8;
229 sc->cmap.tlutBuffer = NULL;
230 InitColorMap(&sc->cmap);
231
232 // dynamic generated textures
233 sc->texture[TEX_CMAP].data = NULL;
234 sc->texture[TEX_SIMG].data = NULL;
235
236 // static background texture
237 GXInitTexObj(
238 &sc->texture[TEX_BG].tobj,
239 BGTextureData,
240 BG_TEXTURE_WIDTH,
241 BG_TEXTURE_HEIGHT,
242 BG_TEXTURE_FORMAT,
243 GX_REPEAT,
244 GX_REPEAT,
245 GX_FALSE );
246 GXInitTexObjLOD(
247 &sc->texture[TEX_BG].tobj,
248 GX_LINEAR,
249 GX_LINEAR,
250 0,
251 0,
252 0,
253 GX_FALSE,
254 GX_FALSE,
255 GX_ANISO_1 );
256
257 // create default scene
258 SetScene(sc);
259
260
261 // Make modelview matrices (never changes in this test)
262
263 // GX_PNMTX0 is used for color map pattern texture wall
264 MTXTrans(mt, -144.0F, 0.0F, 0.0F);
265 MTXConcat(sc->cam.view, mt, mv);
266 MTXScale(ms, 128.0F, 128.0F, 1.0F);
267 MTXConcat(mv, ms, mv);
268 GXLoadPosMtxImm(mv, GX_PNMTX0);
269
270 // GX_PNMTX1 is used for sample image texture wall
271 MTXTrans(mt, 144.0F, 0.0F, 0.0F);
272 MTXConcat(sc->cam.view, mt, mv);
273 MTXScale(ms, 128.0F, 128.0F, 1.0F);
274 MTXConcat(mv, ms, mv);
275 GXLoadPosMtxImm(mv, GX_PNMTX1);
276
277 // GX_PNMTX2 is used for background tesselated wall
278 MTXTrans(mt, -144.0F, 0.0F, -1.0F);
279 MTXConcat(sc->cam.view, mt, mv);
280 MTXScale(ms, 128.0F, 128.0F, 1.0F);
281 MTXConcat(mv, ms, mv);
282 GXLoadPosMtxImm(mv, GX_PNMTX2);
283
284 }
285
286 /*---------------------------------------------------------------------------*
287 Name: DrawTick
288
289 Description: Draws the model by using given scene parameters
290
291 Arguments: sc : pointer to the structure of scene control parameters
292
293 Returns: none
294 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)295 static void DrawTick( MySceneCtrlObj* sc )
296 {
297 static f32 s = 0.0F;
298
299 Mtx ms; // Scale matrix.
300 Mtx mc; // TexCoord matrix.
301
302 // set tev operation to display texture
303 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
304 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
305
306 // enable alpha blend mode
307 GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
308
309 //
310 // Draw background wall
311 //
312
313 // set modelview and texcoord matrix
314 GXSetCurrentMtx(GX_PNMTX2);
315 MTXTrans(mc, s, s, 0.0F);
316 MTXScale(ms, 16.0F, 16.0F, 0.0F);
317 MTXConcat(mc, ms, mc);
318 GXLoadTexMtxImm(mc, GX_TEXMTX0, GX_MTX2x4);
319 // set texture object for background
320 GXLoadTexObj(&sc->texture[TEX_BG].tobj, GX_TEXMAP0);
321 // draw a quad
322 DrawQuad();
323
324 //
325 // Draw color map texture
326 //
327
328 // set modelview and texcoord matrix
329 GXSetCurrentMtx(GX_PNMTX0);
330 MTXIdentity(mc);
331 GXLoadTexMtxImm(mc, GX_TEXMTX0, GX_MTX2x4);
332 // set texture object for test pattern
333 GXLoadTexObj(&sc->texture[TEX_CMAP].tobj, GX_TEXMAP0);
334 // draw a quad
335 DrawQuad();
336
337 //
338 // Draw quantized sample image texture
339 //
340
341 // set modelview and texcoord matrix
342 GXSetCurrentMtx(GX_PNMTX1);
343 MTXIdentity(mc);
344 GXLoadTexMtxImm(mc, GX_TEXMTX0, GX_MTX2x4);
345 // set texture object for sample image
346 GXLoadTexObj(&sc->texture[TEX_SIMG].tobj, GX_TEXMAP0);
347 // draw a quad
348 DrawQuad();
349
350 // texture coord animation
351 s += 0.005F;
352 if ( s >= 1.0F )
353 {
354 s = 0.0F;
355 }
356 }
357
358 /*---------------------------------------------------------------------------*
359 Name: AnimTick
360
361 Description: Changes scene parameters according to the pad status.
362
363 Arguments: sc : pointer to the structure of scene control parameters
364
365 Returns: none
366 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)367 static void AnimTick( MySceneCtrlObj* sc )
368 {
369 u16 down = DEMOPadGetButtonDown(0);
370 u16 dirs = DEMOPadGetDirsNew(0);
371
372
373 // Tlut number (& size) control
374 if ( down & PAD_TRIGGER_L )
375 {
376 if ( sc->cmap.tlutNumber > 0 )
377 {
378 --(sc->cmap.tlutNumber);
379 }
380
381 InitColorMap(&sc->cmap);
382 SetScene(sc);
383 StatusMessage(&sc->cmap);
384 }
385 if ( down & PAD_TRIGGER_R )
386 {
387 if ( sc->cmap.tlutNumber < NUM_REGIONS - 1 )
388 {
389 ++(sc->cmap.tlutNumber);
390 }
391
392 InitColorMap(&sc->cmap);
393 SetScene(sc);
394 StatusMessage(&sc->cmap);
395 }
396
397 // Tlut format control
398 if ( down & PAD_BUTTON_A )
399 {
400 sc->cmap.tlutFormat =
401 ( sc->cmap.tlutFormat == GX_TL_IA8 ) ? GX_TL_RGB565
402 : ( sc->cmap.tlutFormat == GX_TL_RGB565 ) ? GX_TL_RGB5A3
403 : GX_TL_IA8;
404
405 InitColorMap(&sc->cmap);
406 SetScene(sc);
407 StatusMessage(&sc->cmap);
408 }
409
410 // Change color map
411 if ( dirs & DEMO_STICK_RIGHT )
412 {
413 ChangeColorMap(&sc->cmap, 0);
414 SetScene(sc);
415 StatusMessage(&sc->cmap);
416 }
417 if ( dirs & DEMO_STICK_LEFT )
418 {
419 ChangeColorMap(&sc->cmap, 1);
420 SetScene(sc);
421 StatusMessage(&sc->cmap);
422 }
423 if ( dirs & DEMO_STICK_UP )
424 {
425 ChangeColorMap(&sc->cmap, 2);
426 SetScene(sc);
427 StatusMessage(&sc->cmap);
428 }
429 if ( dirs & DEMO_STICK_DOWN )
430 {
431 ChangeColorMap(&sc->cmap, 3);
432 SetScene(sc);
433 StatusMessage(&sc->cmap);
434 }
435 }
436
437 /*---------------------------------------------------------------------------*
438 Name: SetScene
439
440 Description: Sets up tlut data and textures necessary to make a scene
441
442 Arguments: sc : pointer to the structure of scene control parameters
443
444 Returns: none
445 *---------------------------------------------------------------------------*/
SetScene(MySceneCtrlObj * sc)446 void SetScene( MySceneCtrlObj* sc )
447 {
448 LoadColorMap(&sc->cmap);
449 CreateColorMapTexture(&sc->texture[TEX_CMAP], &sc->cmap);
450 CreateSampleImgTexture(&sc->texture[TEX_SIMG], &sc->cmap);
451
452 // Invalidate all cached textures
453 GXInvalidateTexAll();
454 }
455
456 /*---------------------------------------------------------------------------*
457 Name: SetCamera
458
459 Description: Sets view matrix and loads projection matrix into hardware
460
461 Arguments: cam : pointer to the MyCameraObj structure
462
463 Returns: none
464 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)465 static void SetCamera( MyCameraObj* cam )
466 {
467 MTXLookAt(
468 cam->view,
469 &cam->cfg.location,
470 &cam->cfg.up,
471 &cam->cfg.target );
472
473 MTXOrtho(
474 cam->proj,
475 cam->cfg.top,
476 - (cam->cfg.top),
477 cam->cfg.left,
478 - (cam->cfg.left),
479 cam->cfg.znear,
480 cam->cfg.zfar );
481 GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
482 }
483
484 /*---------------------------------------------------------------------------*
485 Name: DrawQuad
486
487 Description: Draws a textured quad
488
489 Arguments: none
490
491 Returns: none
492 *---------------------------------------------------------------------------*/
DrawQuad(void)493 static void DrawQuad( void )
494 {
495 // set vertex descriptor
496 GXClearVtxDesc();
497 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
498 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
499
500 // draw a quad
501 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
502 GXPosition3s16( 1, 1, -1);
503 GXTexCoord2f32(1.0F, 0.0F);
504 GXPosition3s16( 1, -1, -1);
505 GXTexCoord2f32(1.0F, 1.0F);
506 GXPosition3s16(-1, -1, -1);
507 GXTexCoord2f32(0.0F, 1.0F);
508 GXPosition3s16(-1, 1, -1);
509 GXTexCoord2f32(0.0F, 0.0F);
510 GXEnd();
511 }
512
513 /*---------------------------------------------------------------------------*
514 Name: CreateColorMapTexture
515
516 Description: Creates a mosaic texture which shows all indexed
517 color data in given color map
518
519 Arguments: to : a pointer to the MyTextureObj structure
520 where created texture data is stored
521 cmo : a pointer to the MyColorMapObj structure
522 which provides current color map information
523
524 Returns: none
525 *---------------------------------------------------------------------------*/
CreateColorMapTexture(MyTextureObj * to,MyColorMapObj * cmo)526 static void CreateColorMapTexture(MyTextureObj* to, MyColorMapObj* cmo)
527 {
528 u16 iw, ih;
529 u32 ciSize, bufferSize, ic;
530
531 // calculate texture size by CI size
532 ciSize = 1u << ( cmo->tlutNumber + 4 );
533 to->width = to->height = 1;
534 while(1)
535 {
536 to->width *= 2;
537 if ( to->width * to->height >= ciSize )
538 break;
539
540 to->height *= 2;
541 if ( to->width * to->height >= ciSize )
542 break;
543 }
544
545 // determine texture format
546 to->format = ( ciSize <= 16 ) ? GX_TF_C4
547 : ( ciSize <= 256 ) ? GX_TF_C8
548 : GX_TF_C14X2;
549
550 // allocate texture data memory
551 if ( to->data != NULL )
552 {
553 MEMFreeToAllocator(&DemoAllocator1, to->data);
554 }
555 bufferSize = GXGetTexBufferSize(
556 to->width,
557 to->height,
558 to->format,
559 GX_FALSE,
560 0 );
561 to->data = MEMAllocFromAllocator(&DemoAllocator1, bufferSize);
562
563 // make map pattern
564 ic = 0;
565 for ( ih = 0 ; ih < to->height ; ++ih )
566 {
567 for ( iw = 0 ; iw < to->width ; ++iw )
568 {
569 PlotOnTexture(to, iw, ih, ic);
570 ic = ( ic + 1 ) % ciSize;
571 }
572 }
573
574 // initialize texture object
575 GXInitTexObjCI(
576 &to->tobj,
577 to->data,
578 to->width,
579 to->height,
580 to->format,
581 GX_REPEAT,
582 GX_REPEAT,
583 GX_FALSE,
584 cmo->tlutNumber );
585 GXInitTexObjLOD(
586 &to->tobj,
587 GX_NEAR,
588 GX_NEAR,
589 0,
590 0,
591 0,
592 GX_FALSE,
593 GX_FALSE,
594 GX_ANISO_1 );
595
596 // flush data cache to certainly send all created data into main memory.
597 DCFlushRange(to->data, bufferSize);
598 }
599
600 /*---------------------------------------------------------------------------*
601 Name: CreateSampleImgTexture
602
603 Description: Quantizes sample image data by using given color map
604 and store as a texture data
605
606 Arguments: to : a pointer to the MyTextureObj structure
607 where created texture data is stored
608 cmo : a pointer to the MyColorMapObj structure
609 which provides current color map information
610
611 Returns: none
612 *---------------------------------------------------------------------------*/
CreateSampleImgTexture(MyTextureObj * to,MyColorMapObj * cmo)613 static void CreateSampleImgTexture(MyTextureObj* to, MyColorMapObj* cmo)
614 {
615 u8* srcdata = SampleImageData;
616 u16 iw, ih;
617 u32 ciSize;
618 u32 offset;
619 u32 bufferSize;
620
621 ciSize = 1u << ( cmo->tlutNumber + 4 );
622 to->width = SAMPLE_IMG_WIDTH;
623 to->height = SAMPLE_IMG_HEIGHT;
624 offset = 0;
625
626 // determine texture format
627 to->format = ( ciSize <= 16 ) ? GX_TF_C4
628 : ( ciSize <= 256 ) ? GX_TF_C8
629 : GX_TF_C14X2;
630
631 // allocate texture data memory
632 if ( to->data != NULL )
633 {
634 MEMFreeToAllocator(&DemoAllocator1, to->data);
635 }
636 bufferSize = GXGetTexBufferSize(
637 to->width,
638 to->height,
639 to->format,
640 GX_FALSE,
641 0 );
642 to->data = MEMAllocFromAllocator(&DemoAllocator1, bufferSize);
643
644
645 // make quantized sample image
646 for ( ih = 0 ; ih < to->height ; ++ih )
647 {
648 for ( iw = 0 ; iw < to->width ; ++iw )
649 {
650 u32 ic, c, shift, id;
651
652 ic = c = shift = 0;
653
654 switch(cmo->tlutFormat)
655 {
656 case GX_TL_IA8:
657 {
658 for ( id = 0 ; id < 3 ; ++id )
659 {
660 c += srcdata[offset];
661 ++offset;
662 }
663
664 // Intensity
665 ic = ( ( c / 3 ) >> ( 8 - cmo->mapCtrl[0] ));
666 // Alpha
667 shift = cmo->mapCtrl[0];
668 ic += (( 0xFF >> ( 8 - cmo->mapCtrl[1] )) << shift );
669 } break;
670 case GX_TL_RGB565:
671 {
672 for ( id = 0 ; id < 3 ; ++id )
673 {
674 c = srcdata[offset];
675 ic += (( c >> ( 8 - cmo->mapCtrl[id] )) << shift );
676 shift += cmo->mapCtrl[id];
677
678 ++offset;
679 }
680
681 } break;
682 case GX_TL_RGB5A3:
683 {
684 ic = ( 0x00FFu >> ( 8 - cmo->mapCtrl[0] ));
685 shift = cmo->mapCtrl[0];
686
687 for ( id = 1 ; id < 4 ; ++id )
688 {
689 c = srcdata[offset];
690 ic += (( c >> ( 8 - cmo->mapCtrl[id] )) << shift );
691 shift += cmo->mapCtrl[id];
692
693 ++offset;
694 }
695
696 } break;
697 }
698
699 PlotOnTexture( to, iw, ih, ic );
700 }
701 }
702
703 // initialize texture object
704 GXInitTexObjCI(
705 &to->tobj,
706 to->data,
707 to->width,
708 to->height,
709 to->format,
710 GX_REPEAT,
711 GX_REPEAT,
712 GX_FALSE,
713 cmo->tlutNumber );
714 GXInitTexObjLOD(
715 &to->tobj,
716 GX_LINEAR,
717 GX_LINEAR,
718 0,
719 0,
720 0,
721 GX_FALSE,
722 GX_FALSE,
723 GX_ANISO_1 );
724
725 // flush data cache to certainly send all created data into main memory.
726 DCFlushRange(to->data, bufferSize);
727 }
728
729 /*---------------------------------------------------------------------------*
730 Name: InitColorMap
731
732 Description: Makes default color map settings
733
734 Arguments: cmo : a pointer to the MyColorMapObj structure
735 to be initialized
736
737 Returns: none
738 *---------------------------------------------------------------------------*/
InitColorMap(MyColorMapObj * cmo)739 static void InitColorMap( MyColorMapObj* cmo )
740 {
741 u32 tlutNumBits;
742 u32 components, i;
743
744 tlutNumBits = cmo->tlutNumber + 4;
745
746 switch(cmo->tlutFormat)
747 {
748 case GX_TL_IA8:
749 components = 2;
750 break;
751 case GX_TL_RGB565:
752 components = 3;
753 break;
754 case GX_TL_RGB5A3:
755 components = 4;
756 break;
757 }
758
759 for ( i = 0 ; i < 4 ; ++i )
760 {
761 cmo->mapCtrl[i] = (u8)( ( i < components ) ?
762 (tlutNumBits + i ) / components : 0 );
763 }
764 }
765
766 /*---------------------------------------------------------------------------*
767 Name: ChangeColorMap
768
769 Description: Changes the size of a component of color map
770
771 Arguments: cmo : a pointer to the MyColorMapObj structure
772 to be modified
773 cmp_id : specifies which component should be changed
774 (actually the number of bits is incremented)
775
776 Returns: none
777 *---------------------------------------------------------------------------*/
ChangeColorMap(MyColorMapObj * cmo,u32 cmp_id)778 static void ChangeColorMap( MyColorMapObj* cmo, u32 cmp_id )
779 {
780 u32 i, components;
781 u8 limits[4];
782
783 switch(cmo->tlutFormat)
784 {
785 case GX_TL_IA8:
786 {
787 components = 2;
788 limits[0] = 8;
789 limits[1] = 8;
790 } break;
791 case GX_TL_RGB565:
792 {
793 components = 3;
794 limits[0] = 5;
795 limits[1] = 6;
796 limits[2] = 5;
797 } break;
798 case GX_TL_RGB5A3:
799 {
800 components = 4;
801 limits[0] = 3;
802 limits[1] = 4;
803 limits[2] = 4;
804 limits[3] = 4;
805 } break;
806 }
807
808 cmp_id %= components;
809
810 if ( cmo->mapCtrl[cmp_id] >= limits[cmp_id] )
811 return;
812
813 i = ( cmp_id + 1 ) % components ;
814 while ( cmo->mapCtrl[i] <= 1 )
815 {
816 i = ( i + 1 ) % components;
817
818 if ( i == cmp_id )
819 break;
820 }
821 --(cmo->mapCtrl[i]);
822 ++(cmo->mapCtrl[cmp_id]);
823
824 return;
825 }
826
827 /*---------------------------------------------------------------------------*
828 Name: LoadColorMap
829
830 Description: Makes all color index data by using given color map
831 setting and load them into TMEM
832
833 Arguments: cmo : a pointer to the MyColorMapObj structure
834 which provides current color map setting
835
836 Returns: none
837 *---------------------------------------------------------------------------*/
LoadColorMap(MyColorMapObj * cmo)838 static void LoadColorMap(MyColorMapObj* cmo)
839 {
840 GXTlutObj tlutObj;
841 u32 i, offset, ciSize;
842 u32 countTbl[4], sizeTbl[4];
843
844 ciSize = 1u << ( cmo->tlutNumber + 4 );
845 offset = 0;
846
847 if ( cmo->tlutBuffer != NULL )
848 {
849 MEMFreeToAllocator(&DemoAllocator1, cmo->tlutBuffer);
850 }
851 cmo->tlutBuffer = (u16*)MEMAllocFromAllocator(&DemoAllocator1, ciSize * sizeof(u16));
852
853 // reset counter table
854 for ( i = 0 ; i < 4 ; ++i )
855 {
856 countTbl[i] = 0;
857 sizeTbl[i] = ( 1u << cmo->mapCtrl[i] ) - 1;
858 }
859
860 // make color data
861 do
862 {
863 u16 data;
864
865 if ( cmo->tlutFormat == GX_TL_IA8 )
866 {
867 data = (u16)
868 ( ( countTbl[0] * 255 / sizeTbl[0] )
869 + (( countTbl[1] * 255 / sizeTbl[1] ) << 8 ) );
870 }
871 else if ( cmo->tlutFormat == GX_TL_RGB565 )
872 {
873 data = GXPackedRGB565(
874 countTbl[2] * 255 / sizeTbl[2],
875 countTbl[1] * 255 / sizeTbl[1],
876 countTbl[0] * 255 / sizeTbl[0] );
877 }
878 else if ( cmo->tlutFormat == GX_TL_RGB5A3 )
879 {
880 data = GXPackedRGB5A3(
881 countTbl[3] * 255 / sizeTbl[3],
882 countTbl[2] * 255 / sizeTbl[2],
883 countTbl[1] * 255 / sizeTbl[1],
884 countTbl[0] * 255 / sizeTbl[0] );
885 }
886
887 cmo->tlutBuffer[offset] = (u16)data;
888 ++offset;
889 if ( offset >= ciSize )
890 break;
891
892 for ( i = 0 ; i < 4 ; ++i )
893 {
894 ++countTbl[i];
895 if ( countTbl[i] > sizeTbl[i] )
896 {
897 countTbl[i] = 0;
898 }
899 else
900 break;
901 }
902 }
903 while ( i < 4 );
904
905 // flush data cache to certainly send all created data into main memory.
906 DCFlushRange(cmo->tlutBuffer, ciSize * sizeof(u16));
907
908 // initialize TLUT object
909 GXInitTlutObj(
910 &tlutObj,
911 cmo->tlutBuffer,
912 cmo->tlutFormat,
913 (u16)ciSize );
914
915 // load tlut data into TMEM
916 GXLoadTlut(&tlutObj, cmo->tlutNumber);
917 }
918
919 /*---------------------------------------------------------------------------*
920 Name: PlotOnTexture
921
922 Description: Plots a point on texture map
923
924 Arguments: to : a pointer to the MyTextureObj structure
925 on which a point is plotted
926 x : x position
927 y : y position
928 val : color of the point (index)
929
930 Returns: none
931 *---------------------------------------------------------------------------*/
PlotOnTexture(MyTextureObj * to,u32 x,u32 y,u32 val)932 static void PlotOnTexture(MyTextureObj* to, u32 x, u32 y, u32 val)
933 {
934 u32 xp, xb, yp, yb, aw, offset;
935
936 if ( x >= to->width || y >= to->height )
937 {
938 return;
939 }
940
941 switch(to->format)
942 {
943 case GX_TF_C4 :
944 {
945 u8 d = (u8)(val & 0x0F);
946
947 aw = ( to->width + 7 ) / 8u;
948 xp = x % 8;
949 xb = x / 8;
950 yp = y % 8;
951 yb = y / 8;
952 offset = ( yb * aw + xb ) * 32 + ( yp * 4 + xp / 2 );
953
954 if ( ( xp % 2 ) == 0 )
955 {
956 u8 m = (u8)( *(to->data + offset) & 0x0F );
957 *(to->data + offset) = (u8)( m | ( d * 0x10) );
958 }
959 else
960 {
961 u8 m = (u8)( *(to->data + offset) & 0xF0 );
962 *(to->data + offset) = (u8)( m | d );
963 }
964
965 } break;
966 case GX_TF_C8 :
967 {
968 u8 d = (u8)val;
969
970 aw = ( to->width + 7 ) / 8u;
971 xp = x % 8;
972 xb = x / 8;
973 yp = y % 4;
974 yb = y / 4;
975 offset = ( yb * aw + xb ) * 32 + ( yp * 8 + xp );
976 *(to->data + offset) = d;
977 } break;
978 case GX_TF_C14X2 :
979 {
980 u16 d = (u16)val;
981
982 aw = ( to->width + 3 ) / 4u;
983 xp = x % 4;
984 xb = x / 4;
985 yp = y % 4;
986 yb = y / 4;
987 offset = ( yb * aw + xb ) * 32 + ( yp * 4 + xp ) * 2;
988 *(u16*)(to->data + offset) = d;
989 } break;
990 }
991
992 }
993
994 /*---------------------------------------------------------------------------*
995 Name: MyTlutRegionInit
996
997 Description: Initializes and customizes TLUT region configurations.
998 This test doesn't use default TLUT configuration.
999
1000 Arguments: none
1001
1002 Returns: none
1003 *---------------------------------------------------------------------------*/
MyTlutRegionInit(void)1004 static void MyTlutRegionInit( void )
1005 {
1006 s32 i;
1007 u32 addr = 0xC0000; // The lower half of high bank tmem
1008
1009 for ( i = NUM_REGIONS - 1 ; i >= 0 ; --i )
1010 {
1011 GXInitTlutRegion(
1012 &MyTlutRegions[i],
1013 addr,
1014 TlutSizeTable[i].symbol );
1015
1016 addr += TlutSizeTable[i].actualSize;
1017 }
1018
1019 GXSetTlutRegionCallback(MyTlutRegionCallback);
1020 }
1021
1022 /*---------------------------------------------------------------------------*
1023 Name: MyTlutRegionCallback
1024
1025 Description: Looks up TLUT region configuration of this test.
1026 Used by GX TLUT library.
1027
1028 Arguments: idx region identifier
1029 idx = 0 : returns 16 Entry TLUT Region
1030 = 1 : 32
1031 = 2 : 64
1032 = 3 : 128
1033 = 4 : 256
1034 = 5 : 512
1035 = 6 : 1024
1036 = 7 : 2048
1037 = 8 : 4096
1038
1039 Returns: pointer to specified TLUT region
1040 *---------------------------------------------------------------------------*/
MyTlutRegionCallback(u32 idx)1041 static GXTlutRegion* MyTlutRegionCallback( u32 idx )
1042 {
1043 ASSERTMSG(idx < NUM_REGIONS, "Invalid TLUT Region index\n");
1044
1045 return &MyTlutRegions[idx];
1046 }
1047
1048 /*---------------------------------------------------------------------------*
1049 Name: StatusMessage
1050
1051 Description: Shows current status
1052
1053 Arguments: none
1054
1055 Returns: none
1056 *---------------------------------------------------------------------------*/
StatusMessage(MyColorMapObj * cmo)1057 void StatusMessage( MyColorMapObj* cmo )
1058 {
1059 u32 numEntries;
1060
1061 numEntries = 1u << ( cmo->tlutNumber + 4 );
1062 OSReport("%d entries : ", numEntries);
1063
1064 switch(cmo->tlutFormat)
1065 {
1066 case GX_TL_IA8:
1067 {
1068 OSReport(
1069 "I%dA%d (GX_TL_IA8)\n",
1070 cmo->mapCtrl[0],
1071 cmo->mapCtrl[1] );
1072 } break;
1073 case GX_TL_RGB565:
1074 {
1075 OSReport(
1076 "R%dG%dB%d (GX_TL_RGB565)\n",
1077 cmo->mapCtrl[2],
1078 cmo->mapCtrl[1],
1079 cmo->mapCtrl[0] );
1080 } break;
1081 case GX_TL_RGB5A3:
1082 {
1083 OSReport(
1084 "R%dG%dB%dA%d (GX_TL_RGB5A3)\n",
1085 cmo->mapCtrl[3],
1086 cmo->mapCtrl[2],
1087 cmo->mapCtrl[1],
1088 cmo->mapCtrl[0] );
1089 } break;
1090 }
1091 }
1092
1093 /*---------------------------------------------------------------------------*
1094 Name: PrintIntro
1095
1096 Description: Prints the directions on how to use this demo.
1097
1098 Arguments: none
1099
1100 Returns: none
1101 *---------------------------------------------------------------------------*/
PrintIntro(void)1102 static void PrintIntro( void )
1103 {
1104 OSReport("\n\n");
1105 OSReport("******************************************************\n");
1106 OSReport("tex-tlut: CI texture with arbitrary TLUT size test\n");
1107 OSReport("******************************************************\n");
1108 OSReport("to quit hit the start button\n");
1109 OSReport("\n");
1110 OSReport("L/R triggers : change number of tlut entry.\n");
1111 OSReport("A button : change the TLUT format.\n");
1112 OSReport("Main Stick : change color map.\n");
1113 OSReport("******************************************************\n");
1114 OSReport("\n");
1115 }
1116
1117 /*============================================================================*/
1118