1 /*---------------------------------------------------------------------------*
2   Project:  WiiConnect24 API demos
3   File:     MsgViewerRender.c
4 
5   Copyright 2006 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: MsgViewerRender.c,v $
14   Revision 1.1  2006/09/27 08:58:01  torigoe_nobutaka
15   Renamed from render.c
16   Moved from nwc24demo/src.
17 
18   Revision 1.2  2006/09/27 07:34:49  torigoe_nobutaka
19   Improved performance.
20   Changed display layout a bit.
21 
22   Revision 1.1  2006/08/28 08:51:50  torigoe_nobutaka
23   Initial check in.
24 
25 
26   $NoKeywords: $
27  *---------------------------------------------------------------------------*/
28 
29 #include <revolution.h>
30 #include <revolution/mem.h>
31 #include <revolution/nwc24.h>
32 #include <demo.h>
33 
34 #include "MsgViewerRender.h"
35 #include "MsgViewer.h"
36 
37 /*---------------------------------------------------------------------------*
38    Static constants
39  *---------------------------------------------------------------------------*/
40 static const    s16             FONT_LEADING        = FONT_SIZE + 2;
41 static const    s16             MENU_BOX_TL_X       = 4 * FONT_SIZE;
42 static const    s16             MENU_BOX_TL_Y       = 4 * FONT_LEADING;
43 static const    s16             LIST_BOX_TL_X       = 16 * FONT_SIZE;
44 static const    s16             LIST_BOX_TL_Y       = 3 * FONT_LEADING;
45 static const    s16             HEADER_BOX_TL_X     = MENU_BOX_TL_X + FONT_SIZE;
46 static const    s16             HEADER_BOX_TL_Y     = (LIST_BOX_ROWS + 2) * FONT_LEADING + LIST_BOX_TL_Y;
47 static const    s16             TEXT_BOX_TL_X       = HEADER_BOX_TL_X;
48 static const    s16             TEXT_BOX_TL_Y       = 4 * FONT_LEADING + HEADER_BOX_TL_Y;
49 static const    s16             TEXT_BOX_WIDTH      = 29 * FONT_SIZE;
50 static const    s16             HOWTO_BOX_TL_X      = MENU_BOX_TL_X;
51 static const    s16             HOWTO_BOX_TL_Y      = (TEXT_BOX_ROWS + 3) * FONT_LEADING + TEXT_BOX_TL_Y;
52 static const    char*           STR_CURSOR          = ">";
53 static const    char*           STR_UPARROW         = "^";
54 static const    char*           STR_DOWNARROW       = "v";
55 static const    char*           STR_CANNOT_SCROLL   = "x";
56 
57 /* Menu Items */
58 static const    char*           STR_MSG_BOX_MENU[]  =
59 {
60     "RECEIVE BOX",
61     "SEND BOX",
62     "RECEIVE MESSAGE",
63     "POST MESSAGE"
64 };
65 
66 /*---------------------------------------------------------------------------*
67    Local functions
68  *---------------------------------------------------------------------------*/
69 static void     RenderMenu             ( void );
70 static void     RenderMsgList          ( NWC24MsgBoxId mBoxId );
71 static void     RenderMsgContent       ( void );
72 static void     RenderTextDeleteMsg    ( void );
73 static void     RenderTextBeforeRecvMsg( void );
74 static void     RenderTextBeforePostMsg( void );
75 static void     RenderTextDoneRecvMsg  ( void );
76 static void     RenderTextDonePostMsg  ( void );
77 static void     RenderHowToUse         ( void );
78 static void     PrintFrom              ( s16 x, s16 y, MsgData* msgData );
79 static void     PrintTo                ( s16 x, s16 y, MsgData* msgData );
80 static void     PrintSubject           ( s16 x, s16 y, MsgData* msgData );
81 static void     PrintBodyText          ( s16 x, s16 y, MsgData* msgData );
82 
83 /*---------------------------------------------------------------------------*
84   Name: Render
85   Description: Renders the scene.
86   Arguments: None.
87   Returns: None.
88  *---------------------------------------------------------------------------*/
Render()89 void Render()
90 {
91     /* Menu */
92     RenderMenu();
93 
94     /* Message list and contents */
95     if ( g_selectedMenu == MB_MENU_RECV_BOX || g_selectedMenu == MB_MENU_SEND_BOX )
96     {
97         NWC24MsgBoxId   mBoxId  = (g_selectedMenu == MB_MENU_RECV_BOX) ? NWC24_RECV_BOX : NWC24_SEND_BOX;
98         MsgBoxType      mbType  = (g_selectedMenu == MB_MENU_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
99 
100         RenderMsgList( mBoxId );
101         if ( g_state == MB_STATE_MSG_CONTENT && g_numMsgs[mbType] != 0 )
102         {
103             RenderMsgContent();
104         }
105     }
106 
107     /* Other text: */
108     switch ( g_state )
109     {
110         case MB_STATE_DELETE_MSG:      RenderTextDeleteMsg();     break;
111         case MB_STATE_BEFORE_RECV_MSG: RenderTextBeforeRecvMsg(); break;
112         case MB_STATE_BEFORE_POST_MSG: RenderTextBeforePostMsg(); break;
113         case MB_STATE_DONE_RECV_MSG:   RenderTextDoneRecvMsg();   break;
114         case MB_STATE_DONE_POST_MSG:   RenderTextDonePostMsg();   break;
115     }
116 
117     RenderHowToUse();
118 
119     return;
120 }
121 
122 /*---------------------------------------------------------------------------*
123   Name: RenderMenu
124   Description: Displays the menu.
125   Arguments: None.
126   Returns: None.
127  *---------------------------------------------------------------------------*/
RenderMenu(void)128 static void RenderMenu( void )
129 {
130     s16     printX  = MENU_BOX_TL_X;
131     s16     printY  = MENU_BOX_TL_Y;
132     s16     iMenu;
133 
134     /* Menu */
135     for ( iMenu = 0; iMenu < NUM_MSG_BOX_MENUS; ++iMenu, printY += FONT_LEADING )
136     {
137         printX = MENU_BOX_TL_X;
138 
139         if ( iMenu == g_selectedMenu )
140         {
141             if ( g_state == MB_STATE_MENU )
142             {
143                 (void)DEMORFPrintf( (s16)(printX - FONT_SIZE), printY, 0, "%s", STR_CURSOR );
144             }
145             GXSetTevColor( GX_TEVREG0, CLR_YELLOW );
146         }
147 
148         printX += DEMORFPrintf( printX, printY, 0, "[%s]", STR_MSG_BOX_MENU[iMenu] );
149         GXSetTevColor( GX_TEVREG0, CLR_WHITE );
150 
151         if ( iMenu == MB_MENU_RECV_BOX )
152         {
153             (void)DEMORFPrintf( printX, printY, 0, "(%u)", g_numMsgs[MB_TYPE_RECV] );
154         }
155 
156         if ( iMenu == MB_MENU_SEND_BOX )
157         {
158             (void)DEMORFPrintf( printX, printY, 0, "(%u)", g_numMsgs[MB_TYPE_SEND] );
159         }
160     }
161 }
162 
163 /*---------------------------------------------------------------------------*
164   Name: RenderMsgList
165   Description: Lists the contents of the specified message box.
166   Arguments: mBoxId  - Message box type.
167   Returns: None.
168  *---------------------------------------------------------------------------*/
RenderMsgList(NWC24MsgBoxId mBoxId)169 static void RenderMsgList( NWC24MsgBoxId mBoxId )
170 {
171     s16         printX  = LIST_BOX_TL_X;
172     s16         printY  = LIST_BOX_TL_Y;
173     u32         i;
174     MsgBoxType  mbType  = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
175 
176     if ( g_numMsgs[mbType] == 0 )
177     {
178         /* If the specified message box is empty... */
179         printY += FONT_LEADING;
180 
181         (void)DEMORFPrintf( printX, printY, 0, "(%s box has no message.)",
182                             (mBoxId == NWC24_RECV_BOX) ? "Receive" : "Send" );
183         return;
184     }
185 
186     (void)DEMORFPrintf( printX, printY, 0, "ID:" );
187     printX += DEMOGetRFTextWidth( "[00000000] " );
188     (void)DEMORFPrintf( printX, printY, 0, "Subject:" );
189 
190     for ( i = 0; i < LIST_BOX_ROWS && (u32)(g_idxIdTopOfList[mbType] + i) < g_numMsgs[mbType]; ++i )
191     {
192         u32     idxSubjectBuf   = (u32)((g_idxSubjectBufStart[mbType] + i) % LIST_BOX_ROWS);
193         u32     idxMsgId        = (u32)(g_idxIdTopOfList[mbType] + i);
194 
195         printX = LIST_BOX_TL_X;
196         printY += FONT_LEADING;
197 
198         if ( idxMsgId == g_idxSelectedId[mbType] )
199         {
200             if ( g_state == MB_STATE_RECV_BOX || g_state == MB_STATE_SEND_BOX )
201             {
202                 (void)DEMORFPrintf( (s16)(printX - FONT_SIZE), printY, 0, "%s", STR_CURSOR );
203             }
204             GXSetTevColor( GX_TEVREG0, CLR_YELLOW );
205         }
206 
207         (void)DEMORFPrintf( printX, printY, 0, "[%08d] ", g_idListBuf[mbType][idxMsgId] );
208         printX += DEMOGetRFTextWidth( "[00000000] " );
209         (void)DEMORFPrintf( printX, printY, 0, "%s", g_subjectBuf[mbType][idxSubjectBuf] );
210 
211         GXSetTevColor( GX_TEVREG0, CLR_WHITE );
212     }
213 
214     return;
215 }
216 
217 /*---------------------------------------------------------------------------*
218   Name: RenderMsgContent
219   Description: Displays the message contents.
220   Arguments: None.
221   Returns: None.
222  *---------------------------------------------------------------------------*/
RenderMsgContent(void)223 static void RenderMsgContent( void )
224 {
225     s16         printX;
226     s16         printY;
227     s16         indent;
228 
229     /* Simple header information */
230     printX = HEADER_BOX_TL_X;
231     printY = HEADER_BOX_TL_Y;
232     indent = (s16)DEMOGetRFTextWidth( "[Subject] " );
233 
234     (void)DEMORFPrintf( printX, printY, 0, "[From]" );
235     PrintFrom( (s16)(printX + indent), printY, &g_msgData );
236 
237     printY += FONT_LEADING;
238     (void)DEMORFPrintf( printX, printY, 0, "[To]" );
239     PrintTo( (s16)(printX + indent), printY, &g_msgData );
240 
241     printY += FONT_LEADING;
242     (void)DEMORFPrintf( printX, printY, 0, "[Subject]" );
243     PrintSubject( (s16)(printX + indent), printY, &g_msgData );
244 
245     /* This text */
246     printX = TEXT_BOX_TL_X;
247     printY = TEXT_BOX_TL_Y;
248     PrintBodyText( printX, printY, &g_msgData );
249 
250     if ( g_state == MB_STATE_MSG_CONTENT )
251     {
252         /* Scroll bar*/
253         printX += TEXT_BOX_WIDTH + FONT_SIZE;
254         printY -= FONT_SIZE;
255         if ( g_lineTopOfBodyText != 0 )
256         {
257             (void)DEMORFPrintf( printX, printY, 0, "%s", STR_UPARROW );
258         }
259         else
260         {
261             (void)DEMORFPrintf( printX, printY, 0, "%s", STR_CANNOT_SCROLL );
262         }
263 
264         printY += TEXT_BOX_ROWS * FONT_LEADING + FONT_SIZE;
265         if ( (s32)g_lineTopOfBodyText < (s32)(g_numLinesBodyText - TEXT_BOX_ROWS) )
266         {
267             (void)DEMORFPrintf( printX, printY, 0, "%s", STR_DOWNARROW );
268         }
269         else
270         {
271             (void)DEMORFPrintf( printX, printY, 0, "%s", STR_CANNOT_SCROLL );
272         }
273 
274         /* Message delete text. */
275         printX = HOWTO_BOX_TL_X;
276         printY = (s16)(HOWTO_BOX_TL_Y - (2 * FONT_LEADING));
277         printX += DEMORFPrintf( printX, printY, 0, "(Push " );
278 
279         DEMOSetFontType( DM_FT_RVS );
280         printX += DEMORFPrintf( printX, printY, 0, "<A>" );
281 
282         DEMOSetFontType( DM_FT_XLU );
283         (void)DEMORFPrintf( printX, printY, 0, " to DELETE this message.)" );
284     }
285 
286     return;
287 }
288 
289 /*---------------------------------------------------------------------------*
290   Name: RenderTextDeleteMsg
291   Description: Displays message delete text.
292   Arguments: None.
293   Returns: None.
294  *---------------------------------------------------------------------------*/
RenderTextDeleteMsg(void)295 static void RenderTextDeleteMsg( void )
296 {
297     s16     printX  = TEXT_BOX_TL_X;
298     s16     printY  = TEXT_BOX_TL_Y;
299 
300     DEMOSetFontType( DM_FT_RVS );
301     (void)DEMORFPrintf( printX, printY, 0, "Are you sure you want to delete this message?" );
302 
303     printY += 2 * FONT_LEADING;
304     DEMOSetFontType( DM_FT_XLU );
305     printX += DEMORFPrintf( printX, printY, 0, "Push " );
306     DEMOSetFontType( DM_FT_RVS );
307     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
308     DEMOSetFontType( DM_FT_XLU );
309     (void)DEMORFPrintf( printX, printY, 0, " to DELETE this message." );
310 
311     printX = TEXT_BOX_TL_X;
312     printY += FONT_LEADING;
313     printX += DEMORFPrintf( printX, printY, 0, "Push " );
314     DEMOSetFontType( DM_FT_RVS );
315     printX += DEMORFPrintf( printX, printY, 0, "<B>" );
316     DEMOSetFontType( DM_FT_XLU );
317     (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." );
318 
319     return;
320 }
321 
322 /*---------------------------------------------------------------------------*
323   Name: RenderTextBeforeRecvMsg
324   Description: Displays message receive text.
325   Arguments: None.
326   Returns: None.
327  *---------------------------------------------------------------------------*/
RenderTextBeforeRecvMsg(void)328 static void RenderTextBeforeRecvMsg( void )
329 {
330     s16     printX  = TEXT_BOX_TL_X;
331     s16     printY  = TEXT_BOX_TL_Y;
332 
333     printX += DEMORFPrintf( printX, printY, 0, "Push " );
334     DEMOSetFontType( DM_FT_RVS );
335     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
336     DEMOSetFontType( DM_FT_XLU );
337     (void)DEMORFPrintf( printX, printY, 0, " to RECEIVE a test message." );
338 
339     printX = TEXT_BOX_TL_X;
340     printY += FONT_LEADING;
341     printX += DEMORFPrintf( printX, printY, 0, "Push " );
342     DEMOSetFontType( DM_FT_RVS );
343     printX += DEMORFPrintf( printX, printY, 0, "<B>" );
344     DEMOSetFontType( DM_FT_XLU );
345     (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." );
346 
347     return;
348 }
349 
350 /*---------------------------------------------------------------------------*
351   Name: RenderTextBeforePostMsg
352   Description: Displays message send text.
353   Arguments: None.
354   Returns: None.
355  *---------------------------------------------------------------------------*/
RenderTextBeforePostMsg(void)356 static void RenderTextBeforePostMsg( void )
357 {
358     s16     printX  = TEXT_BOX_TL_X;
359     s16     printY  = TEXT_BOX_TL_Y;
360 
361     printX += DEMORFPrintf( printX, printY, 0, "Push " );
362     DEMOSetFontType( DM_FT_RVS );
363     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
364     DEMOSetFontType( DM_FT_XLU );
365     (void)DEMORFPrintf( printX, printY, 0, " to POST a test message." );
366 
367     printX = TEXT_BOX_TL_X;
368     printY += FONT_LEADING;
369     printX += DEMORFPrintf( printX, printY, 0, "Push " );
370     DEMOSetFontType( DM_FT_RVS );
371     printX += DEMORFPrintf( printX, printY, 0, "<B>" );
372     DEMOSetFontType( DM_FT_XLU );
373     (void)DEMORFPrintf( printX, printY, 0, " to CANCEL." );
374 
375     return;
376 }
377 
378 /*---------------------------------------------------------------------------*
379   Name: RenderTextDoneRecvMsg
380   Description: Displays message send text.
381   Arguments: None.
382   Returns: None.
383  *---------------------------------------------------------------------------*/
RenderTextDoneRecvMsg(void)384 static void RenderTextDoneRecvMsg( void )
385 {
386     s16     printX  = TEXT_BOX_TL_X;
387     s16     printY  = TEXT_BOX_TL_Y;
388 
389     (void)DEMORFPrintf( printX, printY, 0, "Received a test message successfully." );
390 
391     printY += 2 * FONT_LEADING;
392     printX += DEMORFPrintf( printX, printY, 0, "Push " );
393     DEMOSetFontType( DM_FT_RVS );
394     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
395     DEMOSetFontType( DM_FT_XLU );
396     (void)DEMORFPrintf( printX, printY, 0, " to return to MENU." );
397 
398     return;
399 }
400 
401 /*---------------------------------------------------------------------------*
402   Name: RenderTextDonePostMsg
403   Description: Displays message send complete text.
404   Arguments: None.
405   Returns: None.
406  *---------------------------------------------------------------------------*/
RenderTextDonePostMsg(void)407 static void RenderTextDonePostMsg( void )
408 {
409     s16     printX  = TEXT_BOX_TL_X;
410     s16     printY  = TEXT_BOX_TL_Y;
411 
412     (void)DEMORFPrintf( printX, printY, 0, "Posted a test message successfully." );
413 
414     printY += 2 * FONT_LEADING;
415     printX += DEMORFPrintf( printX, printY, 0, "Push " );
416     DEMOSetFontType( DM_FT_RVS );
417     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
418     DEMOSetFontType( DM_FT_XLU );
419     (void)DEMORFPrintf( printX, printY, 0, " to return to MENU." );
420 
421     return;
422 }
423 
424 /*---------------------------------------------------------------------------*
425   Name: RenderHowToUse
426   Description :Displays how to use instructions.
427   Arguments: None.
428   Returns: None.
429  *---------------------------------------------------------------------------*/
RenderHowToUse(void)430 static void RenderHowToUse( void )
431 {
432     static u8   frame           = 0;
433     s16         printX          = HOWTO_BOX_TL_X;
434     s16         printY          = HOWTO_BOX_TL_Y;
435 
436     DEMOSetFontType( DM_FT_RVS );
437     printX += DEMORFPrintf( printX, printY, 0, "<UP/DOWN>" );
438     DEMOSetFontType( DM_FT_XLU );
439     printX += DEMORFPrintf( printX, printY, 0, " Select or Scroll  " );
440     DEMOSetFontType( DM_FT_RVS );
441     printX += DEMORFPrintf( printX, printY, 0, "<A>" );
442     DEMOSetFontType( DM_FT_XLU );
443     printX += DEMORFPrintf( printX, printY, 0, " Enter  " );
444     DEMOSetFontType( DM_FT_RVS );
445     printX += DEMORFPrintf( printX, printY, 0, "<B>" );
446     DEMOSetFontType( DM_FT_XLU );
447     printX += DEMORFPrintf( printX, printY, 0, " Cancel  " );
448 
449     // Frame count
450     frame = (u8)((frame + 1) % 60);
451     (void)DEMORFPrintf( printX, printY, 0, "%d", frame );
452 
453     return;
454 }
455 
456 /*---------------------------------------------------------------------------*
457   Name: PrintFrom
458   Description: Displays the sender of the specified message.
459   Arguments   : x       - x value of the display position.
460                 y       - y value of the display position.
461                 msgData - Pointer to the MsgData type message data.
462   Returns: None.
463  *---------------------------------------------------------------------------*/
PrintFrom(s16 x,s16 y,MsgData * msgData)464 static void PrintFrom( s16 x, s16 y, MsgData* msgData )
465 {
466     (void)DEMORFPrintf( x, y, 0, "%s", msgData->from );
467     return;
468 }
469 
470 /*---------------------------------------------------------------------------*
471   Name: PrintTo
472   Description: Displays the receiver of the specified message.
473   Arguments   : x       - x value of the display position.
474                 y       - y value of the display position.
475                 msgData - Pointer to the MsgData type message data.
476   Returns: None.
477  *---------------------------------------------------------------------------*/
PrintTo(s16 x,s16 y,MsgData * msgData)478 static void PrintTo( s16 x, s16 y, MsgData* msgData )
479 {
480     u32     i;
481 
482     for ( i = 0; i < msgData->numTo; ++i )
483     {
484         x += DEMORFPrintf( x, y, 0, "%s", msgData->to[i] );
485         if ( i < msgData->numTo - 1 )
486         {
487             x += DEMORFPrintf( x, y, 0, ", " );
488         }
489     }
490 
491     return;
492 }
493 
494 /*---------------------------------------------------------------------------*
495   Name: PrintSubject
496   Description: Displays the subject of the specified message.
497   Arguments   : x       - x value of the display position.
498                 y       - y value of the display position.
499                 msgData - Pointer to the MsgData type message data.
500   Returns: None.
501  *---------------------------------------------------------------------------*/
PrintSubject(s16 x,s16 y,MsgData * msgData)502 static void PrintSubject( s16 x, s16 y, MsgData* msgData )
503 {
504     char*   pt  = msgData->subject;
505 
506     while ( *pt != '\0' )
507     {
508         if ( *pt != '\r' && *pt != '\n' )
509         {
510             x += DEMORFPrintf( x, y, 0, "%c", *pt );
511         }
512 
513         ++pt;
514     }
515 
516     return;
517 }
518 
519 /*---------------------------------------------------------------------------*
520   Name: PrintBodyText
521   Description: Displays the body text of the specified message.
522   Arguments   : x       - x value of the display position.
523                 y       - y value of the display position.
524                 msgData - Pointer to the MsgData type message data.
525   Returns: None.
526  *---------------------------------------------------------------------------*/
PrintBodyText(s16 x,s16 y,MsgData * msgData)527 static void PrintBodyText( s16 x, s16 y, MsgData* msgData )
528 {
529     char*   pt          = msgData->text;
530     s16     width       = 0;
531     u32     rowCount    = 0;
532     s32     texWidth;
533     s32     pxWidth;
534     char*   next        = NULL;
535     s16     printX;
536     s16     printY;
537 
538     while ( *pt != '\0' )
539     {
540         if ( *pt == '\r' )
541         {
542             ++pt;
543             continue;
544         }
545 
546         // Line break
547         if ( *pt == '\n' )
548         {
549             width = 0;
550             ++rowCount;
551             ++pt;
552             continue;
553         }
554 
555         next = OSGetFontWidth( pt, &texWidth );
556         pxWidth = (s16)(texWidth * FONT_SIZE / g_fontData->cellWidth);
557 
558         // Line break
559         if ( TEXT_BOX_WIDTH < (s16)(width + pxWidth) )
560         {
561             width = 0;
562             ++rowCount;
563         }
564 
565         if ( g_lineTopOfBodyText <= rowCount && rowCount < g_lineTopOfBodyText + TEXT_BOX_ROWS )
566         {
567             printX = (s16)(x + width);
568             printY = (s16)(y + ((rowCount - g_lineTopOfBodyText) * FONT_LEADING));
569             (void)DEMORFPutsEx( printX, printY, 0, pt, (s16)(pxWidth + 1), next - pt );
570         }
571 
572         width += pxWidth;
573         pt = next;
574     }
575 
576     g_numLinesBodyText = rowCount + 1;
577     return;
578 }
579 
580 /*======== End of MsgViewerRender.c ========*/
581