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