1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/RamOverFlow
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 //  A sample to be over limit of ListRam.
19 //
20 //  One circle, which is devided by parameter, is displayed.
21 //
22 //  HOWTO:
23 //  1.  Draw circle which is too devied over limit.
24 //
25 //  OPERATION:
26 //  1.  Push cross button to change devision parameter.
27 //  2.  Push L or R button to change circle scale.
28 //
29 //---------------------------------------------------------------------------
30 #ifdef SDK_TWL
31 #include <twl.h>
32 #else
33 #include <nitro.h>
34 #endif
35 #include "DEMO.h"
36 
37 //---------------------------------------------------------------------------
38 //  Calculate normal from original point and vertex information.
39 //  And set vertex and normal information.
40 //  input:
41 //      x,y,z:  vertex information
42 //---------------------------------------------------------------------------
CircleVertex(const s32 x,const s32 y,const s32 z)43 static void CircleVertex(const s32 x, const s32 y, const s32 z)
44 {
45     u32     length;
46     fx16    nx, ny, nz;
47 
48     // Square root calculation
49     CP_SetSqrt32((u32)(x * x + y * y + z * z));
50     length = CP_GetSqrtResult32();
51 
52     // Normalize
53     nx = (fx16)((x * 511) / length);
54     ny = (fx16)((y * 511) / length);
55     nz = (fx16)((z * 511) / length);
56 
57     // Set information
58     G3_Normal(nx, ny, nz);
59     G3_Vtx((fx16)x, (fx16)y, (fx16)z);
60 }
61 
62 //---------------------------------------------------------------------------
63 //  Draw circle
64 //  input:
65 //      i_numMajor: vertical division of circle
66 //      i_numMinor: horizontal division of circle
67 //---------------------------------------------------------------------------
Circle(const u32 i_numMajor,const u32 i_numMinor)68 static void Circle(const u32 i_numMajor, const u32 i_numMinor)
69 {
70     const int majorStep = (32767 / (s32)(i_numMajor - 1));
71     const int minorStep = (65535 / (s32)i_numMinor);
72     int     a, b;
73     int     x0, z0, x1, z1;
74     int     r0, y0;
75     int     x0r0, x1r0, z0r0, z1r0;
76     int     i, j;
77 
78     for (i = 0; i < i_numMinor; i++)
79     {
80         a = i * minorStep;
81         x0 = FX_SinIdx(a);
82         z0 = FX_CosIdx(a);
83 
84         if (i < i_numMinor - 1)
85         {
86             a += minorStep;
87             x1 = FX_SinIdx(a);
88             z1 = FX_CosIdx(a);
89         }
90         else
91         {
92             x1 = FX_SinIdx(0);
93             z1 = FX_CosIdx(0);
94         }
95 
96         // Draw circle
97         G3_Begin(GX_BEGIN_TRIANGLE_STRIP);
98 
99         {
100             CircleVertex(0, 4096, 0);
101             for (j = 1; j < i_numMajor - 1; j++)
102             {
103                 b = (j * majorStep) + 16383;
104                 r0 = FX_CosIdx(b);
105                 y0 = FX_SinIdx(b);
106 
107                 x0r0 = (x0 * r0) >> 12;
108                 z0r0 = (z0 * -r0) >> 12;
109                 CircleVertex(x0r0, y0, z0r0);
110 
111                 x1r0 = (x1 * r0) >> 12;
112                 z1r0 = (z1 * -r0) >> 12;
113                 CircleVertex(x1r0, y0, z1r0);
114             }
115             CircleVertex(0, -4096, 0);
116         }
117         G3_End();
118     }
119 }
120 
121 //---------------------------------------------------------------------------
122 // VBlank interrupt function:
123 //
124 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
125 // OS_EnableIrqMask selects IRQ interrupts to enable, and
126 // OS_EnableIrq enables IRQ interrupts.
127 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
128 //---------------------------------------------------------------------------
VBlankIntr(void)129 void VBlankIntr(void)
130 {
131     // Set flag which checks VBlank interrupt.
132     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
133 }
134 
135 //---------------------------------------------------------------------------
136 //  main
137 //---------------------------------------------------------------------------
138 #ifdef SDK_TWL
TwlMain(void)139 void TwlMain(void)
140 #else
141 void NitroMain(void)
142 #endif
143 {
144     fx32    scale = FX32_ONE;
145     u16     Rotate = 0;                // for rotating cubes(0-65535)
146     u32     numMajor = 3, numMinor = 2;
147 
148     // Initialize
149     DEMOInitCommon();
150     DEMOInitVRAM();
151     DEMOInitDisplay3D();
152 
153     DEMOStartDisplay();
154 
155     // main loop
156     while (1)
157     {
158         G3X_Reset();
159         Rotate += 256;
160 
161         // Read input
162         DEMOReadKey();
163 #ifdef SDK_AUTOTEST                    // code for auto test
164         {
165             const EXTKeys keys[8] = { {PAD_KEY_UP | PAD_KEY_RIGHT | PAD_BUTTON_R, 40}, {0, 0} };
166             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
167         }
168 #endif
169 
170 
171         // Change devision of circle
172         if (DEMO_IS_PRESS(PAD_KEY_UP))
173         {
174             numMajor++;
175         }
176         else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
177         {
178             numMajor--;
179         }
180         if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
181         {
182             numMinor++;
183         }
184         else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
185         {
186             numMinor--;
187         }
188         if (numMajor < 3)
189             numMajor = 3;
190         if (numMinor < 2)
191             numMinor = 2;
192         // Change scale of circle
193         if (DEMO_IS_PRESS(PAD_BUTTON_R))
194         {
195             scale += 256;
196         }
197         else if (DEMO_IS_PRESS(PAD_BUTTON_L))
198         {
199             scale -= 256;
200             if (scale < 1)
201             {
202                 scale = 1;
203             }
204         }
205 
206         // Camera setting
207         {
208             VecFx32 Eye = { 0, 0, FX32_ONE };   // Sight position
209             VecFx32 at = { 0, 0, 0 };  // Viewpoint
210             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
211             G3_LookAt(&Eye, &vUp, &at, NULL);   // Sight setting
212         }
213 
214         // Light setting
215         G3_LightVector(GX_LIGHTID_0, 0, -FX32_ONE + 1, 0);
216         G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
217 
218         // Matrix setting
219         G3_MtxMode(GX_MTXMODE_TEXTURE);
220         G3_Identity();
221         G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
222         G3_PushMtx();
223 
224         // Rotate and translate circle
225         {
226             fx16    s = FX_SinIdx(Rotate);
227             fx16    c = FX_CosIdx(Rotate);
228 
229             G3_Translate(0, 0, -5 * FX32_ONE);
230 
231             G3_RotX(s, c);
232             G3_RotY(s, c);
233             G3_RotZ(s, c);
234 
235             G3_Scale(scale, scale, scale);
236         }
237 
238         // Draw setting
239         G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31),     // Diffuse
240                                 GX_RGB(16, 16, 16),     // Ambient
241                                 TRUE); // Color
242         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular
243                                 GX_RGB(0, 0, 0),        // Emission
244                                 FALSE); // Shininess
245         G3_TexImageParam(GX_TEXFMT_NONE,        // Texture format
246                          GX_TEXGEN_TEXCOORD,    // Texture generation
247                          GX_TEXSIZE_S64,        // Texture width
248                          GX_TEXSIZE_T64,        // Texture height
249                          GX_TEXREPEAT_NONE,     // Texture repeat
250                          GX_TEXFLIP_NONE,       // Texture flip
251                          GX_TEXPLTTCOLOR0_USE,  // Palette color
252                          0);           // Texture address
253         G3_PolygonAttr(GX_LIGHTMASK_0, // Light
254                        GX_POLYGONMODE_MODULATE, // Polygon mode
255                        GX_CULL_BACK,   // Culling
256                        0,              // Polygon ID
257                        31,             // Alpha
258                        GX_POLYGON_ATTR_MISC_NONE);      // Misc
259 
260         // Draw circle
261         Circle(numMajor, numMinor);
262 
263         G3_PopMtx(1);
264 
265         // If boot on ensata , print message.
266         if (OS_IsRunOnEmulator())
267         {
268             OS_Warning("On \"ensata\" , list count is not over limit.\n");
269         }
270 
271         // Print information
272         OS_Printf("NumMajor:NumMinor;Scale = %d : %d : %d\n", numMajor, numMinor, scale);
273         OS_Printf("PolygonListRAM = %d/2048\n", G3X_GetPolygonListRamCount());
274         OS_Printf("VertexListRAM  = %d/6144\n", G3X_GetVtxListRamCount());
275         OS_Printf("LinesOverFlow  = %s\n\n", (G3X_IsLineBufferUnderflow()? "TRUE" : "FALSE"));
276         if (G3X_IsListRamOverflow())
277         {
278             OS_Printf("!!!! ListRAM OverFlow !!!!\n\n");
279         }
280 
281         // swapping the polygon list RAM, the vertex RAM, etc.
282         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
283 
284         // Wait VBlank
285         OS_WaitVBlankIntr();
286     }
287 }
288