1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/2D_CharBg_256BMP
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-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // A sample that uses 256 color BITMAP BG:
20 //
21 // This sample draws a picture on the display with 256 color palette BITMAP BG
22 //
23 //
24 // USAGE:
25 // UP, DOWN, LEFT, RIGHT : Slide the BG
26 // A, B : Scale the BG
27 // L, R : Rotate the BG
28 // SELECT + [UP, DOWN, LEFT, RIGHT] : Change the center of rotation
29 // SELECT : Toggle the BG area over mode between
30 // loop and transparent
31 //
32 // HOWTO:
33 // 1. Transfer the palette data by GX_LoadBGPltt
34 // 2. Transfer the screen data by GX_LoadBGxScr
35 // 3. Set 256 color BITMAP mode with G2_SetBGxControl256Bmp
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 // V-Blank interrupt process
49 // Description:
50 // Enables a flag that confirms that a V-Blank interrupt has been performed
51 //
52 // The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
53 // * Select IRQ interrupt (OS_SetIrqMask)
54 // * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
55 // * Enable IRQ interrupts (OS_EnableIrq)
56 //
57 //---------------------------------------------------------------------------
VBlankIntr(void)58 void VBlankIntr(void)
59 {
60 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
61 }
62
63 //---------------------------------------------------------------------------
64 // Summary:
65 // Displays an Affine extended 256 color bit map BG
66 // Description:
67 // Performs an affine transformation (rotation / scale) on a 256-color bitmap BG and then displays it
68 //
69 //
70 // 1. Use BG surface 3 with BGMODE number 3
71 // 2. Configure settings with G2_SetBG3Control256Bmp and transfer character data to the specified location
72 //
73 // 3. Transfer screen data to the specified location
74 // Controls:
75 // PLUS_KEY : BG screen offset operation
76 // SELECT + PLUS_KEY: Manipulate center position for rotating and scaling
77 // BUTTON_A, B : Enlarge, reduce
78 // BUTTON_L, R : Rotate
79 // SELECT : Area over process switch
80 // START : Initialize settings values
81 //---------------------------------------------------------------------------
82 #ifdef SDK_TWL
TwlMain(void)83 void TwlMain(void)
84 #else
85 void NitroMain(void)
86 #endif
87 {
88 int trg = 0;
89 int offset_H = 0;
90 int offset_V = 30;
91 fx32 scale = FX32_ONE;
92 s16 x_0 = 0, y_0 = 0;
93 s16 x_1 = 0, y_1 = 0;
94 u16 rotate = 0;
95
96 //---------------------
97 // Initialization
98 //---------------------
99 DEMOInitCommon();
100 DEMOInitVRAM();
101
102 /* BG configuration */
103 GX_SetBankForBG(GX_VRAM_BG_256_AB); // Allocate VRAM-A, B banks to BG
104
105 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, // 2D/3D mode
106 GX_BGMODE_3, // BGMODE 3
107 GX_BG0_AS_2D); // 2D display to BG0
108
109 GX_SetBGScrOffset(GX_BGSCROFFSET_0x00000); // Set screen offset value
110 GX_SetBGCharOffset(GX_BGCHAROFFSET_0x10000); // Set character offset
111
112 GX_SetVisiblePlane(GX_PLANEMASK_BG3); // Select BG3 for display
113 G2_SetBG3Priority(0); // Set BG3 priority to top
114 G2_BG3Mosaic(FALSE); // Do not apply mosaic to BG3
115
116 /* Read palette data (transmit the BG palette data to VRAM) */
117 GX_LoadBGPltt((const void *)bitmapBG_256color_Palette, // Pointer to transfer origin
118 0, // offset
119 PALETTE_SIZE); // Size
120
121 /* Transfer bitmap data to BG3 */
122 GX_LoadBG3Bmp(bitmapBG_256color_Texel, 0, SCREEN_SIZE);
123
124 DEMOStartDisplay();
125
126 //---------------------
127 // Main loop
128 //---------------------
129 while (1)
130 {
131 MtxFx22 mtx;
132
133 /* Reading pad information and controls */
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_UP | 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_BUTTON_SELECT))
146 {
147 if (DEMO_IS_PRESS(PAD_KEY_UP))
148 {
149 y_0 -= 2;
150 }
151 if (DEMO_IS_PRESS(PAD_KEY_DOWN))
152 {
153 y_0 += 2;
154 }
155 if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
156 {
157 x_0 += 2;
158 }
159 if (DEMO_IS_PRESS(PAD_KEY_LEFT))
160 {
161 x_0 -= 2;
162 }
163 }
164 else
165 {
166 if (DEMO_IS_PRESS(PAD_KEY_UP))
167 {
168 offset_V += 2;
169 }
170 if (DEMO_IS_PRESS(PAD_KEY_DOWN))
171 {
172 offset_V -= 2;
173 }
174 if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
175 {
176 offset_H -= 2;
177 }
178 if (DEMO_IS_PRESS(PAD_KEY_LEFT))
179 {
180 offset_H += 2;
181 }
182 }
183 if (DEMO_IS_PRESS(PAD_BUTTON_A))
184 {
185 scale += 2 << (FX32_SHIFT - 8);
186 }
187 if (DEMO_IS_PRESS(PAD_BUTTON_B))
188 {
189 scale -= 2 << (FX32_SHIFT - 8);
190 }
191 if (DEMO_IS_PRESS(PAD_BUTTON_L))
192 {
193 rotate -= 256;
194 }
195 if (DEMO_IS_PRESS(PAD_BUTTON_R))
196 {
197 rotate += 256;
198 }
199 if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
200 {
201 trg = (trg + 1) & 0x01;
202 OS_Printf("area_over=%d\n", trg);
203 }
204
205 if (DEMO_IS_TRIG(PAD_BUTTON_START))
206 {
207 offset_H = 0;
208 offset_V = 0;
209 x_0 = 32;
210 y_0 = 32;
211 scale = 1 << FX32_SHIFT;
212 rotate = 0;
213 }
214
215 /* Set BG3 to a screen size of 256x256 dots and a 256-color bitmapB */
216 {
217 GXBGAreaOver area_over = (trg ? GX_BG_AREAOVER_REPEAT : GX_BG_AREAOVER_XLU);
218
219 // Set BG3 to the 256-color bitmap BG
220 // Screen size: A screen size of 256x256 pixels
221 // Area overflow processing: Determined by area_over
222 // Screen base block: 0x00000
223 G2_SetBG3Control256Bmp(GX_BG_SCRSIZE_256BMP_256x256,
224 area_over, GX_BG_BMPSCRBASE_0x00000);
225 }
226
227 /* Generate affine conversion matrix */
228 {
229 fx16 sinVal = FX_SinIdx(rotate);
230 fx16 cosVal = FX_CosIdx(rotate);
231 fx32 rScale = FX_Inv(scale);
232
233 mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
234 mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
235 mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
236 mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
237 }
238
239 #ifdef SDK_AUTOTEST // Code for auto-test
240 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
241 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
242 EXT_TestScreenShot(100, 0xCB08F058);
243 EXT_TestTickCounter();
244 #endif //SDK_AUTOTEST
245
246 /* V-Blank wait */
247 OS_WaitVBlankIntr();
248
249 /* configure the affine conversion that is applied to the BG3 surface */
250 G2_SetBG3Affine(&mtx, // Conversion matrix
251 x_0, // Rotation center (x) coordinate
252 y_0, // Rotation center (y) coordinate
253 offset_H, // Pre-rotation coordinate (x)
254 offset_V); // Pre-rotation coordinate (y)
255 }
256 }
257