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