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