1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MATH - demos
3   File:     main.c
4 
5   Copyright 2007-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   Demo using linear congruential method to get random numbers
19  *---------------------------------------------------------------------------*/
20 
21 #include    <nitro.h>
22 
23 
24 
25 static void VBlankIntr(void);
26 static void KeyRead(void);
27 static void DisplayInit();
28 static void PutDot(u16 x, u16 y, u16 col);
29 
30 /*---------------------------------------------------------------------------*
31     Variable Definitions
32  *---------------------------------------------------------------------------*/
33 static struct
34 {
35     u16     trig;
36     u16     press;
37 }
38 gKey;                                  // Key input
39 
40 
41 
42 /*---------------------------------------------------------------------------*
43     Function Definitions
44  *---------------------------------------------------------------------------*/
45 
46 /*---------------------------------------------------------------------------*
47   Name:         NitroMain
48 
49   Description:  Initialization and main loop.
50 
51   Arguments:    None.
52 
53   Returns:      None.
54  *---------------------------------------------------------------------------*/
NitroMain(void)55 void NitroMain(void)
56 {
57     MATHRandContext16 rnd;
58     u16     init_rnd = 0;
59 
60     // Various types of initialization
61     OS_Init();
62 
63     DisplayInit();
64 
65     // Empty call for getting key input data (strategy for pressing A Button in the IPL)
66     KeyRead();
67 
68     OS_TPrintf("press any button\n");
69 
70     // Main loop
71     while (TRUE)
72     {
73         static u16 col = 0;
74         static u16 *pVram = (u16 *)HW_LCDC_VRAM_C;
75         static u16 *pbVram = (u16 *)(HW_LCDC_VRAM_C + 0x18000 - 2);
76 
77         // Waiting for the V-Blank
78         OS_WaitVBlankIntr();
79 
80         // Get key input data
81         KeyRead();
82 
83         if (!init_rnd)
84         {
85             if (gKey.trig)
86             {
87                 // Initialize random number, use the value of V-Blank counter as the base
88                 MATH_InitRand16(&rnd, OS_GetVBlankCount());
89                 init_rnd = 1;
90             }
91             continue;
92         }
93 
94         {
95             u16     x, y;
96             u32     i;
97 
98             for (i = 0; i < 0x400; i++)
99             {
100                 // Get random number
101                 x = (u16)MATH_Rand16(&rnd, HW_LCD_WIDTH);
102                 y = (u16)MATH_Rand16(&rnd, HW_LCD_HEIGHT);
103 
104                 PutDot(x, y, col);
105             }
106         }
107 
108         // All white/black
109         while (*pVram == col)
110         {
111             pVram++;
112             if (pVram > pbVram)
113             {
114                 pVram = (u16 *)HW_LCDC_VRAM_C;
115                 pbVram = (u16 *)(HW_LCDC_VRAM_C + 0x18000 - 2);
116                 col ^= 0x7FFF;
117             }
118         }
119         while (*pbVram == col)
120         {
121             pbVram--;
122             if (pVram > pbVram)
123             {
124                 pVram = (u16 *)HW_LCDC_VRAM_C;
125                 pbVram = (u16 *)(HW_LCDC_VRAM_C + 0x18000 - 2);
126                 col ^= 0x7FFF;
127             }
128         }
129     }
130 }
131 
132 /*---------------------------------------------------------------------------*
133   Name:         VBlankIntr
134 
135   Description:  V-Blank interrupt vector.
136 
137   Arguments:    None.
138 
139   Returns:      None.
140  *---------------------------------------------------------------------------*/
VBlankIntr(void)141 static void VBlankIntr(void)
142 {
143     // Sets the IRQ check flag
144     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
145 }
146 
147 /*---------------------------------------------------------------------------*
148   Name:         KeyRead
149 
150   Description:  Edits key input data.
151                 Detects press trigger, release trigger, and press-and-hold repeat.
152 
153   Arguments:    pKey:   Structure that holds key input data to be edited
154 
155   Returns:      None.
156  *---------------------------------------------------------------------------*/
KeyRead(void)157 static void KeyRead(void)
158 {
159     u16     readData = PAD_Read();
160     gKey.trig = (u16)(readData & (readData ^ gKey.press));
161     gKey.press = readData;
162 }
163 
164 
165 /*---------------------------------------------------------------------------*
166   Name:         DisplayInit
167 
168   Description:  Graphics Initialization
169 
170   Arguments:    None.
171 
172   Returns:      None.
173  *---------------------------------------------------------------------------*/
DisplayInit()174 static void DisplayInit()
175 {
176 
177     GX_Init();
178     FX_Init();
179 
180     GX_DispOff();
181     GXS_DispOff();
182 
183     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
184 
185     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
186     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
187     (void)GX_VBlankIntr(TRUE);         // To generate V-Blank interrupt request
188     (void)OS_EnableIrq();
189 
190 
191     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
192     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
193 
194     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);   // Clear OAM
195     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);     // Clear the standard palette
196 
197     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);     // Clear OAM
198     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);       // Clear the standard palette
199     MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
200 
201 
202     GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB);       // Set VRAM-A,B for OBJ
203 
204     GX_SetGraphicsMode(GX_DISPMODE_VRAM_C,      // VRAM mode
205                        (GXBGMode)0,    // Dummy
206                        (GXBG0As)0);    // Dummy
207 
208     GX_SetVisiblePlane(GX_PLANEMASK_OBJ);       // Make OBJs visible
209     GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K);   // 2D mapping OBJ
210 
211     OS_WaitVBlankIntr();               // Waiting for the end of the V-Blank interrupt
212     GX_DispOn();
213 
214 }
215 
216 
217 /*---------------------------------------------------------------------------*
218   Name:         PutDot
219 
220   Description:  Draw a Dot in VRAM for LCDC.
221 
222   Arguments:    x: position X
223                 y: position Y
224                 col: DotColor
225 
226   Returns:      None.
227  *---------------------------------------------------------------------------*/
PutDot(u16 x,u16 y,u16 col)228 static inline void PutDot(u16 x, u16 y, u16 col)
229 {
230     if (x >= HW_LCD_WIDTH || y >= HW_LCD_HEIGHT)
231     {
232         return;
233     }
234     *(u16 *)(HW_LCDC_VRAM_C + y * 256 * 2 + x * 2) = col;
235 }
236 
237 
238 /*---------------------------------------------------------------------------*
239   End of file
240  *---------------------------------------------------------------------------*/
241