/*---------------------------------------------------------------------------* Project: WiiConnect24 API demos File: MsgViewer.c Copyright 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: MsgViewer.c,v $ Revision 1.7 2008/05/30 02:27:03 seiki_masashi Reverted code consequent upon reverted SDK code. Revision 1.5 2008/05/01 08:50:26 hirose_kazuki Added "Close library" mode. Revision 1.4 2008/04/28 11:20:23 hirose_kazuki Updated framework. Revision 1.3 2008/01/21 10:39:05 hirose_kazuki Changed to suspend the scheduler by default. Modified main sequence to avoid calling OpenLib/CloseLib every frame. Revision 1.2 2007/02/02 02:20:33 torigoe_nobutaka Added OpenLib() and CloseLib(). Added handling of messages without subject or body text. Fixed bug in GetMsgIdList(). Revision 1.1 2006/09/27 08:57:45 torigoe_nobutaka Renamed from MessageViewer.c Moved from nwc24demo/src. Revision 1.4 2006/09/27 07:31:45 torigoe_nobutaka Improved performance. Revision 1.3 2006/09/13 08:14:22 yosizaki Changed to call VFInit(). Revision 1.2 2006/09/10 09:20:56 hirose_kazuki Changed to use NWC24OpenLib/NWC24CloseLib instead of obsolete functions. Revision 1.1 2006/08/28 08:51:51 torigoe_nobutaka Initial check in. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #define DEMO_USE_MEMLIB 1 #include #include "MsgViewer.h" #include "MsgViewerRender.h" #include "MsgViewerUpdate.h" /*---------------------------------------------------------------------------* Global variables *---------------------------------------------------------------------------*/ s16 g_screenWidth; s16 g_screenHeight; OSFontHeader* g_fontData = NULL; MsgBoxState g_state = MB_STATE_MENU; MsgBoxMenu g_selectedMenu = MB_MENU_RECV_BOX; u32* g_idListBuf[NUM_MSG_BOX_TYPES] = { NULL }; u32 g_numMsgs[NUM_MSG_BOX_TYPES] = { 0 }; u32 g_idxSelectedId[NUM_MSG_BOX_TYPES] = { 0 }; u32 g_idxIdTopOfList[NUM_MSG_BOX_TYPES] = { 0 }; u32 g_lineTopOfBodyText = 0; u32 g_numLinesBodyText = 1; char* g_subjectBuf[NUM_MSG_BOX_TYPES][LIST_BOX_ROWS] = { { NULL }, { NULL } }; u32 g_idxSubjectBufStart[NUM_MSG_BOX_TYPES] = { 0 }; MsgData g_msgData; s32 g_errorCode = 0; /*---------------------------------------------------------------------------* Global constants *---------------------------------------------------------------------------*/ const GXColor CLR_DARKBLUE = { 0, 0, 40, 255 }; const GXColor CLR_WHITE = { 255, 255, 255, 255 }; const char* HIDDEN_MESSAGE = "(Cannot read.)"; const char* BROKEN_MESSAGE = "(May be broken.)"; /*---------------------------------------------------------------------------* Static constants *---------------------------------------------------------------------------*/ static const u32 HOLD_THRESHOLD = 10; #define NUM_KPAD_BUTTONS 16 #define PAD_BUTTONS_USED \ ((PAD_BUTTON_A)|(PAD_BUTTON_B)|(PAD_BUTTON_UP)|(PAD_BUTTON_DOWN)) #define KPAD_BUTTONS_USED \ ((KPAD_BUTTON_A)|(KPAD_BUTTON_B)|(KPAD_BUTTON_UP)|(KPAD_BUTTON_DOWN)) #define ALL_BUTTONS_USED \ ((KPAD_BUTTONS_USED)|((PAD_BUTTONS_USED)<<16)) #define PAD_BUTTONS_REPEATABLE \ ((PAD_BUTTON_UP)|(PAD_BUTTON_DOWN)) #define KPAD_BUTTONS_REPEATABLE \ ((KPAD_BUTTON_UP)|(KPAD_BUTTON_DOWN)) #define ALL_BUTTONS_REPEATABLE \ ((KPAD_BUTTONS_REPEATABLE)|((PAD_BUTTONS_REPEATABLE)<<16)) /*---------------------------------------------------------------------------* Static variables *---------------------------------------------------------------------------*/ static char* s_libWorkMem = NULL; static u32 s_longHold = 0; // Button held down static u32 s_holdCount[32] = { 0 }; /*---------------------------------------------------------------------------* Local functions *---------------------------------------------------------------------------*/ static void* AllocFromPadHeap( u32 size ); static u8 FreeToPadHeap ( void* ptr ); static void SampleInitialize( void ); static void SampleFinalize ( void ); /*---------------------------------------------------------------------------* App entry point *---------------------------------------------------------------------------*/ int main( void ) { KPADStatus input; u32 hold; u32 trig; u8 iButton; SampleInitialize(); (void)memset( &input, 0, sizeof(KPADStatus) ); /* App main loop */ while ( TRUE ) { DEMOPadRead(); (void)KPADRead( WPAD_CHAN0, &input, 1 ); /* Combination of KPAD and PAD */ hold = (input.hold) | (DEMOPadGetButton(0) << 16); trig = (input.trig) | (DEMOPadGetButtonDown(0) << 16); /* Button hold detect */ for ( iButton = 0; iButton < 32; ++iButton ) { if ( (hold >> iButton) & 0x1 ) { ++s_holdCount[iButton]; } else { s_holdCount[iButton] = 0; } if ( HOLD_THRESHOLD < s_holdCount[iButton] ) { s_longHold |= 0x1 << iButton; } else { s_longHold &= ~(0x1 << iButton); } } trig |= (s_longHold & ALL_BUTTONS_REPEATABLE); /* Update processing other than rendering */ Update( trig ); /* Render */ DEMOBeforeRender(); Render(); DEMODoneRender(); } SampleFinalize(); OSHalt( "All done." ); return 0; } /*---------------------------------------------------------------------------* Name : CheckError Description : Checks the error code of NWC24Err-type errors, and if not NWC24_OK, displays the error content. Arguments : strFunc - Name of function that returned the error code. err - NWC24Err-type error code. Returns : NWC24Err -Same value as err. *---------------------------------------------------------------------------*/ void CheckError( const char* strFunc, NWC24Err err ) { if ( err != NWC24_OK ) { OSReport( "%s: error %d\n", strFunc, err ); OSHalt( "Failed.\n" ); } return; } /*---------------------------------------------------------------------------* Name : GetMsgIdList Description : Get the total message count and message ID list in the specified message box. Arguments : mBoxId - Message box type. Returns : None. *---------------------------------------------------------------------------*/ void GetMsgIdList( NWC24MsgBoxId mBoxId ) { NWC24Err err; u32 bufSize; MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; err = NWC24GetNumMsgs( mBoxId, &g_numMsgs[mbType] ); CheckError( "NWC24GetNumMsgs()", err ); if ( g_numMsgs[mbType] == 0 ) { g_idListBuf[mbType] = NULL; return; } bufSize = OSRoundUp32B( g_numMsgs[mbType] * sizeof(u32) ); g_idListBuf[mbType] = (u32*)MEMAllocFromAllocator( &DemoAllocator1, bufSize ); err = NWC24GetMsgIdList( mBoxId, g_idListBuf[mbType], g_numMsgs[mbType] ); CheckError( "NWC24GetMsgIdList()", err ); return; } /*---------------------------------------------------------------------------* Name : ReleaseMsgIdList Description : Deallocates the memory used for the message ID list in the specified message box. Arguments : mBoxId - Message box type. Returns : None. *---------------------------------------------------------------------------*/ void ReleaseMsgIdList( NWC24MsgBoxId mBoxId ) { MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; if ( g_idListBuf[mbType] ) { MEMFreeToAllocator( &DemoAllocator1, g_idListBuf[mbType] ); g_idListBuf[mbType] = NULL; } return; } /*---------------------------------------------------------------------------* Name : ReadSubject Description : Reads the subject from the specified message and copies only the specified length to the buffer. Arguments : buf - Buffer to copy to size - Maximum size to copy mBoxId - Message box type. msgId - Message ID. Returns : BOOL - TRUE if successful. *---------------------------------------------------------------------------*/ BOOL ReadSubject( char* buf, u32 size, NWC24MsgBoxId mBoxId, u32 msgId ) { NWC24Err err; NWC24MsgObj msgObj; BOOL result = FALSE; u32 subjectSize; char* subjectBuf = NULL; err = NWC24GetMsgObj( &msgObj, mBoxId, msgId ); if ( err == NWC24_ERR_HIDDEN ) { (void)strncpy(buf, HIDDEN_MESSAGE, size); return FALSE; } else { err = NWC24GetMsgSubjectSize( &msgObj, &subjectSize ); if ( err != NWC24_OK ) { (void)strncpy( buf, BROKEN_MESSAGE, size ); return FALSE; } if ( subjectSize < 1 ) { subjectSize = 1; } subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, subjectSize ); err = NWC24ReadMsgSubject( &msgObj, subjectBuf, subjectSize ); if ( err != NWC24_OK ) { result = FALSE; (void)strncpy( buf, BROKEN_MESSAGE, size ); } else { result = TRUE; (void)strncpy( buf, subjectBuf, size ); } MEMFreeToAllocator( &DemoAllocator1, subjectBuf ); } return result; } /*---------------------------------------------------------------------------* Name : GetListedSubjects Description : Gets the title of the message displayed onscreen for the specified message box. Arguments : mBoxId - Message box type. Returns : None. *---------------------------------------------------------------------------*/ void GetListedSubjects( NWC24MsgBoxId mBoxId ) { u32 i; MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; g_idxSubjectBufStart[mbType] = 0; for ( i = 0; i < LIST_BOX_ROWS; ++i ) { u32 idxIdListBuf = (u32)(g_idxIdTopOfList[mbType] + i); if ( g_numMsgs[mbType] <= idxIdListBuf ) { break; } g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP ); (void)NETMemSet( g_subjectBuf[mbType][i], 0, LEN_SUBJECT_DISP ); (void)ReadSubject( g_subjectBuf[mbType][i], LEN_SUBJECT_DISP-1, mBoxId, g_idListBuf[mbType][idxIdListBuf] ); } return; } /*---------------------------------------------------------------------------* Name : ReleaseListedSubjects Description : Deallocates the buffer for the title of the message displayed onscreen for the specified message box. Arguments : mBoxId - Message box type. Returns : None. *---------------------------------------------------------------------------*/ void ReleaseListedSubjects( NWC24MsgBoxId mBoxId ) { u32 i; MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; for ( i = 0; i < LIST_BOX_ROWS; ++i ) { if ( g_subjectBuf[mbType][i] ) { MEMFreeToAllocator( &DemoAllocator1, g_subjectBuf[mbType][i] ); g_subjectBuf[mbType][i] = NULL; } } return; } /*---------------------------------------------------------------------------* Name : OpenLib Description : Calls NWC24OpenLib(). Arguments : None. Returns : None. *---------------------------------------------------------------------------*/ BOOL OpenLib( void ) { NWC24Err err; err = NWC24OpenLib( s_libWorkMem ); if ( err == NWC24_ERR_BUSY || err == NWC24_ERR_MUTEX || err == NWC24_ERR_INPROGRESS ) { g_errorCode = NWC24GetErrorCode(); return FALSE; } if ( err != NWC24_OK ) { g_errorCode = NWC24GetErrorCode(); g_state = MB_STATE_ERROR_STOP; return FALSE; } g_errorCode = 0; g_state = MB_STATE_MENU; return TRUE; } /*---------------------------------------------------------------------------* Name : CloseLib Description : Calls NWC24CloseLib(). Arguments : None. Returns : None. *---------------------------------------------------------------------------*/ BOOL CloseLib( void ) { NWC24Err err; err = NWC24CloseLib(); if ( err != NWC24_OK ) { g_errorCode = NWC24_ERRCODE_UNDEFINED; g_state = MB_STATE_ERROR_STOP; return FALSE; } g_errorCode = 0; g_state = MB_STATE_LIB_CLOSED; return TRUE; } /*---------------------------------------------------------------------------* Name : AllocFromPadHeap Description : Dynamically allocates memory for the WPAD library. Arguments : size - Specifies the size of memory to allocate (in bytes). Returns : void* - Start address of the allocated memory. *---------------------------------------------------------------------------*/ static void* AllocFromPadHeap( u32 size ) { return MEMAllocFromAllocator( &DemoAllocator2, size ); } /*---------------------------------------------------------------------------* Name : FreeToPadHeap Description : Deallocates memory dynamically allocated for the WPAD library. Arguments : ptr - Start address of the memory to deallocate. Returns : u8 - Returns 0 if the attempt to deallocate memory fails. *---------------------------------------------------------------------------*/ static u8 FreeToPadHeap( void* ptr ) { if ( !ptr ) { return 0; } MEMFreeToAllocator( &DemoAllocator2, ptr ); ptr = NULL; return 1; } /*---------------------------------------------------------------------------* Name : SampleInitialize Description : Initializes the sample program. Arguments : None. Returns : None. *---------------------------------------------------------------------------*/ static void SampleInitialize( void ) { OSInit(); /* Initialize DEMO and GX */ { GXRenderModeObj* renderMode = NULL; DEMOInit( NULL ); g_fontData = DEMOInitROMFont(); DEMOSetROMFontSize( FONT_SIZE, 0 ); renderMode = DEMOGetRenderModeObj(); g_screenWidth = (s16)renderMode->fbWidth; g_screenHeight = (s16)renderMode->efbHeight; DEMOInitCaption( DM_FT_XLU, g_screenWidth, g_screenHeight ); GXSetCopyClear( CLR_DARKBLUE, GX_MAX_Z24 ); GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO ); GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ); GXSetTevColor( GX_TEVREG0, CLR_WHITE ); } /* Initialize NAND */ { s32 result; result = NANDInit(); if ( result != NAND_RESULT_OK ) { OSHalt("NANDInit() failed.\n"); } } /* Initialize VF */ { VFInit(); } /* Initialize KPAD. */ { WPADRegisterAllocator( AllocFromPadHeap, FreeToPadHeap ); KPADInit(); } /* Initialize other applications */ { s_libWorkMem = MEMAllocFromAllocator( &DemoAllocator1, NWC24_WORK_MEM_SIZE ); /* Fundamentally, NWC24 is left open in this demo */ if ( OpenLib() ) { /* Initialize message ID list */ GetMsgIdList( NWC24_RECV_BOX ); GetMsgIdList( NWC24_SEND_BOX ); /* Initialize the title buffer of displayed message */ GetListedSubjects( NWC24_RECV_BOX ); GetListedSubjects( NWC24_SEND_BOX ); } } return; } /*---------------------------------------------------------------------------* Name : SampleFinalize Description : Finalizes the sample program. Arguments : None. Returns : None. *---------------------------------------------------------------------------*/ static void SampleFinalize( void ) { MEMFreeToAllocator( &DemoAllocator1, s_libWorkMem ); ReleaseMsgIdList( NWC24_RECV_BOX ); ReleaseMsgIdList( NWC24_SEND_BOX ); ReleaseListedSubjects( NWC24_RECV_BOX ); ReleaseListedSubjects( NWC24_SEND_BOX ); return; } /*======== End of MsgViewer.c ========*/