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