1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tex-fmt-tpl.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-fmt-tpl
15         display various format textures ( tpl version )
16  *---------------------------------------------------------------------------*/
17 
18 
19 /*---------------------------------------------------------------------------*
20    Header files
21  *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <string.h>
24 
25 /*---------------------------------------------------------------------------*
26    Macro definitions
27  *---------------------------------------------------------------------------*/
28 #define MAX_SCOORD         0x4000  // for 16b, 2.14 fixed point format
29 #define MAX_TCOORD         0x4000  // for 16b, 2.14 fixed point format
30 #define STEP_SCOORD        2
31 #define STEP_TCOORD        3
32 
33 #define Clamp(val,min,max) \
34     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
35 
36 /*---------------------------------------------------------------------------*
37    Structure definitions
38  *---------------------------------------------------------------------------*/
39 // for camera
40 typedef struct
41 {
42     Vec    location;
43     Vec    up;
44     Vec    target;
45     f32    left;
46     f32    top;
47     f32    znear;
48     f32    zfar;
49 } CameraConfig;
50 
51 typedef struct
52 {
53     CameraConfig  cfg;
54     Mtx           view;
55     Mtx44         proj;
56 } MyCameraObj;
57 
58 // for texture
59 typedef struct
60 {
61     GXTexObj      tobj;
62     u32           width;
63     u32           height;
64 } MyTexObj;
65 
66 // for entire scene control
67 typedef struct
68 {
69     MyCameraObj    cam;
70     MyTexObj       texture;
71     Mtx            modelCtrl;
72     f32            modelScale;
73     u32            texNumber;
74     u32            texFileNumber;
75     GXTevMode      tevMode;
76 } MySceneCtrlObj;
77 
78 /*---------------------------------------------------------------------------*
79    Forward references
80  *---------------------------------------------------------------------------*/
81 void        main           ( void );
82 static void DrawInit       ( MySceneCtrlObj* sc );
83 static void DrawTick       ( MySceneCtrlObj* sc );
84 static void AnimTick       ( MySceneCtrlObj* sc );
85 static void GetTplTexture  ( MyTexObj* to, u32 num );
86 static void LoadTplFile    ( char* fileName );
87 static void DrawBox        ( void );
88 static void SetCamera      ( MyCameraObj* cam );
89 static void PrintIntro     ( void );
90 
91 /*---------------------------------------------------------------------------*
92    Model Data
93  *---------------------------------------------------------------------------*/
94 /*---------------------------------------------------------------------------*
95    Data arrays for indexed primitives must be 32B aligned.  Normally, memory
96    for the arrays would be OSAlloc'd (which returns 32B aligned pointers) and
97    the data would be loaded from ROM.  The pragma variable_align provides a
98    convenient way to align initialized arrays.
99  *---------------------------------------------------------------------------*/
100 static s16 TopVerts[] ATTRIBUTE_ALIGN(32) =
101 {
102     -1, -1,  1, // 0
103      1, -1,  1, // 1
104      1,  1,  1, // 2
105     -1,  1,  1, // 3
106     -1, -1, -1, // 4
107      1, -1, -1, // 5
108      1,  1, -1, // 6
109     -1,  1, -1  // 7
110 };
111 
112 static u8 Colors[] ATTRIBUTE_ALIGN(32) =
113 {
114     0x80, 0x00, 0x00, 0x80,
115     0x00, 0x80, 0x00, 0x80,
116     0x00, 0x00, 0x80, 0x80,
117     0x80, 0x80, 0x00, 0x80,
118     0x80, 0x00, 0x80, 0x80,
119     0x00, 0x80, 0x80, 0x80,
120 };
121 
122 /*---------------------------------------------------------------------------*
123    Debug Message Strings
124  *---------------------------------------------------------------------------*/
125 static char* TxFmtStr[] =
126 {
127     "I4",
128     "I8",
129     "IA4",
130     "IA8",
131     "RGB565",
132     "RGB5A3",
133     "RGBA8",
134     "?",
135     "CI4",
136     "CI8",
137     "CI14X2",
138     "?",
139     "?",
140     "?",
141     "Compressed"
142 };
143 
144 static char* TxWrapStr[] =
145 {
146     "Clamp",
147     "Repeat",
148     "Mirror"
149 };
150 
151 static char* TxFilterStr[] =
152 {
153     "Near",
154     "Linear",
155     "Near/Near",
156     "Linear/Near",
157     "Near/Linear",
158     "Linear/Linear"
159 };
160 
161 static char* TxSwStr[] =
162 {
163     "OFF",
164     "ON"
165 };
166 
167 /*---------------------------------------------------------------------------*
168   Tpl File List
169  *---------------------------------------------------------------------------*/
170 #define NUM_OF_TPL_FILES    26
171 
172 static char* TplFileList[] =
173 {
174     // I4
175     "i4_1",     "i4_1mm",     "i4_odd",
176     // I8
177     "i8_1",     "i8_1mm",     "i8_odd",
178     // IA4
179     "ia4_1",    "ia4_1mm",    "ia4_odd",
180     // IA8
181     "ia8_1",    "ia8_1mm",    "ia8_odd",
182     // RGB565
183     "rgb565_1", "rgb565mm",   "rgb565od",
184     // RGB5A3
185     "rgb5a3_1", "rgb5a3mm",   "rgb5a3od",
186     // RGBA8
187     "rgba8_1",  "rgba8mm",    "rgba8od",
188     // Compressed
189     "cmp_1",    "cmp_1mm",    "cmp_even",
190     // CI8
191     "ci8_1",    "ci8_2"
192 };
193 
194 /*---------------------------------------------------------------------------*
195    Camera configuration
196  *---------------------------------------------------------------------------*/
197 static CameraConfig DefaultCamera =
198 {
199     { 0.0F, -5000.0F, 0.0F }, // location
200     { 0.0F,     0.0F, 1.0F }, // up
201     { 0.0F,     0.0F, 0.0F }, // target
202     -320.0F, // left
203     240.0F,  // top
204     0.0F,    // near
205     10000.0F // far
206 };
207 
208 /*---------------------------------------------------------------------------*
209    Global variables
210  *---------------------------------------------------------------------------*/
211 static MySceneCtrlObj    SceneCtrl;      // scene control parameters
212 static TPLPalettePtr     MyTplObj = 0;   // texture palette
213 static u32               TexNumMax;      // number of textures
214 
215 /*---------------------------------------------------------------------------*
216    Application main loop
217  *---------------------------------------------------------------------------*/
main(void)218 void main ( void )
219 {
220     DEMOInit(NULL);  // Init the OS, game pad, graphics and video.
221 
222     PrintIntro(); // Print demo directions
223 
224     DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
225                           // and default scene settings.
226 
227     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
228     {
229 		DEMOBeforeRender();
230         DrawTick(&SceneCtrl);    // Draw the model.
231         DEMODoneRender();
232         DEMOPadRead();           // Read controller
233         AnimTick(&SceneCtrl);    // Do animation
234     }
235 
236     OSHalt("End of test");
237 }
238 
239 /*---------------------------------------------------------------------------*
240    Functions
241  *---------------------------------------------------------------------------*/
242 /*---------------------------------------------------------------------------*
243     Name:           DrawInit
244 
245     Description:    Initializes the vertex attribute format and sets up
246                     the array pointer for the indexed data.
247                     This function also initializes scene control parameters.
248 
249     Arguments:      sc : pointer to the structure of scene control parameters
250 
251     Returns:        none
252  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)253 static void DrawInit( MySceneCtrlObj* sc )
254 {
255     // Vertex Attribute
256     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
257     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
258     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 14);
259 
260     // Array Pointers and Strides
261     GXInvalidateVtxCache();
262     // stride = 3 elements (x,y,z) each of type s16
263     GXSetArray(GX_VA_POS, TopVerts, 3*sizeof(s16));
264     // stride = 4 elements (r,g,b,a) each of type u8
265     GXSetArray(GX_VA_CLR0, Colors, 4*sizeof(u8));
266 
267     // backface culling off
268     GXSetCullMode(GX_CULL_NONE);
269 
270 	GXSetNumChans(1); // GXInit passes vertex color to color channel/default
271 	GXSetNumTexGens(1);
272 	GXSetNumTevStages(1);
273 	GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
274 
275     // Default scene control parameter settings
276 
277     // camera
278     sc->cam.cfg = DefaultCamera;
279     SetCamera(&sc->cam);   // never changes in this test
280 
281     // Load the first Tpl Texture
282     sc->texFileNumber = 0;
283     sc->texNumber     = 0;
284     LoadTplFile(TplFileList[sc->texFileNumber]);
285     GetTplTexture(&sc->texture, sc->texNumber);
286 
287     // model control parameters
288     sc->modelScale = 1.0F;
289     MTXIdentity(sc->modelCtrl);
290 
291     // tev mode
292     sc->tevMode = GX_REPLACE;
293 }
294 
295 /*---------------------------------------------------------------------------*
296     Name:           DrawTick
297 
298     Description:    Draw the model by using given scene parameters
299 
300     Arguments:      sc : pointer to the structure of scene control parameters
301 
302     Returns:        none
303  *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)304 static void DrawTick( MySceneCtrlObj* sc )
305 {
306     static u32 s = 0;
307     static u32 t = 0;
308 
309     Mtx  ms; // Model scale matrix.
310     Mtx  mv; // Modelview matrix.
311 
312     // Set modelview matrix
313     MTXConcat(sc->cam.view, sc->modelCtrl, mv);
314     MTXScale(
315         ms,
316         sc->modelScale * sc->texture.width / 2,
317         sc->modelScale * sc->texture.height / 2,
318         sc->modelScale * sc->texture.height / 2 );
319     MTXConcat(mv, ms, mv);
320     GXLoadPosMtxImm(mv, GX_PNMTX0);
321 
322     // tev mode
323     GXSetTevOp(GX_TEVSTAGE0, sc->tevMode);
324     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
325 
326     // load texture obj
327     GXLoadTexObj(&sc->texture.tobj, GX_TEXMAP0);
328 
329     // draw a box
330     DrawBox();
331 
332     // translate s, t coordinates
333     s += STEP_SCOORD;
334     t += STEP_TCOORD;
335     if (s > MAX_SCOORD) s = 0;
336     if (t > MAX_TCOORD) t = 0;
337 
338 }
339 
340 /*---------------------------------------------------------------------------*
341     Name:           AnimTick
342 
343     Description:    Changes scene parameters according to the pad status.
344 
345     Arguments:      sc : pointer to the structure of scene control parameters
346 
347     Returns:        none
348  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)349 static void AnimTick( MySceneCtrlObj* sc )
350 {
351     u16  down;
352     Mtx  mrx, mry;
353 
354     // PAD
355     down = DEMOPadGetButtonDown(0);
356 
357     // Model Rotation Calculation
358     MTXRotDeg(mry, 'x', -(DEMOPadGetStickY(0) / 16));
359     MTXRotDeg(mrx, 'z',  (DEMOPadGetStickX(0) / 16));
360     MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
361     MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
362 
363     // Changes model scale
364     sc->modelScale += (DEMOPadGetSubStickY(0) / 16) * 0.0125F;
365     Clamp(sc->modelScale, 0.1F, 4.0F);
366 
367 
368     // Change texture
369     if ( down & PAD_BUTTON_Y )
370     {
371         sc->texNumber = ( sc->texNumber + 1 ) % TexNumMax;
372         GetTplTexture(&sc->texture, sc->texNumber);
373     }
374     if ( down & PAD_BUTTON_X )
375     {
376         sc->texNumber = ( sc->texNumber + TexNumMax - 1 ) % TexNumMax;
377         GetTplTexture(&sc->texture, sc->texNumber);
378     }
379 
380     // Change tpl file
381     if ( down & PAD_TRIGGER_R )
382     {
383         sc->texFileNumber = ( sc->texFileNumber + 1 ) % NUM_OF_TPL_FILES;
384         LoadTplFile(TplFileList[sc->texFileNumber]);
385         sc->texNumber = 0;
386         GetTplTexture(&sc->texture, sc->texNumber);
387     }
388     if ( down & PAD_TRIGGER_L )
389     {
390         sc->texFileNumber = ( sc->texFileNumber + NUM_OF_TPL_FILES - 1 ) % NUM_OF_TPL_FILES;
391         LoadTplFile(TplFileList[sc->texFileNumber]);
392         sc->texNumber = 0;
393         GetTplTexture(&sc->texture, sc->texNumber);
394     }
395 
396     // Change Tev mode
397     if ( down & PAD_BUTTON_B )
398     {
399         sc->tevMode = ( sc->tevMode == GX_REPLACE ) ? GX_DECAL : GX_REPLACE;
400     }
401 
402     // Reset view
403     if ( down & PAD_BUTTON_A )
404     {
405         sc->modelScale = 1.0F;
406         MTXIdentity(sc->modelCtrl);
407     }
408 
409 }
410 
411 /*---------------------------------------------------------------------------*
412     Name:           GetTplTexture
413 
414     Description:    get current texture from the texture palette
415 
416     Arguments:      to  : a pointer to MyTexObj structure to be set
417                     num : texture number in the tpl
418 
419     Returns:        none
420  *---------------------------------------------------------------------------*/
GetTplTexture(MyTexObj * to,u32 num)421 void GetTplTexture( MyTexObj* to, u32 num )
422 {
423     TPLDescriptorPtr tdp;
424     u32              fmt;
425     GXBool           mipMapFlag;
426 
427     if ( num >= MyTplObj->numDescriptors )
428     {
429         num = 0;
430     }
431 
432     // Get a texture descriptor
433     tdp = TPLGet(MyTplObj, num);
434 
435     mipMapFlag =
436         (GXBool)(( tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD ) ?
437                  GX_FALSE : GX_TRUE);
438 
439     fmt = (u32)tdp->textureHeader->format;
440     to->width  = tdp->textureHeader->width;
441     to->height = tdp->textureHeader->height;
442 
443     if ( fmt == GX_TF_C4 || fmt == GX_TF_C8 )
444     {
445         GXTlutObj tlutObj;
446 
447         GXInitTexObjCI(
448             &to->tobj,
449             tdp->textureHeader->data,
450             tdp->textureHeader->width,
451             tdp->textureHeader->height,
452             (GXCITexFmt)fmt,
453             tdp->textureHeader->wrapS, // s
454             tdp->textureHeader->wrapT, // t
455             mipMapFlag, // Mipmap
456             GX_TLUT0 );
457 
458         GXInitTlutObj(
459             &tlutObj,
460             tdp->CLUTHeader->data,
461             (GXTlutFmt)tdp->CLUTHeader->format,
462             tdp->CLUTHeader->numEntries );
463 
464         GXLoadTlut(&tlutObj, GX_TLUT0);
465     }
466     else
467     {
468         GXInitTexObj(
469             &to->tobj,
470             tdp->textureHeader->data,
471             tdp->textureHeader->width,
472             tdp->textureHeader->height,
473             (GXTexFmt)fmt,
474             tdp->textureHeader->wrapS, // s
475             tdp->textureHeader->wrapT, // t
476             mipMapFlag ); // Mipmap
477     }
478 
479     GXInitTexObjLOD(
480         &to->tobj,
481         tdp->textureHeader->minFilter,
482         tdp->textureHeader->magFilter,
483         tdp->textureHeader->minLOD,
484         tdp->textureHeader->maxLOD,
485         tdp->textureHeader->LODBias,
486         GX_FALSE,
487         tdp->textureHeader->edgeLODEnable,
488         GX_ANISO_1 );
489 
490     OSReport("*******************************************\n");
491     OSReport("Width  = %04d\t\t", tdp->textureHeader->width);
492     OSReport("Height = %04d\n", tdp->textureHeader->height);
493     OSReport("Format = %s ", TxFmtStr[tdp->textureHeader->format]);
494     OSReport("(%d)\n", tdp->textureHeader->format);
495     OSReport("Wrap_s = %s\t\t", TxWrapStr[tdp->textureHeader->wrapS]);
496     OSReport("Wrap_t = %s\n", TxWrapStr[tdp->textureHeader->wrapT]);
497     OSReport("MinFilter = %s\t", TxFilterStr[tdp->textureHeader->minFilter]);
498     OSReport("MagFilter = %s\n", TxFilterStr[tdp->textureHeader->magFilter]);
499     OSReport("MinLOD = %d\t\t\t", tdp->textureHeader->minLOD);
500     OSReport("MaxLOD = %d\n", tdp->textureHeader->maxLOD);
501     OSReport("LODBias = %f\n", tdp->textureHeader->LODBias);
502     OSReport("MipMap  = %s\n", TxSwStr[mipMapFlag]);
503     OSReport("*******************************************\n");
504 }
505 
506 /*---------------------------------------------------------------------------*
507     Name:           LoadTplFile
508 
509     Description:    Load tpl file with specified name.
510 
511     Arguments:      fileName : tpl file name
512 
513     Returns:        none
514  *---------------------------------------------------------------------------*/
LoadTplFile(char * fileName)515 void LoadTplFile( char* fileName )
516 {
517     char strBuffer[64];
518 
519     if ( MyTplObj != 0 )
520     {
521         TPLReleasePalette(&MyTplObj);
522     }
523 
524     strcpy(strBuffer,"gxTests/tex-02/");
525     strcat(strBuffer, fileName);
526     strcat(strBuffer, ".tpl");
527     OSReport("File: %s\n", strBuffer);
528 
529     TPLGetPalette(&MyTplObj, strBuffer);
530     TexNumMax = MyTplObj->numDescriptors;
531 
532     GXInvalidateTexAll();
533 }
534 
535 /*---------------------------------------------------------------------------*
536     Name:           VertexT
537 
538     Description:    Draw a vertex with texture, direct data
539 
540     Arguments:      v        8-bit position index
541                     s, t     16-bit tex coord
542 
543     Returns:        none
544  *---------------------------------------------------------------------------*/
VertexT(u8 v,u32 s,u32 t,u8 c)545 static inline void VertexT( u8 v, u32 s, u32 t, u8 c )
546 {
547     GXPosition1x8(v);
548     GXColor1x8(c);
549     GXTexCoord2u16((u16)s, (u16)t);
550 }
551 
552 /*---------------------------------------------------------------------------*
553     Name:           DrawTexQuad
554 
555     Description:    Draw a textured quad.  Map extends to corners of the quad.
556                     MAX_SCOORD is the value of 1.0 in the fixed point format.
557 
558     Arguments:      v0        8-bit position
559                     v1        8-bit position
560                     v2        8-bit position
561                     v3        8-bit position
562                     s0        s tex coord at v0
563                     t0        t tex coord at v0
564 
565     Returns:        none
566  *---------------------------------------------------------------------------*/
DrawTexQuad(u8 v0,u8 v1,u8 v2,u8 v3,u32 s0,u32 t0,u8 c)567 static inline void DrawTexQuad(
568     u8  v0,
569     u8  v1,
570     u8  v2,
571     u8  v3,
572     u32 s0,
573     u32 t0,
574     u8  c )
575 {
576     VertexT(v0, s0+MAX_SCOORD, t0, c);
577     VertexT(v1, s0, t0, c);
578     VertexT(v2, s0, t0+MAX_TCOORD, c);
579     VertexT(v3, s0+MAX_SCOORD, t0+MAX_TCOORD, c);
580 }
581 
582 /*---------------------------------------------------------------------------*
583     Name:           DrawBox
584 
585     Description:    Draw a box model.
586 
587     Arguments:      none
588 
589     Returns:        none
590  *---------------------------------------------------------------------------*/
DrawBox(void)591 static void DrawBox( void )
592 {
593     // set vertex descriptor
594     GXClearVtxDesc();
595     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
596     GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
597     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
598 
599     // draw the box
600     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
601         DrawTexQuad(1, 0, 3, 2, 0, 0, 0);
602         DrawTexQuad(6, 7, 4, 5, 0, 0, 1);
603         DrawTexQuad(3, 0, 4, 7, 0, 0, 2);
604         DrawTexQuad(0, 1, 5, 4, 0, 0, 3);
605         DrawTexQuad(1, 2, 6, 5, 0, 0, 4);
606         DrawTexQuad(2, 3, 7, 6, 0, 0, 5);
607     GXEnd();
608 }
609 
610 /*---------------------------------------------------------------------------*
611     Name:           SetCamera
612 
613     Description:    set view matrix and load projection matrix into hardware
614 
615     Arguments:      cam : pointer to the MyCameraObj structure
616 
617     Returns:        none
618  *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)619 static void SetCamera( MyCameraObj* cam )
620 {
621     MTXLookAt(
622         cam->view,
623         &cam->cfg.location,
624         &cam->cfg.up,
625         &cam->cfg.target );
626 
627     MTXOrtho(
628         cam->proj,
629         cam->cfg.top,
630         - (cam->cfg.top),
631         cam->cfg.left,
632         - (cam->cfg.left),
633         cam->cfg.znear,
634         cam->cfg.zfar );
635     GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
636 }
637 
638  /*---------------------------------------------------------------------------*
639     Name:           PrintIntro
640 
641     Description:    Prints the directions on how to use this demo.
642 
643     Arguments:      none
644 
645     Returns:        none
646  *---------------------------------------------------------------------------*/
PrintIntro(void)647 void PrintIntro(void)
648 {
649     OSReport("***************************************\n");
650     OSReport("Instructions:\n");
651     OSReport("    Start       : quit this program\n");
652     OSReport("    Main Stick  : rotate the box\n");
653     OSReport("    Sub Stick Y : change scale of the box\n");
654     OSReport("    X Button    : view next TPL file\n");
655     OSReport("    Y Button    : view previous TPL file\n");
656     OSReport("    B Button    : change tev mode (to check alpha)\n");
657     OSReport("    A Button    : reset the view\n");
658     OSReport("***************************************\n");
659 }
660 
661 /*============================================================================*/
662