1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tf-clip-bug.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 
16 /*---------------------------------------------------------------------------*
17   Model Data
18  *---------------------------------------------------------------------------*/
19 
20 // Notes on vertex numbering:
21 //
22 // Outermost numbers represent quad corners
23 // Inner numbers are for fractional positions
24 //
25 //  3                       0
26 //  |  .  :  .  ;  .  :  .  |
27 // 16 14 12 10  8  6  4  2  0
28 //
29 //
30 //
31 //
32 // 17 15 13 11  9  7  5  3  1
33 //  |  .  :  .  ;  .  :  .  |
34 //  2                       1
35 
36 
37 // indices for verts for drawing order at tessellation = 1, 2, 4, 8
38 
39 static u8 ivert[4][32] =
40 {
41     { 0,  1, 17, 16 },
42     { 0,  1,  9,  8,  8,  9, 17, 16 },
43     { 0,  1,  5,  4,  4,  5,  9,  8,  8,  9, 13, 12, 12, 13, 17, 16 },
44     { 0,  1,  3,  2,  2,  3,  5,  4,  4,  5,  7,  6,  6,  7,  9, 8,
45       8,  9, 11, 10, 10, 11, 13, 12, 12, 13, 15, 14, 14, 15, 17, 16 }
46 };
47 
48 #define IHALF 18
49 
50 // verts
51 
52 static s16 Vert_s16[] ATTRIBUTE_ALIGN(32) =
53 {
54    -10,  100,  100,  // 0 0   0         0 left wall   0
55    -10, -100,  100,  // 1 1   1         1             1
56    -10,  100,   75,  //                 3 4           2
57    -10, -100,   75,  //                 2 5           3
58    -10,  100,   50,  //       3 4         7 8         4
59    -10, -100,   50,  //       2 5         6 9         5
60    -10,  100,   25,  //                    11 12      6
61    -10, -100,   25,  //                    10 13      7
62    -10,  100,    0,  //   3 4   7 8           15 16   8
63    -10, -100,    0,  //   2 5   6 9           14 17   9
64    -10,  100,  -25,  //                       20 19   10
65    -10, -100,  -25,  //                       21 18   11
66    -10,  100,  -50,  //          11 12     24 23      12
67    -10, -100,  -50,  //          10 13     25 22      13
68    -10,  100,  -75,  //                 28 27         14
69    -10, -100,  -75,  //                 29 26         15
70    -10,  100, -100,  // 3   7       15  31            16
71    -10, -100, -100,  // 2   6       14  30            17
72 
73     10,  100,  100,  // 0 0   0         0 right wall  18
74     10, -100,  100,  // 1 1   1         1             19
75     10,  100,   75,  //                 3 4           20
76     10, -100,   75,  //                 2 5           21
77     10,  100,   50,  //       3 4         7 8         22
78     10, -100,   50,  //       2 5         6 9         23
79     10,  100,   25,  //                    11 12      24
80     10, -100,   25,  //                    10 13      25
81     10,  100,    0,  //   3 4   7 8           15 16   26
82     10, -100,    0,  //   2 5   6 9           14 17   27
83     10,  100,  -25,  //                       20 19   28
84     10, -100,  -25,  //                       21 18   29
85     10,  100,  -50,  //          11 12     24 23      30
86     10, -100,  -50,  //          10 13     25 22      31
87     10,  100,  -75,  //                 28 27         32
88     10, -100,  -75,  //                 29 26         33
89     10,  100, -100,  // 3   7       15  31            34
90     10, -100, -100,  // 2   6       14  30            35
91 };
92 
93 // colors
94 
95 static u32 Colors_u32[] ATTRIBUTE_ALIGN(32) =
96 {
97 //    r g b a
98     0xc0c0c0ff, // 0        0
99     0xa0a0c0ff, // 1        1
100     0xb4b4c0ff, // 1/8 0-3  2
101     0x9c9cc0ff, // 1/8 1-2  3
102     0xa8a8c0ff, // 1/4 0-3  4
103     0x9898c0ff, // 1/4 1-2  5
104     0x9c9cc0ff, // 3/8 0-3  6
105     0x9494c0ff, // 3/8 1-2  7
106     0x9090c0ff, // 1/2 0-3  8
107     0x9090c0ff, // 1/2 1-2  9
108     0x8484c0ff, // 5/8 0-3  10
109     0x8c8cc0ff, // 5/8 1-2  11
110     0x7878c0ff, // 3/4 0-3  12
111     0x8888c0ff, // 3/4 1-2  13
112     0x6c6cc0ff, // 7/8 0-3  14
113     0x8484c0ff, // 7/8 1-2  15
114     0x8080c0ff, // 2        16
115     0x6060c0ff, // 3        17
116 
117     0x2020c0ff, // 0        18
118     0x4040c0ff, // 1        19
119     0x2c2cc0ff, // 1/8 0-3  20
120     0x4444c0ff, // 1/8 1-2  21
121     0x3838c0ff, // 1/4 0-3  22
122     0x4848c0ff, // 1/4 1-2  23
123     0x4444c0ff, // 3/8 0-3  24
124     0x4c4cc0ff, // 3/8 1-2  25
125     0x5050c0ff, // 1/2 0-3  26
126     0x5050c0ff, // 1/2 1-2  27
127     0x5c5cc0ff, // 5/8 0-3  28
128     0x5454c0ff, // 5/8 1-2  29
129     0x6868c0ff, // 3/4 0-3  30
130     0x5858c0ff, // 3/4 1-2  31
131     0x7474c0ff, // 7/8 0-3  32
132     0x5c5cc0ff, // 7/8 1-2  33
133     0x6060c0ff, // 2        34
134     0x8080c0ff, // 3        35
135 };
136 
137 /*---------------------------------------------------------------------------*
138    Application main loop
139  *---------------------------------------------------------------------------*/
140 
main(void)141 void main ( void )
142 {
143     u16 button, down;   // button return codes
144 
145     Mtx44   pm;         // projection matrix
146     Mtx     cm;         // camera matrix
147     Mtx     vm;         // view matrix
148     Mtx     sm;         // scale matrix
149     Mtx     ym;         // yet another view matrix
150 
151     s16      i;         // loop variable
152     s16      j;         // loop variable
153     u8    tess = 0;     // tessellation factor
154     u8    mode = 0;     // AA/zbuffer mode
155 
156     Vec   vTmp = {0.0F, 0.0F, 0.0F};     // camera position
157     Vec   at   = {0.0F, 0.0F, -6000.0F}; // look at position
158     Vec   up   = {0.0F, 1.0F, 0.0F};     // camera up vector
159     f32   fovy = 90.0F; // FOV in Y direction
160     f32   near = 5.0f;  // near plane distance
161 
162     char  nums[100];    // number string
163     GXColor green = { 0, 255, 0, 255 };
164     GXColor red   = { 255, 0, 0, 255 };
165     s16   spacing = 5;  // interplanar distance for Z tags
166     s16   xp, yp, zp;   // Z tag position
167     f32   fi;           // fractional i for distance calculation
168 
169     //----------------------------------------------------------------------
170 
171     // We use GXNtsc240Int since that makes it easy to change
172     // between 16-bit and 24-bit framebuffer modes.
173 
174     DEMOInit(&GXNtsc240Int);    // Init os, pad, gx, vi
175 
176     GXSetCullMode(GX_CULL_NONE);
177 
178     GXSetArray(GX_VA_POS,  Vert_s16, 3*sizeof(s16));
179     GXSetArray(GX_VA_CLR0, Colors_u32, 1*sizeof(u32));
180 
181     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS,  GX_POS_XYZ,  GX_S16,   0);
182     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
183 
184     DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE );
185 
186     MTXIdentity(sm);
187 
188     OSReport("\n\n********************************\n");
189     OSReport("Running...\n\n");
190     OSReport("Main stick   - move camera\n");
191     OSReport("Sub stick    - move camera in Z\n");
192     OSReport("L trigger    - hold to adjust FOV with A/B buttons\n");
193     OSReport("R trigger    - hold to adjust tessellation with X/Y buttons\n");
194     OSReport("A/B buttons  - adjust near plane or FOV\n");
195     OSReport("X/Y buttons  - adjust Z tag interplanar dist or tessellation\n");
196     OSReport("Start button - toggle 16/24-bit mode\n");
197     OSReport("********************************\n");
198     while(1)
199     {
200         DEMOPadRead();
201 
202         down   = DEMOPadGetButtonDown(0);
203         button = DEMOPadGetButton(0);
204 
205         vTmp.x -= DEMOPadGetStickX(0) / 100.0f;
206         vTmp.y -= DEMOPadGetStickY(0) / 100.0f;
207         vTmp.z += DEMOPadGetSubStickY(0) / 100.0f;
208 
209         if (button & PAD_TRIGGER_R)
210         {
211             if (down & PAD_BUTTON_X)
212             {
213                 if (tess > 0)
214                     tess--;
215             }
216             if (down & PAD_BUTTON_Y)
217             {
218                 if (tess < 3)
219                     tess++;
220             }
221         } else {
222             if (down & PAD_BUTTON_X)
223             {
224                 spacing += 1;
225                 if (spacing > 10)
226                     spacing = 10;
227             }
228             if (down & PAD_BUTTON_Y)
229             {
230                 spacing  -= 1;
231                 if (spacing < 1)
232                     spacing = 1;
233             }
234         }
235 
236 
237         if (button & PAD_TRIGGER_L)
238         {
239             if (button & PAD_BUTTON_A)
240             {
241                 fovy += 1.0F;
242                 if (fovy > 179.0F)
243                     fovy = 179.0F;
244             }
245             if (button & PAD_BUTTON_B)
246             {
247                 fovy -= 1.0F;
248                 if (fovy < 1.0F)
249                     fovy = 1.0F;
250             }
251         } else {
252             if (button & PAD_BUTTON_A)
253             {
254                 near += 0.1F;
255                 if (near > 10.0F)
256                     near = 10.0F;
257             }
258             if (button & PAD_BUTTON_B)
259             {
260                 near -= 0.1F;
261                 if (near < 0.1F)
262                     near = 0.1F;
263             }
264         }
265 
266         if (down & PAD_BUTTON_MENU)
267         {
268             mode++;
269             if (mode == 5)
270                 mode = 0;
271         }
272 
273 
274         if (mode)
275         {
276             GXSetPixelFmt( GX_PF_RGB565_Z16, (GXZFmt16)(mode - 1) );
277         } else {
278             GXSetPixelFmt( GX_PF_RGB8_Z24, GX_ZC_LINEAR );
279         }
280 
281         DEMOBeforeRender();
282 
283         // Cancel out changes done by DEMOInitCaption (below)
284         GXSetZMode( GX_ENABLE, GX_LEQUAL, GX_TRUE);
285         GXSetNumChans(1);
286 
287         // Set up projection, matrices
288         MTXPerspective(pm, fovy, 4.0F/3.0F, near, 10000);
289         GXSetProjection(pm, GX_PERSPECTIVE);
290 
291         // Set up camera/view matrices
292         MTXLookAt(cm, &vTmp, &up, &at);
293 
294         // If you want any viewing transforms, put them here
295         MTXCopy(cm, vm);
296         GXLoadPosMtxImm(vm, GX_PNMTX0);
297 
298         // Set up for drawing walls
299         GXClearVtxDesc();
300         GXSetVtxDesc(GX_VA_POS,  GX_INDEX8);
301         GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
302 
303         // Use vertex colors
304         GXSetChanCtrl(
305             GX_COLOR0A0,
306             GX_DISABLE,
307             GX_SRC_REG,
308             GX_SRC_VTX,
309             GX_LIGHT_NULL,
310             GX_DF_NONE,
311             GX_AF_NONE );
312 
313         GXSetNumTexGens(0);
314         GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
315         GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
316 
317         // Draw the walls
318         GXBegin(GX_QUADS, GX_VTXFMT1, (u16) ((1<<tess)*4*2));
319         for (i = 0; i < (1<<tess); i++)
320         {
321             for(j=0; j<4; j++)  // left wall
322             {
323                 GXPosition1x8( (u8) ivert[tess][i*4+j]);
324                 GXColor1x8( (u8) ivert[tess][i*4+j]);
325             }
326             for(j=0; j<4; j++)  // right wall
327             {
328                 GXPosition1x8( (u8) (ivert[tess][i*4+j]+IHALF));
329                 GXColor1x8( (u8) (ivert[tess][i*4+j]+IHALF));
330             }
331         }
332         GXEnd();
333 
334         // Set up for drawing signs
335         vm[1][1] = - vm[1][1];
336 
337         // Use register colors
338         GXSetChanCtrl(
339             GX_COLOR0A0,
340             GX_DISABLE,
341             GX_SRC_REG,
342             GX_SRC_REG,
343             GX_LIGHT_NULL,
344             GX_DF_NONE,
345             GX_AF_NONE );
346 
347         GXSetNumTexGens(1);
348         GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
349         GXSetTevOp(GX_TEVSTAGE0, GX_BLEND);
350 
351         // Draw the signs
352         for (i = 1; i < 60; i++)
353         {
354             sprintf( nums, "%d00", i );
355 
356             xp = (s16) ((i>9) ? -16 : -12);
357             yp = (s16) -8;
358             zp = (s16) (-i * 100);
359 
360             // scale signs larger as they get further away
361             sm[0][0] = i * (5.0F / 12.0F);
362             sm[1][1] = i * (5.0F / 12.0F);
363             MTXConcat(vm, sm, ym);
364             // position signs up and down in vertical FOV
365             ym[1][3] = - i * 100 + i * i * (10.0F / 3.0F);
366             GXLoadPosMtxImm(ym, GX_PNMTX0);
367 
368             // Draw green sign
369             GXSetChanMatColor(GX_COLOR0A0, green);
370             DEMOPuts( xp, yp, zp, nums );
371 
372             // Adjust for red sign
373             zp -= spacing;
374             fi  = i + spacing / 100.0F;
375             ym[1][3] = - fi * 100 + fi * fi * (10.0F / 3.0F);
376             GXLoadPosMtxImm(ym, GX_PNMTX0);
377 
378             // Draw red sign
379             GXSetChanMatColor(GX_COLOR0A0, red);
380             DEMOPuts( xp, yp, zp, nums );
381         }
382 
383         // Draw the control panel
384         DEMOInitCaption(DM_FT_OPQ, 640, 480);
385 
386         sprintf(nums, "camera= [%g, %g, %g]", vTmp.x, vTmp.y, vTmp.z);
387         DEMOPuts( 24, 20, 0, nums );
388         sprintf(nums, "fovy = %g", fovy);
389         DEMOPuts( 24, 28, 0, nums );
390         sprintf(nums, "near = %g", near);
391         DEMOPuts( 24, 36, 0, nums );
392         sprintf(nums, "tess = %d", 1 << tess);
393         DEMOPuts( 24, 44, 0, nums );
394         sprintf(nums, "Z spacing = %d", spacing);
395         DEMOPuts( 24, 52, 0, nums );
396 
397         switch (mode)
398         {
399           case 0: sprintf(nums, "24-bit linear mode"); break;
400           case 1: sprintf(nums, "16-bit linear mode"); break;
401           case 2: sprintf(nums, "16-bit near mode"); break;
402           case 3: sprintf(nums, "16-bit mid mode"); break;
403           case 4: sprintf(nums, "16-bit far mode"); break;
404         }
405 
406         DEMOPuts( 24, 60, 0, nums );
407 
408         DEMODoneRender();
409     }
410     OSHalt("End of demo");
411 }
412 
413 /*===========================================================================*/
414