1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/3D_BoxTest
3 File: main.c
4
5 Copyright 2003-2008 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 $Date:: 2008-12-16#$
14 $Rev: 9663 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // A sample that uses BoxTest
20 //
21 // This sample displays a cube and a rotating sphere.
22 // If the sphere comes in contact with the cube, it is displayed normally
23 // Otherwise it is displayed with a wire frame
24 //
25 //---------------------------------------------------------------------------
26
27
28 #ifdef SDK_TWL
29 #include <twl.h>
30 #else
31 #include <nitro.h>
32 #endif
33 #include "DEMO.h"
34 #include "data.h"
35 //---------------------------------------------------------------------------
36 // Summary:
37 // V-Blank interrupt process
38 // Description:
39 // Enables a flag that confirms that a V-Blank interrupt has been performed
40 //
41 // The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
42 // * Select IRQ interrupt (OS_SetIrqMask)
43 // * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
44 // * Enable IRQ interrupts (OS_EnableIrq)
45 //
46 //---------------------------------------------------------------------------
VBlankIntr(void)47 void VBlankIntr(void)
48 {
49 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
50 }
51
52 //---------------------------------------------------------------------------
53 // Summary:
54 // Perform the box test
55 // Description:
56 // When a rotating wireframe sphere touches a surface of the cube that surrounds it, the result of the box test will be rendered normally
57 //
58 //
59 // 1. Establish a space in the orthogonal projection to perform culling with BoxTest
60 // 2. Using a cube equal in size to the sphere, run BoxTest on the current clip coordinate matrix established in the orthogonal projection
61 //
62 // 3. Next, convert to a perspective projection, and use the wire frame to draw the previously established culling space
63 //
64 // 4. When rendering the sphere, switch between normal rendering and wireframe rendering based on the results of the previous BoxTest
65 //
66 //---------------------------------------------------------------------------
67 #ifdef SDK_TWL
TwlMain(void)68 void TwlMain(void)
69 #else
70 void NitroMain(void)
71 #endif
72 {
73 u16 Rotate = 0; // For rotating cubes (0-65535)
74
75 //---------------------
76 // Initialization
77 //---------------------
78 DEMOInitCommon();
79 DEMOInitVRAM();
80
81 G3X_Init(); // Initialize 3D graphics
82 G3X_InitTable(); // Initialize graphic table
83 G3X_InitMtxStack(); // Initialize matrix stack
84
85 /* 3D graphics configuration */
86 GX_SetVisiblePlane(GX_PLANEMASK_BG0); // Use BG number 0
87
88 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, // 2D/3D mode
89 GX_BGMODE_4, // Set BGMODE to 4
90 GX_BG0_AS_3D); // Use BG 0 as 3D
91 G2_SetBG0Priority(0); // BG 0 display priority to top
92
93 G3X_SetShading(GX_SHADING_HIGHLIGHT); // Set shading mode
94 G3X_AntiAlias(TRUE); // Enable antialiasing
95
96 G3_SwapBuffers(GX_SORTMODE_AUTO, // Swap buffer settings
97 GX_BUFFERMODE_W);
98 // Clear color settings
99 G3X_SetClearColor(GX_RGB(0, 0, 0), // clear color
100 31, // clear alpha
101 0x7fff, // clear depth
102 63, // clear polygon ID
103 FALSE); // fog
104
105 G3_ViewPort(0, 0, 255, 191); // Viewport settings
106
107 DEMOStartDisplay();
108
109 //---------------------
110 // Main loop
111 //---------------------
112 while (1)
113 {
114 int sphere_alpha;
115
116 G3X_Reset();
117 Rotate += 256;
118
119 /* Orthogonal projection settings */
120 {
121 fx32 pos1_x = -((5 * FX32_ONE) / 2);
122 fx32 pos1_y = ((5 * FX32_ONE) / 2);
123 fx32 pos2_x = ((5 * FX32_ONE) / 2);
124 fx32 pos2_y = -((5 * FX32_ONE) / 2);
125 fx32 near = (5 * FX32_ONE) / 2;
126 fx32 far = ((5 * FX32_ONE) / 2) + (5 * FX32_ONE);
127
128 G3_MtxMode(GX_MTXMODE_PROJECTION); // Set the matrix to projection mode
129 G3_Identity(); // Initialize current matrix to a unit matrix
130 // Orthogonal projection settings
131 G3_Ortho(pos1_y, // up pos y
132 pos2_y, // down pos y
133 pos1_x, // left pos x
134 pos2_x, // right pos x
135 near, // Near
136 far, // Far
137 NULL);
138
139 G3_StoreMtx(0);
140 }
141
142 /* Box test */
143 {
144 G3_MtxMode(GX_MTXMODE_TEXTURE); // Set matrix to texture mode
145 G3_Identity(); // Initialize current matrix to a unit matrix
146 // The matrix is set to Position-Vector simultaneous set mode
147 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
148 G3_PushMtx();
149 {
150 GXBoxTestParam box;
151 fx16 s = FX_SinIdx(Rotate);
152 fx16 c = FX_CosIdx(Rotate);
153 s32 result;
154
155 G3_Translate(0, 0, -11 * FX32_ONE);
156 G3_RotY(s, c);
157 G3_Translate(0, 0, 6 * FX32_ONE);
158 G3_RotX(s, c);
159 G3_RotY(s, c);
160 G3_RotZ(s, c);
161
162 // Set FAR clip and 1-dot polygon rendering to ON before the BoxTest
163 //
164 G3_PolygonAttr(GX_LIGHTMASK_0,
165 GX_POLYGONMODE_MODULATE,
166 GX_CULL_NONE,
167 0,
168 0,
169 GX_POLYGON_ATTR_MISC_FAR_CLIPPING | GX_POLYGON_ATTR_MISC_DISP_1DOT);
170 G3_Begin(GX_BEGIN_TRIANGLES);
171 G3_End();
172
173 box.x = -7200;
174 box.y = -7200;
175 box.z = -7200;
176 box.width = 7200 * 2;
177 box.height = 7200 * 2;
178 box.depth = 7200 * 2;
179 G3_BoxTest(&box); // Do the box test
180
181 while (G3X_GetBoxTestResult(&result) != 0)
182 {
183 // Loop to wait for box text results
184 ;
185 }
186 sphere_alpha = (result ? 31 : 0);
187 OS_Printf("result %d\n", result);
188 }
189 G3_PopMtx(1);
190 }
191
192 /* Perspective projection settings */
193 G3_MtxMode(GX_MTXMODE_PROJECTION); // Set the matrix to projection mode
194 G3_Identity(); // Initialize current matrix to a unit matrix
195 {
196 fx32 right = FX32_ONE;
197 fx32 top = FX32_ONE * 3 / 4;
198 fx32 near = FX32_ONE;
199 fx32 far = FX32_ONE * 400;
200 // Perspective projection settings
201 G3_Perspective(FX32_SIN30, // Sine FOVY
202 FX32_COS30, // Cosine FOVY
203 FX32_ONE * 4 / 3, // Aspect
204 near, // Near
205 far, // Far
206 NULL);
207
208 G3_StoreMtx(0);
209 }
210
211 /* Camera configuration */
212 {
213 VecFx32 Eye = { 0, 8 * FX32_ONE, FX32_ONE }; // Eye point position
214 VecFx32 at = { 0, 0, -5 * FX32_ONE }; // Viewpoint
215 VecFx32 vUp = { 0, FX32_ONE, 0 }; // Up
216
217 G3_LookAt(&Eye, &vUp, &at, NULL); // Eye point settings
218 }
219
220 /* Light settings */
221 {
222 G3_LightVector(GX_LIGHTID_0, 0, -FX32_ONE + 1, 0); // Light color
223 G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31)); // Light direction
224 }
225
226 G3_MtxMode(GX_MTXMODE_TEXTURE); // Set matrix to texture mode
227 G3_Identity(); // Initialize current matrix to a unit matrix
228 // The matrix is set to Position-Vector simultaneous set mode
229 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
230
231 /* Generate and render box */
232 {
233 G3_PushMtx();
234 G3_Translate(0, 0, -5 * FX32_ONE); // Set box position
235 // Set material's diffuse reflection color and ambient reflection color
236 G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // Diffuse reflection color
237 GX_RGB(16, 16, 16), // Ambient reflection color
238 FALSE); // Do not set vertex color
239 // Configure the specular color and the emission color of the material
240 G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // Specular reflection color
241 GX_RGB(0, 0, 0), // The emission color
242 FALSE); // Do not use specular reflection table
243 // Specify texture parameters
244 G3_TexImageParam(GX_TEXFMT_NONE, // No texture
245 GX_TEXGEN_NONE, // No texture coordinate conversion
246 GX_TEXSIZE_S8,
247 GX_TEXSIZE_T8,
248 GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
249 // Polygon attribute settings
250 G3_PolygonAttr(GX_LIGHTMASK_0, // Light 0 ON
251 GX_POLYGONMODE_MODULATE, // Modulation mode
252 GX_CULL_NONE, // No culling
253 1, // Polygon ID 1
254 0, // Alpha value
255 GX_POLYGON_ATTR_MISC_NONE);
256 G3_Begin(GX_BEGIN_QUADS); // Begin vertex list
257 // (Declaration to draw with quadrilateral polygons)
258 {
259 G3_Normal(0, 1 << 9, 0);
260 G3_Vtx(((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
261 G3_Vtx(((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
262 G3_Vtx(-((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
263 G3_Vtx(-((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
264
265 G3_Normal(0, -1 << 9, 0);
266 G3_Vtx(((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
267 G3_Vtx(((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
268 G3_Vtx(-((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
269 G3_Vtx(-((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
270
271 G3_Normal(1 << 9, 0, 0);
272 G3_Vtx(((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
273 G3_Vtx(((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
274 G3_Vtx(((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
275 G3_Vtx(((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
276
277 G3_Normal(-1 << 9, 0, 0);
278 G3_Vtx(-((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
279 G3_Vtx(-((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
280 G3_Vtx(-((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), -((5 * FX16_ONE) / 2));
281 G3_Vtx(-((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2), ((5 * FX16_ONE) / 2));
282 }
283 G3_End(); // End vertex list
284 G3_PopMtx(1);
285 }
286
287 /* Generate and render sphere */
288 {
289 G3_PushMtx(); // Matrix to stack
290 { // Calculate move position
291 fx16 s = FX_SinIdx(Rotate);
292 fx16 c = FX_CosIdx(Rotate);
293
294 G3_Translate(0, 0, -11 * FX32_ONE);
295 G3_RotY(s, c);
296 G3_Translate(0, 0, 6 * FX32_ONE);
297 G3_RotX(s, c);
298 G3_RotY(s, c);
299 G3_RotZ(s, c);
300 }
301 // Set material's diffuse reflection color and ambient reflection color
302 G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // Diffuse reflection color
303 GX_RGB(16, 16, 16), // Ambient reflection color
304 FALSE); // Do not set vertex color
305 // Configure the specular color and the emission color of the material
306 G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // Specular reflection color
307 GX_RGB(0, 0, 0), // The emission color
308 FALSE); // Do not use specular reflection table
309 // Specify texture parameters
310 G3_TexImageParam(GX_TEXFMT_NONE, // No texture
311 GX_TEXGEN_NONE, // No texture coordinate conversion
312 GX_TEXSIZE_S8,
313 GX_TEXSIZE_T8,
314 GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
315 // Set polygon related attribute values
316 G3_PolygonAttr(GX_LIGHTMASK_0, // Light 0 ON
317 GX_POLYGONMODE_MODULATE, // Modulation mode
318 GX_CULL_NONE, // No culling
319 1, // Polygon ID 1
320 sphere_alpha, // Alpha value
321 GX_POLYGON_ATTR_MISC_NONE);
322
323 OS_Printf("sphere_alpha=%d\n", sphere_alpha);
324 // Draw sphere
325 G3_Begin(GX_BEGIN_TRIANGLES); /* Begin vertex list
326 (Declaration to draw with triangular polygons) */
327 {
328 MI_SendGXCommand(3, sphere1, sphere_size);
329 }
330 G3_End(); // End vertex list
331 G3_PopMtx(1);
332 }
333
334 // swapping the polygon list RAM, the vertex RAM, etc.
335 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
336
337 /* V-Blank wait */
338 OS_WaitVBlankIntr();
339
340 #ifdef SDK_AUTOTEST
341 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
342 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
343 EXT_TestScreenShot(100, 0xD28FEA7);
344 EXT_TestTickCounter();
345 #endif //SDK_AUTOTEST
346
347 }
348 }
349