/*---------------------------------------------------------------------------* Project: WPAD demo program File: extension.c 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: handling.c,v $ Revision 1.6 08/03/2006 13:33:02 tojo Removed old APIs. Revision 1.5 07/20/2006 06:40:28 tojo (none) Revision 1.4 06/17/2006 12:56:54 ekwon Added explicit demonstration of handling sampling callback and auto-sampling buffer registratiion for various events. Revision 1.3 06/16/2006 14:01:25 ekwon Added scrolling debug buffer. Completed event handling. NOTE: Classic controller support is pending, as I don't have one of those yet. Revision 1.2 06/15/2006 13:47:44 tojo Removed DOLPHIN. Swept warnings. Revision 1.1 06/15/2006 04:25:35 ekwon preliminary checkins for event handling demos. *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps. #include /*---------------------------------------------------------------------------* * Local Definitions *---------------------------------------------------------------------------*/ #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 #define FONT_HEIGHT 8 /*---------------------------------------------------------------------------* * Local Data *---------------------------------------------------------------------------*/ #define SMPBUF_SIZE 100 static WPADFSStatus fs_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE]; static WPADStatus co_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE]; /*---------------------------------------------------------------------------* * 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); // sampling callback void samplingCallback (s32 chan); // callbacks for CONNECT and EXTENSION events void connectCallback (s32 chan, s32 reason); void extensionCallback (s32 chan, s32 result); // internal functions static void initialize (void); static void renderStatus (void); static void printBuffer (char *string, ...); static u8 *get_dev_name (u32 type); static u8 *get_status_name (s32 status); static void renderAimings (void); /*===========================================================================* * 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 ) { int i; 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); for (i=0; ibutton & WPAD_BUTTON_LEFT ) buf1[ 0] = '<'; if( wpad_ptr->button & WPAD_BUTTON_UP ) buf1[ 1] = '^'; if( wpad_ptr->button & WPAD_BUTTON_DOWN ) buf1[ 2] = 'v'; if( wpad_ptr->button & WPAD_BUTTON_RIGHT ) buf1[ 3] = '>'; if( wpad_ptr->button & WPAD_BUTTON_START ) buf1[ 4] = 'S'; if( wpad_ptr->button & WPAD_BUTTON_SELECT ) buf1[ 5] = 'T'; if( wpad_ptr->button & WPAD_BUTTON_A ) buf1[ 6] = 'A'; if( wpad_ptr->button & WPAD_BUTTON_B ) buf1[ 7] = 'B'; if( wpad_ptr->button & WPAD_BUTTON_SMALL_A) buf2[ 0] = 'a'; if( wpad_ptr->button & WPAD_BUTTON_SMALL_B) buf2[ 1] = 'b'; if( wpad_ptr->button & WPAD_BUTTON_HOME ) buf2[ 2] = 'H'; DEMOPrintf(x, y, 0, " %s", buf1); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %s", buf2); y+= FONT_HEIGHT; y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->obj[0].x)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->obj[0].y)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->obj[1].x)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->obj[1].y)); y+= FONT_HEIGHT; y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->accX)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->accY)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(wpad_ptr->accZ)); y+= FONT_HEIGHT; y+= FONT_HEIGHT; if (WPAD_DEV_FREESTYLE == type) { DEMOPrintf(x, y, 0, " %04X", (u16)(fs_ptr->fsStickX)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(fs_ptr->fsStickY)); y+= FONT_HEIGHT; y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(fs_ptr->fsAccX)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(fs_ptr->fsAccY)); y+= FONT_HEIGHT; DEMOPrintf(x, y, 0, " %04X", (u16)(fs_ptr->fsAccZ)); y+= FONT_HEIGHT; y+= FONT_HEIGHT; } // if freestyle } // if no error } // for...WPAD_MAX_CONTROLLERS // for scrolling debug-message buffer // it's convenient to see past event messages... y = 300; line = __curr_line; for (i=0; i> %s", &__buffer[line][0]); line = (line + 1) % BUFFER_SIZE_LINES; y+= FONT_HEIGHT; } } // end renderStatus() static void printBuffer(char *string, ...) { va_list vlist; memset(&__buffer[__curr_line][0], 0, BUFFER_SIZE_BYTES); va_start(vlist, string); vsprintf((char *)(&__buffer[__curr_line][0]), string, vlist); va_end(vlist); __curr_line = (__curr_line + 1) % BUFFER_SIZE_LINES; } // clear and dump string to buffer static u8 *get_dev_name(u32 type) { u8 str_dev_core [] = " Core "; u8 str_dev_extn [] = " Extn "; u8 str_dev_cl [] = " Classic "; u8 str_dev_dol [] = " Dolphin "; u8 str_dev_unknown[] = " Unknwon "; u8 *ptr; switch(type) { case WPAD_DEV_CORE: ptr = &str_dev_core[0]; break; case WPAD_DEV_FREESTYLE: ptr = &str_dev_extn[0]; break; case WPAD_DEV_CLASSIC: ptr = &str_dev_cl[0]; break; case WPAD_DEV_UNKNOWN: default: ptr = &str_dev_unknown[0]; break; } // end switch return(ptr); } // end static u8 *get_status_name(s32 status) { u8 str_status_ok [] = " OK "; u8 str_status_none[] = " NONE "; u8 str_status_busy[] = " BUSY "; u8 str_status_xfer[] = " Transfer "; u8 str_status_inv [] = " INVALID "; u8 str_status_unk [] = " UNKNOWN "; u8 *ptr; switch(status) { case WPAD_ERR_NONE: ptr = &str_status_ok[0]; break; case WPAD_ERR_NO_CONTROLLER: ptr = &str_status_none[0]; break; case WPAD_ERR_BUSY: ptr = &str_status_busy[0]; break; case WPAD_ERR_TRANSFER: ptr = &str_status_xfer[0]; break; case WPAD_ERR_INVALID: ptr = &str_status_inv[0]; default: ptr = &str_status_unk[0]; break; } // end switch return(ptr); } // end 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*BUFFER_SIZE_LINES); } // end /*---------------------------------------------------------------------------* * Name : renderAimings() * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void renderAimings(void) { u32 latest; u32 index; int i; int j; u32 fmt; WPADStatus *co_ptr; WPADFSStatus *fs_ptr; for (j=0; j