1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/Capture
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 for capture display.
19 //
20 // Rotating cube is displayed.
21 // There is motion blur effect by capturing display.
22 //
23 // HOWTO:
24 // 1. Call "GX_SetCapture" to capture display and blend with rendered image.
25 //
26 // OPERATION:
27 // 1. Push cross button to move cube position.
28 // 2. Push start button to reset cube position.
29 // 3. Push A or B button to change blending parameter for captured data.
30 //
31 //---------------------------------------------------------------------------
32 #ifdef SDK_TWL
33 #include <twl.h>
34 #else
35 #include <nitro.h>
36 #endif
37 #include "DEMO.h"
38 #include "tex_32768.h"
39
40 //---------------------------------------------------------------------------
41 // Cube model data
42 //---------------------------------------------------------------------------
43 // Vertex data
44 static s16 s_Vertex[3 * 8] = {
45 FX16_ONE, FX16_ONE, FX16_ONE,
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 };
54 // Normal data
55 static VecFx10 s_Normal[6] = {
56 GX_VECFX10(0, 0, FX32_ONE - 1),
57 GX_VECFX10(0, FX32_ONE - 1, 0),
58 GX_VECFX10(FX32_ONE - 1, 0, 0),
59 GX_VECFX10(0, 0, -FX32_ONE + 1),
60 GX_VECFX10(0, -FX32_ONE + 1, 0),
61 GX_VECFX10(-FX32_ONE + 1, 0, 0)
62 };
63 // Texture coordinate data
64 static GXSt s_TextureCoord[] = {
65 GX_ST(0, 0),
66 GX_ST(0, 64 * FX32_ONE),
67 GX_ST(64 * FX32_ONE, 0),
68 GX_ST(64 * FX32_ONE, 64 * FX32_ONE)
69 };
70
71 //---------------------------------------------------------------------------
72 // Set vertex coordinate.
73 // input:
74 // i_idx: ID of vertex data
75 //---------------------------------------------------------------------------
Vertex(int i_idx)76 inline void Vertex(int i_idx)
77 {
78 G3_Vtx(s_Vertex[i_idx * 3], s_Vertex[i_idx * 3 + 1], s_Vertex[i_idx * 3 + 2]);
79 }
80
81 //---------------------------------------------------------------------------
82 // Set normal setting.
83 // input:
84 // i_idx: ID of normal data
85 //---------------------------------------------------------------------------
Normal(int i_idx)86 inline void Normal(int i_idx)
87 {
88 G3_Direct1(G3OP_NORMAL, s_Normal[i_idx]);
89 }
90
91 //---------------------------------------------------------------------------
92 // Set texture coordinate.
93 // input:
94 // i_idx: ID of texture data
95 //---------------------------------------------------------------------------
TextureCoord(int i_idx)96 inline void TextureCoord(int i_idx)
97 {
98 G3_Direct1(G3OP_TEXCOORD, s_TextureCoord[i_idx]);
99 }
100
101 //---------------------------------------------------------------------------
102 // Draw a cube and set texture.
103 //---------------------------------------------------------------------------
DrawCube(void)104 static void DrawCube(void)
105 {
106 G3_Begin(GX_BEGIN_QUADS); // start to set vertex.(use square polygon)
107 {
108 TextureCoord(1);
109 Normal(0);
110 Vertex(2);
111 TextureCoord(0);
112 Normal(0);
113 Vertex(0);
114 TextureCoord(2);
115 Normal(0);
116 Vertex(4);
117 TextureCoord(3);
118 Normal(0);
119 Vertex(6);
120
121 TextureCoord(1);
122 Normal(3);
123 Vertex(7);
124 TextureCoord(0);
125 Normal(3);
126 Vertex(5);
127 TextureCoord(2);
128 Normal(3);
129 Vertex(1);
130 TextureCoord(3);
131 Normal(3);
132 Vertex(3);
133
134 TextureCoord(1);
135 Normal(5);
136 Vertex(6);
137 TextureCoord(0);
138 Normal(5);
139 Vertex(4);
140 TextureCoord(2);
141 Normal(5);
142 Vertex(5);
143 TextureCoord(3);
144 Normal(5);
145 Vertex(7);
146
147 TextureCoord(1);
148 Normal(2);
149 Vertex(3);
150 TextureCoord(0);
151 Normal(2);
152 Vertex(1);
153 TextureCoord(2);
154 Normal(2);
155 Vertex(0);
156 TextureCoord(3);
157 Normal(2);
158 Vertex(2);
159
160 TextureCoord(1);
161 Normal(1);
162 Vertex(5);
163 TextureCoord(0);
164 Normal(1);
165 Vertex(4);
166 TextureCoord(2);
167 Normal(1);
168 Vertex(0);
169 TextureCoord(3);
170 Normal(1);
171 Vertex(1);
172
173 TextureCoord(1);
174 Normal(4);
175 Vertex(6);
176 TextureCoord(0);
177 Normal(4);
178 Vertex(7);
179 TextureCoord(2);
180 Normal(4);
181 Vertex(3);
182 TextureCoord(3);
183 Normal(4);
184 Vertex(2);
185 }
186
187 G3_End(); // end
188 }
189
190
191 //---------------------------------------------------------------------------
192 // VBlank interrupt function:
193 //
194 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
195 // OS_EnableIrqMask selects IRQ interrupts to enable, and
196 // OS_EnableIrq enables IRQ interrupts.
197 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
198 //---------------------------------------------------------------------------
VBlankIntr(void)199 void VBlankIntr(void)
200 {
201 // Set flag which checks VBlank interrupt.
202 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
203 }
204
205 //---------------------------------------------------------------------------
206 // main
207 //---------------------------------------------------------------------------
208 #ifdef SDK_CW_WA_CONSTPOOLS
209 #pragma optimization_level 1
210 #endif
211 #ifdef SDK_TWL
TwlMain(void)212 void TwlMain(void)
213 #else
214 void NitroMain(void)
215 #endif
216 {
217 unsigned int count = 0;
218 u16 Rotate = 0;
219 u32 myTexAddr = 0x00000; // Address of texture image slot
220 fx32 pos_x = 0;
221 fx32 pos_y = 0;
222 int eva = 0x04;
223 int evb = 0x0c;
224
225 // Initialize
226 DEMOInitCommon();
227 DEMOInitVRAM();
228 DEMOInitDisplay3D();
229
230 // Set VRAM-C to LCDC
231 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
232
233 // Set display mode
234 GX_SetGraphicsMode(GX_DISPMODE_VRAM_C, GX_BGMODE_4, // value used by capture circuit
235 GX_BG0_AS_3D); // can't pass dummy value
236
237 // Load texture image into texture image slot.
238 GX_BeginLoadTex();
239 {
240 GX_LoadTex((void *)&tex_32768_64x64[0], // Src address
241 myTexAddr, // Destination slot address
242 8192); // Size to load
243 }
244 GX_EndLoadTex();
245
246 DEMOStartDisplay();
247
248 // Show information message
249 OS_Printf("If EVB is over 8/16, the afterimage of blur stay eternally.\n");
250 OS_Printf("eva=%d : evb=%d\n", eva, evb);
251
252 // main loop
253 while (1)
254 {
255 G3X_Reset();
256 Rotate += 256;
257
258 // Read input
259 DEMOReadKey();
260 // Move cube position
261 if (DEMO_IS_PRESS(PAD_KEY_UP))
262 {
263 pos_y += 500;
264 }
265 else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
266 {
267 pos_y -= 500;
268 }
269 if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
270 {
271 pos_x += 500;
272 }
273 else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
274 {
275 pos_x -= 500;
276 }
277 if (DEMO_IS_TRIG(PAD_BUTTON_START))
278 {
279 pos_x = pos_y = 0;
280 }
281
282 // Change blending parameter
283 if (DEMO_IS_TRIG(PAD_BUTTON_A))
284 {
285 if (++evb > 0x10)
286 {
287 evb = 0x10;
288 }
289 eva = 0x10 - evb;
290 OS_Printf("eva=%d : evb=%d\n", eva, evb);
291 }
292 else if (DEMO_IS_TRIG(PAD_BUTTON_B))
293 {
294 if (--evb < 0x00)
295 {
296 evb = 0x00;
297 }
298 eva = 0x10 - evb;
299 OS_Printf("eva=%d : evb=%d\n", eva, evb);
300 }
301
302 // Camera setting
303 {
304 VecFx32 Eye = { 0, 0, FX32_ONE }; // Sight position
305 VecFx32 at = { 0, 0, 0 }; // Viewpoint
306 VecFx32 vUp = { 0, FX32_ONE, 0 }; // Up
307 G3_LookAt(&Eye, &vUp, &at, NULL); // Sight setting
308 }
309
310 // Light setting
311 G3_LightVector(GX_LIGHTID_0, 0, -FX32_ONE + 1, 0);
312 G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
313
314 // Matrix setting
315 G3_MtxMode(GX_MTXMODE_TEXTURE);
316 G3_Identity();
317 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
318 G3_PushMtx();
319
320 // Rotate and translate cube
321 {
322 fx16 s = FX_SinIdx(Rotate);
323 fx16 c = FX_CosIdx(Rotate);
324
325 G3_Translate(pos_x, pos_y, -5 * FX32_ONE);
326 G3_RotX(s, c);
327 G3_RotY(s, c);
328 G3_RotZ(s, c);
329 }
330
331 // Draw setting
332 G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31), // Diffuse
333 GX_RGB(16, 16, 16), // Ambient
334 TRUE); // Color
335 G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16), // Specular
336 GX_RGB(0, 0, 0), // Emission
337 FALSE); // Shininess
338 G3_TexImageParam(GX_TEXFMT_DIRECT, // Texture format
339 GX_TEXGEN_TEXCOORD, // Texture generation
340 GX_TEXSIZE_S64, // Texture width
341 GX_TEXSIZE_T64, // Texture hight
342 GX_TEXREPEAT_NONE, // Texture repeat
343 GX_TEXFLIP_NONE, // Texture flip
344 GX_TEXPLTTCOLOR0_USE, // Palette color
345 myTexAddr); // Texture address
346 G3_PolygonAttr(GX_LIGHTMASK_0, // Light
347 GX_POLYGONMODE_MODULATE, // Polygon mode
348 GX_CULL_NONE, // Culling
349 0, // Polygon ID
350 31, // Alpha
351 0); // Misc
352
353 // Draw cube
354 DrawCube();
355
356 G3_PopMtx(1);
357
358 // swapping the polygon list RAM, the vertex RAM, etc.
359 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
360
361 // Wait VBlank
362 OS_WaitVBlankIntr();
363
364 //---------------------------------------------------------------------------
365 // Execute capture
366 // Blend rendered image and displayed image (VRAM), and output to VRAM-C
367 GX_SetCapture(GX_CAPTURE_SIZE_256x192, // Capture size
368 GX_CAPTURE_MODE_AB, // Capture mode
369 GX_CAPTURE_SRCA_2D3D, // Blend src A
370 GX_CAPTURE_SRCB_VRAM_0x00000, // Blend src B
371 GX_CAPTURE_DEST_VRAM_C_0x00000, // Output VRAM
372 eva, // Blend parameter for src A
373 evb); // Blend parameter for src B
374 //---------------------------------------------------------------------------
375 }
376 }
377