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