/*---------------------------------------------------------------------------* Project: WiiConnect24 API demos File: MsgViewerRender.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: MsgViewerRender.c,v $ Revision 1.1 2006/09/27 08:58:01 torigoe_nobutaka Renamed from render.c Moved from nwc24demo/src. Revision 1.2 2006/09/27 07:34:49 torigoe_nobutaka Improved performance. Changed display layout a bit. Revision 1.1 2006/08/28 08:51:50 torigoe_nobutaka Initial check in. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include #include "MsgViewerRender.h" #include "MsgViewer.h" /*---------------------------------------------------------------------------* Static constants *---------------------------------------------------------------------------*/ static const s16 FONT_LEADING = FONT_SIZE + 2; static const s16 MENU_BOX_TL_X = 4 * FONT_SIZE; static const s16 MENU_BOX_TL_Y = 4 * FONT_LEADING; static const s16 LIST_BOX_TL_X = 16 * FONT_SIZE; static const s16 LIST_BOX_TL_Y = 3 * FONT_LEADING; static const s16 HEADER_BOX_TL_X = MENU_BOX_TL_X + FONT_SIZE; static const s16 HEADER_BOX_TL_Y = (LIST_BOX_ROWS + 2) * FONT_LEADING + LIST_BOX_TL_Y; static const s16 TEXT_BOX_TL_X = HEADER_BOX_TL_X; static const s16 TEXT_BOX_TL_Y = 4 * FONT_LEADING + HEADER_BOX_TL_Y; static const s16 TEXT_BOX_WIDTH = 29 * FONT_SIZE; static const s16 HOWTO_BOX_TL_X = MENU_BOX_TL_X; static const s16 HOWTO_BOX_TL_Y = (TEXT_BOX_ROWS + 3) * FONT_LEADING + TEXT_BOX_TL_Y; static const char* STR_CURSOR = ">"; static const char* STR_UPARROW = "^"; static const char* STR_DOWNARROW = "v"; static const char* STR_CANNOT_SCROLL = "x"; /* Menu Items */ static const char* STR_MSG_BOX_MENU[] = { "RECEIVE BOX", "SEND BOX", "RECEIVE MESSAGE", "POST MESSAGE" }; /*---------------------------------------------------------------------------* Local functions *---------------------------------------------------------------------------*/ static void RenderMenu ( void ); static void RenderMsgList ( NWC24MsgBoxId mBoxId ); static void RenderMsgContent ( void ); static void RenderTextDeleteMsg ( void ); static void RenderTextBeforeRecvMsg( void ); static void RenderTextBeforePostMsg( void ); static void RenderTextDoneRecvMsg ( void ); static void RenderTextDonePostMsg ( void ); static void RenderHowToUse ( void ); static void PrintFrom ( s16 x, s16 y, MsgData* msgData ); static void PrintTo ( s16 x, s16 y, MsgData* msgData ); static void PrintSubject ( s16 x, s16 y, MsgData* msgData ); static void PrintBodyText ( s16 x, s16 y, MsgData* msgData ); /*---------------------------------------------------------------------------* Name: Render Description: Renders the scene. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void Render() { /* Menu */ RenderMenu(); /* Message list and contents */ if ( g_selectedMenu == MB_MENU_RECV_BOX || g_selectedMenu == MB_MENU_SEND_BOX ) { NWC24MsgBoxId mBoxId = (g_selectedMenu == MB_MENU_RECV_BOX) ? NWC24_RECV_BOX : NWC24_SEND_BOX; MsgBoxType mbType = (g_selectedMenu == MB_MENU_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; RenderMsgList( mBoxId ); if ( g_state == MB_STATE_MSG_CONTENT && g_numMsgs[mbType] != 0 ) { RenderMsgContent(); } } /* Other text: */ switch ( g_state ) { case MB_STATE_DELETE_MSG: RenderTextDeleteMsg(); break; case MB_STATE_BEFORE_RECV_MSG: RenderTextBeforeRecvMsg(); break; case MB_STATE_BEFORE_POST_MSG: RenderTextBeforePostMsg(); break; case MB_STATE_DONE_RECV_MSG: RenderTextDoneRecvMsg(); break; case MB_STATE_DONE_POST_MSG: RenderTextDonePostMsg(); break; } RenderHowToUse(); return; } /*---------------------------------------------------------------------------* Name: RenderMenu Description: Displays the menu. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderMenu( void ) { s16 printX = MENU_BOX_TL_X; s16 printY = MENU_BOX_TL_Y; s16 iMenu; /* Menu */ for ( iMenu = 0; iMenu < NUM_MSG_BOX_MENUS; ++iMenu, printY += FONT_LEADING ) { printX = MENU_BOX_TL_X; if ( iMenu == g_selectedMenu ) { if ( g_state == MB_STATE_MENU ) { (void)DEMORFPrintf( (s16)(printX - FONT_SIZE), printY, 0, "%s", STR_CURSOR ); } GXSetTevColor( GX_TEVREG0, CLR_YELLOW ); } printX += DEMORFPrintf( printX, printY, 0, "[%s]", STR_MSG_BOX_MENU[iMenu] ); GXSetTevColor( GX_TEVREG0, CLR_WHITE ); if ( iMenu == MB_MENU_RECV_BOX ) { (void)DEMORFPrintf( printX, printY, 0, "(%u)", g_numMsgs[MB_TYPE_RECV] ); } if ( iMenu == MB_MENU_SEND_BOX ) { (void)DEMORFPrintf( printX, printY, 0, "(%u)", g_numMsgs[MB_TYPE_SEND] ); } } } /*---------------------------------------------------------------------------* Name: RenderMsgList Description: Lists the contents of the specified message box. Arguments: mBoxId - Message box type. Returns: None. *---------------------------------------------------------------------------*/ static void RenderMsgList( NWC24MsgBoxId mBoxId ) { s16 printX = LIST_BOX_TL_X; s16 printY = LIST_BOX_TL_Y; u32 i; MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND; if ( g_numMsgs[mbType] == 0 ) { /* If the specified message box is empty... */ printY += FONT_LEADING; (void)DEMORFPrintf( printX, printY, 0, "(%s box has no message.)", (mBoxId == NWC24_RECV_BOX) ? "Receive" : "Send" ); return; } (void)DEMORFPrintf( printX, printY, 0, "ID:" ); printX += DEMOGetRFTextWidth( "[00000000] " ); (void)DEMORFPrintf( printX, printY, 0, "Subject:" ); for ( i = 0; i < LIST_BOX_ROWS && (u32)(g_idxIdTopOfList[mbType] + i) < g_numMsgs[mbType]; ++i ) { u32 idxSubjectBuf = (u32)((g_idxSubjectBufStart[mbType] + i) % LIST_BOX_ROWS); u32 idxMsgId = (u32)(g_idxIdTopOfList[mbType] + i); printX = LIST_BOX_TL_X; printY += FONT_LEADING; if ( idxMsgId == g_idxSelectedId[mbType] ) { if ( g_state == MB_STATE_RECV_BOX || g_state == MB_STATE_SEND_BOX ) { (void)DEMORFPrintf( (s16)(printX - FONT_SIZE), printY, 0, "%s", STR_CURSOR ); } GXSetTevColor( GX_TEVREG0, CLR_YELLOW ); } (void)DEMORFPrintf( printX, printY, 0, "[%08d] ", g_idListBuf[mbType][idxMsgId] ); printX += DEMOGetRFTextWidth( "[00000000] " ); (void)DEMORFPrintf( printX, printY, 0, "%s", g_subjectBuf[mbType][idxSubjectBuf] ); GXSetTevColor( GX_TEVREG0, CLR_WHITE ); } return; } /*---------------------------------------------------------------------------* Name: RenderMsgContent Description: Displays the message contents. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderMsgContent( void ) { s16 printX; s16 printY; s16 indent; /* Simple header information */ printX = HEADER_BOX_TL_X; printY = HEADER_BOX_TL_Y; indent = (s16)DEMOGetRFTextWidth( "[Subject] " ); (void)DEMORFPrintf( printX, printY, 0, "[From]" ); PrintFrom( (s16)(printX + indent), printY, &g_msgData ); printY += FONT_LEADING; (void)DEMORFPrintf( printX, printY, 0, "[To]" ); PrintTo( (s16)(printX + indent), printY, &g_msgData ); printY += FONT_LEADING; (void)DEMORFPrintf( printX, printY, 0, "[Subject]" ); PrintSubject( (s16)(printX + indent), printY, &g_msgData ); /* This text */ printX = TEXT_BOX_TL_X; printY = TEXT_BOX_TL_Y; PrintBodyText( printX, printY, &g_msgData ); if ( g_state == MB_STATE_MSG_CONTENT ) { /* Scroll bar*/ printX += TEXT_BOX_WIDTH + FONT_SIZE; printY -= FONT_SIZE; if ( g_lineTopOfBodyText != 0 ) { (void)DEMORFPrintf( printX, printY, 0, "%s", STR_UPARROW ); } else { (void)DEMORFPrintf( printX, printY, 0, "%s", STR_CANNOT_SCROLL ); } printY += TEXT_BOX_ROWS * FONT_LEADING + FONT_SIZE; if ( (s32)g_lineTopOfBodyText < (s32)(g_numLinesBodyText - TEXT_BOX_ROWS) ) { (void)DEMORFPrintf( printX, printY, 0, "%s", STR_DOWNARROW ); } else { (void)DEMORFPrintf( printX, printY, 0, "%s", STR_CANNOT_SCROLL ); } /* Message delete text. */ printX = HOWTO_BOX_TL_X; printY = (s16)(HOWTO_BOX_TL_Y - (2 * FONT_LEADING)); printX += DEMORFPrintf( printX, printY, 0, "(Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to DELETE this message.)" ); } return; } /*---------------------------------------------------------------------------* Name: RenderTextDeleteMsg Description: Displays message delete text. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderTextDeleteMsg( void ) { s16 printX = TEXT_BOX_TL_X; s16 printY = TEXT_BOX_TL_Y; DEMOSetFontType( DM_FT_RVS ); (void)DEMORFPrintf( printX, printY, 0, "Are you sure you want to delete this message?" ); printY += 2 * FONT_LEADING; DEMOSetFontType( DM_FT_XLU ); printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to DELETE this message." ); printX = TEXT_BOX_TL_X; printY += FONT_LEADING; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." ); return; } /*---------------------------------------------------------------------------* Name: RenderTextBeforeRecvMsg Description: Displays message receive text. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderTextBeforeRecvMsg( void ) { s16 printX = TEXT_BOX_TL_X; s16 printY = TEXT_BOX_TL_Y; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to RECEIVE a test message." ); printX = TEXT_BOX_TL_X; printY += FONT_LEADING; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." ); return; } /*---------------------------------------------------------------------------* Name: RenderTextBeforePostMsg Description: Displays message send text. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderTextBeforePostMsg( void ) { s16 printX = TEXT_BOX_TL_X; s16 printY = TEXT_BOX_TL_Y; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to POST a test message." ); printX = TEXT_BOX_TL_X; printY += FONT_LEADING; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." ); return; } /*---------------------------------------------------------------------------* Name: RenderTextDoneRecvMsg Description: Displays message send text. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderTextDoneRecvMsg( void ) { s16 printX = TEXT_BOX_TL_X; s16 printY = TEXT_BOX_TL_Y; (void)DEMORFPrintf( printX, printY, 0, "Received a test message successfully." ); printY += 2 * FONT_LEADING; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to return to MENU." ); return; } /*---------------------------------------------------------------------------* Name: RenderTextDonePostMsg Description: Displays message send complete text. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderTextDonePostMsg( void ) { s16 printX = TEXT_BOX_TL_X; s16 printY = TEXT_BOX_TL_Y; (void)DEMORFPrintf( printX, printY, 0, "Posted a test message successfully." ); printY += 2 * FONT_LEADING; printX += DEMORFPrintf( printX, printY, 0, "Push " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); (void)DEMORFPrintf( printX, printY, 0, " to return to MENU." ); return; } /*---------------------------------------------------------------------------* Name: RenderHowToUse Description :Displays how to use instructions. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void RenderHowToUse( void ) { static u8 frame = 0; s16 printX = HOWTO_BOX_TL_X; s16 printY = HOWTO_BOX_TL_Y; DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); printX += DEMORFPrintf( printX, printY, 0, " Select or Scroll " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); printX += DEMORFPrintf( printX, printY, 0, " Enter " ); DEMOSetFontType( DM_FT_RVS ); printX += DEMORFPrintf( printX, printY, 0, "" ); DEMOSetFontType( DM_FT_XLU ); printX += DEMORFPrintf( printX, printY, 0, " Cancel " ); // Frame count frame = (u8)((frame + 1) % 60); (void)DEMORFPrintf( printX, printY, 0, "%d", frame ); return; } /*---------------------------------------------------------------------------* Name: PrintFrom Description: Displays the sender of the specified message. Arguments : x - x value of the display position. y - y value of the display position. msgData - Pointer to the MsgData type message data. Returns: None. *---------------------------------------------------------------------------*/ static void PrintFrom( s16 x, s16 y, MsgData* msgData ) { (void)DEMORFPrintf( x, y, 0, "%s", msgData->from ); return; } /*---------------------------------------------------------------------------* Name: PrintTo Description: Displays the receiver of the specified message. Arguments : x - x value of the display position. y - y value of the display position. msgData - Pointer to the MsgData type message data. Returns: None. *---------------------------------------------------------------------------*/ static void PrintTo( s16 x, s16 y, MsgData* msgData ) { u32 i; for ( i = 0; i < msgData->numTo; ++i ) { x += DEMORFPrintf( x, y, 0, "%s", msgData->to[i] ); if ( i < msgData->numTo - 1 ) { x += DEMORFPrintf( x, y, 0, ", " ); } } return; } /*---------------------------------------------------------------------------* Name: PrintSubject Description: Displays the subject of the specified message. Arguments : x - x value of the display position. y - y value of the display position. msgData - Pointer to the MsgData type message data. Returns: None. *---------------------------------------------------------------------------*/ static void PrintSubject( s16 x, s16 y, MsgData* msgData ) { char* pt = msgData->subject; while ( *pt != '\0' ) { if ( *pt != '\r' && *pt != '\n' ) { x += DEMORFPrintf( x, y, 0, "%c", *pt ); } ++pt; } return; } /*---------------------------------------------------------------------------* Name: PrintBodyText Description: Displays the body text of the specified message. Arguments : x - x value of the display position. y - y value of the display position. msgData - Pointer to the MsgData type message data. Returns: None. *---------------------------------------------------------------------------*/ static void PrintBodyText( s16 x, s16 y, MsgData* msgData ) { char* pt = msgData->text; s16 width = 0; u32 rowCount = 0; s32 texWidth; s32 pxWidth; char* next = NULL; s16 printX; s16 printY; while ( *pt != '\0' ) { if ( *pt == '\r' ) { ++pt; continue; } // Line break if ( *pt == '\n' ) { width = 0; ++rowCount; ++pt; continue; } next = OSGetFontWidth( pt, &texWidth ); pxWidth = (s16)(texWidth * FONT_SIZE / g_fontData->cellWidth); // Line break if ( TEXT_BOX_WIDTH < (s16)(width + pxWidth) ) { width = 0; ++rowCount; } if ( g_lineTopOfBodyText <= rowCount && rowCount < g_lineTopOfBodyText + TEXT_BOX_ROWS ) { printX = (s16)(x + width); printY = (s16)(y + ((rowCount - g_lineTopOfBodyText) * FONT_LEADING)); (void)DEMORFPutsEx( printX, printY, 0, pt, (s16)(pxWidth + 1), next - pt ); } width += pxWidth; pt = next; } g_numLinesBodyText = rowCount + 1; return; } /*======== End of MsgViewerRender.c ========*/