1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_Edge_Marking
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 for edge marking:
20 //
21 // Display three rotating cubes with edge marking in three colors.
22 //
23 // HOWTO:
24 // 1. Enable edge marking by G3X_EdgeMarking(TRUE).
25 // 2. Set up the edge color table by G3X_SetEdgeColorTable(table).
26 //    The color table[n] is used for the polygons with polygonID = 8*n to 8*n + 7.
27 // 3. Render polygons.
28 //---------------------------------------------------------------------------
29 
30 #ifdef SDK_TWL
31 #include <twl.h>
32 #else
33 #include <nitro.h>
34 #endif
35 #include "DEMO.h"
36 
37 s16     gCubeGeometry[3 * 8] = {
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     -FX16_ONE, -FX16_ONE, FX16_ONE,
45     -FX16_ONE, -FX16_ONE, -FX16_ONE
46 };
47 
48 VecFx10 gCubeNormal[8] = {
49     GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
50     GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
51     GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
52     GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3),
53     GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
54     GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
55     GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
56     GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3)
57 };
58 
vtx(int idx)59 inline void vtx(int idx)
60 {
61     G3_Vtx(gCubeGeometry[idx * 3], gCubeGeometry[idx * 3 + 1], gCubeGeometry[idx * 3 + 2]);
62 }
63 
normal(int idx)64 inline void normal(int idx)
65 {
66     G3_Direct1(G3OP_NORMAL, gCubeNormal[idx]);
67     // use G3_Normal(x, y, z) if not packed
68 }
69 
70 
NrmVtxQuad(int idx0,int idx1,int idx2,int idx3)71 static void NrmVtxQuad(int idx0, int idx1, int idx2, int idx3)
72 {
73     normal(idx0);
74     vtx(idx0);
75     normal(idx1);
76     vtx(idx1);
77     normal(idx2);
78     vtx(idx2);
79     normal(idx3);
80     vtx(idx3);
81 }
82 
83 
84 GXRgb   gEdgeColor[8] = {
85     GX_RGB(31, 0, 0),
86     GX_RGB(0, 31, 0),
87     GX_RGB(0, 0, 31),
88     GX_RGB(0, 0, 0),
89     GX_RGB(0, 0, 0),
90     GX_RGB(0, 0, 0),
91     GX_RGB(0, 0, 0),
92     GX_RGB(0, 0, 0)
93 };
94 
drawCube(int polygonID,u16 Rotate)95 static void drawCube(int polygonID, u16 Rotate)
96 {
97     {
98         fx16    s = FX_SinIdx(Rotate);
99         fx16    c = FX_CosIdx(Rotate);
100 
101         G3_RotX(s, c);
102         G3_RotY(s, c);
103         G3_RotZ(s, c);
104     }
105 
106     // Set the Material As basic whilte
107     DEMO_Set3DDefaultMaterial(TRUE, TRUE);
108     DEMO_Set3DDefaultShininessTable();
109 
110     G3_PolygonAttr(GX_LIGHTMASK_0,     // Light #0 is on
111                    GX_POLYGONMODE_MODULATE,     // modulation mode
112                    GX_CULL_BACK,       // cull back
113                    polygonID,          // polygon ID(0 - 63)
114                    31,                 // alpha(0 - 31)
115                    0                   // OR of GXPolygonAttrMisc's value
116         );
117 
118 
119     G3_Begin(GX_BEGIN_QUADS);
120     {
121         NrmVtxQuad(2, 0, 4, 6);
122         NrmVtxQuad(7, 5, 1, 3);
123         NrmVtxQuad(6, 4, 5, 7);
124         NrmVtxQuad(3, 1, 0, 2);
125         NrmVtxQuad(5, 4, 0, 1);
126         NrmVtxQuad(6, 7, 3, 2);
127     }
128     G3_End();
129 }
130 
131 #ifdef SDK_TWL
TwlMain(void)132 void TwlMain(void)
133 #else
134 void NitroMain(void)
135 #endif
136 {
137     u16     Rotate = 0;                // for rotating cubes(0-65535)
138 
139     //---------------------------------------------------------------------------
140     // Initialize:
141     // They enable IRQ interrupts, initialize VRAM, and set BG #0 for 3D mode.
142     //---------------------------------------------------------------------------
143     DEMOInitCommon();
144     DEMOInitVRAM();
145     DEMOInitDisplay3D();
146 
147     G3X_EdgeMarking(TRUE);             // Enable edge marking
148 
149 
150 
151     //---------------------------------------------------------------------------
152     // Set up the edge color table:
153     //
154     // Use different edge colors from each other
155     //---------------------------------------------------------------------------
156     G3X_SetEdgeColorTable(&gEdgeColor[0]);
157 
158     DEMOStartDisplay();
159     while (1)
160     {
161         G3X_Reset();
162         Rotate += 256;
163 
164         //---------------------------------------------------------------------------
165         // Set up camera matrix
166         //---------------------------------------------------------------------------
167         {
168             VecFx32 Eye = { 0, 0, FX32_ONE };   // Eye Position
169             VecFx32 at = { 0, 0, 0 };  // Viewpoint
170             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
171 
172             G3_LookAt(&Eye, &vUp, &at, NULL);
173         }
174 
175         //---------------------------------------------------------------------------
176         // Set up light colors and direction.
177         // Notice that light vector is transformed by the current vector matrix
178         // immediately after LightVector command is issued.
179         //
180         // GX_LIGHTID_0: white, downward
181         //---------------------------------------------------------------------------
182         G3_LightVector(GX_LIGHTID_0, FX16_SQRT1_3, -FX16_SQRT1_3, -FX16_SQRT1_3);
183         G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
184 
185         G3_PushMtx();
186         G3_Translate(0, 0, -5 * FX32_ONE);
187 
188         //---------------------------------------------------------------------------
189         // Draw cube #1 with polygonID= 0
190         //---------------------------------------------------------------------------
191         G3_PushMtx();
192         G3_Translate(-1 * (FX32_ONE >> 1), -1 * (FX32_ONE >> 1), 0);
193         drawCube(0, Rotate);
194         G3_PopMtx(1);
195 
196         //---------------------------------------------------------------------------
197         // Draw cube #2 with polygonID= 8
198         //---------------------------------------------------------------------------
199         G3_PushMtx();
200         G3_Translate(1 * (FX32_ONE >> 1), -1 * (FX32_ONE >> 1), 0);
201         drawCube(8, Rotate);
202         G3_PopMtx(1);
203 
204         //---------------------------------------------------------------------------
205         // Draw cube #3 with polygonID= 16
206         //---------------------------------------------------------------------------
207         G3_PushMtx();
208         G3_Translate(0, 1 * (FX32_ONE >> 1), -2 * FX32_ONE);
209         drawCube(16, Rotate);
210         G3_PopMtx(1);
211 
212         G3_PopMtx(1);
213 
214         // swapping the polygon list RAM, the vertex RAM, etc.
215         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
216 
217 #ifdef SDK_AUTOTEST
218         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
219         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
220         EXT_TestScreenShot(100, 0x408C5C88);
221         EXT_TestTickCounter();
222 #endif //SDK_AUTOTEST
223 
224         OS_WaitVBlankIntr();           // Waiting the end of VBlank interrupt
225     }
226 }
227 
228 
229 //---------------------------------------------------------------------------
230 // VBlank interrupt function:
231 //
232 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
233 // OS_EnableIrqMask selects IRQ interrupts to enable, and
234 // OS_EnableIrq enables IRQ interrupts.
235 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
236 //---------------------------------------------------------------------------
VBlankIntr(void)237 void VBlankIntr(void)
238 {
239     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
240 }
241