1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/2D_Oam_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-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 //---------------------------------------------------------------------------
19 // A sample that use extended 256x16 color palette in OBJ:
20 //
21 // This sample displays some objects on the display with extended 256x16 color
22 // palette
23 //
24 // USAGE:
25 //   UP, DOWN, LEFT, RIGHT      : Slide the OBJs
26 //   A, B                       : Scaling the OBJs
27 //   L, R                       : Rotate the OBJs
28 //   SELECT     : Switch palette Number of the OBJs
29 //   START      : Initialize status of the OBJs
30 //
31 // HOWTO:
32 // 1. Allocate VRAM to extended palette with GX_SetBankForOBJExtPltt
33 // 2. Transfer the palette data with GX_BeginLoadOBJExtPltt, GX_LoadOBJExtPltt,
34 //    and GX_EndLoadOBJExtPltt
35 // 3. Set GX_OAM_COLOR_256 to OAM attribute to use the extended palette
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 //        OAM buffer region
49 //---------------------------------------------------------------------------
50 static GXOamAttr s_OAMBuffer[128];
51 
52 //---------------------------------------------------------------------------
53 //  Summary:
54 //    VBlank interrupt process
55 //  Description:
56 //    Enables a flag that confirms that a V-Blank interrupt has been performed
57 //
58 //        The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
59 //        * Select IRQ interrupt (OS_SetIrqMask)
60 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
61 //        * Enable IRQ interrupts (OS_EnableIrq)
62 //
63 //---------------------------------------------------------------------------
VBlankIntr(void)64 void VBlankIntr(void)
65 {
66     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
67 }
68 
69 //---------------------------------------------------------------------------
70 //  Summary:
71 //   Displays 256 color x 16 extended palette character of affine OBJ
72 //  Description:
73 //   Performs an extended affine transformation (rotation / scale) on an OBJ with sixteen 256-color extended palettes and displays the result
74 //
75 //  Controls:
76 //        UP, DOWN: Manipulate display position
77 //        BUTTON_A, B : Enlarge, reduce
78 //        BUTTON_L, R : rotation
79 //        SELECT     : Switch palette
80 //        START      : Initialize settings
81 //---------------------------------------------------------------------------
82 #ifdef SDK_TWL
TwlMain(void)83 void TwlMain(void)
84 #else
85 void NitroMain(void)
86 #endif
87 {
88     int     base_pos_x = 0, base_pos_y = 0;
89     int     base_pal = 0;
90     int     base_pat = 0;
91     fx32    scale = FX32_ONE;
92     u16     rotate = 0;
93 
94     //---------------------
95     // Initialization
96     //---------------------
97     DEMOInitCommon();
98     DEMOInitVRAM();
99     DEMOInitDisplayOBJOnly();
100 
101     /* Allocate VRAM bank to OBJ extended palette. */
102     GX_SetBankForOBJExtPltt(GX_VRAM_OBJEXTPLTT_0_F);
103 
104     /* Load character data and palette data. */
105     GX_LoadOBJ(bitmapOBJ_256color_icg, // Transfer OBJ data to VRAM A
106                0, sizeof(bitmapOBJ_256color_icg));
107     {
108         GX_BeginLoadOBJExtPltt();      // Prepare to transfer palette data
109         GX_LoadOBJExtPltt(bitmapOBJ_256color_icl,       // Transfer palette data to VRAM
110                           0, sizeof(bitmapOBJ_256color_icl));
111         GX_EndLoadOBJExtPltt();        // Palette data transfer complete
112     }
113 
114     DEMOStartDisplay();
115 
116     //---------------------
117     //  Main loop
118     //---------------------
119     while (1)
120     {
121         int     i, j;
122         int     pos_x = base_pos_x;
123         int     pos_y = base_pos_y;
124         int     palette = base_pal;
125 
126         /* Obtain pad information and configure operations */
127         DEMOReadKey();
128 #ifdef SDK_AUTOTEST                    // Code for auto-test
129         {
130             const EXTKeys keys[8] =
131                 { {PAD_BUTTON_A, 10}, {PAD_BUTTON_SELECT, 1}, {PAD_BUTTON_L, 10},
132             {PAD_KEY_UP | PAD_KEY_RIGHT, 20}
133             };
134             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
135         }
136 #endif
137 
138         if (DEMO_IS_PRESS(PAD_KEY_UP))
139         {
140             --base_pos_y;
141             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
142         }
143         else if (DEMO_IS_PRESS(PAD_KEY_DOWN))
144         {
145             ++base_pos_y;
146             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
147         }
148         if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
149         {
150             ++base_pos_x;
151             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
152         }
153         else if (DEMO_IS_PRESS(PAD_KEY_LEFT))
154         {
155             --base_pos_x;
156             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
157         }
158         if (DEMO_IS_PRESS(PAD_BUTTON_L))
159         {
160             rotate -= 512;
161             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
162         }
163         else if (DEMO_IS_PRESS(PAD_BUTTON_R))
164         {
165             rotate += 512;
166             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
167         }
168         if (DEMO_IS_PRESS(PAD_BUTTON_A))
169         {
170             scale += 128;
171             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
172         }
173         else if (DEMO_IS_PRESS(PAD_BUTTON_B))
174         {
175             scale -= 128;
176             if (scale < 0)
177             {
178                 scale = 0;
179             }
180             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
181         }
182         if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
183         {
184             if (++base_pal > 15)
185             {
186                 base_pal = 0;
187             }
188             OS_Printf("base_pal=%d\n", base_pal);
189         }
190 
191         if (DEMO_IS_TRIG(PAD_BUTTON_START))
192         {
193             base_pal = 0;
194             base_pos_x = 0;
195             base_pos_y = 0;
196             rotate = 0;
197             scale = FX32_ONE;
198             OS_Printf("pos=%d:%d rotate=%d scale=%d\n", base_pos_x, base_pos_y, rotate, scale);
199         }
200 
201         /* Generation and configuration of the affine transformation matrix */
202         {
203             MtxFx22 mtx;
204             fx16    sinVal = FX_SinIdx(rotate);
205             fx16    cosVal = FX_CosIdx(rotate);
206             fx32    rScale = FX_Inv(scale);
207             GXOamAffine *oamBuffp = (GXOamAffine *)&s_OAMBuffer[0];
208 
209             mtx._00 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
210             mtx._01 = (fx32)((sinVal * rScale) >> FX32_SHIFT);
211             mtx._10 = -(fx32)((sinVal * rScale) >> FX32_SHIFT);
212             mtx._11 = (fx32)((cosVal * rScale) >> FX32_SHIFT);
213             // Set OBJ affine transformation
214             G2_SetOBJAffine(oamBuffp,  // OAM buffer pointer
215                             &mtx);     // 2x2 matrix for affine transformation
216         }
217 
218         /* OAM configuration (configure 16 32-dot x 32-dot OBJs) */
219         for (i = 0; i < 4; i++)
220         {
221             for (j = 0; j < 4; j++)
222             {
223                 int     count = (i * 4) + j;
224                 int     pattern = ((count / 4) * 0x80) + ((count % 4) * 0x08);
225 
226                 /* Configure the OAM attributes of the OBJ */
227                 G2_SetOBJAttr(&s_OAMBuffer[count],      // Specify the location of OAM
228                               pos_x,   // x position
229                               pos_y,   // y position
230                               0,       // Priority order
231                               GX_OAM_MODE_NORMAL,       // Normal OBJ
232                               FALSE,   // Disable mosaic
233                               GX_OAM_EFFECT_AFFINE,     // Affine effect
234                               GX_OAM_SHAPE_32x32,       // OBJ size
235                               GX_OAM_COLOR_256, // 256 colors
236                               pattern, // Character name
237                               palette, // Color palette
238                               0);
239                 pos_x += 32;
240                 if (++palette > 15)
241                 {
242                     palette = 0;
243                 }
244             }
245             pos_x = base_pos_x;
246             pos_y += 32;
247         }
248 
249         /* Flush the cache to main memory */
250         DC_FlushRange(s_OAMBuffer, sizeof(s_OAMBuffer));
251         /* I/O register is accessed using DMA operation, so cache wait is not needed */
252         // DC_WaitWriteBufferEmpty();
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, 0x8B9FC4A0);
258         EXT_TestTickCounter();
259 #endif //SDK_AUTOTEST
260 
261         /* V-Blank wait */
262         OS_WaitVBlankIntr();
263 
264         /* Transfer to OAM */
265         GX_LoadOAM(s_OAMBuffer,        // Transfer OAM buffer to OAM
266                    0, sizeof(s_OAMBuffer));
267         MI_DmaFill32(3,                // Clear OAM buffer
268                      s_OAMBuffer, 192, sizeof(s_OAMBuffer));
269     }
270 }
271