1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/2D_Oam_Bmp1D
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 OBJ in 1D mapped bitmap mode
20 //
21 // This sample displays a object on the display in 1D bitmap 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 // START : Initialize status of the OBJ
28 //
29 // HOWTO:
30 // 1. Set VRAM size and mapping mode of OBJ by GX_SetOBJVRamModeBmp
31 // 2. Transfer the bitmap data by GX_LoadOBJ
32 // 3. Set GX_OAM_MODE_BITMAPOBJ to OAM attribute to use the bitmap OBJ
33 //---------------------------------------------------------------------------
34
35
36 #ifdef SDK_TWL
37 #include <twl.h>
38 #else
39 #include <nitro.h>
40 #endif
41 #include "DEMO.h"
42 #include "data.h"
43 //---------------------------------------------------------------------------
44 // Summary:
45 // OAM buffer region
46 //---------------------------------------------------------------------------
47
48 static GXOamAttr s_OAMBuffer[128];
49
50 //---------------------------------------------------------------------------
51 // Summary:
52 // V-Blank 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 // Display a 1D mapping bitmap OBJ
70 // Description:
71 // Affine conversion (rotate/scale) of the OBJ that holds the 1-dimensional mapping bitmap data and displays it
72 //
73 // Controls:
74 // UP, DOWN: Manipulate display position
75 // BUTTON_A, B : Enlarge, reduce
76 // BUTTON_L, R : rotation
77 // START : Initialize settings
78 //---------------------------------------------------------------------------
79 #ifdef SDK_TWL
TwlMain(void)80 void TwlMain(void)
81 #else
82 void NitroMain(void)
83 #endif
84 {
85 int base_pos_x = 0, base_pos_y = 0;
86 int base_pat = 0;
87 fx32 scale = FX32_ONE;
88 u16 rotate = 0;
89
90 //---------------------
91 // Initialization
92 //---------------------
93 DEMOInitCommon();
94 DEMOInitVRAM();
95
96 /* OAM configuration */
97 GX_SetVisiblePlane(GX_PLANEMASK_OBJ); // Sets OBJ to visible
98 GX_SetBankForOBJ(GX_VRAM_OBJ_128_A); // Allocate VRAM-A to OBJ
99
100 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, // 2D/3D mode
101 GX_BGMODE_0, // Set BGMODE to 0
102 GX_BG0_AS_2D); // Use BG 0 as 2D
103 // Sets OBJ-VRAM capacity and mapping mode for bitmap OBJ
104 GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K); // 1D mapping
105
106 /* load character data */
107 GX_LoadOBJ((const void *)IMAGE_DATA, 0, IMAGE_DATA_SIZE);
108
109 DEMOStartDisplay();
110
111 //---------------------
112 // Main loop
113 //---------------------
114 while (1)
115 {
116 int pos_x = base_pos_x;
117 int pos_y = base_pos_y;
118
119 /* Obtain pad information and configure operations */
120 DEMOReadKey();
121 #ifdef SDK_AUTOTEST // Code for auto-test
122 {
123 const EXTKeys keys[8] =
124 { {PAD_BUTTON_A, 10}, {PAD_BUTTON_L, 10}, {PAD_KEY_DOWN | PAD_KEY_RIGHT, 20}, {0,
125 0}
126 };
127 EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
128 }
129 #endif
130
131 if (DEMO_IS_PRESS(PAD_KEY_UP))
132 {
133 if (--base_pos_y < 0)
134 base_pos_y = 255;
135 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
136 }
137 else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
138 {
139 if (++base_pos_y > 255)
140 base_pos_y = 0;
141 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
142 }
143 if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
144 {
145 if (++base_pos_x > 511)
146 base_pos_x = 0;
147 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
148 }
149 else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
150 {
151 if (--base_pos_x < 0)
152 base_pos_x = 511;
153 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
154 }
155 if (DEMO_IS_PRESS(PAD_BUTTON_L))
156 {
157 rotate -= 512;
158 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
159 }
160 else if (DEMO_IS_PRESS(PAD_BUTTON_R))
161 {
162 rotate += 512;
163 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
164 }
165 if (DEMO_IS_PRESS(PAD_BUTTON_A))
166 {
167 scale += 128;
168 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
169 }
170 else if (DEMO_IS_PRESS(PAD_BUTTON_B))
171 {
172 scale -= 128;
173 if (scale < 0)
174 scale = 0;
175 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
176 }
177
178 if (DEMO_IS_TRIG(PAD_BUTTON_START))
179 {
180 base_pos_x = 0;
181 base_pos_y = 0;
182 rotate = 0;
183 scale = FX32_ONE;
184 OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
185 }
186
187 /* Generation and configuration of the affine transformation matrix */
188 {
189 MtxFx22 mtx;
190 fx16 sinVal = FX_SinIdx(rotate);
191 fx16 cosVal = FX_CosIdx(rotate);
192 fx32 rScale = FX_Inv(scale);
193 GXOamAffine *oamBuffp = (GXOamAffine *)&s_OAMBuffer[0];
194
195 mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
196 mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
197 mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
198 mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
199 // Set OBJ affine transformation
200 G2_SetOBJAffine(oamBuffp, // OAM buffer pointer
201 &mtx); // 2x2 matrix for affine transformation
202 }
203
204 /* OAM configuration */
205 G2_SetOBJAttr(&s_OAMBuffer[0], // Specify the location of OAM
206 pos_x, // x position
207 pos_y, // y position
208 0, // Priority order
209 GX_OAM_MODE_BITMAPOBJ, // Bitmap mode
210 FALSE, // Disable mosaic
211 GX_OAM_EFFECT_AFFINE, // Affine effect
212 GX_OAM_SHAPE_32x32, // OBJ size
213 GX_OAM_COLOR_16, // �P�U colors
214 0, // Character name
215 15, // Alpha value
216 0);
217
218 #ifdef SDK_AUTOTEST // Code for auto-test
219 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
220 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
221 EXT_TestScreenShot(100, 0xC8135726);
222 EXT_TestTickCounter();
223 #endif //SDK_AUTOTEST
224
225 /* Flush the cache to main memory */
226 DC_FlushRange(s_OAMBuffer, sizeof(s_OAMBuffer));
227 /* I/O register is accessed using DMA operation, so cache wait is not needed */
228 // DC_WaitWriteBufferEmpty();
229
230 /* V-Blank wait */
231 OS_WaitVBlankIntr();
232
233 /* Transfer to OAM */
234 GX_LoadOAM(s_OAMBuffer, // Transfer OAM buffer to OAM
235 0, sizeof(s_OAMBuffer));
236 MI_DmaFill32(3, // Clear OAM buffer
237 s_OAMBuffer, 192, sizeof(s_OAMBuffer));
238 }
239 }
240