1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WXC - demos - relayStation-1
3 File: main.c
4
5 Copyright 2005-2009 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:: 2007-11-15#$
14 $Rev: 2414 $
15 $Author: hatamoto_minoru $
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 This sample runs chance encounter communications over a wireless connection.
20 Child mode becomes 100%, and it operates identically to a relay station
21 *---------------------------------------------------------------------------*/
22
23 #include <nitro.h>
24
25 #include <nitro/wxc.h>
26 #include "user.h"
27 #include "common.h"
28 #include "dispfunc.h"
29
30
31 /*---------------------------------------------------------------------------*
32 Internal Function Definitions
33 *---------------------------------------------------------------------------*/
34 static void ModeSelect(void); // Parent/child select screen
35 static void ModeError(void); // Error display screen
36 static void VBlankIntr(void); // V-Blank interrupt handler
37
38 // General purpose subroutines
39 static void InitializeAllocateSystem(void);
40
41 static void Menu(void);
42
43 /*---------------------------------------------------------------------------*
44 Internal Variable Definitions
45 *---------------------------------------------------------------------------*/
46 static s32 gFrame; // Frame counter
47
48 /*---------------------------------------------------------------------------*
49 External Variable Definitions
50 *---------------------------------------------------------------------------*/
51 int passby_endflg;
52 int menu_flg;
53
54 BOOL keep_flg;
55
56 BOOL passby_ggid[MENU_MAX]; // GGID that does chance encounter
57
58 u16 keyData;
59
60 /*---------------------------------------------------------------------------*
61 Name: NitroMain
62
63 Description: Initialization and main loop.
64
65 Arguments: None.
66
67 Returns: None.
68 *---------------------------------------------------------------------------*/
NitroMain(void)69 void NitroMain(void)
70 {
71 int i;
72
73 // Various types of initialization
74 OS_Init();
75 OS_InitTick();
76
77 OS_InitAlarm();
78
79 FX_Init();
80
81 { /* Rendering settings initialization */
82 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
83 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
84 (void)GX_DisableBankForLCDC();
85 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
86 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
87 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
88 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
89 BgInitForPrintStr();
90 GX_SetBankForOBJ(GX_VRAM_OBJ_128_B);
91 GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
92 GX_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
93 GXS_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ);
94 GX_LoadOBJ(sampleCharData, 0, sizeof(sampleCharData));
95 GX_LoadOBJPltt(samplePlttData, 0, sizeof(samplePlttData));
96 MI_DmaFill32(3, oamBak, 0xc0, sizeof(oamBak));
97 }
98
99 /* V-Blank interrupt configuration */
100 (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
101 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
102 (void)OS_EnableIrqMask(OS_IE_FIFO_RECV);
103 (void)OS_EnableIrq();
104 (void)OS_EnableInterrupts();
105 (void)GX_VBlankIntr(TRUE);
106
107 // RTC initialization
108 RTC_Init();
109
110 /* Start display */
111 GX_DispOn();
112 GXS_DispOn();
113 G2_SetBG0Offset(0, 0);
114 G2S_SetBG0Offset(0, 0);
115
116 /* Memory allocation initialization */
117 InitializeAllocateSystem();
118
119 // Debug string output
120 OS_Printf("ARM9: WM simple demo started.");
121
122
123 passby_endflg = 0;
124 menu_flg = MENU_MIN;
125 keep_flg = TRUE;
126
127 // Set all initial GGID values as capable of chance encounter
128 for(i = 0; i < MENU_MAX; i++)
129 {
130 passby_ggid[i] = TRUE;
131 }
132
133 /* Main loop */
134 while(1)
135 {
136 OS_WaitVBlankIntr();
137
138 keyData = ReadKeySetTrigger(PAD_Read());
139
140 /* Display clear */
141 BgClear();
142
143 // Chance encounter communications configuration screen
144 Menu();
145
146 // Transition to chance encounter communications
147 if(menu_flg == 9)
148 {
149 int i;
150
151 // Initialize only the selected GGID
152 for(i = 0; i < MENU_MAX; i++)
153 {
154 if(passby_ggid[i])
155 {
156 /* Initializes, registers, and runs chance encounter communications */
157 User_Init();
158 break;
159 }
160 }
161 if(i >= MENU_MAX)
162 {
163 /* Starts an error message display */
164 BgClear();
165 BgPutString(5, 19, WHITE, "Set at least one GGID");
166 passby_endflg = 4;
167 }
168
169 /* Display clear */
170 BgClear();
171
172 /* Main chance encounter communications loop */
173 // Continues to act as a relay station until the start button is pressed
174 for (gFrame = 0; passby_endflg != 3; gFrame++)
175 {
176 OS_WaitVBlankIntr();
177
178 keyData = ReadKeySetTrigger(PAD_Read());
179
180 /* Distributes processes based on communication status */
181 switch (WXC_GetStateCode())
182 {
183 case WXC_STATE_END:
184 ModeSelect();
185 break;
186 case WXC_STATE_ENDING:
187 break;
188 case WXC_STATE_ACTIVE:
189 if(WXC_IsParentMode() == TRUE)
190 {
191 BgPutString(8, 2, WHITE, "Now parent...");
192 }
193 else
194 {
195 BgPutString(8, 2, WHITE, "Now child...");
196 }
197 break;
198 }
199
200 BgPutString(5, 19, WHITE, "Push START to Reset");
201
202 if (keyData & PAD_BUTTON_START)
203 {
204 passby_endflg = 3;
205 /* Display clear */
206 BgClear();
207 }
208 // Waiting for the V-Blank
209 OS_WaitVBlankIntr();
210 }
211
212 // End here if the WXC_RegisterCommonData function is being called
213 if(passby_endflg != 4)
214 {
215 (void)WXC_End();
216 }
217
218 while( WXC_GetStateCode() != WXC_STATE_END )
219 {
220 ;
221 }
222 // Wait for A button
223 while(1)
224 {
225 keyData = ReadKeySetTrigger(PAD_Read());
226
227 BgPutString(3, 1, WHITE, "Push A to Reset");
228
229 if (keyData & PAD_BUTTON_A)
230 {
231 passby_endflg = 0;
232 menu_flg = MENU_MIN;
233 break;
234 }
235 OS_WaitVBlankIntr();
236 }
237 }
238 }
239 }
240
241 /*---------------------------------------------------------------------------*
242 Name: Menu
243
244 Description: Processing for the chance encounter configuration screen.
245
246 Arguments: None.
247
248 Returns: None.
249 *---------------------------------------------------------------------------*/
Menu(void)250 static void Menu(void)
251 {
252 int i;
253 enum
254 { DISP_OX = 5, DISP_OY = 5 };
255
256 /* Change cursor number */
257 if (keyData & PAD_KEY_DOWN)
258 {
259 menu_flg++;
260 if(menu_flg > MENU_MAX)
261 {
262 menu_flg = MENU_MIN;
263 }
264 }
265 else if (keyData & PAD_KEY_UP)
266 {
267 menu_flg--;
268 if(menu_flg < MENU_MIN)
269 {
270 menu_flg = MENU_MAX;
271 }
272 }
273 else if (keyData & (PAD_BUTTON_A | PAD_BUTTON_START))
274 {
275 menu_flg = 9;
276 }
277
278 /* Start display */
279 BgPutString((s16)(DISP_OX + 3), (s16)(DISP_OY - 3), WHITE, "Main Menu");
280
281 for(i = 0; i < MENU_MAX-1; i++)
282 {
283 BgPrintf((s16)(DISP_OX), (s16)(DISP_OY + i), WHITE,
284 "GGID No.%01d %s", (i+1), (passby_ggid[i]) ? "[Yes]" : "[No ]");
285 }
286
287 BgPrintf((s16)(DISP_OX), (s16)(DISP_OY + i), WHITE,
288 "RelayMode %s", (keep_flg) ? "[KEEP ]" : "[THROW]");
289
290 /* Cursor display */
291 BgPutChar((s16)(DISP_OX - 2), (s16)(DISP_OY + menu_flg-1), RED, '*');
292 /* Wait for A button */
293 BgPutString(DISP_OX, DISP_OY + 14, WHITE, " Push A or START Button");
294
295
296 if (keyData & (PAD_KEY_RIGHT | PAD_KEY_LEFT))
297 {
298 if(menu_flg < MENU_MAX)
299 {
300 passby_ggid[menu_flg-1] ^= TRUE;
301 }
302 else
303 {
304 keep_flg ^= TRUE;
305 }
306 }
307 }
308
309 /*---------------------------------------------------------------------------*
310 Name: ModeSelect
311
312 Description: Processing in parent/child selection screen.
313
314 Arguments: None.
315
316 Returns: None.
317 *---------------------------------------------------------------------------*/
ModeSelect(void)318 static void ModeSelect(void)
319 {
320 BgPutString(3, 1, WHITE, "Push A to start");
321
322 if (keyData & PAD_BUTTON_A)
323 {
324 User_Init();
325 }
326 }
327
328 /*---------------------------------------------------------------------------*
329 Name: ModeError
330
331 Description: Processing in error display screen.
332
333 Arguments: None.
334
335 Returns: None.
336 *---------------------------------------------------------------------------*/
ModeError(void)337 static void ModeError(void)
338 {
339 BgPutString(5, 0, WHITE, "======= ERROR! =======");
340 BgPutString(5, 1, WHITE, " Fatal error occured.");
341 BgPutString(5, 2, WHITE, "Please reboot program.");
342 }
343
344 /*---------------------------------------------------------------------------*
345 Name: VBlankIntr
346
347 Description: V-Blank interrupt handler.
348
349 Arguments: None.
350
351 Returns: None.
352 *---------------------------------------------------------------------------*/
VBlankIntr(void)353 static void VBlankIntr(void)
354 {
355 //---- OAM updating
356 DC_FlushRange(oamBak, sizeof(oamBak));
357 /* I/O register is accessed using DMA operation, so cache wait is not needed */
358 // DC_WaitWriteBufferEmpty();
359 MI_DmaCopy32(3, oamBak, (void *)HW_OAM, sizeof(oamBak));
360
361 //---- background screen update
362 BgScrSetVblank();
363
364 //(void)rand();
365
366 //---- Interrupt check flag
367 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
368 }
369
370 /*---------------------------------------------------------------------------*
371 Name: InitializeAllocateSystem
372
373 Description: Initializes the memory allocation system within the main memory arena.
374
375 Arguments: None.
376
377 Returns: None.
378 *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)379 static void InitializeAllocateSystem(void)
380 {
381 void *tempLo;
382 OSHeapHandle hh;
383
384 OS_Printf(" arena lo = %08x\n", OS_GetMainArenaLo());
385 OS_Printf(" arena hi = %08x\n", OS_GetMainArenaHi());
386
387 tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
388 OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
389 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
390 if (hh < 0)
391 {
392 OS_Panic("ARM9: Fail to create heap...\n");
393 }
394 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
395 }
396
397
398 /*----------------------------------------------------------------------------*
399
400 /*---------------------------------------------------------------------------*
401 End of file
402 *---------------------------------------------------------------------------*/
403