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