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