1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/2D_Oam_Char1D
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-12-01#$
14 $Rev: 9460 $
15 $Author: okajima_manabu $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // A sample that uses OBJ in 1D mapped character mode
20 //
21 // This sample displays objects on the display in 1D mapped character format
22 //
23 // USAGE:
24 // UP, DOWN, LEFT, RIGHT : Slide the OBJ
25 // A, B : Scaling the OBJ
26 // L, R : Rotate the OBJ
27 // SELECT : Switch palette Number of the OBJs
28 // START : Initialize status of the OBJ
29 //
30 // HOWTO:
31 // 1. Set VRAM size and mapping mode of OBJ with GX_SetOBJVRamModeChar
32 // 2. Transfer the bitmap data by GX_LoadOBJ
33 // 3. Set GX_OAM_MODE_NORMAL to OAM attribute to use the character OBJ
34 //---------------------------------------------------------------------------
35
36
37 #ifdef SDK_TWL
38 #include <twl.h>
39 #else
40 #include <nitro.h>
41 #endif
42 #include "DEMO.h"
43 #include "data.h"
44 //---------------------------------------------------------------------------
45 // Summary:
46 // OAM buffer region
47 //---------------------------------------------------------------------------
48 static GXOamAttr s_OAMBuffer[128];
49
50 //---------------------------------------------------------------------------
51 // Summary:
52 // VBlank interrupt process
53 // Description:
54 // Enables a flag that confirms that a V-Blank interrupt has been performed.
55 //
56 // The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
57 // * Select IRQ interrupt (OS_SetIrqMask)
58 // * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
59 // * Enable IRQ interrupts (OS_EnableIrq)
60 //
61 //---------------------------------------------------------------------------
VBlankIntr(void)62 void VBlankIntr(void)
63 {
64 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
65 }
66
67 //---------------------------------------------------------------------------
68 // Summary:
69 // Displays 1D mapping character OBJ
70 // Description:
71 // Affine converts (rotate / scale) the OBJ that holds the 1-dimensional mapping character data, then displays it
72 //
73 // Controls:
74 // UP, DOWN: Manipulate display position
75 // BUTTON_A, B : Enlarge, reduce
76 // BUTTON_L, R : rotation
77 // SELECT : Switch palette
78 // START : Initialize settings
79 //---------------------------------------------------------------------------
80 #ifdef SDK_TWL
TwlMain(void)81 void TwlMain(void)
82 #else
83 void NitroMain(void)
84 #endif
85 {
86 int base_pos_x = 0, base_pos_y = 0;
87 int base_pal = 0;
88 int base_pat = 0;
89 fx32 scale = FX32_ONE;
90 u16 rotate = 0;
91
92 //---------------------
93 // Initialization
94 //---------------------
95 DEMOInitCommon();
96 DEMOInitVRAM();
97
98 /* 2D configuration */
99 GX_SetBankForOBJ(GX_VRAM_OBJ_128_A); // Allocate VRAM-A to OBJ
100
101 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, // 2D/3D mode
102 GX_BGMODE_0, // Set BGMODE to 0
103 GX_BG0_AS_2D); // Use BG 0 as 2D
104
105 GX_SetVisiblePlane(GX_PLANEMASK_OBJ); // Sets OBJ to visible
106 // Set OBJ-VRAM capacity and mapping mode for character OBJ, and set mapping mode
107 GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_1D_32K); // 1D mapping mode
108 // Allocate VRAM bank to OBJ extended palette
109 GX_SetBankForOBJExtPltt(GX_VRAM_OBJEXTPLTT_0_F);
110
111 /* Load character data and palette data */
112 GX_LoadOBJ(bitmapOBJ_256color_icg, // Transfer OBJ data to VRAM-A
113 0, sizeof(bitmapOBJ_256color_icg));
114 {
115 GX_BeginLoadOBJExtPltt(); // Prepare to transfer palette data
116 GX_LoadOBJExtPltt(bitmapOBJ_256color_icl, // Transfer palette data to VRAM
117 0, sizeof(bitmapOBJ_256color_icl));
118 GX_EndLoadOBJExtPltt(); // Palette data transfer complete
119 }
120
121 DEMOStartDisplay();
122
123 //---------------------
124 // Main loop
125 //---------------------
126 while (1)
127 {
128 int i, j;
129 int pos_x = base_pos_x;
130 int pos_y = base_pos_y;
131 int palette = base_pal;
132
133 /* Obtain pad information and configure operations */
134 DEMOReadKey();
135 #ifdef SDK_AUTOTEST // Code for auto-test
136 {
137 const EXTKeys keys[8] =
138 { {PAD_BUTTON_A, 10}, {PAD_BUTTON_L, 10}, {PAD_KEY_DOWN | PAD_KEY_RIGHT, 20}, {0,
139 0}
140 };
141 EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
142 }
143 #endif
144
145 if (DEMO_IS_PRESS(PAD_KEY_UP))
146 {
147 if (--base_pos_y < 0)
148 {
149 base_pos_y = 255;
150 }
151 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
152 }
153 else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
154 {
155 if (++base_pos_y > 255)
156 {
157 base_pos_y = 0;
158 }
159 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
160 }
161 if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
162 {
163 if (++base_pos_x > 511)
164 {
165 base_pos_x = 0;
166 }
167 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
168 }
169 else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
170 {
171 if (--base_pos_x < 0)
172 {
173 base_pos_x = 511;
174 }
175 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
176 }
177 if (DEMO_IS_PRESS(PAD_BUTTON_L))
178 {
179 rotate -= 512;
180 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
181 }
182 else if (DEMO_IS_PRESS(PAD_BUTTON_R))
183 {
184 rotate += 512;
185 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
186 }
187 if (DEMO_IS_PRESS(PAD_BUTTON_A))
188 {
189 scale += 128;
190 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
191 }
192 else if (DEMO_IS_PRESS(PAD_BUTTON_B))
193 {
194 scale -= 128;
195 if (scale < 0)
196 scale = 0;
197 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
198 }
199 if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
200 {
201 if (++base_pal > 15)
202 base_pal = 0;
203 OS_Printf("base_pal=%d\n", base_pal);
204 }
205
206 if (DEMO_IS_TRIG(PAD_BUTTON_START))
207 {
208 base_pal = 0;
209 base_pos_x = 0;
210 base_pos_y = 0;
211 rotate = 0;
212 scale = FX32_ONE;
213 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
214 }
215
216 /* Generation and configuration of the affine transformation matrix */
217 {
218 MtxFx22 mtx;
219 fx16 sinVal = FX_SinIdx(rotate);
220 fx16 cosVal = FX_CosIdx(rotate);
221 fx32 rScale = FX_Inv(scale);
222 GXOamAffine *oamBuffp = (GXOamAffine *)&s_OAMBuffer[0];
223
224 mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
225 mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
226 mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
227 mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
228 // Set OBJ affine transformation
229 G2_SetOBJAffine(oamBuffp, // OAM buffer pointer
230 &mtx); // 2x2 matrix for affine transformation
231 }
232
233 /* OAM configuration (configures 32 OBJs) */
234 for (i = 0; i < 8; i++)
235 {
236 for (j = 0; j < 4; j++)
237 {
238 int count = (i * 4) + j;
239 int pattern = count * 0x20;
240
241 /* Configure the OAM attributes of the OBJ */
242 G2_SetOBJAttr(&s_OAMBuffer[count], // Specify the location of OAM
243 pos_x, // x position
244 pos_y, // y position
245 0, // Priority order
246 GX_OAM_MODE_NORMAL, // Normal OBJ
247 FALSE, // Disable mosaic
248 GX_OAM_EFFECT_AFFINE, // Affine effect
249 GX_OAM_SHAPE_32x32, // OBJ size
250 GX_OAM_COLOR_256, // 256 colors
251 pattern, // Character name
252 palette, // Color palette
253 0);
254 pos_x += 32;
255 if (++palette > 15)
256 {
257 palette = 0;
258 }
259 }
260 pos_x = base_pos_x;
261 pos_y += 32;
262 }
263
264 #ifdef SDK_AUTOTEST // Code for auto-test
265 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
266 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
267 EXT_TestScreenShot(100, 0xF81231F2);
268 EXT_TestTickCounter();
269 #endif //SDK_AUTOTEST
270
271 /* Flush the cache to main memory */
272 DC_FlushRange(s_OAMBuffer, sizeof(s_OAMBuffer));
273 /* I/O register is accessed using DMA operation, so cache wait is not needed */
274 // DC_WaitWriteBufferEmpty();
275
276 /* V-Blank wait */
277 OS_WaitVBlankIntr();
278
279 /* Transfer to OAM */
280 GX_LoadOAM(s_OAMBuffer, // Transfer OAM buffer to OAM
281 0, sizeof(s_OAMBuffer));
282 MI_DmaFill32(3, // Clear OAM buffer
283 s_OAMBuffer, 192, sizeof(s_OAMBuffer));
284 }
285 }
286