1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_Pol_Env_Mapping
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 environment mapping
20 //
21 // HOWTO:
22 // 1. Set up the texture matrix.
23 // 2. Specify GX_TEXGEN_NORMAL as a parameter for G3_TexImageParam.
24 //
25 // Notice that the normal vectors sent to the texture matrix are in the local space.
26 // Thus, you must multiply the appropriate rotational matrices in advance.
27 //---------------------------------------------------------------------------
28 
29 #ifdef SDK_TWL
30 #include <twl.h>
31 #else
32 #include <nitro.h>
33 #endif
34 #include "DEMO.h"
35 #include "tex_4plett.h"
36 
37 MtxFx44 textureMtx = {
38     32 * FX32_ONE, 0, 0, 0,
39     0, -32 * FX32_ONE, 0, 0,
40     0, 0, FX32_ONE, 0,
41     0, 0, 0, FX32_ONE
42 };
43 
44 
45 s16     gCubeGeometry[3 * 8] = {
46     FX16_ONE, FX16_ONE, FX16_ONE,
47     FX16_ONE, FX16_ONE, -FX16_ONE,
48     FX16_ONE, -FX16_ONE, FX16_ONE,
49     FX16_ONE, -FX16_ONE, -FX16_ONE,
50     -FX16_ONE, FX16_ONE, FX16_ONE,
51     -FX16_ONE, FX16_ONE, -FX16_ONE,
52     -FX16_ONE, -FX16_ONE, FX16_ONE,
53     -FX16_ONE, -FX16_ONE, -FX16_ONE
54 };
55 
56 VecFx10 gCubeNormal[8] = {
57     GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
58     GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
59     GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
60     GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3),
61     GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
62     GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
63     GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
64     GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3)
65 };
66 
vtx(int idx)67 inline void vtx(int idx)
68 {
69     G3_Vtx(gCubeGeometry[idx * 3], gCubeGeometry[idx * 3 + 1], gCubeGeometry[idx * 3 + 2]);
70 }
71 
normal(int idx)72 inline void normal(int idx)
73 {
74     G3_Direct1(G3OP_NORMAL, gCubeNormal[idx]);
75     // use G3_Normal(x, y, z) if not packed
76 }
77 
NrmVtxQuad(int idx0,int idx1,int idx2,int idx3)78 static void NrmVtxQuad(int idx0, int idx1, int idx2, int idx3)
79 {
80     normal(idx0);
81     vtx(idx0);
82     normal(idx1);
83     vtx(idx1);
84     normal(idx2);
85     vtx(idx2);
86     normal(idx3);
87     vtx(idx3);
88 }
89 
90 #ifdef SDK_TWL
TwlMain(void)91 void TwlMain(void)
92 #else
93 void NitroMain(void)
94 #endif
95 {
96     u32     myTexAddr = 0x1000;        // texture image address in texture image slots
97     u32     myTexPlttAddr = 0x1000;    // texture palette address in texture palette slots
98     u16     Rotate = 0;
99 
100     //---------------------------------------------------------------------------
101     // Initialize:
102     // They enable IRQ interrupts, initialize VRAM, and set BG #0 for 3D mode.
103     //---------------------------------------------------------------------------
104     DEMOInitCommon();
105     DEMOInitVRAM();
106     DEMOInitDisplay3D();
107 
108     //---------------------------------------------------------------------------
109     // Download the texture images:
110     //
111     // Transfer the texture data on the main memory to the texture image slots.
112     //---------------------------------------------------------------------------
113     GX_BeginLoadTex();                 // map the texture image slots onto LCDC address space
114     {
115         GX_LoadTex((void *)&tex_4plett64x64[0], // a pointer to the texture data on the main memory(4 bytes aligned)
116                    myTexAddr,          // an offset address in the texture image slots
117                    1024                // the size of the texture(s)(in bytes)
118             );
119     }
120     GX_EndLoadTex();                   // restore the texture image slots
121 
122     //---------------------------------------------------------------------------
123     // Download the texture palettes:
124     //
125     // Transfer the texture palette data on the main memory to the texture palette slots.
126     //---------------------------------------------------------------------------
127     GX_BeginLoadTexPltt();             // map the texture palette slots onto LCDC address space
128     {
129         GX_LoadTexPltt((void *)&pal_4plett[0],  // a pointer to the texture data on the main memory(4 bytes aligned)
130                        myTexPlttAddr,  // an offset address in the texture palette slots
131                        8               // the size of the texture palette(s)(in bytes)
132             );
133     }
134     GX_EndLoadTexPltt();               // restore the texture palette slots
135 
136     DEMOStartDisplay();
137     while (1)
138     {
139         MtxFx43 camera;
140 
141         G3X_Reset();
142         Rotate += 256;
143 
144         //---------------------------------------------------------------------------
145         // Set up a camera matrix
146         //---------------------------------------------------------------------------
147         {
148             VecFx32 Eye = { 0, 0, 10 * FX32_ONE };      // Eye position
149             VecFx32 at = { 0, 0, 0 };  // Viewpoint
150             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
151             G3_LookAt(&Eye, &vUp, &at, &camera);
152         }
153 
154         //---------------------------------------------------------------------------n
155         // Set up light colors and direction.
156         // Notice that light vector is transformed by the current vector matrix
157         // immediately after LightVector command is issued.
158         //
159         // GX_LIGHTID_0: white, downward
160         //---------------------------------------------------------------------------
161         G3_LightVector(GX_LIGHTID_0, FX16_SQRT1_3, -FX16_SQRT1_3, -FX16_SQRT1_3);
162         G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
163 
164         G3_PushMtx();
165 
166         {
167             fx16    s = FX_SinIdx(Rotate);
168             fx16    c = FX_CosIdx(Rotate);
169 
170             G3_RotZ(s, c);
171             G3_RotY(s, c);
172             G3_RotX(s, c);
173         }
174 
175         //---------------------------------------------------------------------------
176         // Set up the texture matrix for environment mapping
177         //---------------------------------------------------------------------------
178         {
179             fx16    s = FX_SinIdx(Rotate);
180             fx16    c = FX_CosIdx(Rotate);
181 
182             //---------------------------------------------------------------------------
183             // Load a texture matrix(in the case of GX_TEXGEN_NORMAL):
184             //
185             // Internally, the argument matrix is (16, 16, 16) scaled
186             // before it is set to the current texture matrix.
187             // If you use G3_MtxMode(GX_MTXMODE_TEXTURE) and G3_LoadMtx44,
188             // you have to scale the matrix by yourself.
189             //---------------------------------------------------------------------------
190             G3_LoadTexMtxEnv(&textureMtx);
191 #if 0
192             // You can see the texture in the same way if you multiply the camera matrix at this point.
193             // Generally, the matrix at this point specifies the direction of the light/environment.
194             G3_MultMtx33((MtxFx33 *)&camera);   // a 3x3 matrix is enough
195 #endif
196             G3_RotZ(s, c);
197             G3_RotY(s, c);
198             G3_RotX(s, c);
199 
200             G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
201 
202             //---------------------------------------------------------------------------
203             // Specify the center of the texture.
204             // (32, 32) specified because a 64x64 texture is used.
205             //---------------------------------------------------------------------------
206             G3_TexCoord(32 * FX32_ONE, 32 * FX32_ONE);
207         }
208 
209         G3_TexImageParam(GX_TEXFMT_PLTT4,       // use 4 colors palette texture
210                          GX_TEXGEN_NORMAL,      // use normal source
211                          GX_TEXSIZE_S64,        // 64 pixels
212                          GX_TEXSIZE_T64,        // 64 pixels
213                          GX_TEXREPEAT_NONE,     // no repeat
214                          GX_TEXFLIP_NONE,       // no flip
215                          GX_TEXPLTTCOLOR0_USE,  // use color 0 of the palette
216                          myTexAddr     // the offset of the texture image
217             );
218 
219         G3_TexPlttBase(myTexPlttAddr,  // the offset of the texture palette
220                        GX_TEXFMT_PLTT4 // 4 colors palette texture
221             );
222 
223         // Set the material color( diffuse, ambient , specular ) as basic white
224         DEMO_Set3DDefaultMaterial(TRUE, TRUE);
225         DEMO_Set3DDefaultShininessTable();
226 
227 
228         G3_PolygonAttr(GX_LIGHTMASK_0, // Light #0 is on
229                        GX_POLYGONMODE_MODULATE, // modulation mode
230                        GX_CULL_BACK,   // cull back
231                        0,              // polygon ID(0 - 63)
232                        31,             // alpha(0 - 31)
233                        0               // OR of GXPolygonAttrMisc's value
234             );
235 
236         G3_Begin(GX_BEGIN_QUADS);
237 
238         {
239             NrmVtxQuad(2, 0, 4, 6);
240             NrmVtxQuad(7, 5, 1, 3);
241             NrmVtxQuad(6, 4, 5, 7);
242             NrmVtxQuad(3, 1, 0, 2);
243             NrmVtxQuad(5, 4, 0, 1);
244             NrmVtxQuad(6, 7, 3, 2);
245         }
246         G3_End();
247 
248         G3_PopMtx(1);
249 
250         // swapping the polygon list RAM, the vertex RAM, etc.
251         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
252 
253 #ifdef SDK_AUTOTEST
254         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
255         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
256         EXT_TestScreenShot(100, 0x440EB69B);
257         EXT_TestTickCounter();
258 #endif //SDK_AUTOTEST
259 
260         OS_WaitVBlankIntr();           // Waiting the end of VBlank interrupt
261     }
262 }
263 
264 //---------------------------------------------------------------------------
265 // VBlank interrupt function:
266 //
267 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
268 // OS_EnableIrqMask selects IRQ interrupts to enable, and
269 // OS_EnableIrq enables IRQ interrupts.
270 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
271 //---------------------------------------------------------------------------
VBlankIntr(void)272 void VBlankIntr(void)
273 {
274     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
275 }
276