1 /*---------------------------------------------------------------------------*
2 Project: WiiConnect24 API demos
3 File: MsgViewer.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: MsgViewer.c,v $
14 Revision 1.7 2008/05/30 02:27:03 seiki_masashi
15 Reverted code consequent upon reverted SDK code.
16
17 Revision 1.5 2008/05/01 08:50:26 hirose_kazuki
18 Added "Close library" mode.
19
20 Revision 1.4 2008/04/28 11:20:23 hirose_kazuki
21 Updated framework.
22
23 Revision 1.3 2008/01/21 10:39:05 hirose_kazuki
24 Changed to suspend the scheduler by default.
25 Modified main sequence to avoid calling OpenLib/CloseLib every frame.
26
27 Revision 1.2 2007/02/02 02:20:33 torigoe_nobutaka
28 Added OpenLib() and CloseLib().
29 Added handling of messages without subject or body text.
30 Fixed bug in GetMsgIdList().
31
32 Revision 1.1 2006/09/27 08:57:45 torigoe_nobutaka
33 Renamed from MessageViewer.c
34 Moved from nwc24demo/src.
35
36 Revision 1.4 2006/09/27 07:31:45 torigoe_nobutaka
37 Improved performance.
38
39 Revision 1.3 2006/09/13 08:14:22 yosizaki
40 Changed to call VFInit().
41
42 Revision 1.2 2006/09/10 09:20:56 hirose_kazuki
43 Changed to use NWC24OpenLib/NWC24CloseLib instead of obsolete functions.
44
45 Revision 1.1 2006/08/28 08:51:51 torigoe_nobutaka
46 Initial check in.
47
48
49 $NoKeywords: $
50 *---------------------------------------------------------------------------*/
51
52 #include <revolution.h>
53 #include <revolution/mem.h>
54 #include <revolution/kpad.h>
55 #include <revolution/nand.h>
56 #include <revolution/vf.h>
57 #include <revolution/nwc24.h>
58 #include <revolution/net.h>
59 #include <string.h>
60
61 #define DEMO_USE_MEMLIB 1
62 #include <demo.h>
63
64 #include "MsgViewer.h"
65 #include "MsgViewerRender.h"
66 #include "MsgViewerUpdate.h"
67
68 /*---------------------------------------------------------------------------*
69 Global variables
70 *---------------------------------------------------------------------------*/
71 s16 g_screenWidth;
72 s16 g_screenHeight;
73 OSFontHeader* g_fontData = NULL;
74 MsgBoxState g_state = MB_STATE_MENU;
75 MsgBoxMenu g_selectedMenu = MB_MENU_RECV_BOX;
76 u32* g_idListBuf[NUM_MSG_BOX_TYPES] = { NULL };
77 u32 g_numMsgs[NUM_MSG_BOX_TYPES] = { 0 };
78 u32 g_idxSelectedId[NUM_MSG_BOX_TYPES] = { 0 };
79 u32 g_idxIdTopOfList[NUM_MSG_BOX_TYPES] = { 0 };
80 u32 g_lineTopOfBodyText = 0;
81 u32 g_numLinesBodyText = 1;
82 char* g_subjectBuf[NUM_MSG_BOX_TYPES][LIST_BOX_ROWS] = { { NULL }, { NULL } };
83 u32 g_idxSubjectBufStart[NUM_MSG_BOX_TYPES] = { 0 };
84 MsgData g_msgData;
85 s32 g_errorCode = 0;
86
87 /*---------------------------------------------------------------------------*
88 Global constants
89 *---------------------------------------------------------------------------*/
90 const GXColor CLR_DARKBLUE = { 0, 0, 40, 255 };
91 const GXColor CLR_WHITE = { 255, 255, 255, 255 };
92 const char* HIDDEN_MESSAGE = "(Cannot read.)";
93 const char* BROKEN_MESSAGE = "(May be broken.)";
94
95 /*---------------------------------------------------------------------------*
96 Static constants
97 *---------------------------------------------------------------------------*/
98 static const u32 HOLD_THRESHOLD = 10;
99 #define NUM_KPAD_BUTTONS 16
100
101 #define PAD_BUTTONS_USED \
102 ((PAD_BUTTON_A)|(PAD_BUTTON_B)|(PAD_BUTTON_UP)|(PAD_BUTTON_DOWN))
103
104 #define KPAD_BUTTONS_USED \
105 ((KPAD_BUTTON_A)|(KPAD_BUTTON_B)|(KPAD_BUTTON_UP)|(KPAD_BUTTON_DOWN))
106
107 #define ALL_BUTTONS_USED \
108 ((KPAD_BUTTONS_USED)|((PAD_BUTTONS_USED)<<16))
109
110 #define PAD_BUTTONS_REPEATABLE \
111 ((PAD_BUTTON_UP)|(PAD_BUTTON_DOWN))
112
113 #define KPAD_BUTTONS_REPEATABLE \
114 ((KPAD_BUTTON_UP)|(KPAD_BUTTON_DOWN))
115
116 #define ALL_BUTTONS_REPEATABLE \
117 ((KPAD_BUTTONS_REPEATABLE)|((PAD_BUTTONS_REPEATABLE)<<16))
118
119
120 /*---------------------------------------------------------------------------*
121 Static variables
122 *---------------------------------------------------------------------------*/
123 static char* s_libWorkMem = NULL;
124 static u32 s_longHold = 0; // Button held down
125 static u32 s_holdCount[32] = { 0 };
126
127 /*---------------------------------------------------------------------------*
128 Local functions
129 *---------------------------------------------------------------------------*/
130 static void* AllocFromPadHeap( u32 size );
131 static u8 FreeToPadHeap ( void* ptr );
132 static void SampleInitialize( void );
133 static void SampleFinalize ( void );
134
135 /*---------------------------------------------------------------------------*
136 App entry point
137 *---------------------------------------------------------------------------*/
main(void)138 int main( void )
139 {
140 KPADStatus input;
141 u32 hold;
142 u32 trig;
143 u8 iButton;
144
145 SampleInitialize();
146 (void)memset( &input, 0, sizeof(KPADStatus) );
147
148 /* App main loop */
149 while ( TRUE )
150 {
151 DEMOPadRead();
152 (void)KPADRead( WPAD_CHAN0, &input, 1 );
153
154 /* Combination of KPAD and PAD */
155 hold = (input.hold) | (DEMOPadGetButton(0) << 16);
156 trig = (input.trig) | (DEMOPadGetButtonDown(0) << 16);
157
158 /* Button hold detect */
159 for ( iButton = 0; iButton < 32; ++iButton )
160 {
161 if ( (hold >> iButton) & 0x1 )
162 {
163 ++s_holdCount[iButton];
164 }
165 else
166 {
167 s_holdCount[iButton] = 0;
168 }
169
170 if ( HOLD_THRESHOLD < s_holdCount[iButton] )
171 {
172 s_longHold |= 0x1 << iButton;
173 }
174 else
175 {
176 s_longHold &= ~(0x1 << iButton);
177 }
178 }
179
180 trig |= (s_longHold & ALL_BUTTONS_REPEATABLE);
181
182 /* Update processing other than rendering */
183 Update( trig );
184
185 /* Render */
186 DEMOBeforeRender();
187 Render();
188 DEMODoneRender();
189 }
190
191 SampleFinalize();
192
193 OSHalt( "All done." );
194 return 0;
195 }
196
197 /*---------------------------------------------------------------------------*
198 Name : CheckError
199 Description : Checks the error code of NWC24Err-type errors, and if not NWC24_OK, displays the error content.
200
201 Arguments : strFunc - Name of function that returned the error code.
202 err - NWC24Err-type error code.
203 Returns : NWC24Err -Same value as err.
204 *---------------------------------------------------------------------------*/
CheckError(const char * strFunc,NWC24Err err)205 void CheckError( const char* strFunc, NWC24Err err )
206 {
207 if ( err != NWC24_OK )
208 {
209 OSReport( "%s: error %d\n", strFunc, err );
210 OSHalt( "Failed.\n" );
211 }
212
213 return;
214 }
215
216 /*---------------------------------------------------------------------------*
217 Name : GetMsgIdList
218 Description : Get the total message count and message ID list in the specified message box.
219
220 Arguments : mBoxId - Message box type.
221 Returns : None.
222 *---------------------------------------------------------------------------*/
GetMsgIdList(NWC24MsgBoxId mBoxId)223 void GetMsgIdList( NWC24MsgBoxId mBoxId )
224 {
225 NWC24Err err;
226 u32 bufSize;
227 MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
228
229 err = NWC24GetNumMsgs( mBoxId, &g_numMsgs[mbType] );
230 CheckError( "NWC24GetNumMsgs()", err );
231
232 if ( g_numMsgs[mbType] == 0 )
233 {
234 g_idListBuf[mbType] = NULL;
235 return;
236 }
237
238 bufSize = OSRoundUp32B( g_numMsgs[mbType] * sizeof(u32) );
239 g_idListBuf[mbType] = (u32*)MEMAllocFromAllocator( &DemoAllocator1, bufSize );
240 err = NWC24GetMsgIdList( mBoxId, g_idListBuf[mbType], g_numMsgs[mbType] );
241 CheckError( "NWC24GetMsgIdList()", err );
242
243 return;
244 }
245
246 /*---------------------------------------------------------------------------*
247 Name : ReleaseMsgIdList
248 Description : Deallocates the memory used for the message ID list in the specified message box.
249
250 Arguments : mBoxId - Message box type.
251 Returns : None.
252 *---------------------------------------------------------------------------*/
ReleaseMsgIdList(NWC24MsgBoxId mBoxId)253 void ReleaseMsgIdList( NWC24MsgBoxId mBoxId )
254 {
255 MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
256
257 if ( g_idListBuf[mbType] )
258 {
259 MEMFreeToAllocator( &DemoAllocator1, g_idListBuf[mbType] );
260 g_idListBuf[mbType] = NULL;
261 }
262
263 return;
264 }
265
266 /*---------------------------------------------------------------------------*
267 Name : ReadSubject
268 Description : Reads the subject from the specified message and copies only the specified length to the buffer.
269
270 Arguments : buf - Buffer to copy to
271 size - Maximum size to copy
272 mBoxId - Message box type.
273 msgId - Message ID.
274 Returns : BOOL - TRUE if successful.
275 *---------------------------------------------------------------------------*/
ReadSubject(char * buf,u32 size,NWC24MsgBoxId mBoxId,u32 msgId)276 BOOL ReadSubject( char* buf, u32 size, NWC24MsgBoxId mBoxId, u32 msgId )
277 {
278 NWC24Err err;
279 NWC24MsgObj msgObj;
280 BOOL result = FALSE;
281 u32 subjectSize;
282 char* subjectBuf = NULL;
283
284 err = NWC24GetMsgObj( &msgObj, mBoxId, msgId );
285 if ( err == NWC24_ERR_HIDDEN )
286 {
287 (void)strncpy(buf, HIDDEN_MESSAGE, size);
288 return FALSE;
289 }
290 else
291 {
292 err = NWC24GetMsgSubjectSize( &msgObj, &subjectSize );
293 if ( err != NWC24_OK )
294 {
295 (void)strncpy( buf, BROKEN_MESSAGE, size );
296 return FALSE;
297 }
298
299 if ( subjectSize < 1 )
300 {
301 subjectSize = 1;
302 }
303
304 subjectBuf = MEMAllocFromAllocator( &DemoAllocator1, subjectSize );
305 err = NWC24ReadMsgSubject( &msgObj, subjectBuf, subjectSize );
306
307 if ( err != NWC24_OK )
308 {
309 result = FALSE;
310 (void)strncpy( buf, BROKEN_MESSAGE, size );
311 }
312 else
313 {
314 result = TRUE;
315 (void)strncpy( buf, subjectBuf, size );
316 }
317 MEMFreeToAllocator( &DemoAllocator1, subjectBuf );
318 }
319
320 return result;
321 }
322
323 /*---------------------------------------------------------------------------*
324 Name : GetListedSubjects
325 Description : Gets the title of the message displayed onscreen for the specified message box.
326
327 Arguments : mBoxId - Message box type.
328 Returns : None.
329 *---------------------------------------------------------------------------*/
GetListedSubjects(NWC24MsgBoxId mBoxId)330 void GetListedSubjects( NWC24MsgBoxId mBoxId )
331 {
332 u32 i;
333 MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
334
335 g_idxSubjectBufStart[mbType] = 0;
336
337 for ( i = 0; i < LIST_BOX_ROWS; ++i )
338 {
339 u32 idxIdListBuf = (u32)(g_idxIdTopOfList[mbType] + i);
340
341 if ( g_numMsgs[mbType] <= idxIdListBuf )
342 {
343 break;
344 }
345
346 g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, LEN_SUBJECT_DISP );
347 (void)NETMemSet( g_subjectBuf[mbType][i], 0, LEN_SUBJECT_DISP );
348 (void)ReadSubject( g_subjectBuf[mbType][i], LEN_SUBJECT_DISP-1, mBoxId,
349 g_idListBuf[mbType][idxIdListBuf] );
350 }
351
352 return;
353 }
354
355 /*---------------------------------------------------------------------------*
356 Name : ReleaseListedSubjects
357 Description : Deallocates the buffer for the title of the message displayed onscreen for the specified message box.
358
359 Arguments : mBoxId - Message box type.
360 Returns : None.
361 *---------------------------------------------------------------------------*/
ReleaseListedSubjects(NWC24MsgBoxId mBoxId)362 void ReleaseListedSubjects( NWC24MsgBoxId mBoxId )
363 {
364 u32 i;
365 MsgBoxType mbType = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
366
367 for ( i = 0; i < LIST_BOX_ROWS; ++i )
368 {
369 if ( g_subjectBuf[mbType][i] )
370 {
371 MEMFreeToAllocator( &DemoAllocator1, g_subjectBuf[mbType][i] );
372 g_subjectBuf[mbType][i] = NULL;
373 }
374 }
375
376 return;
377 }
378
379 /*---------------------------------------------------------------------------*
380 Name : OpenLib
381 Description : Calls NWC24OpenLib().
382 Arguments : None.
383 Returns : None.
384 *---------------------------------------------------------------------------*/
OpenLib(void)385 BOOL OpenLib( void )
386 {
387 NWC24Err err;
388
389 err = NWC24OpenLib( s_libWorkMem );
390 if ( err == NWC24_ERR_BUSY ||
391 err == NWC24_ERR_MUTEX ||
392 err == NWC24_ERR_INPROGRESS )
393 {
394 g_errorCode = NWC24GetErrorCode();
395 return FALSE;
396 }
397 if ( err != NWC24_OK )
398 {
399 g_errorCode = NWC24GetErrorCode();
400 g_state = MB_STATE_ERROR_STOP;
401 return FALSE;
402 }
403
404 g_errorCode = 0;
405 g_state = MB_STATE_MENU;
406 return TRUE;
407 }
408
409 /*---------------------------------------------------------------------------*
410 Name : CloseLib
411 Description : Calls NWC24CloseLib().
412 Arguments : None.
413 Returns : None.
414 *---------------------------------------------------------------------------*/
CloseLib(void)415 BOOL CloseLib( void )
416 {
417 NWC24Err err;
418
419 err = NWC24CloseLib();
420 if ( err != NWC24_OK )
421 {
422 g_errorCode = NWC24_ERRCODE_UNDEFINED;
423 g_state = MB_STATE_ERROR_STOP;
424 return FALSE;
425 }
426
427 g_errorCode = 0;
428 g_state = MB_STATE_LIB_CLOSED;
429 return TRUE;
430 }
431
432 /*---------------------------------------------------------------------------*
433 Name : AllocFromPadHeap
434 Description : Dynamically allocates memory for the WPAD library.
435 Arguments : size - Specifies the size of memory to allocate (in bytes).
436 Returns : void* - Start address of the allocated memory.
437 *---------------------------------------------------------------------------*/
AllocFromPadHeap(u32 size)438 static void* AllocFromPadHeap( u32 size )
439 {
440 return MEMAllocFromAllocator( &DemoAllocator2, size );
441 }
442
443 /*---------------------------------------------------------------------------*
444 Name : FreeToPadHeap
445 Description : Deallocates memory dynamically allocated for the WPAD library.
446 Arguments : ptr - Start address of the memory to deallocate.
447 Returns : u8 - Returns 0 if the attempt to deallocate memory fails.
448 *---------------------------------------------------------------------------*/
FreeToPadHeap(void * ptr)449 static u8 FreeToPadHeap( void* ptr )
450 {
451 if ( !ptr )
452 {
453 return 0;
454 }
455
456 MEMFreeToAllocator( &DemoAllocator2, ptr );
457 ptr = NULL;
458
459 return 1;
460 }
461
462 /*---------------------------------------------------------------------------*
463 Name : SampleInitialize
464 Description : Initializes the sample program.
465 Arguments : None.
466 Returns : None.
467 *---------------------------------------------------------------------------*/
SampleInitialize(void)468 static void SampleInitialize( void )
469 {
470 OSInit();
471
472 /* Initialize DEMO and GX */
473 {
474 GXRenderModeObj* renderMode = NULL;
475
476 DEMOInit( NULL );
477 g_fontData = DEMOInitROMFont();
478 DEMOSetROMFontSize( FONT_SIZE, 0 );
479 renderMode = DEMOGetRenderModeObj();
480 g_screenWidth = (s16)renderMode->fbWidth;
481 g_screenHeight = (s16)renderMode->efbHeight;
482 DEMOInitCaption( DM_FT_XLU, g_screenWidth, g_screenHeight );
483 GXSetCopyClear( CLR_DARKBLUE, GX_MAX_Z24 );
484 GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO );
485 GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
486 GXSetTevColor( GX_TEVREG0, CLR_WHITE );
487 }
488
489 /* Initialize NAND */
490 {
491 s32 result;
492
493 result = NANDInit();
494 if ( result != NAND_RESULT_OK )
495 {
496 OSHalt("NANDInit() failed.\n");
497 }
498 }
499
500 /* Initialize VF */
501 {
502 VFInit();
503 }
504
505 /* Initialize KPAD. */
506 {
507 WPADRegisterAllocator( AllocFromPadHeap, FreeToPadHeap );
508 KPADInit();
509 }
510
511 /* Initialize other applications */
512 {
513 s_libWorkMem = MEMAllocFromAllocator( &DemoAllocator1, NWC24_WORK_MEM_SIZE );
514
515 /* Fundamentally, NWC24 is left open in this demo */
516 if ( OpenLib() )
517 {
518 /* Initialize message ID list */
519 GetMsgIdList( NWC24_RECV_BOX );
520 GetMsgIdList( NWC24_SEND_BOX );
521
522 /* Initialize the title buffer of displayed message */
523 GetListedSubjects( NWC24_RECV_BOX );
524 GetListedSubjects( NWC24_SEND_BOX );
525 }
526 }
527
528 return;
529 }
530
531 /*---------------------------------------------------------------------------*
532 Name : SampleFinalize
533 Description : Finalizes the sample program.
534 Arguments : None.
535 Returns : None.
536 *---------------------------------------------------------------------------*/
SampleFinalize(void)537 static void SampleFinalize( void )
538 {
539 MEMFreeToAllocator( &DemoAllocator1, s_libWorkMem );
540 ReleaseMsgIdList( NWC24_RECV_BOX );
541 ReleaseMsgIdList( NWC24_SEND_BOX );
542 ReleaseListedSubjects( NWC24_RECV_BOX );
543 ReleaseListedSubjects( NWC24_SEND_BOX );
544 return;
545 }
546
547 /*======== End of MsgViewer.c ========*/
548