1 /*---------------------------------------------------------------------------*
2 Project: WiiConnect24 API demos
3 File: MsgViewerUpdate.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: MsgViewerUpdate.c,v $
14 Revision 1.4 2008/05/01 08:50:26 hirose_kazuki
15 Added "Close library" mode.
16
17 Revision 1.3 2008/04/28 11:20:23 hirose_kazuki
18 Updated framework.
19
20 Revision 1.2 2007/02/02 02:20:46 torigoe_nobutaka
21 Added handling of messages without subject or body text.
22
23 Revision 1.1 2006/09/27 08:58:21 torigoe_nobutaka
24 Renamed from update.c
25 Moved from nwc24demo/src.
26
27 Revision 1.2 2006/09/27 07:31:45 torigoe_nobutaka
28 Improved performance.
29
30 Revision 1.1 2006/08/28 08:51:50 torigoe_nobutaka
31 Initial check in.
32
33
34 $NoKeywords: $
35 *---------------------------------------------------------------------------*/
36
37 #include <revolution.h>
38 #include <revolution/mem.h>
39 #include <revolution/nwc24.h>
40 #include <revolution/net.h>
41 #include <demo.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 #include "MsgViewerUpdate.h"
46 #include "MsgViewer.h"
47
48 /*---------------------------------------------------------------------------*
49 Local functions
50 *---------------------------------------------------------------------------*/
51 static BOOL GetMsgData ( MsgData* msgData, NWC24MsgBoxId mBoxId, u32 msgId );
52 static void ReceiveMessage ( void );
53 static void PostMessage ( void );
54 static void CreateMessage ( NWC24MsgBoxId mBoxId );
55 static void UpdateMenu ( u32 input );
56 static void UpdateRecvBox ( u32 input );
57 static void UpdateSendBox ( u32 input );
58 static void UpdateMsgContent ( u32 input );
59 static void UpdateDeleteMsg ( u32 input );
60 static void UpdateBeforeRecvMsg ( u32 input );
61 static void UpdateBeforePostMsg ( u32 input );
62 static void UpdateDoneRecvMsg ( u32 input );
63 static void UpdateDonePostMsg ( u32 input );
64 static void UpdateLibClosed ( u32 input );
65 static void UpdateWaitOpen ( u32 input );
66 static void UpdateErrorMsg ( u32 input );
67
68 /*---------------------------------------------------------------------------*
69 Name : Render
70 Description : Updates scenes not being rendered.
71 Arguments : input - Input data from controller buttons (KPAD & PAD)
72 Returns : None.
73 *---------------------------------------------------------------------------*/
Update(u32 input)74 void Update( u32 input )
75 {
76 switch ( g_state )
77 {
78 case MB_STATE_MENU: UpdateMenu( input ); break;
79 case MB_STATE_RECV_BOX: UpdateRecvBox( input ); break;
80 case MB_STATE_SEND_BOX: UpdateSendBox( input ); break;
81 case MB_STATE_MSG_CONTENT: UpdateMsgContent( input ); break;
82 case MB_STATE_DELETE_MSG: UpdateDeleteMsg( input ); break;
83 case MB_STATE_BEFORE_RECV_MSG: UpdateBeforeRecvMsg( input ); break;
84 case MB_STATE_BEFORE_POST_MSG: UpdateBeforePostMsg( input ); break;
85 case MB_STATE_DONE_RECV_MSG: UpdateDoneRecvMsg( input ); break;
86 case MB_STATE_DONE_POST_MSG: UpdateDonePostMsg( input ); break;
87 case MB_STATE_LIB_CLOSED: UpdateLibClosed( input ); break;
88 case MB_STATE_WAIT_OPEN: UpdateWaitOpen( input ); break;
89 case MB_STATE_ERROR_CONT: UpdateErrorMsg( input ); break;
90 case MB_STATE_ERROR_STOP: break;
91 }
92 return;
93 }
94
95 /*---------------------------------------------------------------------------*
96 Name : GetMsgData
97 Description : Gets data from the specified message.
98 Arguments : msgData - Pointer to the MsgData-type structure that stores the message data.
99
100 mBoxId - Message box type.
101 msgId - Message ID.
102 Returns : BOOL - TRUE if successful.
103 *---------------------------------------------------------------------------*/
104 #define THROW_ERROR(func, err) \
105 { \
106 if ( err != NWC24_OK ) \
107 { \
108 OSReport("%s : error %d\n", func, err); \
109 goto errorHandling; \
110 } \
111 }
112
GetMsgData(MsgData * msgData,NWC24MsgBoxId mBoxId,u32 msgId)113 static BOOL GetMsgData( MsgData* msgData, NWC24MsgBoxId mBoxId, u32 msgId )
114 {
115 NWC24Err err;
116 NWC24MsgObj msgObj;
117 u32 subjectSize;
118 char* subject;
119 u32 textSize;
120 char* text;
121 NWC24Charset charset;
122 NWC24Encoding encoding;
123 MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
124
125 err = NWC24GetMsgObj( &msgObj, mBoxId, msgId );
126 if ( err == NWC24_ERR_HIDDEN )
127 {
128 return FALSE;
129 }
130 THROW_ERROR( "NWC24InitMsgObj()", err );
131
132 /* Message type */
133 err = NWC24GetMsgType( &msgObj, &msgData->type );
134 THROW_ERROR( "NWC24GetMsgType()", err );
135
136 /* Number of recipients */
137 err = NWC24GetMsgNumTo( &msgObj, &msgData->numTo );
138 THROW_ERROR( "NWC24GetMsgNumTo()", err );
139
140 if ( MAX_NUM_TO < msgData->numTo )
141 {
142 msgData->numTo = MAX_NUM_TO;
143 }
144
145 /* Subject Line */
146 err = NWC24GetMsgSubjectSize( &msgObj, &subjectSize );
147 THROW_ERROR( "NWC24GetMsgSubjectSize()", err );
148
149 if ( subjectSize < 1 )
150 {
151 subjectSize = 1;
152 }
153 subject = MEMAllocFromAllocator( &DemoAllocator1, subjectSize );
154
155 err = NWC24ReadMsgSubject( &msgObj, subject, subjectSize );
156 if ( err != NWC24_OK )
157 {
158 MEMFreeToAllocator( &DemoAllocator1, subject );
159 THROW_ERROR( "NWC24ReadMsgSubject()", err );
160 }
161
162 if ( MAX_SUBJECT_SIZE < subjectSize )
163 {
164 subjectSize = MAX_SUBJECT_SIZE;
165 }
166 (void)memcpy( msgData->subject, subject, subjectSize );
167 msgData->subject[subjectSize] = '\0';
168
169 MEMFreeToAllocator( &DemoAllocator1, subject );
170
171 /* Text */
172 err = NWC24GetMsgTextSize( &msgObj, &textSize );
173 THROW_ERROR( "NWC24GetMsgTextSize()", err );
174
175 if ( textSize < 1 )
176 {
177 textSize = 1;
178 }
179
180 text = MEMAllocFromAllocator( &DemoAllocator1, textSize );
181
182 err = NWC24ReadMsgText( &msgObj, text, textSize, &charset, &encoding );
183 if ( err != NWC24_OK )
184 {
185 MEMFreeToAllocator( &DemoAllocator1, text );
186 THROW_ERROR( "NWC24ReadMsgText()", err );
187 }
188
189 if ( MAX_TEXT_SIZE < textSize )
190 {
191 textSize = MAX_TEXT_SIZE;
192 }
193
194 (void)memcpy( msgData->text, text, textSize );
195 msgData->text[textSize] = '\0';
196
197 MEMFreeToAllocator( &DemoAllocator1, text );
198
199 /* Sender/recipient */
200 if ( msgData->type != NWC24_MSGTYPE_PUBLIC )
201 {
202 NWC24UserId temp;
203 u32 i;
204
205 err = NWC24GetMsgFromId( &msgObj, &temp );
206 THROW_ERROR( "NWC24GetMsgFromId()", err );
207
208 (void)sprintf( msgData->from, "%016llu", temp );
209
210 for ( i = 0; i < msgData->numTo; ++i )
211 {
212 err = NWC24ReadMsgToId( &msgObj, i, &temp );
213 THROW_ERROR( "NWC24ReadMsgToId()", err );
214
215 (void)sprintf( msgData->to[i], "%016llu", temp );
216 }
217 }
218 else
219 {
220 u32 i;
221
222 err = NWC24ReadMsgFromAddr( &msgObj, msgData->from, MAX_ADDR_SIZE );
223 THROW_ERROR( "NWC24ReadMsgFromAddr()", err );
224
225 for ( i = 0; i < msgData->numTo; ++i )
226 {
227 err = NWC24ReadMsgToAddr( &msgObj, i, msgData->to[i], MAX_ADDR_SIZE );
228 THROW_ERROR( "NWC24ReadMsgToAddr()", err );
229 }
230 }
231
232 return TRUE;
233
234 errorHandling:
235 msgData->subject[0] = '\0';
236 msgData->text[0] = '\0';
237 msgData->from[0] = '\0';
238 msgData->numTo = 0;
239 return TRUE;
240 }
241
242 #undef THROW_ERROR
243
244 /*---------------------------------------------------------------------------*
245 Name : ReceiveMessage
246 Description : Creates a Wii message and stores it in the Inbox.
247 Arguments : None.
248 Returns : None.
249 *---------------------------------------------------------------------------*/
ReceiveMessage(void)250 static void ReceiveMessage( void )
251 {
252 CreateMessage( NWC24_RECV_BOX );
253 ReleaseMsgIdList( NWC24_RECV_BOX );
254 GetMsgIdList( NWC24_RECV_BOX );
255 ReleaseListedSubjects( NWC24_RECV_BOX );
256 GetListedSubjects( NWC24_RECV_BOX );
257 return;
258 }
259
260 /*---------------------------------------------------------------------------*
261 Name : PostMessage
262 Description : Creates a Wii message and stores it in the Outbox.
263 Arguments : None.
264 Returns : None.
265 *---------------------------------------------------------------------------*/
PostMessage(void)266 static void PostMessage( void )
267 {
268 NWC24Err err;
269
270 err = NWC24Check(NWC24_USE_MESSAGES);
271 if ( err != NWC24_OK )
272 {
273 /* Cannot create a message to send */
274 g_errorCode = NWC24GetErrorCode();
275 g_state = MB_STATE_ERROR_CONT;
276 return;
277 }
278
279 CreateMessage( NWC24_SEND_BOX );
280 ReleaseMsgIdList( NWC24_SEND_BOX );
281 GetMsgIdList( NWC24_SEND_BOX );
282 ReleaseListedSubjects( NWC24_SEND_BOX );
283 GetListedSubjects( NWC24_SEND_BOX );
284 return;
285 }
286
287 /*---------------------------------------------------------------------------*
288 Name : CreateMessage
289 Description : Creates a Wii message and stores it in the specified message box.
290 Arguments : None.
291 Returns : None.
292 *---------------------------------------------------------------------------*/
CreateMessage(NWC24MsgBoxId mBoxId)293 static void CreateMessage( NWC24MsgBoxId mBoxId )
294 {
295 NWC24Err err;
296 NWC24MsgObj msgObj;
297
298 const NWC24UserId UID_TO = 9999999999999999ULL;
299 const char* STR_SUBJECT = "TEST MESSAGE";
300 const char* STR_BODY_TEXT =
301 "Hello Wii Connect 24 World!!\x0d\x0a"
302 "This is a test mail.\x0d\x0a"
303 "Thank you.\x0d\x0a";
304
305 err = NWC24InitMsgObj( &msgObj, NWC24_MSGTYPE_WII );
306 CheckError( "NWC24InitMsgObj()", err );
307
308 if ( mBoxId == NWC24_SEND_BOX )
309 {
310 err = NWC24SetMsgToId( &msgObj, UID_TO );
311 }
312 else
313 {
314 // Set the local hardware as the recipient if the storage destination is the Inbox.
315 NWC24UserId uidMy;
316 err = NWC24GetMyUserId( &uidMy );
317 CheckError( "NWC24GetMyUserId()", err );
318 err = NWC24SetMsgToId( &msgObj, uidMy );
319 }
320 CheckError( "NWC24SetMsgToId()", err );
321
322 err = NWC24SetMsgSubject( &msgObj, STR_SUBJECT, (u32)strlen( STR_SUBJECT ) );
323 CheckError( "NWC24SetMsgSubject()", err );
324
325 err = NWC24SetMsgText( &msgObj, (char*)STR_BODY_TEXT, (u32)strlen( STR_BODY_TEXT ),
326 NWC24_US_ASCII, NWC24_ENC_7BIT );
327 CheckError( "NWC24SetMsgText()", err );
328
329 err = NWC24CommitMsg( &msgObj );
330 CheckError( "NWC24CommitMsg()", err );
331
332 return;
333 }
334
335 /*---------------------------------------------------------------------------*
336 Name : UpdateMenu
337 Description : This function is called each frame to perform updating other than rendering during menu selection.
338 Arguments : input - Input data from controller buttons (KPAD and PAD)
339 Returns : None.
340 *---------------------------------------------------------------------------*/
UpdateMenu(u32 input)341 static void UpdateMenu ( u32 input )
342 {
343 /* (A) button */
344 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
345 {
346 switch ( g_selectedMenu )
347 {
348 case MB_MENU_RECV_BOX:
349 {
350 if ( g_numMsgs[MB_TYPE_RECV] != 0 )
351 {
352 g_state = MB_STATE_RECV_BOX;
353 }
354 break;
355 }
356
357 case MB_MENU_SEND_BOX:
358 {
359 if ( g_numMsgs[MB_TYPE_SEND] != 0 )
360 {
361 g_state = MB_STATE_SEND_BOX;
362 }
363 break;
364 }
365
366 case MB_MENU_RECV_MSG:
367 {
368 g_state = MB_STATE_BEFORE_RECV_MSG;
369 break;
370 }
371
372 case MB_MENU_POST_MSG:
373 {
374 g_state = MB_STATE_BEFORE_POST_MSG;
375 break;
376 }
377 }
378 }
379
380 /* (up) button */
381 if ( input & (KPAD_BUTTON_UP|(PAD_BUTTON_UP<<16)) )
382 {
383 if ( 0 < g_selectedMenu )
384 {
385 --g_selectedMenu;
386 g_lineTopOfBodyText = 0;
387 }
388 }
389
390 /* (down) button */
391 if ( input & (KPAD_BUTTON_DOWN|(PAD_BUTTON_DOWN<<16)) )
392 {
393 if (g_selectedMenu < NUM_MSG_BOX_MENUS - 1)
394 {
395 ++g_selectedMenu;
396 g_lineTopOfBodyText = 0;
397 }
398 }
399
400 /* (B) button */
401 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
402 {
403 /* Close the library */
404 (void)CloseLib();
405 }
406
407 return;
408 }
409
410 /*---------------------------------------------------------------------------*
411 Name : UpdateRecvBox
412 Description : This function is called each frame to perform updating other than rendering during inbox selection.
413 Arguments : input - Input data from controller buttons (KPAD and PAD)
414 Returns : None.
415 *---------------------------------------------------------------------------*/
UpdateRecvBox(u32 input)416 static void UpdateRecvBox( u32 input )
417 {
418
419 /* (A) button */
420 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
421 {
422 if ( GetMsgData( &g_msgData, NWC24_RECV_BOX,
423 g_idListBuf[MB_TYPE_RECV][g_idxSelectedId[MB_TYPE_RECV]] ) )
424 {
425 g_state = MB_STATE_MSG_CONTENT;
426 }
427 else
428 {
429 g_state = MB_STATE_RECV_BOX;
430 }
431 }
432
433 /* (B) button */
434 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
435 {
436 g_state = MB_STATE_MENU;
437 }
438
439 /* (up) button */
440 if ( input & (KPAD_BUTTON_UP|(PAD_BUTTON_UP<<16)) )
441 {
442 if ( 0 < g_idxSelectedId[MB_TYPE_RECV] )
443 {
444 if ( g_idxSelectedId[MB_TYPE_RECV] == g_idxIdTopOfList[MB_TYPE_RECV] )
445 {
446 u32 msgId;
447 char* subjectBuf = NULL;
448
449 --g_idxIdTopOfList[MB_TYPE_RECV];
450 g_idxSubjectBufStart[MB_TYPE_RECV]
451 = (u32)((g_idxSubjectBufStart[MB_TYPE_RECV] + LIST_BOX_ROWS - 1) % LIST_BOX_ROWS);
452
453 msgId = g_idListBuf[MB_TYPE_RECV][g_idxIdTopOfList[MB_TYPE_RECV]];
454 subjectBuf = g_subjectBuf[MB_TYPE_RECV][g_idxSubjectBufStart[MB_TYPE_RECV]];
455
456 if ( subjectBuf )
457 {
458 MEMFreeToAllocator( &DemoAllocator1, subjectBuf );
459 subjectBuf = NULL;
460 }
461
462 subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP );
463 (void)NETMemSet( subjectBuf, 0, LEN_SUBJECT_DISP );
464 (void)ReadSubject( subjectBuf, LEN_SUBJECT_DISP-1, NWC24_RECV_BOX, msgId );
465
466 g_subjectBuf[MB_TYPE_RECV][g_idxSubjectBufStart[MB_TYPE_RECV]] = subjectBuf;
467 }
468 --g_idxSelectedId[MB_TYPE_RECV];
469 g_lineTopOfBodyText = 0;
470 }
471 }
472
473 /* (down) button */
474 if ( input & (KPAD_BUTTON_DOWN|(PAD_BUTTON_DOWN<<16)) )
475 {
476 if ( g_idxSelectedId[MB_TYPE_RECV] < g_numMsgs[MB_TYPE_RECV] - 1 )
477 {
478 u32 idxIdBottomOfList = g_idxIdTopOfList[MB_TYPE_RECV] + LIST_BOX_ROWS - 1;
479
480 if ( g_idxSelectedId[MB_TYPE_RECV] == idxIdBottomOfList )
481 {
482 u32 msgId;
483 char* subjectBuf = NULL;
484 u32 idxSubjectBufEnd;
485
486 ++g_idxIdTopOfList[MB_TYPE_RECV];
487 ++idxIdBottomOfList;
488 idxSubjectBufEnd = g_idxSubjectBufStart[MB_TYPE_RECV];
489 g_idxSubjectBufStart[MB_TYPE_RECV]
490 = (u32)((g_idxSubjectBufStart[MB_TYPE_RECV] + 1) % LIST_BOX_ROWS);
491
492 msgId = g_idListBuf[MB_TYPE_RECV][idxIdBottomOfList];
493 subjectBuf = g_subjectBuf[MB_TYPE_RECV][idxSubjectBufEnd];
494
495 if ( subjectBuf )
496 {
497 MEMFreeToAllocator( &DemoAllocator1, subjectBuf );
498 subjectBuf = NULL;
499 }
500
501 subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP );
502 (void)NETMemSet( subjectBuf, 0, LEN_SUBJECT_DISP );
503 (void)ReadSubject( subjectBuf, LEN_SUBJECT_DISP-1, NWC24_RECV_BOX, msgId );
504
505 g_subjectBuf[MB_TYPE_RECV][idxSubjectBufEnd] = subjectBuf;
506 }
507 ++g_idxSelectedId[MB_TYPE_RECV];
508 g_lineTopOfBodyText = 0;
509 }
510 }
511
512 return;
513 }
514
515 /*---------------------------------------------------------------------------*
516 Name : UpdateSendBox
517 Description : This function is called each frame to perform updating other than rendering during outbox selection.
518 Arguments : input - Input data from controller buttons (KPAD and PAD)
519 Returns : None.
520 *---------------------------------------------------------------------------*/
UpdateSendBox(u32 input)521 static void UpdateSendBox( u32 input )
522 {
523 /* (A) button */
524 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
525 {
526 if ( GetMsgData( &g_msgData, NWC24_SEND_BOX,
527 g_idListBuf[MB_TYPE_SEND][g_idxSelectedId[MB_TYPE_SEND]] ) )
528 {
529 g_state = MB_STATE_MSG_CONTENT;
530 }
531 else
532 {
533 g_state = MB_STATE_SEND_BOX;
534 }
535 }
536
537 /* (B) button */
538 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
539 {
540 g_state = MB_STATE_MENU;
541 }
542
543 /* (up) button */
544 if ( input & (KPAD_BUTTON_UP|(PAD_BUTTON_UP<<16)) )
545 {
546 if ( 0 < g_idxSelectedId[MB_TYPE_SEND] )
547 {
548 if ( g_idxSelectedId[MB_TYPE_SEND] == g_idxIdTopOfList[MB_TYPE_SEND] )
549 {
550 u32 msgId;
551 char* subjectBuf = NULL;
552
553 --g_idxIdTopOfList[MB_TYPE_SEND];
554 g_idxSubjectBufStart[MB_TYPE_SEND]
555 = (u32)((g_idxSubjectBufStart[MB_TYPE_SEND] + LIST_BOX_ROWS - 1) % LIST_BOX_ROWS);
556
557 msgId = g_idListBuf[MB_TYPE_SEND][g_idxIdTopOfList[MB_TYPE_SEND]];
558 subjectBuf = g_subjectBuf[MB_TYPE_SEND][g_idxSubjectBufStart[MB_TYPE_SEND]];
559
560 if ( subjectBuf )
561 {
562 MEMFreeToAllocator( &DemoAllocator1, subjectBuf );
563 subjectBuf = NULL;
564 }
565
566 subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP );
567 (void)NETMemSet( subjectBuf, 0, LEN_SUBJECT_DISP );
568 (void)ReadSubject( subjectBuf, LEN_SUBJECT_DISP-1, NWC24_SEND_BOX, msgId );
569
570 g_subjectBuf[MB_TYPE_SEND][g_idxSubjectBufStart[MB_TYPE_SEND]] = subjectBuf;
571 }
572 --g_idxSelectedId[MB_TYPE_SEND];
573 g_lineTopOfBodyText = 0;
574 }
575 }
576
577 /* (down) button */
578 if ( input & (KPAD_BUTTON_DOWN|(PAD_BUTTON_DOWN<<16)) )
579 {
580 if ( g_idxSelectedId[MB_TYPE_SEND] < g_numMsgs[MB_TYPE_SEND] - 1 )
581 {
582 u32 idxIdBottomOfList = g_idxIdTopOfList[MB_TYPE_SEND] + LIST_BOX_ROWS - 1;
583
584 if ( g_idxSelectedId[MB_TYPE_SEND] == idxIdBottomOfList )
585 {
586 u32 msgId;
587 char* subjectBuf = NULL;
588 u32 idxSubjectBufEnd;
589
590 ++g_idxIdTopOfList[MB_TYPE_SEND];
591 ++idxIdBottomOfList;
592 idxSubjectBufEnd = g_idxSubjectBufStart[MB_TYPE_SEND];
593 g_idxSubjectBufStart[MB_TYPE_SEND]
594 = (u32)((g_idxSubjectBufStart[MB_TYPE_SEND] + 1) % LIST_BOX_ROWS);
595
596 msgId = g_idListBuf[MB_TYPE_SEND][idxIdBottomOfList];
597 subjectBuf = g_subjectBuf[MB_TYPE_SEND][idxSubjectBufEnd];
598
599 if ( subjectBuf )
600 {
601 MEMFreeToAllocator( &DemoAllocator1, subjectBuf );
602 subjectBuf = NULL;
603 }
604
605 subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP );
606 (void)NETMemSet( subjectBuf, 0, LEN_SUBJECT_DISP );
607 (void)ReadSubject( subjectBuf, LEN_SUBJECT_DISP-1, NWC24_SEND_BOX, msgId );
608
609 g_subjectBuf[MB_TYPE_SEND][idxSubjectBufEnd] = subjectBuf;
610 }
611 ++g_idxSelectedId[MB_TYPE_SEND];
612 g_lineTopOfBodyText = 0;
613 }
614 }
615
616 return;
617 }
618
619 /*---------------------------------------------------------------------------*
620 Name : UpdateMsgContent
621 Description : This function is called each frame to perform updating other than rendering during message selection.
622 Arguments : input - Input data from controller buttons (KPAD and PAD)
623 Returns : None.
624 *---------------------------------------------------------------------------*/
UpdateMsgContent(u32 input)625 static void UpdateMsgContent( u32 input )
626 {
627 /* (A) button */
628 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
629 {
630 g_state = MB_STATE_DELETE_MSG;
631 }
632
633 /* (B) button */
634 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
635 {
636 g_state = (g_selectedMenu == MB_MENU_RECV_BOX) ? MB_STATE_RECV_BOX : MB_STATE_SEND_BOX;
637 }
638
639 /* (up) button */
640 if ( input & (KPAD_BUTTON_UP|(PAD_BUTTON_UP<<16)) )
641 {
642 if ( 0 < g_lineTopOfBodyText )
643 {
644 --g_lineTopOfBodyText;
645 }
646 }
647
648 /* (down) button */
649 if ( input & (KPAD_BUTTON_DOWN|(PAD_BUTTON_DOWN<<16)) )
650 {
651 if ( (s32)g_lineTopOfBodyText < (s32)(g_numLinesBodyText - TEXT_BOX_ROWS) )
652 {
653 ++g_lineTopOfBodyText;
654 }
655 }
656
657 return;
658 }
659
660 /*---------------------------------------------------------------------------*
661 Name : UpdateDeleteMsg
662 Description : This function is called each frame to perform updating other than rendering when delete message is selected.
663 Arguments : input - Input data from controller buttons (KPAD and PAD)
664 Returns : None.
665 *---------------------------------------------------------------------------*/
UpdateDeleteMsg(u32 input)666 static void UpdateDeleteMsg( u32 input )
667 {
668 /* (A) button */
669 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
670 {
671 NWC24Err err;
672 NWC24MsgBoxId mBoxId = (g_selectedMenu == MB_MENU_RECV_BOX) ? NWC24_RECV_BOX : NWC24_SEND_BOX;
673 MsgBoxType mbType = (g_selectedMenu == MB_MENU_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
674
675 err = NWC24DeleteMsg( mBoxId, g_idListBuf[mbType][ g_idxSelectedId[mbType] ] );
676 if ( err == NWC24_ERR_PROTECTED )
677 {
678 OSReport("Can't delete this message. (protected)\n");
679 g_state = MB_STATE_MSG_CONTENT;
680 }
681 else
682 {
683 CheckError( "NWC24DeleteMsg()", err );
684 }
685 ReleaseMsgIdList( mBoxId );
686 GetMsgIdList( mBoxId );
687
688 if ( g_numMsgs[mbType] == 0 )
689 {
690 g_idxSelectedId[mbType] = 0;
691 g_state = MB_STATE_MENU;
692 }
693 else
694 {
695 if ( g_numMsgs[mbType] <= g_idxSelectedId[mbType] )
696 {
697 g_idxSelectedId[mbType] = g_numMsgs[mbType] - 1;
698 }
699
700 if ( g_idxIdTopOfList[mbType] != 0
701 && g_numMsgs[mbType] - g_idxIdTopOfList[mbType] < LIST_BOX_ROWS )
702 {
703 g_idxIdTopOfList[mbType] = g_numMsgs[mbType] - LIST_BOX_ROWS;
704 }
705
706 g_state = (g_selectedMenu == MB_MENU_RECV_BOX) ? MB_STATE_RECV_BOX : MB_STATE_SEND_BOX;
707 }
708
709 ReleaseListedSubjects( mBoxId );
710 GetListedSubjects( mBoxId );
711 }
712
713 /* (B) button */
714 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
715 {
716 g_state = MB_STATE_MSG_CONTENT;
717 }
718
719 return;
720 }
721
722 /*---------------------------------------------------------------------------*
723 Name : UpdateBeforeRecvMsg
724 Description : This function is called each frame to perform updating other than rendering when receive message is selected.
725 Arguments : input - Input data from controller buttons (KPAD and PAD)
726 Returns : None.
727 *---------------------------------------------------------------------------*/
UpdateBeforeRecvMsg(u32 input)728 static void UpdateBeforeRecvMsg( u32 input )
729 {
730 /* (A) button */
731 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
732 {
733 ReceiveMessage();
734 g_state = MB_STATE_DONE_RECV_MSG;
735 }
736
737 /* (B) button */
738 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
739 {
740 g_state = MB_STATE_MENU;
741 }
742
743 return;
744 }
745
746 /*---------------------------------------------------------------------------*
747 Name : UpdateBeforePostMsg
748 Description : This function is called each frame to perform updating other than rendering when send message is selected.
749 Arguments : input - Input data from controller buttons (KPAD and PAD)
750 Returns : None.
751 *---------------------------------------------------------------------------*/
UpdateBeforePostMsg(u32 input)752 static void UpdateBeforePostMsg( u32 input )
753 {
754 /* (A) button */
755 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
756 {
757 PostMessage();
758 g_state = MB_STATE_DONE_POST_MSG;
759 }
760
761 /* (B) button */
762 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
763 {
764 g_state = MB_STATE_MENU;
765 }
766
767 return;
768 }
769
770 /*---------------------------------------------------------------------------*
771 Name : UpdateDoneRecvMsg
772 Description : This function is called each frame to perform updating other than rendering after the message is received.
773 Arguments : input - Input data from controller buttons (KPAD and PAD)
774 Returns : None.
775 *---------------------------------------------------------------------------*/
UpdateDoneRecvMsg(u32 input)776 static void UpdateDoneRecvMsg( u32 input )
777 {
778 /* (A) button */
779 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
780 {
781 g_state = MB_STATE_MENU;
782 }
783
784 return;
785 }
786
787 /*---------------------------------------------------------------------------*
788 Name : UpdateDonePostMsg
789 Description : This function is called each frame to perform updating other than rendering after the message is sent.
790 Arguments : input - Input data from controller buttons (KPAD and PAD)
791 Returns : None.
792 *---------------------------------------------------------------------------*/
UpdateDonePostMsg(u32 input)793 static void UpdateDonePostMsg( u32 input )
794 {
795 /* (A) button */
796 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
797 {
798 g_state = MB_STATE_MENU;
799 }
800
801 return;
802 }
803
804 /*---------------------------------------------------------------------------*
805 Name : UpdateLibClosed
806 Description : This function is called each frame while closing the library to perform non-rendering updates.
807 Arguments : input - Input data from controller buttons (KPAD and PAD)
808 Returns : None.
809 *---------------------------------------------------------------------------*/
UpdateLibClosed(u32 input)810 static void UpdateLibClosed( u32 input )
811 {
812 /* (A) button */
813 if ( input & (KPAD_BUTTON_A|(PAD_BUTTON_A<<16)) )
814 {
815 g_state = MB_STATE_WAIT_OPEN;
816 }
817
818 return;
819 }
820
821 /*---------------------------------------------------------------------------*
822 Name : UpdateWaitOpen
823 Description : This function is called each frame while waiting for the open state to perform non-rendering updates.
824 Arguments : input - Input data from controller buttons (KPAD and PAD)
825 Returns : None.
826 *---------------------------------------------------------------------------*/
UpdateWaitOpen(u32 input)827 static void UpdateWaitOpen( u32 input )
828 {
829 static u32 waitCount = 0;
830
831 (void)input;
832
833 if ( waitCount == 0 )
834 {
835 if ( OpenLib() )
836 {
837 /* Get the state after being reopened */
838 ReleaseMsgIdList( NWC24_RECV_BOX );
839 ReleaseMsgIdList( NWC24_SEND_BOX );
840 ReleaseListedSubjects( NWC24_RECV_BOX );
841 ReleaseListedSubjects( NWC24_SEND_BOX );
842 GetMsgIdList( NWC24_RECV_BOX );
843 GetMsgIdList( NWC24_SEND_BOX );
844 GetListedSubjects( NWC24_RECV_BOX );
845 GetListedSubjects( NWC24_SEND_BOX );
846 g_state = MB_STATE_MENU;
847
848 return;
849 }
850 }
851
852 /* processing to retry once per second */
853 ++waitCount;
854 waitCount %= 60;
855
856 /* It is recommended to wait for approximately 10 to 20 seconds and then briefly display a message prompting the user to try again later.
857 */
858
859 return;
860 }
861
862 /*---------------------------------------------------------------------------*
863 Name : UpdateErrorMsg
864 Description : This function is called each frame while displaying an error to perform non-rendering updates.
865 Arguments : input - Input data from controller buttons (KPAD and PAD)
866 Returns : None.
867 *---------------------------------------------------------------------------*/
UpdateErrorMsg(u32 input)868 static void UpdateErrorMsg( u32 input )
869 {
870 /* (B) button */
871 if ( input & (KPAD_BUTTON_B|(PAD_BUTTON_B<<16)) )
872 {
873 g_state = MB_STATE_MENU;
874 }
875
876 return;
877 }
878
879 /*======== End of MsgViewerUpdate.c ========*/
880