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