1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/2D_CharBg_3
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 BG #2 as affine mode(scaling):
20 //
21 // USAGE:
22 //   UP, DOWN, LEFT, RIGHT      : Change the center position of scaling
23 //   A,B:                   Scaling BG #2
24 //
25 // HOWTO:
26 // 1. Set up the character/palette/screen data same as 2D_CharBG_1.
27 // 2. Set up a matrix and points with G2_SetBGxAffine().
28 //---------------------------------------------------------------------------
29 
30 #include <nitro/code32.h>              // avoid byte access problems
31 #ifdef SDK_TWL
32 #include <twl.h>
33 #else
34 #include <nitro.h>
35 #endif
36 #include "DEMO.h"
37 #include "data.h"
38 
39 #define STANDARD_SIZE        (1 << 8)
40 
41 static u8 sScrnBuf[SCREEN_SIZE];       // Buffer for screen data (BG #2)
42 
43 #ifdef SDK_TWL
TwlMain(void)44 void TwlMain(void)
45 #else
46 void NitroMain(void)
47 #endif
48 {
49     s16     x_0 = 0, y_0 = 0;
50     s16     x_1 = 0, y_1 = 0;
51 
52     fx32    scale = 1 << FX32_SHIFT;
53 
54     //---------------------------------------------------------------------------
55     // Initialize:
56     // Enables IRQ interrupts, initializes VRAM, and sets BG #2 for affine mode.
57     //---------------------------------------------------------------------------
58     DEMOInitCommon();
59     DEMOInitVRAM();
60     DEMOInitDisplayBG2Only();
61 
62     //---------------------------------------------------------------------------
63     // Transmitting the character data and the palette data
64     //---------------------------------------------------------------------------
65     GX_LoadBG2Char(d_64_256_bg_schDT, 0, sizeof(d_64_256_bg_schDT));
66     GX_LoadBGPltt(d_64_256_bg_sclDT, 0, sizeof(d_64_256_bg_sclDT));
67 
68     {
69         int     i, j;
70         for (i = 0; i < 8; i++)
71         {
72             for (j = 0; j < 8; j++)
73             {
74                 sScrnBuf[(i * 16) + j] = (u8)((i * 0x10) + j);
75             }
76         }
77     }
78     // Store the data in the main memory, and invalidate the cache.
79     DC_FlushRange(sScrnBuf, sizeof(sScrnBuf));
80     /* I/O register is accessed using DMA operation, so cache wait is not needed */
81     // DC_WaitWriteBufferEmpty();
82 
83     // DMA Transfer to BG #2 screen
84     GX_LoadBG2Scr(sScrnBuf, 0, sizeof(sScrnBuf));
85 
86     DEMOStartDisplay();
87     //---------------------------------------------------------------------------
88     // Main Loop
89     //---------------------------------------------------------------------------
90     while (1)
91     {
92         MtxFx22 mtx;
93         fx32    rScale;
94 
95         DEMOReadKey();
96         if (DEMO_IS_PRESS(PAD_KEY_UP))
97             y_0 -= 2;
98         if (DEMO_IS_PRESS(PAD_KEY_DOWN))
99             y_0 += 2;
100         if (DEMO_IS_PRESS(PAD_KEY_RIGHT))
101             x_0 += 2;
102         if (DEMO_IS_PRESS(PAD_KEY_LEFT))
103             x_0 -= 2;
104         if (DEMO_IS_PRESS(PAD_BUTTON_A))
105             scale -= 2 << (FX32_SHIFT - 8);
106         if (DEMO_IS_PRESS(PAD_BUTTON_B))
107             scale += 2 << (FX32_SHIFT - 8);
108         if (DEMO_IS_TRIG(PAD_BUTTON_SELECT))
109         {
110             x_0 = 32;
111             y_0 = 32;
112             scale = 1 << FX32_SHIFT;
113         }
114 
115 #ifdef SDK_AUTOTEST
116         x_0 = 10;
117         y_0 = 15;
118         scale = 8 << (FX32_SHIFT - 8); // default params for testing.
119         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
120         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
121         EXT_TestScreenShot(100, 0x3E71721B);
122         EXT_TestTickCounter();
123 #endif //SDK_AUTOTEST
124 
125         scale = MATH_CLAMP(scale, 0x100, 0x3000);
126 
127         rScale = FX_Inv(scale);
128         mtx._00 = rScale;
129         mtx._01 = 0;
130         mtx._10 = 0;
131         mtx._11 = rScale;
132 
133 
134         OS_WaitVBlankIntr();           // Waiting for the end of the VBlank interrupt
135 
136         //---------------------------------------------------------------------------
137         // Set up affine transformation for BG #2
138         //---------------------------------------------------------------------------
139         G2_SetBG2Affine(&mtx,          // a matrix for rotation and scaling
140                         x_0, y_0,      // the center of rotation
141                         0, 0           // the reference point before rotation and scaling applied
142             );
143     }
144 }
145 
146 //---------------------------------------------------------------------------
147 // VBlank interrupt function:
148 //
149 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
150 // OS_EnableIrqMask selects IRQ interrupts to enable, and
151 // OS_EnableIrq enables IRQ interrupts.
152 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
153 //---------------------------------------------------------------------------
VBlankIntr(void)154 void VBlankIntr(void)
155 {
156     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Checking VBlank interrupt
157 }
158