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