/*---------------------------------------------------------------------------* Project: TwlSDK - WXC - demos - wxc-dataShare File: main.c Copyright 2005-2009 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2007-11-15#$ $Rev: 2414 $ $Author: hatamoto_minoru $ *---------------------------------------------------------------------------*/ #include #include #include "user.h" #include "common.h" #include "disp.h" #include "gmain.h" #include "wh.h" void VBlankIntr(void); // V-Blank interrupt handler /*---------------------------------------------------------------------------* Constant Definitions *---------------------------------------------------------------------------*/ #define KEY_REPEAT_START 25 // Number of frames until key repeat starts #define KEY_REPEAT_SPAN 10 // Number of frames between key repeats #define PICTURE_FRAME_PER_GAME_FRAME 2 /* GGID used for testing */ #define SDK_MAKEGGID_SYSTEM(num) (0x003FFF00 | (num)) #define GGID_ORG_1 SDK_MAKEGGID_SYSTEM(0x52) /* GGID used for this Sharing */ #define WH_GGID SDK_MAKEGGID_SYSTEM(0x21) /*---------------------------------------------------------------------------* Structure Definitions *---------------------------------------------------------------------------*/ // Key input data typedef struct KeyInfo { u16 cnt; // Unprocessed input value u16 trg; // Push trigger input u16 up; // Release trigger input u16 rep; // Press and hold repeat input } KeyInfo; /*---------------------------------------------------------------------------* Internal Function Definitions *---------------------------------------------------------------------------*/ static void ModeSelect(void); // Parent/child select screen static void ModeError(void); // Error display screen // General purpose subroutines static void KeyRead(KeyInfo * pKey); static void InitializeAllocateSystem(void); static void GetMacAddress(u8 * macAddr, u16 * gScreen); static void ModeConnect(); static void ModeWorking(void); /*---------------------------------------------------------------------------* Internal Variable Definitions *---------------------------------------------------------------------------*/ static KeyInfo gKey; // Key input static vs32 gPictureFrame; // Picture frame counter /*---------------------------------------------------------------------------* External Variable Definitions *---------------------------------------------------------------------------*/ int passby_endflg; WMBssDesc bssdesc; WMParentParam parentparam; u8 macAddress[6]; static void WaitPressButton(void); static void GetChannelMain(void); static BOOL ConnectMain(u16 tgid); static void PrintChildState(void); static BOOL JudgeConnectableChild(WMStartParentCallback *cb); //============================================================================ // Variable Definitions //============================================================================ static s32 gFrame; // Frame counter //============================================================================ // Function Definitions //============================================================================ /*---------------------------------------------------------------------------* Name: VBlankIntr Description: Gets key trigger. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void VBlankIntr(void) { // Increment picture frame counter gPictureFrame++; // Repeat rendering to match game frame if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME)) { DispVBlankFunc(); } //---- Interrupt check flag OS_SetIrqCheckFlag(OS_IE_V_BLANK); } /*---------------------------------------------------------------------------* Name: NitroMain Description: Main routine. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void NitroMain(void) { u16 tgid = 0; // Initialize screen and OS CommonInit(); // Initialize screen DispInit(); // Initialize the heap InitAllocateSystem(); // Enable interrupts (void)OS_EnableIrq(); (void)OS_EnableInterrupts(); OS_InitTick(); FX_Init(); DispOn(); passby_endflg = 0; /* Initializes, registers, and runs chance encounter communications */ User_Init(); for (gFrame = 0; passby_endflg == 0; gFrame++) { /* Get key input data */ KeyRead(&gKey); // Clear the screen BgClear(); /* Distributes processes based on communication status */ switch (WXC_GetStateCode()) { case WXC_STATE_END: ModeSelect(); break; case WXC_STATE_ENDING: break; case WXC_STATE_ACTIVE: if(WXC_IsParentMode() == TRUE) { BgPutString(9, 2, 0x2, "Now parent..."); } else { BgPutString(9, 2, 0x2, "Now child..."); } break; } if (gKey.trg & PAD_BUTTON_START) { (void)WXC_End(); } // Waiting for the V-Blank OS_WaitVBlankIntr(); } (void)WXC_End(); // Wait for WXC_End to complete while( WXC_GetStateCode() != WXC_STATE_END ) { ; } // Variable initialization gPictureFrame = 0; // Set buffer for data sharing communication GInitDataShare(); // Initialize wireless if( WH_Initialize() == FALSE ) { OS_Printf("\n WH_Initialize() ERROR!!\n"); } if(passby_endflg == 1) { WH_SetGgid(WH_GGID); // Set the function to determine connected children WH_SetJudgeAcceptFunc(JudgeConnectableChild); /* Main routine */ for (gFrame = 0; TRUE; gFrame++) { BgClear(); switch (WH_GetSystemState()) { case WH_SYSSTATE_IDLE: (void)WH_ParentConnect(WH_CONNECTMODE_DS_PARENT, (u16)(parentparam.tgid+1), parentparam.channel); break; case WH_SYSSTATE_CONNECTED: case WH_SYSSTATE_KEYSHARING: case WH_SYSSTATE_DATASHARING: { BgPutString(8, 1, 0x2, "Parent mode"); if(GStepDataShare(gPictureFrame) == FALSE) { gPictureFrame--; } GMain(); } break; } // Wait for completion of multiple cycles of picture frames while (TRUE) { // Wait for V-Blank OS_WaitVBlankIntr(); if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME)) { break; } } } } else { 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]); bssdesc.gameInfo.tgid++; // Main loop for (gFrame = 0; TRUE; gFrame++) { // Clear the screen BgClear(); // Distributes processes based on communication status switch (WH_GetSystemState()) { case WH_SYSSTATE_CONNECT_FAIL: { // 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 // WH_Reset(); } break; case WH_SYSSTATE_IDLE: { static retry = 0; enum { MAX_RETRY = 30 }; if (retry < MAX_RETRY) { ModeConnect(bssdesc.bssid); retry++; break; } // If connection to parent is not possible after MAX_RETRY, display ERROR } case WH_SYSSTATE_ERROR: ModeError(); break; case WH_SYSSTATE_BUSY: case WH_SYSSTATE_SCANNING: ModeWorking(); break; case WH_SYSSTATE_CONNECTED: case WH_SYSSTATE_KEYSHARING: case WH_SYSSTATE_DATASHARING: { BgPutString(8, 1, 0x2, "Child mode"); if(GStepDataShare(gPictureFrame) == FALSE) { gPictureFrame--; } GMain(); } break; } // Display of signal strength { int level; level = WH_GetLinkLevel(); BgPrintStr(31, 23, 0xf, "%d", level); } // Wait for completion of multiple cycles of picture frames while (TRUE) { // Wait for V-Blank OS_WaitVBlankIntr(); if (!(gPictureFrame % PICTURE_FRAME_PER_GAME_FRAME)) { break; } } } } } /*---------------------------------------------------------------------------* Name: ModeSelect Description: Processing in parent/child selection screen. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void ModeSelect(void) { BgPutString(3, 1, 0x2, "Push A to start"); if (gKey.trg & PAD_BUTTON_A) { //******************************** User_Init(); //******************************** } } /*---------------------------------------------------------------------------* Name: ModeError Description: Processing in error display screen. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void ModeError(void) { BgPutString(5, 10, 0x2, "======= ERROR! ======="); BgPutString(5, 13, 0x2, " Fatal error occured."); BgPutString(5, 14, 0x2, "Please reboot program."); } /*---------------------------------------------------------------------------* Name: KeyRead Description: Edits key input data. Detects press trigger, release trigger, and press-and-hold repeat. Arguments: pKey: Structure that holds key input data to be edited Returns: None. *---------------------------------------------------------------------------*/ static void KeyRead(KeyInfo * pKey) { static u16 repeat_count[12]; int i; u16 r; r = PAD_Read(); pKey->trg = 0x0000; pKey->up = 0x0000; pKey->rep = 0x0000; for (i = 0; i < 12; i++) { if (r & (0x0001 << i)) { if (!(pKey->cnt & (0x0001 << i))) { pKey->trg |= (0x0001 << i); // Press trigger repeat_count[i] = 1; } else { if (repeat_count[i] > KEY_REPEAT_START) { pKey->rep |= (0x0001 << i); // Press-and-hold repeat repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN; } else { repeat_count[i]++; } } } else { if (pKey->cnt & (0x0001 << i)) { pKey->up |= (0x0001 << i); // Release trigger } } } pKey->cnt = r; // Unprocessed key input } /*---------------------------------------------------------------------------* Name: JudgeConnectableChild Description: Determines if the child is connectable during reconnect. Arguments: cb: Information for the child attempting to connect Returns: If connection is accepted, TRUE. If not accepted, FALSE. *---------------------------------------------------------------------------*/ static BOOL JudgeConnectableChild(WMStartParentCallback *cb) { if (cb->macAddress[0] != macAddress[0] || cb->macAddress[1] != macAddress[1] || cb->macAddress[2] != macAddress[2] || cb->macAddress[3] != macAddress[3] || cb->macAddress[4] != macAddress[4] || cb->macAddress[5] != macAddress[5] ) { return FALSE; } return TRUE; } /*---------------------------------------------------------------------------* Name: ModeConnect Description: Connection start. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void ModeConnect() { WH_SetGgid(WH_GGID); //******************************** (void)WH_ChildConnectAuto(WH_CONNECTMODE_DS_CHILD, bssdesc.bssid, bssdesc.channel); //******************************** } /*---------------------------------------------------------------------------* Name: ModeWorking Description: Displays working screen. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void ModeWorking(void) { BgPrintStr(9, 11, 0xf, "Now working..."); }