1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_PolAttr_1Dot
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-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 //---------------------------------------------------------------------------
19 // A sample that controls the display of 1-dot polygons by depth value
20 //
21 // This sample displays three cubes, and allows the user to change scale and depth using the +Control Pad.
22 // If the cubes are smaller than 1 dot, toggle visibility by pressing A.
23 //
24 // USAGE:
25 //   UP, DOWN: Change the value of the depth limit at which a 1-pixel polygon is visible
26 //   L, R: Change the scale of the object
27 //   A: Toggle visibility of 1-dot polygons
28 //
29 //---------------------------------------------------------------------------
30 
31 #ifdef SDK_TWL
32 #include <twl.h>
33 #else
34 #include <nitro.h>
35 #endif
36 #include "DEMO.h"
37 #include "data.h"
38 
39 //---------------------------------------------------------------------------
40 //  Summary:
41 //        Cube model data
42 //---------------------------------------------------------------------------
43 /* Vertex data */
44 static s16 s_Vertex[3 * 8] = {
45     FX16_ONE, FX16_ONE, FX16_ONE,
46     FX16_ONE, FX16_ONE, -FX16_ONE,
47     FX16_ONE, -FX16_ONE, FX16_ONE,
48     FX16_ONE, -FX16_ONE, -FX16_ONE,
49     -FX16_ONE, FX16_ONE, FX16_ONE,
50     -FX16_ONE, FX16_ONE, -FX16_ONE,
51     -FX16_ONE, -FX16_ONE, FX16_ONE,
52     -FX16_ONE, -FX16_ONE, -FX16_ONE
53 };
54 /* Normal data */
55 static GXSt s_TextureCoord[] = {
56     GX_ST(0, 0),
57     GX_ST(0, 64 * FX32_ONE),
58     GX_ST(64 * FX32_ONE, 0),
59     GX_ST(64 * FX32_ONE, 64 * FX32_ONE)
60 };
61 
62 //---------------------------------------------------------------------------
63 //  Summary:
64 //        Set vertex coordinates
65 //  Description:
66 //        Use specified vertex data to set vertex coordinates
67 //  Input:
68 //        i_idx: Vertex data ID
69 //---------------------------------------------------------------------------
Vertex(int i_idx)70 inline void Vertex(int i_idx)
71 {
72     G3_Vtx(s_Vertex[i_idx * 3], s_Vertex[i_idx * 3 + 1], s_Vertex[i_idx * 3 + 2]);
73 }
74 
75 //---------------------------------------------------------------------------
76 //  Summary:
77 //       Set vertex color
78 //---------------------------------------------------------------------------
Color(void)79 inline void Color(void)
80 {
81     G3_Color(GX_RGB(31, 31, 31));
82 }
83 
84 //---------------------------------------------------------------------------
85 //  Summary:
86 //        Texture coordinate settings
87 //  Description:
88 //
89 //  Input:
90 //        i_idx: Texture data ID
91 //---------------------------------------------------------------------------
TextureCoord(int i_idx)92 inline void TextureCoord(int i_idx)
93 {
94     G3_Direct1(G3OP_TEXCOORD, s_TextureCoord[i_idx]);
95 }
96 
97 //---------------------------------------------------------------------------
98 //  Summary:
99 //        Cube drawing information type
100 //  Description:
101 //---------------------------------------------------------------------------
102 #pragma  warn_padding off
103 typedef struct
104 {
105     int     trg;
106     fx32    scale;
107     fx32    depth;
108     u32     texAddr;
109     u16     rotate;
110     // [PADDING 2 BYTE HERE]
111 }
112 cubu_c;
113 #pragma  warn_padding reset
114 
115 
116 //---------------------------------------------------------------------------
117 //  Summary:
118 //        Draw cube
119 //  Description:
120 //
121 //  Input:
122 //        *p : Cube information pointer
123 //        x: x position
124 //        y: y position
125 //        z: z position
126 //---------------------------------------------------------------------------
Cube(cubu_c * p,fx32 x,fx32 y,fx32 z)127 static void Cube(cubu_c * p, fx32 x, fx32 y, fx32 z)
128 {
129     G3_PushMtx();
130 
131     /* Cube rotation and position configuration */
132     {
133         fx16    s = FX_SinIdx(p->rotate);
134         fx16    c = FX_CosIdx(p->rotate);
135 
136         G3_Translate(x, y, z);
137 
138         G3_RotX(s, c);
139         G3_RotY(s, c);
140         G3_RotZ(s, c);
141 
142         G3_Scale(p->scale, p->scale, p->scale);
143     }
144 
145     /* Cube rendering configuration */
146     // Set material's diffuse reflection color and ambient reflection color
147     G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // Diffuse reflection color
148                             GX_RGB(16, 16, 16), // Ambient reflection color
149                             TRUE);     // Set vertex color
150     // Configure the specular color and the emission color of the material
151     G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // Specular reflection color
152                             GX_RGB(0, 0, 0),    // The emission color
153                             FALSE);    // Specular reflection not used
154     // Polygon attribute settings
155 
156     // Specify texture parameters
157     G3_TexImageParam(GX_TEXFMT_DIRECT, // Use direct texture
158                      GX_TEXGEN_TEXCOORD,        // Set texture coordinate conversion mode
159                      GX_TEXSIZE_S64,   // 64 texture s size
160                      GX_TEXSIZE_T64,   // 64 texture t size
161                      GX_TEXREPEAT_NONE, // No repeat
162                      GX_TEXFLIP_NONE,  // No flip
163                      GX_TEXPLTTCOLOR0_USE,      // Enable palette color 0 set value
164                      p->texAddr);      // Texture address
165 
166     {
167         int     attr;
168 
169         if (p->trg)
170         {
171             attr = GX_POLYGON_ATTR_MISC_DISP_1DOT;
172         }
173         else
174         {
175             attr = GX_POLYGON_ATTR_MISC_NONE;
176         }
177         // Polygon attribute settings
178         G3_PolygonAttr(GX_LIGHTMASK_NONE,       // Do not reflect light
179                        GX_POLYGONMODE_MODULATE, // Modulation mode
180                        GX_CULL_NONE,   // No culling
181                        0,              // Polygon ID 0
182                        31,             // Alpha value
183                        attr);          // 1-dot polygon display setting
184     }
185     //
186     G3X_SetDisp1DotDepth(p->depth);    // 1-dot polygon display border depth value
187 
188     G3_Begin(GX_BEGIN_QUADS);          // Start vertex list (draw with quadrilateral polygons)
189     {
190         TextureCoord(1);
191         Color();
192         Vertex(2);
193         TextureCoord(0);
194         Color();
195         Vertex(0);
196         TextureCoord(2);
197         Color();
198         Vertex(4);
199         TextureCoord(3);
200         Color();
201         Vertex(6);
202 
203         TextureCoord(1);
204         Color();
205         Vertex(7);
206         TextureCoord(0);
207         Color();
208         Vertex(5);
209         TextureCoord(2);
210         Color();
211         Vertex(1);
212         TextureCoord(3);
213         Color();
214         Vertex(3);
215 
216         TextureCoord(1);
217         Color();
218         Vertex(6);
219         TextureCoord(0);
220         Color();
221         Vertex(4);
222         TextureCoord(2);
223         Color();
224         Vertex(5);
225         TextureCoord(3);
226         Color();
227         Vertex(7);
228 
229         TextureCoord(1);
230         Color();
231         Vertex(3);
232         TextureCoord(0);
233         Color();
234         Vertex(1);
235         TextureCoord(2);
236         Color();
237         Vertex(0);
238         TextureCoord(3);
239         Color();
240         Vertex(2);
241 
242         TextureCoord(1);
243         Color();
244         Vertex(5);
245         TextureCoord(0);
246         Color();
247         Vertex(4);
248         TextureCoord(2);
249         Color();
250         Vertex(0);
251         TextureCoord(3);
252         Color();
253         Vertex(1);
254 
255         TextureCoord(1);
256         Color();
257         Vertex(6);
258         TextureCoord(0);
259         Color();
260         Vertex(7);
261         TextureCoord(2);
262         Color();
263         Vertex(3);
264         TextureCoord(3);
265         Color();
266         Vertex(2);
267     }
268     G3_End();                          // End vertex list
269 
270     G3_PopMtx(1);
271 }
272 
273 //---------------------------------------------------------------------------
274 //  Summary:
275 //        V-Blank interrupt process
276 //  Description:
277 //        Enables a flag that confirms that a V-Blank interrupt has been performed.
278 //
279 //        The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
280 //        * Select IRQ interrupt (OS_SetIrqMask)
281 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
282 //        * Enable IRQ interrupts (OS_EnableIrq)
283 //
284 //---------------------------------------------------------------------------
VBlankIntr(void)285 void VBlankIntr(void)
286 {
287     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
288 }
289 
290 //---------------------------------------------------------------------------
291 //  Summary:
292 //        Setting GX_POLYGON_ATTR_MISC_DISP_1DOT in G3_PolygonAttr
293 //        (Use depth value to suppress 1-dot polygon display)
294 //  Description:
295 //        Use depth value to suppress 1-dot polygon display
296 //
297 //        1. When the sample starts up, press BUTTON_L and set the object's Scale value to 0
298 //
299 //        2. The scale value becomes 0, and three objects are displayed as 1 dot
300 //        3. By pressing UP and DOWN on the +Control Pad and increasing or decreasing the depth value, objects displayed in the background will blink in order, starting from the object on the left (which is the deepest object)
301 //
302 //  Controls:
303 //        BUTTON_L, R: Object scale value
304 //        UP, DOWN: Increase and decrease the object's depth value
305 //        START: Return to initial value
306 //        SELECT: Update the depth value with a close value in the position test
307 //---------------------------------------------------------------------------
308 #ifdef SDK_TWL
TwlMain(void)309 void TwlMain(void)
310 #else
311 void NitroMain(void)
312 #endif
313 {
314     cubu_c  cubu;
315 
316     cubu.trg = 1;
317     cubu.scale = FX32_ONE;
318     cubu.depth = 16384;
319     cubu.texAddr = 0x01000;            // Slot address of the texture image
320     cubu.rotate = 0;
321 
322     /*
323      * Initialize (enable IRQ, initialize VRAM, use BG0 in 3D mode)
324      */
325     DEMOInitCommon();
326     DEMOInitVRAM();
327     DEMOInitDisplay3D();
328 
329     /* Load the texture image to the texture image slot */
330     GX_BeginLoadTex();                 // Map the bank allocated to the slot to LCDC memory
331     {
332         GX_LoadTex((void *)&tex_32768_64x64[0], // Load source pointer
333                    cubu.texAddr,       // Load destination slot address
334                    8192);              // Load size
335     }
336     GX_EndLoadTex();                   // Restore the slot mapped to LCDC to its original state
337 
338     DEMOStartDisplay();
339 
340     while (1)
341     {
342         G3X_Reset();
343         cubu.rotate += 256;
344 
345         DEMOReadKey();
346 #ifdef SDK_AUTOTEST                    // Code for auto-test
347         {
348             const EXTKeys keys[8] =
349                 { {PAD_BUTTON_L, 80}, {PAD_KEY_DOWN, 8}, {PAD_BUTTON_A, 1}, {0, 0} };
350             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
351         }
352 #endif
353 
354         if (DEMO_IS_PRESS(PAD_BUTTON_R))
355         {
356             cubu.scale += 64;
357             OS_Printf("Scale=%d Depth=%d\n", cubu.scale, cubu.depth);
358         }
359         else if (DEMO_IS_PRESS(PAD_BUTTON_L))
360         {
361             cubu.scale -= 64;
362             if (cubu.scale < 0)
363             {
364                 cubu.scale = 0;
365             }
366             OS_Printf("Scale=%d Depth=%d\n", cubu.scale, cubu.depth);
367         }
368         if (DEMO_IS_PRESS(PAD_KEY_UP))
369         {
370             cubu.depth += 256;
371             if (cubu.depth > 0xffffff)
372             {
373                 cubu.depth = 0xffffff;
374             }
375             OS_Printf("Scale=%d Depth=%d\n", cubu.scale, cubu.depth);
376         }
377         else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
378         {
379             cubu.depth -= 256;
380             if (cubu.depth < 0)
381             {
382                 cubu.depth = 0;
383             }
384             OS_Printf("Scale=%d Depth=%d\n", cubu.scale, cubu.depth);
385         }
386         if (DEMO_IS_TRIG(PAD_BUTTON_A))
387         {
388             cubu.trg = (cubu.trg + 1) & 0x01;
389             OS_Printf("PolygonAttr_1DotPoly=%s\n", (cubu.trg ? "ON" : "OFF"));
390         }
391         if (DEMO_IS_TRIG(PAD_BUTTON_START))
392         {
393             cubu.scale = FX32_ONE;
394             cubu.depth = 16384;
395             OS_Printf("Scale=%d Depth=%d\n", cubu.scale, cubu.depth);
396         }
397         if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
398         {
399             fx16    s = FX_SinIdx(cubu.rotate);
400             fx16    c = FX_CosIdx(cubu.rotate);
401 
402             G3_Translate(-FX32_ONE, 0, -4 * FX32_ONE);
403 
404             G3_RotX(s, c);
405             G3_RotY(s, c);
406             G3_RotZ(s, c);
407 
408             G3_Scale(cubu.scale, cubu.scale, cubu.scale);
409 
410             {
411                 VecFx32 m;
412                 fx32    w;
413 
414                 G3_PositionTest(FX16_ONE, FX16_ONE, FX16_ONE);
415                 while (G3X_GetPositionTestResult(&m, &w))
416                 {
417                     // Wait for position test
418                 }
419 
420                 OS_Printf("Position Test : Pos(%d, %d, %d) W(%d)\n", m.x, m.y, m.z, w);
421                 cubu.depth = w;
422             }
423         }
424 
425         /* Camera configuration */
426         {
427             VecFx32 Eye = { 0, 0, FX32_ONE };   // Eye position
428             VecFx32 at = { 0, 0, 0 };  // Viewpoint
429             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
430 
431             G3_LookAt(&Eye, &vUp, &at, NULL);   // Eye point settings
432         }
433 
434         G3_MtxMode(GX_MTXMODE_TEXTURE); // Set matrix to texture mode
435         G3_Identity();                 // Initialize current matrix to a unit matrix
436         // The matrix is set to Position-Vector simultaneous set mode
437         G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
438 
439         /* Draw cube */
440         Cube(&cubu, FX32_ONE, 0, -2 * FX32_ONE);
441         Cube(&cubu, 0, 0, -3 * FX32_ONE);
442         Cube(&cubu, -FX32_ONE, 0, -4 * FX32_ONE);
443 
444         // Swapping the polygon list RAM, the vertex RAM, etc.
445         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
446 
447         /* V-Blank wait */
448         OS_WaitVBlankIntr();
449 
450 #ifdef SDK_AUTOTEST                    // For auto test
451         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
452         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
453         EXT_TestScreenShot(150, 0xA00DF599);
454         EXT_TestTickCounter();
455 #endif //SDK_AUTOTEST
456 
457     }
458 }
459