1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/2D_CharBg_Direct
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 use direct color BITMAP BG:
20 //
21 // This sample display picture on the display by direct color BITMAP BG
22 //
23 // USAGE:
24 //   UP, DOWN, LEFT, RIGHT      : Slide the BG
25 //   A, B                       : Scale the BG
26 //   L, R                       : Rotate the BG
27 //   SELECT + [UP, DOWN, LEFT, RIGHT] : Change the center of rotation
28 //   SELECT                     : Toggle the BG area over mode between
29 //                                loop and transparent
30 //
31 // HOWTO:
32 // 1. Transfer the bitmap data with GX_LoadBGxScr
33 // 2. Set the direct color BG mode with G2_SetBGxControlDCBmp
34 //---------------------------------------------------------------------------
35 
36 
37 #ifdef SDK_TWL
38 #include <twl.h>
39 #else
40 #include <nitro.h>
41 #endif
42 #include "DEMO.h"
43 #include "data.h"
44 //---------------------------------------------------------------------------
45 //  Summary:
46 //     V-Blank interrupt process
47 //  Description:
48 //     Enables a flag that confirms that a V-Blank interrupt has been performed
49 //
50 //        The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
51 //        * Select IRQ interrupt (OS_SetIrqMask)
52 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
53 //        * Enable IRQ interrupts (OS_EnableIrq)
54 //
55 //---------------------------------------------------------------------------
VBlankIntr(void)56 void VBlankIntr(void)
57 {
58     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
59 }
60 
61 //---------------------------------------------------------------------------
62 //  Summary:
63 //        Display affine extended direct color bit map BG
64 //  Description:
65 //        Performs affine conversions (rotate / scale) on a 256-color bitmap background and displays the result
66 //
67 //
68 //        1. Use BG surface 3 with BGMODE number 3
69 //        2. Perform the configuration in G2_SetBG3ControlDCBmp, and transmit the character data to the specified location
70 //
71 //        3. Transfer screen data to the specified location
72 //  Controls:
73 //        PLUS_KEY         : BG screen offset operation
74 //        SELECT + PLUS_KEY: Manipulate center position for rotating and scaling
75 //        BUTTON_A, B : Enlarge, reduce
76 //        BUTTON_L, R : Rotate
77 //        SELECT     : Area over process switch
78 //        START      : Initialize settings values
79 //---------------------------------------------------------------------------
80 #ifdef SDK_TWL
TwlMain(void)81 void TwlMain(void)
82 #else
83 void NitroMain(void)
84 #endif
85 {
86     int     trg = 0;
87     int     offset_H = 0;
88     int     offset_V = 30;
89     fx32    scale = FX32_ONE;
90     s16     x_0 = 0, y_0 = 0;
91     s16     x_1 = 0, y_1 = 0;
92     u16     rotate = 0;
93 
94     GXBGAreaOver area_over = GX_BG_AREAOVER_XLU;
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     /* Set BG3 to a screen size of 256x256 dots, and a direct color bitmap */
117     {
118         //   Set BG3 to direct color bitmap BG
119         //   Screen size: Use a screen size of 256x256 pixels
120         //   Area overflow processing: Determined by area_over
121         //   Screen base block: 0x00000
122         G2_SetBG3ControlDCBmp(GX_BG_SCRSIZE_DCBMP_256x256, area_over, GX_BG_BMPSCRBASE_0x00000);
123     }
124 
125     /* Transfer bitmap data to BG3 */
126     GX_LoadBG3Bmp(bitmapBG_directcolor_Texel, 0, SCREEN_SIZE);
127 
128     DEMOStartDisplay();
129 
130     //---------------------
131     //  Main loop
132     //---------------------
133     while (1)
134     {
135         MtxFx22 mtx;
136 
137         /* Reading pad information and controls */
138         DEMOReadKey();
139 
140 #ifdef SDK_AUTOTEST                    // Code for auto-test
141         {
142             const EXTKeys keys[8] =
143                 { {PAD_BUTTON_A, 10}, {PAD_BUTTON_L, 10}, {PAD_KEY_UP | PAD_KEY_RIGHT, 20} };
144             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
145         }
146 #endif
147 
148         if (DEMO_IS_PRESS(PAD_BUTTON_SELECT))
149         {
150             if (DEMO_IS_PRESS(PAD_KEY_UP))
151                 y_0 -= 2;
152             if (DEMO_IS_PRESS(PAD_KEY_DOWN))
153                 y_0 += 2;
154             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
155                 x_0 += 2;
156             if (DEMO_IS_PRESS(PAD_KEY_LEFT))
157                 x_0 -= 2;
158         }
159         else
160         {
161             if (DEMO_IS_PRESS(PAD_KEY_UP))
162                 offset_V += 2;
163             if (DEMO_IS_PRESS(PAD_KEY_DOWN))
164                 offset_V -= 2;
165             if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
166                 offset_H -= 2;
167             if (DEMO_IS_PRESS(PAD_KEY_LEFT))
168                 offset_H += 2;
169         }
170         if (DEMO_IS_PRESS(PAD_BUTTON_A))
171             scale += 2 << (FX32_SHIFT - 8);
172         if (DEMO_IS_PRESS(PAD_BUTTON_B))
173             scale -= 2 << (FX32_SHIFT - 8);
174         if (DEMO_IS_PRESS(PAD_BUTTON_L))
175             rotate -= 256;
176         if (DEMO_IS_PRESS(PAD_BUTTON_R))
177             rotate += 256;
178         if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
179         {
180             trg = (trg + 1) & 0x01;
181             OS_Printf("area_over=%d\n", trg);
182         }
183 
184         if (DEMO_IS_TRIG(PAD_BUTTON_START))
185         {
186             offset_H = 0;
187             offset_V = 0;
188             x_0 = 32;
189             y_0 = 32;
190             scale = 1 << FX32_SHIFT;
191             rotate = 0;
192         }
193 
194         /* Set BG3 to a screen size of 256x256 dots, and a direct color bitmap */
195         {
196             GXBGAreaOver area_over = (trg ? GX_BG_AREAOVER_REPEAT : GX_BG_AREAOVER_XLU);
197 
198             //   Set BG3 to direct color bitmap BG
199             //   Screen size: Use a screen size of 256x256 pixels
200             //   Area overflow processing: Determined by area_over
201             //   Screen base block: 0x00000
202             G2_SetBG3ControlDCBmp(GX_BG_SCRSIZE_DCBMP_256x256, area_over, GX_BG_BMPSCRBASE_0x00000);
203         }
204 
205         /* Generate affine conversion matrix */
206         {
207             fx16    sinVal = FX_SinIdx(rotate);
208             fx16    cosVal = FX_CosIdx(rotate);
209             fx32    rScale = FX_Inv(scale);
210 
211             mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
212             mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
213             mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
214             mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
215         }
216 
217 #ifdef SDK_AUTOTEST                    // Code for auto-test
218         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
219         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
220         EXT_TestScreenShot(100, 0x874F90B5);
221         EXT_TestTickCounter();
222 #endif //SDK_AUTOTEST
223 
224         /* V-Blank wait */
225         OS_WaitVBlankIntr();
226 
227         /* configure the affine conversion that is applied to the BG3 surface */
228         G2_SetBG3Affine(&mtx,          // Conversion matrix
229                         x_0,           // Rotation center (x) coordinate
230                         y_0,           // Rotation center (y) coordinate
231                         offset_H,      // Pre-rotation coordinate (x)
232                         offset_V);     // Pre-rotation coordinate (y)
233     }
234 }
235