/*---------------------------------------------------------------------------* Project: HIO2 demos - dual File: dual-main.c (C)2005 HUDSON SOFT $Header: /home/cvsroot/SDK/build/demos/hio2demo/src/dual-main.c,v 1.3 2006/08/16 08:13:07 mitu Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include "Hio2If.h" #include "dual.h" //----------------------------------------------------------------------------- // define // Coordinates for DEMORFPrintf() #define POS_COMM_X 32 #define POS_COL_X 48 #define POS_TITLE_Y 64 #define POS_R_Y 96 #define POS_G_Y 128 #define POS_B_Y 160 #define POS_RECV_Y 352 #define POS_SEND_Y 384 #define POS_V_Y 416 #define POS_CONNECT_X 200 #define POS_CONNECT_Y 416 #define POS_STAT_X 512 #define POS_RECV_STAT_Y POS_R_Y #define POS_SEND_STAT_Y POS_G_Y #define POS_SYNC_X POS_STAT_X #define POS_SYNC_Y POS_CONNECT_Y //----------------------------------------------------------------------------- // Type definition // Type for calling the HIO2IF API, based on the presence of a PROTOCOL_USED specification typedef HIO2IF_RESULT (* MYREAD)(HIO2IF_ID id, u32 addr, void* buffer, s32 size, BOOL async); typedef HIO2IF_RESULT (* MYWRITE)(HIO2IF_ID id, u32 addr, void* buffer, s32 size, BOOL async); //----------------------------------------------------------------------------- // Local symbol definition // Information to reference/set for Paint Box display static u32 dwFbWidth, dwFbSize; static GXColor gxColor = { 0, 0, 0, 0 }; // Host I/O API buffer static u8 rgbBuffer[DUAL_BUFFER_SIZE] ATTRIBUTE_ALIGN(32); // Color data static const GXColor gxFont = { 0xFF, 0xFF, 0xFF, 0 }, gxBg = { 0, 0, 0, 0 }; // HIO2IF ID static HIO2IF_ID hioRecvID = HIO2IF_INVALID_ID, hioSendID = HIO2IF_INVALID_ID; // Synchronous, asynchronous controls static BOOL hioAsync = FALSE; // Connection-related information volatile const char* pRecvStatus = "NOT FIND"; volatile const char* pSendStatus = "NOT FIND"; #ifdef PROTOCOL_USED volatile BOOL bReceived = FALSE; volatile BOOL bSendPossible = TRUE; #else // PROTOCOL_USED #define bReceived TRUE #define bSendPossible TRUE #endif // PROTOCOL_USED // V counter static u32 dwVCounter = 0; #ifdef PROTOCOL_USED static const char* strProtocol = "protocol used"; #else // PROTOCOL_USED static const char* strProtocol = "non protocol"; #endif // PROTOCOL_USED //----------------------------------------------------------------------------- // Local function definition static void myAppInit(void); static void myHioInit(void); static void myHioExit(void); static u32 myMakeColor(void); static void myPaintBox(void); static void myDispInfo(void); static inline void myHalt(void) { OSFatal(gxFont, gxBg, HIO2IFGetErrorMessage()); } static inline BOOL myIsConnect(void) { return (HIO2IFIsConnected(hioRecvID) | HIO2IFIsConnected(hioSendID)); } /////////////////////////////////////////////////////////////////////////////// // // Event callback // static void myEventCallback(HIO2IF_ID id, HIO2IF_EVENT event) { switch ( event ) { case HIO2IF_EVENT_CONNECT: // Establish connection #ifdef HIO2IF_DEBUG OSReport("EVENT CONNECT : id(%d) hioRecvID(%d) hioSendID(%d)\n", id, hioRecvID, hioSendID); #endif if ( id == hioRecvID ) pRecvStatus = "CONNECT"; else pSendStatus = "CONNECT"; break; case HIO2IF_EVENT_DISCONNECT: // connection released #ifdef HIO2IF_DEBUG OSReport("EVENT DISCONNECT : id(%d) hioRecvID(%d) hioSendID(%d)\n", id, hioRecvID, hioSendID); #endif if ( id == hioRecvID ) pRecvStatus = "DISCONNECT"; else pSendStatus = "DISCONNECT"; (void)HIO2IFClose(id); gxColor.r = gxColor.g = gxColor.b = 0; break; #ifdef PROTOCOL_USED case HIO2IF_EVENT_RECEIVED: // Receive data bReceived = TRUE; break; case HIO2IF_EVENT_SEND_POSSIBLE: // send possible bSendPossible = TRUE; break; #endif // PROTOCOL_USED case HIO2IF_EVENT_READ_ASYNC_DONE: gxColor.r = rgbBuffer[DUAL_DATA_IDX_RED]; gxColor.g = rgbBuffer[DUAL_DATA_IDX_GREEN]; gxColor.b = rgbBuffer[DUAL_DATA_IDX_BLUE]; break; case HIO2IF_EVENT_WRITE_ASYNC_DONE: break; case HIO2IF_EVENT_INTERRUPT: myHalt(); break; } } /////////////////////////////////////////////////////////////////////////////// // // dual-main function // //----------------------------------------------------------------------------- void main(void) { MYREAD hioIfRead; MYWRITE hioIfWrite; // Initialization myAppInit(); // Change communication method depending on the build method #ifdef PROTOCOL_USED hioIfRead = HIO2IFRead; hioIfWrite = HIO2IFWrite; #else // PROTOCOL_USED hioIfRead = HIO2IFReadFree; hioIfWrite = HIO2IFWriteFree; #endif // PROTOCOL_USED // Host I/O initialization myHioInit(); while ( 1 ) { HIO2IF_RESULT result; u32 recvStat = 0, sendStat = 0; // Display communication state (void)HIO2IFReadStatus(hioRecvID, &recvStat); (void)HIO2IFReadStatus(hioSendID, &sendStat); (void)DEMORFPrintf(POS_STAT_X, POS_RECV_STAT_Y, 0, "R:%04X", recvStat); (void)DEMORFPrintf(POS_STAT_X, POS_SEND_STAT_Y, 0, "S:%04X", sendStat); // Controller input DEMOPadRead(); // Connect when A Button is pressed // End connection when B Button is pressed // Switch between SYNC and ASYNC modes when the X Button is pressed if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A ) myHioInit(); else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_B ) myHioExit(); else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_X ) hioAsync=!hioAsync; // Perform receive process when connected to PC if ( bReceived && HIO2IFIsConnected(hioRecvID) ) { // Receive from PC result = hioIfRead(hioRecvID, DUAL_PC2NNGC_ADDR, rgbBuffer, DUAL_BUFFER_SIZE, hioAsync); if ( HIO2IF_FAILED(result) ) myHalt(); #ifdef PROTOCOL_USED bReceived = FALSE; #endif // PROTOCOL_USED // If data has been received, reflect in color data for Paint Box if ( HIO2IF_SUCCESS(result) && !hioAsync ) { gxColor.r = rgbBuffer[DUAL_DATA_IDX_RED]; gxColor.g = rgbBuffer[DUAL_DATA_IDX_GREEN]; gxColor.b = rgbBuffer[DUAL_DATA_IDX_BLUE]; } } // Send current color data to the PC when connected if ( bSendPossible && HIO2IFIsConnected(hioSendID) ) { rgbBuffer[DUAL_DATA_IDX_RED] = gxColor.r; rgbBuffer[DUAL_DATA_IDX_GREEN] = gxColor.g; rgbBuffer[DUAL_DATA_IDX_BLUE] = gxColor.b; result = hioIfWrite(hioSendID, DUAL_NNGC2PC_ADDR, rgbBuffer, DUAL_BUFFER_SIZE, hioAsync); if ( HIO2IF_FAILED(result) ) myHalt(); #ifdef PROTOCOL_USED bSendPossible = FALSE; #endif // PROTOCOL_USED } DEMOBeforeRender(); // Paint Box update myPaintBox(); // Display information update myDispInfo(); DEMODoneRender(); dwVCounter++; // Sync HIO2IFSync(); } } //---------------------------------------------------------------------------- static void myAppInit(void) { GXRenderModeObj* rmp; DEMOInit(NULL); // DEMORFPrintf() initialization (void)DEMOInitROMFont(); rmp = DEMOGetRenderModeObj(); DEMOInitCaption(DM_FT_OPQ, (s16) rmp->fbWidth, (s16) rmp->efbHeight); DEMOSetFontType(DM_FT_OPQ); // Screen initialization GXSetCopyClear(gxBg, 0x00ffffff); GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE); // Paint Box display initialization dwFbWidth = (u32)(VIPadFrameBufferWidth(rmp->fbWidth) * VI_DISPLAY_PIX_SZ ); dwFbSize = (u32)(dwFbWidth * rmp->xfbHeight); // Controller initialization DEMOPadInit(); } //---------------------------------------------------------------------------- static void myHioInit(void) { int count; if ( myIsConnect() ) return; // Host I/O initialization if ( HIO2IF_FAILED(HIO2IFInit()) ) myHalt(); // Gets the number of enumerated devices count = HIO2IFGetDeviceCount(); // Receive channel open if ( count > 0 ) { if ( HIO2IF_FAILED(HIO2IFOpen( HIO2IFGetDevice(0), HIO2IF_MODE_RDONLY, myEventCallback, &hioRecvID)) ) myHalt(); pRecvStatus = "DISCONNECT"; #ifdef PROTOCOL_USED bReceived = FALSE; #endif } // Send channel open if ( count > 1 ) { if ( HIO2IF_FAILED(HIO2IFOpen( HIO2IFGetDevice(1), HIO2IF_MODE_WRONLY, myEventCallback, &hioSendID)) ) myHalt(); pSendStatus = "DISCONNECT"; #ifdef PROTOCOL_USED bSendPossible = TRUE; #endif } } //---------------------------------------------------------------------------- static void myHioExit(void) { if ( HIO2IFIsConnected(hioRecvID) ) { (void)HIO2IFClose(hioRecvID); pRecvStatus = "DISCONNECT"; #ifdef PROTOCOL_USED bReceived = FALSE; #endif } if ( HIO2IFIsConnected(hioSendID) ) { (void)HIO2IFClose(hioSendID); pSendStatus = "DISCONNECT"; #ifdef PROTOCOL_USED bSendPossible = FALSE; #endif } gxColor.r = gxColor.g = gxColor.b = 0; } //---------------------------------------------------------------------------- u32 myMakeColor(void) { #define CLAMP(x,l,h) ((x > h) ? h : ((x < l) ? l : x)) u32 colY , colCr , colCb , colVal; double Y,Cr,Cb; Y = 0.257 * gxColor.r + 0.504 * gxColor.g + 0.098 * gxColor.b + 16.0 + 0.5; Cb = -0.148 * gxColor.r - 0.291 * gxColor.g + 0.439 * gxColor.b + 128.0 + 0.5; Cr = 0.439 * gxColor.r - 0.368 * gxColor.g - 0.071 * gxColor.b + 128.0 + 0.5; Y = CLAMP(Y , 16, 235); Cb = CLAMP(Cb, 16, 240); Cr = CLAMP(Cr, 16, 240); colY = (u32)Y; colCr = (u32)Cr; colCb = (u32)Cb; colVal = (colY << 24) | (colCb << 16) | (colY << 8) | colCr; return colVal; } //---------------------------------------------------------------------------- static void myPaintBox(void) { u32 x=96, y=128, w=128, h=192, col = myMakeColor(); u32 pixSize = (VI_DISPLAY_PIX_SZ << 1), lineSize = pixSize * w, i; u8* xfb = VIGetNextFrameBuffer(); for (i=0; i