/*---------------------------------------------------------------------------* Project: WPAD demo program File: sync.c Programmer: Eugene Kwon Copyright (C) 2005-2006 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. $Log: sync-callback.c,v $ Revision 1.4 08/15/2006 08:55:56 tojo (none) Revision 1.3 06/16/2006 14:10:56 ekwon Ensured that WPADProbe() is used to check channel status and to update device type. Revision 1.2 06/15/2006 13:50:00 tojo Removed DOLPHIN. Added WPAD_CLEAR_EVT_BUSY. Revision 1.1 06/14/2006 11:39:45 ekwon Demonstrates use of the SYNC and CLEAR callbacks. Also demonstrates how to retrieve number of registered devicesl *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps. #include #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 #define FONT_HEIGHT 9 /*---------------------------------------------------------------------------* * Function prototypes *---------------------------------------------------------------------------*/ // MEM2 memory allocation routines. The application must provide these to // WPAD, so it can setup the data transfer buffer. This buffer must reside // in MEM2. static void *myAlloc (u32 size); static u8 myFree (void *ptr); // The sync and clear callbacks are optional; applications can register // callbacks to receive notifications for sync/clear events. static void syncCallback (s32 result, s32 num); static void clearCallback (s32 result); // internal functions static void initialize (void); static void renderStatus (void); static void printBuffer (char *string, ...); /*---------------------------------------------------------------------------* * Local Data *---------------------------------------------------------------------------*/ #define BUFFER_SIZE_BYTES 128 static char __buffer[BUFFER_SIZE_BYTES]; /*===========================================================================* * F U N C T I O N D E F I N I T I O N S *===========================================================================*/ /*---------------------------------------------------------------------------* * Name : main() * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ int main( void ) { s32 wpad_state; initialize(); // - We must now register memory allocation/free functions // for MEM2. // - WPAD requires some memory in MEM2 for data transfers // between the controller and WPAD driver stack. // - Memory allocation only occurs once, at the initialization. // - Memory usage is on the order of 1KB. // - NOTE: We are using the MEM library allocators defined by // the DEMO library. // WPADRegisterAllocator(myAlloc, myFree); // Initialize WPAD! WPADInit(); // The WPAD initialization process is asynchronous. // So we should wait until it's completed. do { wpad_state = WPADGetStatus(); } while (WPAD_STATE_SETUP != wpad_state); // Register our callback. The callback will be invoked when // the user presses the "Sync" button on the console/dev kit. WPADSetSyncDeviceCallback(syncCallback); // Register our callback. The callback will be invoked when // the user presses AND HOLDS the "Sync" button for longer // than 10 seconds or so. WPADSetClearDeviceCallback(clearCallback); while(1) { DEMOBeforeRender(); renderStatus(); DEMODoneRender(); } } // end main() /*---------------------------------------------------------------------------* * Name : myAlloc() * Description : Callback needed by WPAD to allocate mem from MEM2 heap * Arguments : size of block, in bytes. * Returns : pointer to allocated block. *---------------------------------------------------------------------------*/ static void *myAlloc(u32 size) { void *ptr; ptr = MEMAllocFromAllocator(&DemoAllocator2, size); ASSERTMSG(ptr, "Memory allocation failed\n"); return(ptr); } // myAlloc() /*---------------------------------------------------------------------------* * Name : myFree() * Description : Callback needed by WPAD to free mem from MEM2 heap * Arguments : None. * Returns : Always 1. *---------------------------------------------------------------------------*/ static u8 myFree(void *ptr) { MEMFreeToAllocator(&DemoAllocator2, ptr); // we should ensure that memory is free'd properly, but oh well return(1); } // myFree() /*---------------------------------------------------------------------------* * Name : syncCallback() * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void syncCallback(s32 result, s32 num) { #pragma unused(num) switch (result) { case WPAD_SYNC_EVT_BUSY: printBuffer(">> SYNC already in progress."); break; case WPAD_SYNC_EVT_START: printBuffer(">> SYNC process starting..."); // Because we registered a callback for the SYNC button-press // event, we are responsible for invoking the SYNC process. // If we do not register a callback, WPAD will start the process // automatically. if (FALSE == WPADStartSyncDevice()) { printBuffer(">> SYNC Request Failed!"); } break; case WPAD_SYNC_EVT_DONE: // When complete, this callback will be invoked with the number // of devices that were paired during the SYNC process. printBuffer(">> SYNC complete."); break; default: printBuffer(">> SYNC ERROR: 0x%08X", result); break; } // end switch } // end syncCallback() /*---------------------------------------------------------------------------* * Name : clearCallback() * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void clearCallback(s32 result) { switch (result) { case WPAD_CLEAR_EVT_BUSY: printBuffer(">> CLEAR already in progress."); break; case WPAD_CLEAR_EVT_START: printBuffer(">> CLEAR process starting..."); // Again, because we have registered a callback, we are // responsible for invoking the clearing process. // If no callback is registered, WPAD will do this // automatically. WPADStartClearDevice(); break; case WPAD_CLEAR_EVT_DONE: printBuffer(">> All devices cleared."); break; default: printBuffer(">> CLEAR ERROR: Unknown result 0x%08X", result); break; } // end switch } // end clearCallback() /*---------------------------------------------------------------------------* * Name : renderStatus() * Description : Prints interesting data from WPADStatus. * Arguments : Pointer to current WPADStatus. * Returns : None. *---------------------------------------------------------------------------*/ static void renderStatus(void) { s32 i; s16 y; u8 num_paired; s32 status; u32 type; // Retrieve the number of devices currently paired to // to this host num_paired = WPADGetRegisteredDevNum(); y = FONT_HEIGHT; DEMOPrintf(5, y, 0, "SYNC/CLEAR Demo"); y += FONT_HEIGHT; y += FONT_HEIGHT; DEMOPrintf(5, y, 0, "Connect Status"); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, "--------------"); for (i=0; i> There are %2d devices currently <<", num_paired); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, ">> paired to this host. <<"); y += FONT_HEIGHT; y += FONT_HEIGHT; DEMOPrintf(5, y, 0, "- Press SYNC to start pairing. Then"); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, " press the SYNC button on the back"); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, " of the controller."); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, "- Hold SYNC for 10 seconds to CLEAR"); y += FONT_HEIGHT; DEMOPrintf(5, y, 0, " all devices."); y += FONT_HEIGHT; y += FONT_HEIGHT; DEMOPrintf(5, y, 0, __buffer); } // end renderStatus() static void printBuffer(char *string, ...) { va_list vlist; memset(__buffer, 0, BUFFER_SIZE_BYTES); va_start(vlist, string); vsprintf((char *)__buffer, string, vlist); va_end(vlist); } // clear and dump string to buffer /*---------------------------------------------------------------------------* * Name : initialize() * Description : Performs basic system initialization. * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void initialize( void ) { const GXColor DARKBLUE = { 0, 0, 40, 255 }; OSInit(); DEMOInit( &GXNtsc480IntDf ); GXSetCopyClear( DARKBLUE, GX_MAX_Z24 ); GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE ); DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT ); GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode memset(__buffer, 0, BUFFER_SIZE_BYTES); } // end