1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tev-ztex.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 tev-ztex
15 Z texture test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <string.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 // Indices for textures stored in TPL file
29 #define TEX_GROUND 0
30 #define TEX_GROUND_Z 1
31 #define TEX_TREE 2
32 #define TEX_TREE_Z 3
33 #define TEX_WATER 4
34 #define NUM_TEXTURES 5
35
36 // Number of tree sprites
37 #define NUM_TREES 8
38
39 // Number of Z modes
40 #define NUM_ZMODES 4
41
42 // Max value of Z buffer
43 #define MAX_Z 0x00FFFFFF
44
45
46 #define Clamp(cast,val,min,max) \
47 ((val) = (cast)((((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val))))
48
49 /*---------------------------------------------------------------------------*
50 Structure definitions
51 *---------------------------------------------------------------------------*/
52 // for sprite control
53 typedef struct
54 {
55 s16 xpos; // left
56 s16 ypos; // bottom
57 s16 zpos;
58 s16 width;
59 s16 height;
60 s16 s0;
61 s16 s1;
62 s16 t0;
63 s16 t1;
64 u8 texIdx; // texture index
65 u8 ztxIdx; // Z texture index
66 u32 zbias; // Z texture bias
67 } MySpriteObj;
68
69 // for entire scene control
70 typedef struct
71 {
72 u32 cur;
73 u32 zmode;
74 s16 waterLv;
75 MySpriteObj tree[NUM_TREES];
76 u16 screenWd;
77 u16 screenHt;
78 GXTexObj texture[NUM_TEXTURES];
79 } MySceneCtrlObj;
80
81 /*---------------------------------------------------------------------------*
82 Forward references
83 *---------------------------------------------------------------------------*/
84 void main ( void );
85 static void DrawInit ( MySceneCtrlObj* sc );
86 static void DrawTick ( MySceneCtrlObj* sc );
87 static void AnimTick ( MySceneCtrlObj* sc );
88 static void Draw3DSprite ( MySpriteObj* sp, u32 zmode );
89 static void DrawWater ( s16 level );
90 static void MyTexInit ( void );
91 static void SetShaderModeForSprites ( void );
92 static void SetShaderModeForWater ( void );
93 static void SetScreenSpace ( u16 width, u16 height, f32 depth );
94 static void PrintIntro ( void );
95
96 /*---------------------------------------------------------------------------*
97 Data for drawing objects
98 *---------------------------------------------------------------------------*/
99 static MySpriteObj GroundSprite =
100 {
101 0, 0, 32767, // xpos, ypos, zpos
102 640, 256, // width, height
103 0x0000, 0x0280, // s0=0.0, s1=2.5
104 0x0000, 0x0100, // t0=0.0, t1=1.0
105 TEX_GROUND, // texture index
106 TEX_GROUND_Z, // Z texture index
107 0x00FF8000 // Z bias = -32768
108 };
109
110 static MySpriteObj DefaultTreeSprite =
111 {
112 0, 0, 0, // xpos, ypos, zpos (set later)
113 128, 256, // width, height
114 0x0000, 0x0100, // s0=0.0, s1=1.0
115 0x0000, 0x0100, // t0=0.0, t1=1.0
116 TEX_TREE, // texture index
117 TEX_TREE_Z, // Z texture index
118 0x00FFFF80 // Z bias = -128
119 };
120
121 static s16 DefaultTreePos[NUM_TREES][3] =
122 {
123 { -48, 192, 2688 },
124 { 0, 48, 2370 },
125 { 128, 168, 2716 },
126 { 200, 56, 1900 },
127 { 328, 120, 2464 },
128 { 368, 120, 2484 },
129 { 456, -16, 1780 },
130 { 536, 96, 3096 },
131 };
132
133 static GXColor WaterBaseColor = { 160, 160, 192, 80 };
134 static GXColor BgColor = { 120, 136, 152, 0 };
135
136 /*---------------------------------------------------------------------------*
137 Data for Z texturing mode control
138 *---------------------------------------------------------------------------*/
139 static GXZTexOp ZTexOpTbl[NUM_ZMODES] =
140 {
141 GX_ZT_ADD, GX_ZT_ADD, GX_ZT_REPLACE, GX_ZT_DISABLE
142 };
143
144 static char* ZModeMsgTbl[NUM_ZMODES] =
145 {
146 "Z texture add mode with bias",
147 "Z texture add mode without bias",
148 "Z texture replace mode without bias",
149 "Z texture off"
150 };
151
152
153 /*---------------------------------------------------------------------------*
154 Global variables
155 *---------------------------------------------------------------------------*/
156 static MySceneCtrlObj SceneCtrl; // scene control parameters
157 static TPLPalettePtr MyTplObj = NULL; // texture palette
158 static GXTexObj MyTexArray[NUM_TEXTURES]; // texture objects
159
160 /*---------------------------------------------------------------------------*
161 Application main loop
162 *---------------------------------------------------------------------------*/
main(void)163 void main ( void )
164 {
165 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
166
167 DrawInit(&SceneCtrl); // Initialize vertex formats, pixel modes
168 // and default scene settings.
169
170 PrintIntro(); // Print demo directions
171
172 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
173 {
174 DEMOBeforeRender();
175 DrawTick(&SceneCtrl); // Draw the model.
176 DEMODoneRender();
177 DEMOPadRead(); // Read controller
178 AnimTick(&SceneCtrl); // Do animation
179 }
180
181 OSHalt("End of demo");
182 }
183
184 /*---------------------------------------------------------------------------*
185 Functions
186 *---------------------------------------------------------------------------*/
187 /*---------------------------------------------------------------------------*
188 Name: DrawInit
189
190 Description: Initializes the vertex attribute format and sets up
191 the array pointer for the indexed data.
192 This function also initializes scene control parameters.
193
194 Arguments: sc : pointer to the structure of scene control parameters
195
196 Returns: none
197 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)198 static void DrawInit( MySceneCtrlObj* sc )
199 {
200 GXRenderModeObj* rmode;
201 u32 i;
202
203 // Vertex Attribute
204 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
205 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA4, 0);
206 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 8);
207
208 // Get Screen Information defined in DEMOInit()
209 rmode = DEMOGetRenderModeObj();
210 sc->screenWd = rmode->fbWidth; // Screen Width
211 sc->screenHt = rmode->efbHeight; // Screen Height
212
213 // Z compare mode
214 GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_TRUE);
215 GXSetZCompLoc(GX_FALSE);
216
217 // Clear background by specified color at first
218 // The operation can be done by dummy display copy.
219 GXSetCopyClear(BgColor, MAX_Z);
220 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
221
222
223 // Load TPL file
224 MyTexInit();
225
226
227 // Default scene control parameter settings
228
229 // Initialize position of tree sprites
230 for ( i = 0 ; i < NUM_TREES ; ++i )
231 {
232 sc->tree[i] = DefaultTreeSprite;
233
234 // Overwrite position for each tree
235 sc->tree[i].xpos = DefaultTreePos[i][0];
236 sc->tree[i].ypos = DefaultTreePos[i][1];
237 sc->tree[i].zpos = DefaultTreePos[i][2];
238 }
239
240 // water level
241 sc->waterLv = 176;
242
243 // cursor
244 sc->cur = 0;
245 }
246
247 /*---------------------------------------------------------------------------*
248 Name: DrawTick
249
250 Description: Draw the model by using given scene parameters
251
252 Arguments: sc : pointer to the structure of scene control parameters
253
254 Returns: none
255 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)256 static void DrawTick( MySceneCtrlObj* sc )
257 {
258 u32 i;
259
260 // set projection to match screen space coordinate system
261 SetScreenSpace(sc->screenWd, sc->screenHt, 0x01000000);
262
263 // blend mode (semi-transparent values are blended)
264 GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
265
266 //------------------------------------
267 // Draw sprite objects
268 //------------------------------------
269 SetShaderModeForSprites();
270
271 // ground
272 Draw3DSprite(&GroundSprite, sc->zmode);
273
274 // trees
275 for ( i = 0 ; i < NUM_TREES ; ++i )
276 {
277 Draw3DSprite(&sc->tree[i], sc->zmode);
278 }
279
280 //------------------------------------
281 // Draw water surface
282 //------------------------------------
283
284 // Z texture off
285 GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
286
287 SetShaderModeForWater();
288 DrawWater(sc->waterLv);
289 }
290
291 /*---------------------------------------------------------------------------*
292 Name: AnimTick
293
294 Description: Changes scene parameters according to the pad status.
295
296 Arguments: sc : pointer to the structure of scene control parameters
297
298 Returns: none
299 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)300 static void AnimTick( MySceneCtrlObj* sc )
301 {
302 MySpriteObj* sp;
303 u16 down;
304
305 // PAD
306 down = DEMOPadGetButtonDown(0);
307
308 sp = &sc->tree[sc->cur];
309
310 // Move selected tree sprite
311 sp->xpos += ( DEMOPadGetStickX(0) / 16 );
312 Clamp(s16, sp->xpos, (s16)-128, (s16)sc->screenWd);
313 sp->ypos += ( DEMOPadGetStickY(0) / 16 );
314 Clamp(s16, sp->ypos, (s16)-256, (s16)sc->screenHt);
315 sp->zpos += ( DEMOPadGetSubStickY(0) / 4 );
316 Clamp(s16, sp->zpos, (s16)0, (s16)32767);
317
318 // Select a tree
319 if ( down & PAD_BUTTON_X )
320 {
321 sc->cur = ( sc->cur + 1 ) % NUM_TREES;
322 }
323
324 if ( down & PAD_BUTTON_Y )
325 {
326 sc->cur = ( sc->cur + NUM_TREES - 1 ) % NUM_TREES;
327 }
328
329 // Water level
330 sc->waterLv += ( DEMOPadGetTriggerL(0) - DEMOPadGetTriggerR(0) ) / 32;
331 Clamp(s16, sc->waterLv, (s16)0, (s16)256);
332
333 // Z texturing mode
334 if ( down & PAD_BUTTON_B )
335 {
336 sc->zmode = ( sc->zmode + 1 ) % NUM_ZMODES;
337 OSReport("%s\n", ZModeMsgTbl[sc->zmode]);
338 }
339 }
340
341 /*---------------------------------------------------------------------------*
342 Name: Draw3DSprite
343
344 Description: Draw a 3D sprite specified by given data structure.
345
346 Arguments: sp: a pointer to MySpriteObj structure
347 zmode : Z texturing mode
348
349 Returns: none
350 *---------------------------------------------------------------------------*/
Draw3DSprite(MySpriteObj * sp,u32 zmode)351 static void Draw3DSprite( MySpriteObj* sp, u32 zmode )
352 {
353 s16 xpos1, ypos1;
354 u32 zbias;
355
356 // Z bias enable / disable
357 zbias = ( zmode == 0 ) ? sp->zbias : 0U;
358
359 // load textures and set up Z texturing
360 GXLoadTexObj(&MyTexArray[sp->texIdx], GX_TEXMAP0);
361
362 GXLoadTexObj(&MyTexArray[sp->ztxIdx], GX_TEXMAP1);
363 GXSetZTexture(
364 ZTexOpTbl[zmode],
365 GXGetTexObjFmt(&MyTexArray[sp->ztxIdx]),
366 zbias );
367
368 // set vertex descriptor
369 GXClearVtxDesc();
370 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
371 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
372
373 xpos1 = (s16)(sp->xpos + sp->width);
374 ypos1 = (s16)(sp->ypos + sp->height);
375
376 // draw the quad
377 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
378 GXPosition3s16(sp->xpos, sp->ypos, sp->zpos);
379 GXTexCoord2s16(sp->s0, sp->t1);
380 GXPosition3s16(sp->xpos, ypos1, sp->zpos);
381 GXTexCoord2s16(sp->s0, sp->t0);
382 GXPosition3s16(xpos1, ypos1, sp->zpos);
383 GXTexCoord2s16(sp->s1, sp->t0);
384 GXPosition3s16(xpos1, sp->ypos, sp->zpos);
385 GXTexCoord2s16(sp->s1, sp->t1);
386 GXEnd();
387 }
388
389 /*---------------------------------------------------------------------------*
390 Name: DrawWater
391
392 Description: Draw water surface.
393 The water surface is one textured quad
394 which has some degree of gradient.
395
396 Arguments: level : water level
397
398 Returns: none
399 *---------------------------------------------------------------------------*/
DrawWater(s16 level)400 static void DrawWater( s16 level )
401 {
402 static s16 s0 = 0;
403 s16 s1, lv1;
404
405 s1 = (s16)(s0 + 0x1000);
406 lv1 = (s16)(level - 256);
407
408 // load texture
409 GXLoadTexObj(&MyTexArray[TEX_WATER], GX_TEXMAP0);
410
411 // set vertex descriptor
412 GXClearVtxDesc();
413 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
414 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
415
416 // draw the quad
417 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
418 GXPosition3s16(0, lv1, 0);
419 GXTexCoord2s16(s0, 0x0000);
420 GXPosition3s16(0, level, 4096);
421 GXTexCoord2s16(s0, 0x0600);
422 GXPosition3s16(640, level, 4096);
423 GXTexCoord2s16(s1, 0x0600);
424 GXPosition3s16(640, lv1, 0);
425 GXTexCoord2s16(s1, 0x0000);
426 GXEnd();
427
428 s0 = (s16)(++s0 % 0x100);
429 }
430
431 /*---------------------------------------------------------------------------*
432 Name: MyTexInit
433
434 Description: Load texture data from a TPL file and store it
435 into the texture object array. (TexArray)
436
437 Since TPL file is not able to handle Z texture
438 format, Z textures are saved as other format
439 data. This function converts their format
440 and some other fields to make them suitable
441 for Z texturing.
442
443 Arguments: none
444
445 Returns: none
446 *---------------------------------------------------------------------------*/
MyTexInit(void)447 static void MyTexInit( void )
448 {
449 TPLDescriptorPtr tdp;
450 GXTexFmt fmt;
451 GXTexFilter filter;
452 u32 i;
453
454 TPLGetPalette(&MyTplObj, "gxTests/tev-04.tpl");
455
456 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
457 {
458 tdp = TPLGet(MyTplObj, i);
459
460 if ( i % 2 == 0 )
461 {
462 // Even number -> image texture
463 fmt = (GXTexFmt)tdp->textureHeader->format;
464 filter = GX_LINEAR;
465
466 // Ground texture needs special wrap mode setting
467 if ( i == TEX_GROUND )
468 {
469 tdp->textureHeader->wrapS = GX_REPEAT;
470 tdp->textureHeader->wrapT = GX_CLAMP;
471 }
472 }
473 else
474 {
475 // Odd number -> supposed to be Z texture
476
477 // format conversion
478 switch(tdp->textureHeader->format)
479 {
480 case GX_TF_I8 :
481 fmt = GX_TF_Z8;
482 break;
483 case GX_TF_IA8 :
484 fmt = GX_TF_Z16;
485 break;
486 case GX_TF_RGBA8:
487 fmt = GX_TF_Z24X8;
488 break;
489 default:
490 OSHalt("Invalid data for Z texturing.");
491 }
492
493 filter = GX_NEAR;
494 }
495
496 GXInitTexObj(
497 &MyTexArray[i],
498 tdp->textureHeader->data,
499 tdp->textureHeader->width,
500 tdp->textureHeader->height,
501 fmt,
502 tdp->textureHeader->wrapS,
503 tdp->textureHeader->wrapT,
504 GX_FALSE ); // Mipmap is always off
505 GXInitTexObjLOD(
506 &MyTexArray[i],
507 filter, // Z doesn't work well with filtering
508 filter, //
509 0,
510 0,
511 0,
512 GX_FALSE,
513 GX_FALSE,
514 GX_ANISO_1 );
515 }
516 }
517
518 /*---------------------------------------------------------------------------*
519 Name: SetShaderModeForSprites
520
521 Description: Set up shader mode (TEV, color channel, etc.)
522 for drawing sprite objects.
523
524 Arguments: none
525
526 Returns: none
527 *---------------------------------------------------------------------------*/
SetShaderModeForSprites(void)528 static void SetShaderModeForSprites( void )
529 {
530 // accepts alpha > 128 which are used for blending
531 GXSetAlphaCompare(GX_GREATER, 128, GX_AOP_AND, GX_ALWAYS, 0);
532
533 // use no color channel
534 GXSetNumChans(0);
535
536 // use two textures that share the same texcoord
537 // (it is possible only if the size is same.)
538 GXSetNumTexGens(1);
539 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
540
541 // TEV setting
542 GXSetNumTevStages(2);
543 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
544 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
545 GXSetTevOp(GX_TEVSTAGE1, GX_PASSCLR);
546 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL);
547 }
548
549 /*---------------------------------------------------------------------------*
550 Name: SetShaderModeForWater
551
552 Description: Set up shader mode (TEV, color channel, etc.)
553 for drawing water surface.
554
555 Arguments: none
556
557 Returns: none
558 *---------------------------------------------------------------------------*/
SetShaderModeForWater(void)559 static void SetShaderModeForWater( void )
560 {
561 // through all alpha
562 GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
563
564 // use one color channel as constant color
565 GXSetNumChans(1);
566 GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG,
567 GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
568 GXSetChanMatColor(GX_COLOR0A0, WaterBaseColor);
569
570 // use one texture
571 GXSetNumTexGens(1);
572 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
573
574 // TEV setting
575 GXSetNumTevStages(1);
576 GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
577 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
578 }
579
580 /*---------------------------------------------------------------------------*
581 Name: SetScreenSpace
582
583 Description: Set up projection matrices to match the
584 screen coordinate system which is suitable to
585 display sprites.
586 The left-lower corner becomes (0, 0).
587
588 Arguments: width : screen width
589 height : screen height
590 depth : max depth
591
592 Returns: none
593 *---------------------------------------------------------------------------*/
SetScreenSpace(u16 width,u16 height,f32 depth)594 static void SetScreenSpace( u16 width, u16 height, f32 depth )
595 {
596 Mtx44 mp;
597 Mtx mv;
598
599 // Orthographic projection
600 MTXOrtho(mp, (f32)height, 0.0F, 0.0F, (f32)width, 0.0F, -depth);
601 GXSetProjection(mp, GX_ORTHOGRAPHIC);
602
603 // View matrix is set as identity.
604 // (never changed through this demo)
605 MTXIdentity(mv);
606 GXLoadPosMtxImm(mv, GX_PNMTX0);
607 GXSetCurrentMtx(GX_PNMTX0);
608 }
609
610 /*---------------------------------------------------------------------------*
611 Name: PrintIntro
612
613 Description: Prints the directions on how to use this demo.
614
615 Arguments: none
616
617 Returns: none
618 *---------------------------------------------------------------------------*/
PrintIntro(void)619 static void PrintIntro( void )
620 {
621 OSReport("\n\n");
622 OSReport("************************************************\n");
623 OSReport("tex-ztex: Z texture demo\n");
624 OSReport("************************************************\n");
625 OSReport("to quit hit the start button\n");
626 OSReport("\n");
627 OSReport("B Button : Change Z texturing mode\n");
628 OSReport("Sticks : Move selected tree sprite\n");
629 OSReport("X/Y Buttons : Toggle selection of a tree sprite\n");
630 OSReport("L/R Triggers : Adjust water level\n");
631 OSReport("************************************************\n\n");
632 }
633
634 /*============================================================================*/
635