1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_Pol_Split
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 splits a plane into both LCDs.
20 //
21 // Switching LCD during H-Blank splits a plane into two parts.
22 // See 'HBlankIntr(void)' and instruction above it.
23 //---------------------------------------------------------------------------
24 
25 #ifdef SDK_TWL
26 #include <twl.h>
27 #else
28 #include <nitro.h>
29 #endif
30 #include "DEMO.h"
31 
32 s16     gCubeGeometry[3 * 8] = {
33     FX16_ONE, FX16_ONE, FX16_ONE,
34     FX16_ONE, FX16_ONE, -FX16_ONE,
35     FX16_ONE, -FX16_ONE, FX16_ONE,
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 };
42 
43 GXRgb   gCubeColor[8] = {
44     GX_RGB(31, 31, 31),
45     GX_RGB(31, 31, 0),
46     GX_RGB(31, 0, 31),
47     GX_RGB(31, 0, 0),
48     GX_RGB(0, 31, 31),
49     GX_RGB(0, 31, 0),
50     GX_RGB(0, 0, 31),
51     GX_RGB(0, 0, 0)
52 };
53 
Color(int idx)54 static void Color(int idx)
55 {
56     G3_Color(gCubeColor[idx]);
57 }
58 
Vtx(int idx)59 static void Vtx(int idx)
60 {
61     G3_Vtx(gCubeGeometry[idx * 3], gCubeGeometry[idx * 3 + 1], gCubeGeometry[idx * 3 + 2]);
62 }
63 
Quad(int idx0,int idx1,int idx2,int idx3)64 static void Quad(int idx0, int idx1, int idx2, int idx3)
65 {
66     Vtx(idx0);
67     Vtx(idx1);
68     Vtx(idx2);
69     Vtx(idx3);
70 }
71 
ColVtxQuad(int idx0,int idx1,int idx2,int idx3)72 static void ColVtxQuad(int idx0, int idx1, int idx2, int idx3)
73 {
74     Color(idx0);
75     Vtx(idx0);
76     Color(idx1);
77     Vtx(idx1);
78     Color(idx2);
79     Vtx(idx2);
80     Color(idx3);
81     Vtx(idx3);
82 }
83 
drawLeftCube(u16 Rotate)84 static void drawLeftCube(u16 Rotate)
85 {
86     G3_PushMtx();
87 
88     // Rotate and translate
89     G3_Translate(-3 << (FX32_SHIFT - 1), 0, 0);
90     {
91         fx16    s = FX_SinIdx(Rotate);
92         fx16    c = FX_CosIdx(Rotate);
93 
94         G3_RotX(s, c);
95         G3_RotY(s, c);
96         G3_RotZ(s, c);
97     }
98 
99     G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // diffuse
100                             GX_RGB(16, 16, 16), // ambient
101                             FALSE      // use diffuse as vtx color if TRUE
102         );
103 
104     G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // specular
105                             GX_RGB(0, 0, 0),    // emission
106                             FALSE      // use shininess table if TRUE
107         );
108 
109     G3_PolygonAttr(GX_LIGHTMASK_NONE,  // disable lights
110                    GX_POLYGONMODE_MODULATE,     // modulation mode
111                    GX_CULL_BACK,       // cull back
112                    0,                  // polygon ID(0 - 63)
113                    31,                 // alpha(0 - 31)
114                    0                   // OR of GXPolygonAttrMisc's value
115         );
116 
117     //---------------------------------------------------------------------------
118     // Draw a cube:
119     // Specify different colors for the planes.
120     //---------------------------------------------------------------------------
121 
122     G3_Begin(GX_BEGIN_QUADS);
123 
124     {
125         Color(3);
126         Quad(2, 0, 4, 6);
127 
128         Color(4);
129         Quad(7, 5, 1, 3);
130 
131         Color(5);
132         Quad(6, 4, 5, 7);
133 
134         Color(2);
135         Quad(3, 1, 0, 2);
136 
137         Color(6);
138         Quad(5, 4, 0, 1);
139 
140         Color(1);
141         Quad(6, 7, 3, 2);
142     }
143 
144     G3_End();
145 
146     G3_PopMtx(1);
147 }
148 
drawRightCube(u16 Rotate)149 static void drawRightCube(u16 Rotate)
150 {
151     G3_PushMtx();
152 
153     // Rotate and translate
154     G3_Translate(3 << (FX32_SHIFT - 1), 0, 0);
155 
156     {
157         fx16    s = FX_SinIdx(Rotate);
158         fx16    c = FX_CosIdx(Rotate);
159 
160         G3_RotX(s, c);
161         G3_RotY(s, c);
162         G3_RotZ(s, c);
163     }
164 
165     G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // diffuse
166                             GX_RGB(16, 16, 16), // ambient
167                             FALSE      // use diffuse as vtx color if TRUE
168         );
169 
170     G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // specular
171                             GX_RGB(0, 0, 0),    // emission
172                             FALSE      // use shininess table if TRUE
173         );
174 
175     G3_PolygonAttr(GX_LIGHTMASK_NONE,  // disable lights
176                    GX_POLYGONMODE_MODULATE,     // modulation mode
177                    GX_CULL_BACK,       // cull back
178                    0,                  // polygon ID(0 - 63)
179                    31,                 // alpha(0 - 31)
180                    0                   // OR of GXPolygonAttrMisc's value
181         );
182 
183     //---------------------------------------------------------------------------
184     // Draw a cube:
185     // Specify different colors for the vertices.
186     //---------------------------------------------------------------------------
187     G3_Begin(GX_BEGIN_QUADS);
188     {
189         ColVtxQuad(2, 0, 4, 6);
190         ColVtxQuad(7, 5, 1, 3);
191         ColVtxQuad(6, 4, 5, 7);
192         ColVtxQuad(3, 1, 0, 2);
193         ColVtxQuad(5, 4, 0, 1);
194         ColVtxQuad(6, 7, 3, 2);
195     }
196     G3_End();
197 
198     G3_PopMtx(1);
199 
200 }
201 
202 static s32 sBoundary = 96;
203 void    HBlankIntr(void);
204 
205 #ifdef SDK_TWL
TwlMain(void)206 void TwlMain(void)
207 #else
208 void NitroMain(void)
209 #endif
210 {
211     u16     Rotate = 0;                // for rotating cubes(0-65535)
212     int     sw = 0;
213 
214     //---------------------------------------------------------------------------
215     // Initialize:
216     // They enable IRQ interrupts, initialize VRAM, and set BG #0 for 3D mode.
217     //---------------------------------------------------------------------------
218     DEMOInitCommon();
219     DEMOInitVRAM();
220     DEMOInitDisplay3D();
221 
222     //---------------------------------------------------------------------------
223     // Switch LCD during H-blank.
224     //---------------------------------------------------------------------------
225     OS_SetIrqFunction(OS_IE_H_BLANK, HBlankIntr);
226     (void)OS_EnableIrqMask(OS_IE_H_BLANK);
227     (void)GX_HBlankIntr(TRUE);         // to generate HBlank interrupt request
228 
229     DEMOStartDisplay();
230     while (1)
231     {
232         G3X_Reset();
233 
234         DEMOReadKey();
235         if (DEMO_IS_PRESS(PAD_KEY_UP) && sBoundary > 1)
236             --sBoundary;
237         if (DEMO_IS_PRESS(PAD_KEY_DOWN) && sBoundary < 191)
238             ++sBoundary;
239 
240         Rotate += 256;
241 
242         //---------------------------------------------------------------------------
243         // Set up camera matrix
244         //---------------------------------------------------------------------------
245         {
246             VecFx32 Eye = { 0, 0, FX32_ONE * 5 };       // Eye Position
247             VecFx32 at = { 0, 0, 0 };  // Viewpoint
248             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
249 
250             G3_LookAt(&Eye, &vUp, &at, NULL);
251         }
252 
253         G3_PushMtx();
254 
255         drawLeftCube(Rotate);
256         drawRightCube(Rotate);
257 
258         G3_PopMtx(1);
259 
260         // swapping the polygon list RAM, the vertex RAM, etc.
261         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
262 
263 #ifdef SDK_AUTOTEST
264         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
265         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
266         EXT_TestScreenShot(100, 0xA51F0EEF);
267         EXT_TestTickCounter();
268 #endif //SDK_AUTOTEST
269         OS_WaitVBlankIntr();           // Waiting the end of VBlank interrupt
270     }
271 }
272 
273 
274 //---------------------------------------------------------------------------
275 // HBlank interrupt function:
276 // 1. OS_SetIrqFunction(OS_IE_H_BLANK, funcname) to register 'funcname'
277 //    at H-blank interrupt handler.
278 // 2. OS_EnableIrqMask(OS_IE_H_BLANK) to enable H-blank interrupt.
279 // 3. GX_HBlankIntr(TRUE) to generate H-blank interrupt request.
280 // 4. OS_EnableIrq() to allow IRQ interrupt.
281 //---------------------------------------------------------------------------
HBlankIntr(void)282 void HBlankIntr(void)
283 {
284     if (GX_GetVCount() == 0)
285         GX_SetDispSelect((GXDispSelect)0);
286     else if (GX_GetVCount() == sBoundary)
287         GX_SetDispSelect((GXDispSelect)1);
288     OS_SetIrqCheckFlag(OS_IE_H_BLANK); // checking HBlank interrupt
289 }
290 
291 
292 //---------------------------------------------------------------------------
293 // VBlank interrupt function:
294 //
295 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
296 // OS_EnableIrqMask selects IRQ interrupts to enable, and
297 // OS_EnableIrq enables IRQ interrupts.
298 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
299 //---------------------------------------------------------------------------
VBlankIntr(void)300 void VBlankIntr(void)
301 {
302     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
303 }
304