1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/3D_Pol_MakeDL
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-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // A sample that makes display lists dynamically:
20 //
21 // HOWTO:
22 // 1. Call G3_BeginMakeDL to initialize GXDLInfo
23 // 2. Generate a display list by G3B/G3C_xxxxxx
24 // 3. Call G3_EndMakeDL to finish making the display list
25 // 4. Don't forget to flush the cache for the display list
26 //---------------------------------------------------------------------------
27
28 #ifdef SDK_TWL
29 #include <twl.h>
30 #else
31 #include <nitro.h>
32 #endif
33 #include "DEMO.h"
34
35 s16 gCubeGeometry[3 * 8] = {
36 FX16_ONE, FX16_ONE, FX16_ONE,
37 FX16_ONE, FX16_ONE, -FX16_ONE,
38 FX16_ONE, -FX16_ONE, FX16_ONE,
39 FX16_ONE, -FX16_ONE, -FX16_ONE,
40 -FX16_ONE, FX16_ONE, FX16_ONE,
41 -FX16_ONE, FX16_ONE, -FX16_ONE,
42 -FX16_ONE, -FX16_ONE, FX16_ONE,
43 -FX16_ONE, -FX16_ONE, -FX16_ONE
44 };
45
46 GXRgb gCubeColor[8] = {
47 GX_RGB(31, 31, 31),
48 GX_RGB(31, 31, 0),
49 GX_RGB(31, 0, 31),
50 GX_RGB(31, 0, 0),
51 GX_RGB(0, 31, 31),
52 GX_RGB(0, 31, 0),
53 GX_RGB(0, 0, 31),
54 GX_RGB(0, 0, 0)
55 };
56
57 #define LENGTH_DL (1024)
58 GXDLInfo gGXDLInfoB;
59 GXDLInfo gGXDLInfoC;
60 u32 gDL_B[LENGTH_DL];
61 u32 gSzDL_B;
62 u32 gDL_C[LENGTH_DL];
63 u32 gSzDL_C;
64
VtxB(GXDLInfo * info,int idx)65 static void VtxB(GXDLInfo *info, int idx)
66 {
67 G3B_Vtx(info, gCubeGeometry[idx * 3], gCubeGeometry[idx * 3 + 1], gCubeGeometry[idx * 3 + 2]);
68 }
69
VtxC(GXDLInfo * info,int idx)70 static void VtxC(GXDLInfo *info, int idx)
71 {
72 G3C_Vtx(info, gCubeGeometry[idx * 3], gCubeGeometry[idx * 3 + 1], gCubeGeometry[idx * 3 + 2]);
73 }
74
ColorB(GXDLInfo * info,int idx)75 static void ColorB(GXDLInfo *info, int idx)
76 {
77 G3B_Color(info, gCubeColor[idx]);
78 }
79
ColorC(GXDLInfo * info,int idx)80 static void ColorC(GXDLInfo *info, int idx)
81 {
82 G3C_Color(info, gCubeColor[idx]);
83 }
84
QuadB(GXDLInfo * info,int idx0,int idx1,int idx2,int idx3)85 static void QuadB(GXDLInfo *info, int idx0, int idx1, int idx2, int idx3)
86 {
87 VtxB(info, idx0);
88 VtxB(info, idx1);
89 VtxB(info, idx2);
90 VtxB(info, idx3);
91 }
92
ColVtxQuadC(GXDLInfo * info,int idx0,int idx1,int idx2,int idx3)93 static void ColVtxQuadC(GXDLInfo *info, int idx0, int idx1, int idx2, int idx3)
94 {
95 ColorC(info, idx0);
96 VtxC(info, idx0);
97 ColorC(info, idx1);
98 VtxC(info, idx1);
99 ColorC(info, idx2);
100 VtxC(info, idx2);
101 ColorC(info, idx3);
102 VtxC(info, idx3);
103 }
104
105 //---------------------------------------------------------------------------
106 // Make a display list with G3B_xxxxxx, which makes a display list
107 // without packing commands
108 //---------------------------------------------------------------------------
makeLeftCube(void)109 static void makeLeftCube(void)
110 {
111 //---------------------------------------------------------------------------
112 // Call G3_BeginMakeDL before making a display list
113 // This sets up GXDLInfo
114 //---------------------------------------------------------------------------
115 G3_BeginMakeDL(&gGXDLInfoB, // GXDLInfo
116 gDL_B, // buffer
117 LENGTH_DL * sizeof(u32) // Buffer length (in bytes)
118 );
119 {
120 G3B_MaterialColorDiffAmb(&gGXDLInfoB, GX_RGB(31, 31, 31), // diffuse
121 GX_RGB(16, 16, 16), // ambient
122 FALSE // use diffuse as vtx color if TRUE
123 );
124
125 G3B_MaterialColorSpecEmi(&gGXDLInfoB, GX_RGB(16, 16, 16), // specular
126 GX_RGB(0, 0, 0), // emission
127 FALSE // use shininess table if TRUE
128 );
129
130 G3B_PolygonAttr(&gGXDLInfoB, GX_LIGHTMASK_NONE, // disable lights
131 GX_POLYGONMODE_MODULATE, // modulation mode
132 GX_CULL_BACK, // cull back
133 0, // polygon ID(0 - 63)
134 31, // alpha(0 - 31)
135 0 // OR of GXPolygonAttrMisc's value
136 );
137
138 //---------------------------------------------------------------------------
139 // Draw a cube:
140 // Specify different colors for the planes
141 //---------------------------------------------------------------------------
142
143 G3B_Begin(&gGXDLInfoB, GX_BEGIN_QUADS);
144
145 {
146 ColorB(&gGXDLInfoB, 3);
147 QuadB(&gGXDLInfoB, 2, 0, 4, 6);
148
149 ColorB(&gGXDLInfoB, 4);
150 QuadB(&gGXDLInfoB, 7, 5, 1, 3);
151
152 ColorB(&gGXDLInfoB, 5);
153 QuadB(&gGXDLInfoB, 6, 4, 5, 7);
154
155 ColorB(&gGXDLInfoB, 2);
156 QuadB(&gGXDLInfoB, 3, 1, 0, 2);
157
158 ColorB(&gGXDLInfoB, 6);
159 QuadB(&gGXDLInfoB, 5, 4, 0, 1);
160
161 ColorB(&gGXDLInfoB, 1);
162 QuadB(&gGXDLInfoB, 6, 7, 3, 2);
163 }
164
165 G3B_End(&gGXDLInfoB);
166 }
167
168 //---------------------------------------------------------------------------
169 // Call G3_EndMakeDL after making a display list
170 // This returns the size of the display list in bytes
171 //---------------------------------------------------------------------------
172 gSzDL_B = G3_EndMakeDL(&gGXDLInfoB);
173
174 // Don't forget to flush the cache
175 DC_FlushRange(G3_GetDLStart(&gGXDLInfoB), gSzDL_B);
176 /* I/O register is accessed using DMA operation, so cache wait is not needed */
177 // DC_WaitWriteBufferEmpty();
178 }
179
180 //---------------------------------------------------------------------------
181 // Make a display list with G3C_xxxxxx, which makes a display list
182 // with packing commands
183 //---------------------------------------------------------------------------
makeRightCube(void)184 static void makeRightCube(void)
185 {
186 G3_BeginMakeDL(&gGXDLInfoC, // GXDLInfo
187 gDL_C, // buffer
188 LENGTH_DL * sizeof(u32) // Buffer length (in bytes)
189 );
190 {
191
192 G3C_MaterialColorDiffAmb(&gGXDLInfoC, GX_RGB(31, 31, 31), // diffuse
193 GX_RGB(16, 16, 16), // ambient
194 FALSE // use diffuse as vtx color if TRUE
195 );
196
197 G3C_MaterialColorSpecEmi(&gGXDLInfoC, GX_RGB(16, 16, 16), // specular
198 GX_RGB(0, 0, 0), // emission
199 FALSE // use shininess table if TRUE
200 );
201
202 G3C_PolygonAttr(&gGXDLInfoC, GX_LIGHTMASK_NONE, // disable lights
203 GX_POLYGONMODE_MODULATE, // modulation mode
204 GX_CULL_BACK, // cull back
205 0, // polygon ID(0 - 63)
206 31, // alpha(0 - 31)
207 0 // OR of GXPolygonAttrMisc's value
208 );
209
210 //---------------------------------------------------------------------------
211 // Draw a cube:
212 // Specify different colors for the vertices.
213 //---------------------------------------------------------------------------
214 G3C_Begin(&gGXDLInfoC, GX_BEGIN_QUADS);
215 {
216 ColVtxQuadC(&gGXDLInfoC, 2, 0, 4, 6);
217 ColVtxQuadC(&gGXDLInfoC, 7, 5, 1, 3);
218 ColVtxQuadC(&gGXDLInfoC, 6, 4, 5, 7);
219 ColVtxQuadC(&gGXDLInfoC, 3, 1, 0, 2);
220 ColVtxQuadC(&gGXDLInfoC, 5, 4, 0, 1);
221 ColVtxQuadC(&gGXDLInfoC, 6, 7, 3, 2);
222 }
223 G3C_End(&gGXDLInfoC);
224 }
225
226 //---------------------------------------------------------------------------
227 // Call G3_EndMakeDL after making a display list
228 // This returns the size of the display list in bytes
229 //---------------------------------------------------------------------------
230 gSzDL_C = G3_EndMakeDL(&gGXDLInfoC);
231
232 // Don't forget to flush the cache
233 DC_FlushRange(G3_GetDLStart(&gGXDLInfoC), gSzDL_C);
234 /* I/O register is accessed using DMA operation, so cache wait is not needed */
235 // DC_WaitWriteBufferEmpty();
236 }
237
drawLeftCube(u16 Rotate)238 static void drawLeftCube(u16 Rotate)
239 {
240 G3_PushMtx();
241
242 // Rotate and translate
243 G3_Translate(-3 << (FX32_SHIFT - 1), 0, 0);
244 {
245 fx16 s = FX_SinIdx(Rotate);
246 fx16 c = FX_CosIdx(Rotate);
247
248 G3_RotX(s, c);
249 G3_RotY(s, c);
250 G3_RotZ(s, c);
251 }
252
253 // Sending a display list
254 MI_SendGXCommand(3, gDL_B, gSzDL_B);
255
256 G3_PopMtx(1);
257 }
258
drawRightCube(u16 Rotate)259 static void drawRightCube(u16 Rotate)
260 {
261 G3_PushMtx();
262
263 // Rotate and translate
264 G3_Translate(3 << (FX32_SHIFT - 1), 0, 0);
265
266 {
267 fx16 s = FX_SinIdx(Rotate);
268 fx16 c = FX_CosIdx(Rotate);
269
270 G3_RotX(s, c);
271 G3_RotY(s, c);
272 G3_RotZ(s, c);
273 }
274
275 // Sending a display list
276 MI_SendGXCommand(3, gDL_C, gSzDL_C);
277
278 G3_PopMtx(1);
279 }
280
281
282 #ifdef SDK_TWL
TwlMain(void)283 void TwlMain(void)
284 #else
285 void NitroMain(void)
286 #endif
287 {
288 u16 Rotate = 0; // For rotating cubes (0-65535)
289
290 //---------------------------------------------------------------------------
291 // Initialize:
292 // Enable IRQ interrupts, initialize VRAM, and set BG #0 for 3D mode
293 //---------------------------------------------------------------------------
294 DEMOInitCommon();
295 DEMOInitVRAM();
296 DEMOInitDisplay3D();
297
298 makeLeftCube();
299 makeRightCube();
300
301 DEMOStartDisplay();
302 while (1)
303 {
304 G3X_Reset();
305 Rotate += 256;
306
307 //---------------------------------------------------------------------------
308 // Set up a camera matrix
309 //---------------------------------------------------------------------------
310 {
311 VecFx32 Eye = { 0, 0, FX32_ONE * 5 }; // Eye Position
312 VecFx32 at = { 0, 0, 0 }; // Viewpoint
313 VecFx32 vUp = { 0, FX32_ONE, 0 }; // Up
314
315 G3_LookAt(&Eye, &vUp, &at, NULL);
316 }
317
318 G3_PushMtx();
319
320 drawLeftCube(Rotate);
321 drawRightCube(Rotate);
322
323 G3_PopMtx(1);
324
325 // Swapping the polygon list RAM, the vertex RAM, etc.
326 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
327
328 #ifdef SDK_AUTOTEST
329 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
330 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
331 EXT_TestScreenShot(100, 0xA51F0EEF);
332 EXT_TestTickCounter();
333 #endif //SDK_AUTOTEST
334
335 OS_WaitVBlankIntr(); // Waiting for the end of the V-Blank interrupt
336 }
337 }
338
339 //---------------------------------------------------------------------------
340 // V-Blank interrupt function:
341 //
342 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
343 // OS_EnableIrqMask selects IRQ interrupts to enable, and
344 // OS_EnableIrq enables IRQ interrupts.
345 // Notice that you have to call OS_SetIrqCheckFlag to check a V-Blank interrupt.
346 //---------------------------------------------------------------------------
VBlankIntr(void)347 void VBlankIntr(void)
348 {
349 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Checking V-Blank interrupt
350 }
351