/*---------------------------------------------------------------------------* 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.2 2007/02/02 02:20:33 torigoe_nobutaka Added OpenLib() and CloseLib(). Added handling of message 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 APIs. Revision 1.1 2006/08/28 08:51:51 torigoe_nobutaka Initial check in. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #define DEMO_USE_MEMLIB 1 #include #include "MsgViewer.h" #include "MsgViewerRender.h" #include "MsgViewerUpdate.h" /*---------------------------------------------------------------------------* Global constants *---------------------------------------------------------------------------*/ const GXColor CLR_DARKBLUE = { 0, 0, 40, 255 }; const GXColor CLR_WHITE = { 255, 255, 255, 255 }; const GXColor CLR_YELLOW = { 255, 255, 0, 255 }; const char* HIDDEN_MESSAGE = "(Cannot read.)"; /*---------------------------------------------------------------------------* Global variables *---------------------------------------------------------------------------*/ s16 g_screenWidth; s16 g_screenHeight; OSFontHeader* g_fontData = NULL; u32 g_longHold = 0; // Button held down 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; /*---------------------------------------------------------------------------* Static constants *---------------------------------------------------------------------------*/ static const u32 HOLD_THRESHOLD = 10; #define NUM_KPAD_BUTTONS 16 /*---------------------------------------------------------------------------* Static variables *---------------------------------------------------------------------------*/ static char* s_libWorkMem = NULL; static u32 s_holdCount[NUM_KPAD_BUTTONS] = { 0 }; /*---------------------------------------------------------------------------* Local functions *---------------------------------------------------------------------------*/ static void OpenLib ( void ); static void CloseLib ( void ); 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; u8 iButton; SampleInitialize(); (void)memset( &input, 0, sizeof(KPADStatus) ); /* App main loop */ while ( TRUE ) { (void)KPADRead( WPAD_CHAN0, &input, 1 ); /* Button hold detect */ for ( iButton = 0; iButton < NUM_KPAD_BUTTONS; ++iButton ) { if ( (input.hold >> iButton) & 0x1 ) { ++s_holdCount[iButton]; } else { s_holdCount[iButton] = 0; } if ( HOLD_THRESHOLD < s_holdCount[iButton] ) { g_longHold |= 0x1 << iButton; } else { g_longHold &= ~(0x1 << iButton); } } OpenLib(); /* Update processing other than rendering */ Update( &input ); /* Render */ DEMOBeforeRender(); Render(); DEMODoneRender(); CloseLib(); } SampleFinalize(); OSHalt( "All done." ); return 0; } /*---------------------------------------------------------------------------* Name: CheckError Description: Check the error code of NWC24Err type, and if not NWC24_OK, display the error details. Arguments : strFunc - Function name that returned an 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: Obtain 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: Frees 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: GetListedSubjects Description: Obtains the title of the message displayed onscreen for the specified message box. Arguments: mBoxId - Message box type. Returns: None. *---------------------------------------------------------------------------*/ void GetListedSubjects( NWC24MsgBoxId mBoxId ) { NWC24Err err; u32 subjectSize; NWC24MsgObj msgObj; 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; } err = NWC24GetMsgObj( &msgObj, mBoxId, g_idListBuf[mbType][idxIdListBuf] ); if ( err == NWC24_ERR_HIDDEN ) { subjectSize = strlen( HIDDEN_MESSAGE ) + 1; g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, subjectSize ); (void)memcpy( g_subjectBuf[mbType][i], HIDDEN_MESSAGE, subjectSize ); } else { CheckError( "NWC24GetMsgObj()", err ); err = NWC24GetMsgSubjectSize( &msgObj, &subjectSize ); CheckError( "NWC24GetMsgSubjectSize()", err ); if ( subjectSize < 1 ) { subjectSize = 1; } g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, subjectSize ); err = NWC24ReadMsgSubject( &msgObj, g_subjectBuf[mbType][i], subjectSize ); if ( err != NWC24_OK ) { g_subjectBuf[mbType][i][0] = '\0'; } } } return; } /*---------------------------------------------------------------------------* Name: ReleaseListedSubjects Description: Obtains 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. *---------------------------------------------------------------------------*/ static void OpenLib( void ) { NWC24Err err; err = NWC24OpenLib( s_libWorkMem ); while ( err == NWC24_ERR_BUSY ) { OSSleepSeconds( 1 ); err = NWC24OpenLib( s_libWorkMem ); } CheckError( "NWC24OpenLib()", err ); } /*---------------------------------------------------------------------------* Name: CloseLib Description: Calls NWC24CloseLib(). Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void CloseLib( void ) { NWC24Err err; err = NWC24CloseLib(); CheckError( "NWC24CloseLib()", err ); } /*---------------------------------------------------------------------------* Name: AllocFromPadHeap Description: Dynamically allocates memory for the WPAD library. Arguments: size - Specifies the size of memory to be allocated (in bytes). Returns: void* - Start address of the allocated memory. *---------------------------------------------------------------------------*/ static void* AllocFromPadHeap( u32 size ) { return MEMAllocFromAllocator( &DemoAllocator2, size ); } /*---------------------------------------------------------------------------* Name: FreeToPadHeap Description: Frees memory dynamically allocated for the WPAD library. Arguments: ptr - Start address of the memory to be freed. Returns: u8 - Returns 0 if the attempt to free 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 ); 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 ); CloseLib(); } 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 ========*/