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