1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/ViewPort
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-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 //---------------------------------------------------------------------------
18 //  A sample to change viewport size.
19 //
20 //  One cube is displayed on viewport which is specified in screen.
21 //
22 //  HOWTO:
23 //  1.  Call "G3_ViewPort" to set viewport size.
24 //
25 //  OPERATION:
26 //  1.  Push A button and UP or DOWN button to change up side position of viewport.
27 //  2.  Push A button and LEFT or RIGHT button to change left side position of viewport.
28 //  3.  Push B button and UP or DOWN button to chnage down side position of viewport.
29 //  4.  Push B button and LEFT or RIGHT button to change right side position of viewport.
30 //  5.  Push start button to change position of viewport default.
31 //
32 //---------------------------------------------------------------------------
33 #ifdef SDK_TWL
34 #include <twl.h>
35 #else
36 #include <nitro.h>
37 #endif
38 #include "DEMO.h"
39 #include "tex_32768.h"
40 
41 //---------------------------------------------------------------------------
42 //  Cube model data
43 //---------------------------------------------------------------------------
44 // Vertex data
45 static s16 s_Vertex[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 // Normal data
56 static VecFx10 s_Normal[6] = {
57     GX_VECFX10(0, 0, FX32_ONE - 1),
58     GX_VECFX10(0, FX32_ONE - 1, 0),
59     GX_VECFX10(FX32_ONE - 1, 0, 0),
60     GX_VECFX10(0, 0, -FX32_ONE + 1),
61     GX_VECFX10(0, -FX32_ONE + 1, 0),
62     GX_VECFX10(-FX32_ONE + 1, 0, 0)
63 };
64 // Texture data
65 static GXSt s_TextureCoord[] = {
66     GX_ST(0, 0),
67     GX_ST(0, 64 * FX32_ONE),
68     GX_ST(64 * FX32_ONE, 0),
69     GX_ST(64 * FX32_ONE, 64 * FX32_ONE)
70 };
71 
72 //---------------------------------------------------------------------------
73 //  Set vertex coordinate.
74 //  input:
75 //      idx:  ID of vertex data
76 //---------------------------------------------------------------------------
Vertex(int idx)77 inline void Vertex(int idx)
78 {
79     G3_Vtx(s_Vertex[idx * 3], s_Vertex[idx * 3 + 1], s_Vertex[idx * 3 + 2]);
80 }
81 
82 //---------------------------------------------------------------------------
83 //  Set normal setting.
84 //  input:
85 //      idx:  ID of normal data
86 //---------------------------------------------------------------------------
Normal(int idx)87 inline void Normal(int idx)
88 {
89     G3_Direct1(G3OP_NORMAL, s_Normal[idx]);
90 }
91 
92 //---------------------------------------------------------------------------
93 //  Set texture coordinate.
94 //  input:
95 //      idx:  ID of texture data
96 //---------------------------------------------------------------------------
TextureCoord(int idx)97 inline void TextureCoord(int idx)
98 {
99     G3_Direct1(G3OP_TEXCOORD, s_TextureCoord[idx]);
100 }
101 
102 //---------------------------------------------------------------------------
103 //  Draw a cube and set texture.
104 //---------------------------------------------------------------------------
DrawCube(void)105 static void DrawCube(void)
106 {
107     G3_Begin(GX_BEGIN_QUADS);          // start to set vertex.(use square polygon)
108     {
109         TextureCoord(1);
110         Normal(0);
111         Vertex(2);
112         TextureCoord(0);
113         Normal(0);
114         Vertex(0);
115         TextureCoord(2);
116         Normal(0);
117         Vertex(4);
118         TextureCoord(3);
119         Normal(0);
120         Vertex(6);
121 
122         TextureCoord(1);
123         Normal(3);
124         Vertex(7);
125         TextureCoord(0);
126         Normal(3);
127         Vertex(5);
128         TextureCoord(2);
129         Normal(3);
130         Vertex(1);
131         TextureCoord(3);
132         Normal(3);
133         Vertex(3);
134 
135         TextureCoord(1);
136         Normal(5);
137         Vertex(6);
138         TextureCoord(0);
139         Normal(5);
140         Vertex(4);
141         TextureCoord(2);
142         Normal(5);
143         Vertex(5);
144         TextureCoord(3);
145         Normal(5);
146         Vertex(7);
147 
148         TextureCoord(1);
149         Normal(2);
150         Vertex(3);
151         TextureCoord(0);
152         Normal(2);
153         Vertex(1);
154         TextureCoord(2);
155         Normal(2);
156         Vertex(0);
157         TextureCoord(3);
158         Normal(2);
159         Vertex(2);
160 
161         TextureCoord(1);
162         Normal(1);
163         Vertex(5);
164         TextureCoord(0);
165         Normal(1);
166         Vertex(4);
167         TextureCoord(2);
168         Normal(1);
169         Vertex(0);
170         TextureCoord(3);
171         Normal(1);
172         Vertex(1);
173 
174         TextureCoord(1);
175         Normal(4);
176         Vertex(6);
177         TextureCoord(0);
178         Normal(4);
179         Vertex(7);
180         TextureCoord(2);
181         Normal(4);
182         Vertex(3);
183         TextureCoord(3);
184         Normal(4);
185         Vertex(2);
186     }
187     G3_End();                          // end
188 }
189 
190 //---------------------------------------------------------------------------
191 // VBlank interrupt function:
192 //
193 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
194 // OS_EnableIrqMask selects IRQ interrupts to enable, and
195 // OS_EnableIrq enables IRQ interrupts.
196 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
197 //---------------------------------------------------------------------------
VBlankIntr(void)198 void VBlankIntr(void)
199 {
200     // Set flag which checks VBlank interrupt.
201     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
202 }
203 
204 //---------------------------------------------------------------------------
205 //  main
206 //---------------------------------------------------------------------------
207 #ifdef  SDK_CW_WA_CONSTPOOLS
208 #pragma optimization_level 1
209 #endif
210 #ifdef SDK_TWL
TwlMain(void)211 void TwlMain(void)
212 #else
213 void NitroMain(void)
214 #endif
215 {
216     unsigned int count = 0;
217     int     vp_x1 = 0, vp_y1 = 0;
218     int     vp_x2 = 255, vp_y2 = 191;
219     u32     myTexAddr = 0x00000;       // Address of texture image slot
220     u16     Rotate = 0;
221 
222     // Initialize
223     DEMOInitCommon();
224     DEMOInitVRAM();
225     DEMOInitDisplay3D();
226 
227     // Load texture image into texture image slot.
228     GX_BeginLoadTex();
229     {
230         GX_LoadTex((void *)&tex_32768_64x64[0], // Src address
231                    myTexAddr,          // Destination address
232                    8192);              // Size to load
233     }
234     GX_EndLoadTex();
235 
236     DEMOStartDisplay();
237 
238     // Print information
239     OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n", count++, vp_x1, vp_y1, vp_x2, vp_y2);
240 
241     // main loop
242     while (1)
243     {
244         G3X_Reset();
245         Rotate += 256;
246 
247         // Read input
248         DEMOReadKey();
249 #ifdef SDK_AUTOTEST                    // code for auto test
250         {
251             const EXTKeys keys[8] = { {PAD_BUTTON_A | PAD_KEY_DOWN | PAD_KEY_RIGHT, 30},
252             {PAD_BUTTON_B | PAD_KEY_UP | PAD_KEY_LEFT, 30},
253             {PAD_BUTTON_A | PAD_BUTTON_B | PAD_KEY_LEFT, 30}, {0, 0}
254             };
255             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
256         }
257 #endif
258 
259         // Change viewport size
260         if (DEMO_IS_PRESS(PAD_BUTTON_A))
261         {
262             // Change up side position
263             if (DEMO_IS_PRESS(PAD_KEY_UP))
264             {
265                 if (vp_y1 > 0)
266                 {
267                     vp_y1--;
268                 }
269                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
270                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
271             }
272             else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
273             {
274                 if (vp_y1 < 191 && vp_y1 < vp_y2 - 1)
275                 {
276                     vp_y1++;
277                 }
278                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
279                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
280             }
281             // Change left side position
282             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
283             {
284                 if (vp_x1 < 255 && vp_x1 < vp_x2 - 1)
285                 {
286                     vp_x1++;
287                 }
288                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
289                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
290             }
291             else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
292             {
293                 if (vp_x1 > 0)
294                 {
295                     vp_x1--;
296                 }
297                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
298                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
299             }
300         }
301         if (DEMO_IS_PRESS(PAD_BUTTON_B))
302         {
303             // Change down side position
304             if (DEMO_IS_PRESS(PAD_KEY_UP))
305             {
306                 if (vp_y2 > 0 && vp_y1 < vp_y2 - 1)
307                     vp_y2--;
308                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
309                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
310             }
311             else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
312             {
313                 if (vp_y2 < 191)
314                     vp_y2++;
315                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
316                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
317             }
318             // Change right side position
319             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
320             {
321                 if (vp_x2 < 255)
322                     vp_x2++;
323                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
324                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
325             }
326             else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
327             {
328                 if (vp_x2 > 0 && vp_x1 < vp_x2 - 1)
329                     vp_x2--;
330                 OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n",
331                           count++, vp_x1, vp_y1, vp_x2, vp_y2);
332             }
333         }
334         // Change to default position
335         if (DEMO_IS_TRIG(PAD_BUTTON_START))
336         {
337             vp_x1 = 0;
338             vp_y1 = 0;
339             vp_x2 = 255;
340             vp_y2 = 191;
341             OS_Printf("mssg%d:ViewPort=(%d, %d, %d, %d)\n", count++, vp_x1, vp_y1, vp_x2, vp_y2);
342         }
343 
344         //---------------------------------------------------------------------------
345         // Set viewport size
346         G3_ViewPort(vp_x1, vp_y1, vp_x2, vp_y2);
347         //---------------------------------------------------------------------------
348 
349         // Camera setting
350         {
351             VecFx32 Eye = { 0, 0, FX32_ONE };   // Eye position
352             VecFx32 at = { 0, 0, 0 };  // Viewpoint
353             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
354 
355             G3_LookAt(&Eye, &vUp, &at, NULL);
356         }
357 
358         // Light setting
359         G3_LightVector(GX_LIGHTID_0, 0, -FX32_ONE + 1, 0);
360         G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
361 
362         // Matrix setting
363         G3_MtxMode(GX_MTXMODE_TEXTURE);
364         G3_Identity();
365         G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
366         G3_PushMtx();
367 
368         // Rotate and translate cube
369         {
370             fx16    s = FX_SinIdx(Rotate);
371             fx16    c = FX_CosIdx(Rotate);
372 
373             G3_Translate(0, 0, -5 * FX32_ONE);
374 
375             G3_RotX(s, c);
376             G3_RotY(s, c);
377             G3_RotZ(s, c);
378         }
379 
380         // Draw setting
381         G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31),     // Diffuse
382                                 GX_RGB(16, 16, 16),     // Ambient
383                                 TRUE); // Color
384         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular
385                                 GX_RGB(0, 0, 0),        // Emission
386                                 FALSE); // Shininess
387         G3_TexImageParam(GX_TEXFMT_DIRECT,      // Texture format
388                          GX_TEXGEN_TEXCOORD,    // Texture generation
389                          GX_TEXSIZE_S64,        // Texture width
390                          GX_TEXSIZE_T64,        // Texture height
391                          GX_TEXREPEAT_NONE,     // Texture repeat
392                          GX_TEXFLIP_NONE,       // Texture flip
393                          GX_TEXPLTTCOLOR0_USE,  // Palette color
394                          myTexAddr);   // Texture address
395         G3_PolygonAttr(GX_LIGHTMASK_0, // Light
396                        GX_POLYGONMODE_MODULATE, // Polygon mode
397                        GX_CULL_NONE,   // Culling
398                        0,              // Polygon ID
399                        31,             // Alpha
400                        GX_POLYGON_ATTR_MISC_NONE);      // Misc
401 
402         // Draw cube
403         DrawCube();
404 
405         G3_PopMtx(1);
406 
407         // swapping the polygon list RAM, the vertex RAM, etc.
408         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
409 
410         // Wait VBlank
411         OS_WaitVBlankIntr();
412 
413 #ifdef SDK_AUTOTEST                    // code for auto test
414         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
415         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
416         EXT_TestScreenShot(100, 0x66E2DF30);
417         EXT_TestTickCounter();
418 #endif //SDK_AUTOTEST
419     }
420 }
421