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