1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WXC - demos - wxc-dataShare
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 #include <nitro.h>
20 
21 #include <nitro/wxc.h>
22 
23 #include "user.h"
24 #include "common.h"
25 #include "disp.h"
26 #include "gmain.h"
27 #include "wh.h"
28 
29 void VBlankIntr(void);          // V-Blank interrupt handler
30 
31 /*---------------------------------------------------------------------------*
32     Constant Definitions
33  *---------------------------------------------------------------------------*/
34 #define     KEY_REPEAT_START    25     // Number of frames until key repeat starts
35 #define     KEY_REPEAT_SPAN     10     // Number of frames between key repeats
36 
37 #define     PICTURE_FRAME_PER_GAME_FRAME    2
38 
39 
40 /* GGID used for testing */
41 #define SDK_MAKEGGID_SYSTEM(num)              (0x003FFF00 | (num))
42 #define GGID_ORG_1                            SDK_MAKEGGID_SYSTEM(0x52)
43 
44 /* GGID used for this Sharing */
45 #define WH_GGID                 SDK_MAKEGGID_SYSTEM(0x21)
46 
47 /*---------------------------------------------------------------------------*
48     Structure Definitions
49  *---------------------------------------------------------------------------*/
50 // Key input data
51 typedef struct KeyInfo
52 {
53     u16     cnt;                       // Unprocessed input value
54     u16     trg;                       // Push trigger input
55     u16     up;                        // Release trigger input
56     u16     rep;                       // Press and hold repeat input
57 
58 }
59 KeyInfo;
60 
61 
62 /*---------------------------------------------------------------------------*
63     Internal Function Definitions
64  *---------------------------------------------------------------------------*/
65 static void ModeSelect(void);          // Parent/child select screen
66 static void ModeError(void);           // Error display screen
67 
68 
69 // General purpose subroutines
70 static void KeyRead(KeyInfo * pKey);
71 static void InitializeAllocateSystem(void);
72 
73 static void GetMacAddress(u8 * macAddr, u16 * gScreen);
74 
75 
76 static void ModeConnect();
77 static void ModeWorking(void);
78 
79 /*---------------------------------------------------------------------------*
80     Internal Variable Definitions
81  *---------------------------------------------------------------------------*/
82 static KeyInfo gKey;                   // Key input
83 static vs32 gPictureFrame;             // Picture frame counter
84 
85 
86 /*---------------------------------------------------------------------------*
87     External Variable Definitions
88  *---------------------------------------------------------------------------*/
89 int passby_endflg;
90 WMBssDesc bssdesc;
91 WMParentParam parentparam;
92 u8 macAddress[6];
93 
94 
95 static void WaitPressButton(void);
96 static void GetChannelMain(void);
97 static BOOL ConnectMain(u16 tgid);
98 static void PrintChildState(void);
99 static BOOL JudgeConnectableChild(WMStartParentCallback *cb);
100 
101 
102 //============================================================================
103 //   Variable Definitions
104 //============================================================================
105 
106 static s32 gFrame;                     // Frame counter
107 
108 //============================================================================
109 //   Function Definitions
110 //============================================================================
111 
112 /*---------------------------------------------------------------------------*
113   Name:         VBlankIntr
114 
115   Description:  Gets key trigger.
116 
117   Arguments:    None.
118 
119   Returns:      None.
120  *---------------------------------------------------------------------------*/
VBlankIntr(void)121 void VBlankIntr(void)
122 {
123     // Increment picture frame counter
124     gPictureFrame++;
125 
126     // Repeat rendering to match game frame
127     if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME))
128     {
129         DispVBlankFunc();
130     }
131 
132     //---- Interrupt check flag
133     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
134 }
135 
136 /*---------------------------------------------------------------------------*
137   Name:         NitroMain
138 
139   Description:  Main routine.
140 
141   Arguments:    None.
142 
143   Returns:      None.
144  *---------------------------------------------------------------------------*/
NitroMain(void)145 void NitroMain(void)
146 {
147     u16 tgid = 0;
148 
149     // Initialize screen and OS
150     CommonInit();
151     // Initialize screen
152     DispInit();
153     // Initialize the heap
154     InitAllocateSystem();
155 
156     // Enable interrupts
157     (void)OS_EnableIrq();
158     (void)OS_EnableInterrupts();
159 
160     OS_InitTick();
161     FX_Init();
162 
163     DispOn();
164 
165     passby_endflg = 0;
166 
167     /* Initializes, registers, and runs chance encounter communications */
168     User_Init();
169 
170     for (gFrame = 0; passby_endflg == 0; gFrame++)
171     {
172         /* Get key input data */
173         KeyRead(&gKey);
174 
175         // Clear the screen
176         BgClear();
177 
178         /* Distributes processes based on communication status */
179         switch (WXC_GetStateCode())
180         {
181         case WXC_STATE_END:
182             ModeSelect();
183             break;
184         case WXC_STATE_ENDING:
185             break;
186         case WXC_STATE_ACTIVE:
187             if(WXC_IsParentMode() == TRUE)
188             {
189                 BgPutString(9, 2, 0x2, "Now parent...");
190             }
191             else
192             {
193                 BgPutString(9, 2, 0x2, "Now child...");
194             }
195             break;
196         }
197         if (gKey.trg & PAD_BUTTON_START)
198         {
199             (void)WXC_End();
200         }
201 
202         // Waiting for the V-Blank
203         OS_WaitVBlankIntr();
204     }
205 
206     (void)WXC_End();
207 
208     // Wait for WXC_End to complete
209     while( WXC_GetStateCode() != WXC_STATE_END )
210     {
211         ;
212     }
213 
214     // Variable initialization
215     gPictureFrame = 0;
216 
217     // Set buffer for data sharing communication
218     GInitDataShare();
219 
220     // Initialize wireless
221     if( WH_Initialize() == FALSE )
222     {
223         OS_Printf("\n WH_Initialize() ERROR!!\n");
224     }
225 
226     if(passby_endflg == 1)
227     {
228         WH_SetGgid(WH_GGID);
229 
230         // Set the function to determine connected children
231         WH_SetJudgeAcceptFunc(JudgeConnectableChild);
232 
233         /* Main routine */
234         for (gFrame = 0; TRUE; gFrame++)
235         {
236             BgClear();
237 
238             switch (WH_GetSystemState())
239             {
240             case WH_SYSSTATE_IDLE:
241                 (void)WH_ParentConnect(WH_CONNECTMODE_DS_PARENT, (u16)(parentparam.tgid+1), parentparam.channel);
242                 break;
243 
244             case WH_SYSSTATE_CONNECTED:
245             case WH_SYSSTATE_KEYSHARING:
246             case WH_SYSSTATE_DATASHARING:
247                 {
248                     BgPutString(8, 1, 0x2, "Parent mode");
249                     if(GStepDataShare(gPictureFrame) == FALSE)
250                     {
251                         gPictureFrame--;
252                     }
253                     GMain();
254                 }
255                 break;
256             }
257 
258             // Wait for completion of multiple cycles of picture frames
259             while (TRUE)
260             {
261                 // Wait for V-Blank
262                 OS_WaitVBlankIntr();
263                 if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME))
264                 {
265                     break;
266                 }
267             }
268         }
269     }
270     else
271     {
272         OS_Printf("\nmacAddress = %02X:%02X:%02X:%02X:%02X:%02X\n", bssdesc.bssid[0],bssdesc.bssid[1],bssdesc.bssid[2],bssdesc.bssid[3],bssdesc.bssid[4],bssdesc.bssid[5]);
273 
274         bssdesc.gameInfo.tgid++;
275 
276         // Main loop
277         for (gFrame = 0; TRUE; gFrame++)
278         {
279             // Clear the screen
280             BgClear();
281 
282             // Distributes processes based on communication status
283             switch (WH_GetSystemState())
284             {
285             case WH_SYSSTATE_CONNECT_FAIL:
286                 {
287                     // Because the internal WM state is invalid if the WM_StartConnect function fails, WM_Reset must be called once to reset the state to IDLE
288                     //
289                     WH_Reset();
290                 }
291                 break;
292             case WH_SYSSTATE_IDLE:
293                 {
294                     static retry = 0;
295                     enum
296                     {
297                         MAX_RETRY = 30
298                     };
299 
300                     if (retry < MAX_RETRY)
301                     {
302                         ModeConnect(bssdesc.bssid);
303                         retry++;
304                         break;
305                     }
306                     // If connection to parent is not possible after MAX_RETRY, display ERROR
307                 }
308             case WH_SYSSTATE_ERROR:
309                 ModeError();
310                 break;
311             case WH_SYSSTATE_BUSY:
312             case WH_SYSSTATE_SCANNING:
313                 ModeWorking();
314                 break;
315 
316             case WH_SYSSTATE_CONNECTED:
317             case WH_SYSSTATE_KEYSHARING:
318             case WH_SYSSTATE_DATASHARING:
319                 {
320                     BgPutString(8, 1, 0x2, "Child mode");
321                     if(GStepDataShare(gPictureFrame) == FALSE)
322                     {
323                         gPictureFrame--;
324                     }
325                     GMain();
326                 }
327                 break;
328             }
329 
330             // Display of signal strength
331             {
332                 int level;
333                 level = WH_GetLinkLevel();
334                 BgPrintStr(31, 23, 0xf, "%d", level);
335             }
336 
337             // Wait for completion of multiple cycles of picture frames
338             while (TRUE)
339             {
340                 // Wait for V-Blank
341                 OS_WaitVBlankIntr();
342                 if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME))
343                 {
344                     break;
345                 }
346             }
347         }
348     }
349 }
350 
351 
352 /*---------------------------------------------------------------------------*
353   Name:         ModeSelect
354 
355   Description:  Processing in parent/child selection screen.
356 
357   Arguments:    None.
358 
359   Returns:      None.
360  *---------------------------------------------------------------------------*/
ModeSelect(void)361 static void ModeSelect(void)
362 {
363     BgPutString(3, 1, 0x2, "Push A to start");
364 
365     if (gKey.trg & PAD_BUTTON_A)
366     {
367         //********************************
368         User_Init();
369         //********************************
370     }
371 }
372 
373 /*---------------------------------------------------------------------------*
374   Name:         ModeError
375 
376   Description:  Processing in error display screen.
377 
378   Arguments:    None.
379 
380   Returns:      None.
381  *---------------------------------------------------------------------------*/
ModeError(void)382 static void ModeError(void)
383 {
384     BgPutString(5, 10, 0x2, "======= ERROR! =======");
385     BgPutString(5, 13, 0x2, " Fatal error occured.");
386     BgPutString(5, 14, 0x2, "Please reboot program.");
387 }
388 
389 
390 /*---------------------------------------------------------------------------*
391   Name:         KeyRead
392 
393   Description:  Edits key input data.
394                 Detects press trigger, release trigger, and press-and-hold repeat.
395 
396   Arguments:    pKey: Structure that holds key input data to be edited
397 
398   Returns:      None.
399  *---------------------------------------------------------------------------*/
KeyRead(KeyInfo * pKey)400 static void KeyRead(KeyInfo * pKey)
401 {
402     static u16 repeat_count[12];
403     int     i;
404     u16     r;
405 
406     r = PAD_Read();
407     pKey->trg = 0x0000;
408     pKey->up = 0x0000;
409     pKey->rep = 0x0000;
410 
411     for (i = 0; i < 12; i++)
412     {
413         if (r & (0x0001 << i))
414         {
415             if (!(pKey->cnt & (0x0001 << i)))
416             {
417                 pKey->trg |= (0x0001 << i);     // Press trigger
418                 repeat_count[i] = 1;
419             }
420             else
421             {
422                 if (repeat_count[i] > KEY_REPEAT_START)
423                 {
424                     pKey->rep |= (0x0001 << i); // Press-and-hold repeat
425                     repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
426                 }
427                 else
428                 {
429                     repeat_count[i]++;
430                 }
431             }
432         }
433         else
434         {
435             if (pKey->cnt & (0x0001 << i))
436             {
437                 pKey->up |= (0x0001 << i);      // Release trigger
438             }
439         }
440     }
441     pKey->cnt = r;                     // Unprocessed key input
442 }
443 
444 /*---------------------------------------------------------------------------*
445   Name:         JudgeConnectableChild
446 
447   Description:  Determines if the child is connectable during reconnect.
448 
449   Arguments:    cb: Information for the child attempting to connect
450 
451   Returns:      If connection is accepted, TRUE.
452                 If not accepted, FALSE.
453  *---------------------------------------------------------------------------*/
JudgeConnectableChild(WMStartParentCallback * cb)454 static BOOL JudgeConnectableChild(WMStartParentCallback *cb)
455 {
456     if (cb->macAddress[0] != macAddress[0] || cb->macAddress[1] != macAddress[1] ||
457         cb->macAddress[2] != macAddress[2] || cb->macAddress[3] != macAddress[3] ||
458         cb->macAddress[4] != macAddress[4] || cb->macAddress[5] != macAddress[5] )
459     {
460         return FALSE;
461     }
462 
463     return TRUE;
464 }
465 
466 /*---------------------------------------------------------------------------*
467   Name:         ModeConnect
468 
469   Description:  Connection start.
470 
471   Arguments:    None.
472 
473   Returns:      None.
474  *---------------------------------------------------------------------------*/
ModeConnect()475 static void ModeConnect()
476 {
477     WH_SetGgid(WH_GGID);
478     //********************************
479     (void)WH_ChildConnectAuto(WH_CONNECTMODE_DS_CHILD, bssdesc.bssid,
480                               bssdesc.channel);
481     //********************************
482 }
483 
484 /*---------------------------------------------------------------------------*
485   Name:         ModeWorking
486 
487   Description:  Displays working screen.
488 
489   Arguments:    None.
490 
491   Returns:      None.
492  *---------------------------------------------------------------------------*/
ModeWorking(void)493 static void ModeWorking(void)
494 {
495     BgPrintStr(9, 11, 0xf, "Now working...");
496 }
497