1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/2D_CharBg_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-10-20#$
14   $Rev: 9005 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 //---------------------------------------------------------------------------
19 // A sample that uses extended affine BG with extended 256x16 color palette:
20 //
21 // This sample draws spheres that stretch and rotate on the display
22 // with extended 256x16 color palette
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. Allocate VRAM to extended palette by GX_SetBankForBGExtPltt
34 // 2. Transfer the palette data by GX_BeginLoadBGExtPltt, GX_LoadBGExtPltt
35 //    and GX_EndLoadBGExtPltt
36 // 3. Set the extended palette to BG by G2_SetBGxControl256x16Pltt
37 //---------------------------------------------------------------------------
38 
39 
40 #ifdef SDK_TWL
41 #include <twl.h>
42 #else
43 #include <nitro.h>
44 #endif
45 #include "DEMO.h"
46 #include "data.h"
47 
48 //---------------------------------------------------------------------------
49 //  Summary:
50 //        V-Blank interrupt process
51 //  Description:
52 //     Enables a flag that confirms that a V-Blank interrupt has been performed
53 //
54 //        The following steps will be performed during common initialization (DEMOInitCommon()), causing this function to be called during V-Blanks
55 //        * Select IRQ interrupt (OS_SetIrqMask)
56 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
57 //        * Enable IRQ interrupts (OS_EnableIrq)
58 //
59 //---------------------------------------------------------------------------
VBlankIntr(void)60 void VBlankIntr(void)
61 {
62     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
63 }
64 
65 //---------------------------------------------------------------------------
66 //  Summary:
67 //        Display affine extended, 256-color x 16 extended palette character BG
68 //  Description:
69 //         Perform affine conversion (rotate / scale) on and display the 256 x 16 color expanded palette BG
70 //
71 //
72 //       1. Use BG surface 3 with BGMODE number 3
73 //       2. Perform the configuration in G2_SetBG3Control256x16Pltt, and transmit the character data to the specified location
74 //
75 //       3. Use GX_BeginLoadBGExtPltt, GX_LoadBGExtPltt, and GX_EndLoadBGExtPltt to transfer palette data to the extended area
76 //
77 //
78 //       Transfer screen data to the specified location
79 //  Controls:
80 //       PLUS_KEY         : BG screen offset operation
81 //       SELECT + PLUS_KEY: Manipulate center position for rotating and scaling
82 //       BUTTON_A, B : Enlarge, reduce
83 //       BUTTON_L, R : Rotate
84 //       SELECT     : Area over process switch
85 //       START      : Initialize settings values
86 //---------------------------------------------------------------------------
87 #ifdef SDK_TWL
TwlMain(void)88 void TwlMain(void)
89 #else
90 void NitroMain(void)
91 #endif
92 {
93     int     trg = 0;
94     int     offset_H = 0;
95     int     offset_V = 0;
96     fx32    scale = FX32_ONE;
97     s16     x_0 = 0, y_0 = 0;
98     s16     x_1 = 0, y_1 = 0;
99     u16     rotate = 0;
100 
101     //---------------------
102     // Initialization
103     //---------------------
104     DEMOInitCommon();
105     DEMOInitVRAM();
106 
107     /* BG configuration */
108     GX_SetBankForBG(GX_VRAM_BG_256_AB); // Allocate VRAM-A, B banks to BG
109     // Allocate VRAM banks to BG extended palette
110     GX_SetBankForBGExtPltt(GX_VRAM_BGEXTPLTT_0123_E);   /*
111                                                            Allocate slots 0, 1, 2, and 3 of the BG extended palette
112                                                            Allocate VRAM-E */
113     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS,    // 2D/3D mode
114                        GX_BGMODE_3,    // BGMODE 3
115                        GX_BG0_AS_2D);  // 2D display to BG0
116 
117     GX_SetBGScrOffset(GX_BGSCROFFSET_0x00000);  // Set screen offset value
118     GX_SetBGCharOffset(GX_BGCHAROFFSET_0x10000);        // Set character offset
119     GX_SetVisiblePlane(GX_PLANEMASK_BG3);       // Select BG3 for display
120     G2_SetBG3Priority(0);              // Set BG3 priority to top
121     G2_BG3Mosaic(FALSE);               // Do not apply mosaic to BG3
122 
123     /* Load character data and palette data
124        (Transfer BG3 character data and palette data to VRAM) */
125     GX_LoadBG3Char((const void *)kakucho_8bit_icg,      // Transfer character data to VRAM
126                    0, CHAR_SIZE);
127 
128     {
129         GX_BeginLoadBGExtPltt();       // Prepare to transfer palette data
130         // Transfer palette data to VRAM
131         GX_LoadBGExtPltt((const void *)kakucho_8bit_icl, 0x6000, PALETTE_SIZE);
132         GX_EndLoadBGExtPltt();         // Palette data transfer complete
133     }
134 
135     /* Transmit the screen data to BG3 */
136     GX_LoadBG3Scr(kakucho_8bit_isc, 0, SCREEN_SIZE);
137 
138     DEMOStartDisplay();
139 
140     //---------------------
141     //  Main loop
142     //---------------------
143     while (1)
144     {
145         MtxFx22 mtx;
146 
147         /* Reading pad information and controls */
148         DEMOReadKey();
149 #ifdef SDK_AUTOTEST                    // Code for auto-test
150         {
151             const EXTKeys keys[8] =
152                 { {PAD_BUTTON_A, 10}, {PAD_BUTTON_L, 10}, {PAD_KEY_UP | PAD_KEY_RIGHT, 20}, {0,
153                                                                                              0}
154             };
155             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
156         }
157 #endif
158 
159         if (DEMO_IS_PRESS(PAD_BUTTON_SELECT))
160         {
161             if (DEMO_IS_PRESS(PAD_KEY_UP))
162             {
163                 y_0 -= 2;
164             }
165             if (DEMO_IS_PRESS(PAD_KEY_DOWN))
166             {
167                 y_0 += 2;
168             }
169             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
170             {
171                 x_0 += 2;
172             }
173             if (DEMO_IS_PRESS(PAD_KEY_LEFT))
174             {
175                 x_0 -= 2;
176             }
177         }
178         else
179         {
180             if (DEMO_IS_PRESS(PAD_KEY_UP))
181             {
182                 offset_V += 2;
183             }
184             if (DEMO_IS_PRESS(PAD_KEY_DOWN))
185             {
186                 offset_V -= 2;
187             }
188             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
189             {
190                 offset_H -= 2;
191             }
192             if (DEMO_IS_PRESS(PAD_KEY_LEFT))
193             {
194                 offset_H += 2;
195             }
196         }
197         if (DEMO_IS_PRESS(PAD_BUTTON_A))
198         {
199             scale += (2 << (FX32_SHIFT - 8));
200         }
201         if (DEMO_IS_PRESS(PAD_BUTTON_B))
202         {
203             scale -= (2 << (FX32_SHIFT - 8));
204         }
205         if (DEMO_IS_PRESS(PAD_BUTTON_L))
206         {
207             rotate -= 256;
208         }
209         if (DEMO_IS_PRESS(PAD_BUTTON_R))
210         {
211             rotate += 256;
212         }
213         if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
214         {
215             trg = (trg + 1) & 0x01;
216             OS_Printf("area_over=%d\n", trg);
217         }
218 
219         if (DEMO_IS_TRIG(PAD_BUTTON_START))
220         {
221             offset_H = 0;
222             offset_V = 0;
223             x_0 = 32;
224             y_0 = 32;
225             scale = 1 << FX32_SHIFT;
226             rotate = 0;
227         }
228 
229         /* Set a 256-dot x 256-dot screen size and set a 256-color x 16-color extended palette to BG3 */
230         {
231             GXBGAreaOver area_over = (trg ? GX_BG_AREAOVER_REPEAT : GX_BG_AREAOVER_XLU);
232 
233             // Set BG3 to 256 color x 16 extended palette BG
234             //    Screen size: A screen size of 256x256 pixels
235             //   Area overflow processing: Determined by area_over
236             //   Screen base block: 0x00000
237             //   Character base block
238             G2_SetBG3Control256x16Pltt(GX_BG_SCRSIZE_256x16PLTT_256x256,
239                                        area_over, GX_BG_SCRBASE_0x0000, GX_BG_CHARBASE_0x00000);
240         }
241 
242         /* Generate affine conversion matrix */
243         {
244             fx16    sinVal = FX_SinIdx(rotate);
245             fx16    cosVal = FX_CosIdx(rotate);
246             fx32    rScale = FX_Inv(scale);
247 
248             mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
249             mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
250             mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
251             mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
252         }
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, 0x7A94EA54);
258         EXT_TestTickCounter();
259 #endif //SDK_AUTOTEST
260 
261         /* V-Blank wait */
262         OS_WaitVBlankIntr();
263 
264         /* configure the affine conversion that is applied to the BG3 surface */
265         G2_SetBG3Affine(&mtx,          // Conversion matrix
266                         x_0,           // Rotation center (x) coordinate
267                         y_0,           // Rotation center (y) coordinate
268                         offset_H,      // Pre-rotation coordinate (x)
269                         offset_V);     // Pre-rotation coordinate (y)
270     }
271 }
272 
273 /*====== End of main.c ======*/
274