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