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.2  2007/02/02 02:20:33  torigoe_nobutaka
15   Added OpenLib() and CloseLib().
16   Added handling of message without subject or body text.
17   Fixed bug in GetMsgIdList().
18 
19   Revision 1.1  2006/09/27 08:57:45  torigoe_nobutaka
20   Renamed from MessageViewer.c
21   Moved from nwc24demo/src.
22 
23   Revision 1.4  2006/09/27 07:31:45  torigoe_nobutaka
24   Improved performance.
25 
26   Revision 1.3  2006/09/13 08:14:22  yosizaki
27   Changed to call VFInit().
28 
29   Revision 1.2  2006/09/10 09:20:56  hirose_kazuki
30   Changed to use NWC24OpenLib/NWC24CloseLib instead of obsolete APIs.
31 
32   Revision 1.1  2006/08/28 08:51:51  torigoe_nobutaka
33   Initial check in.
34 
35 
36   $NoKeywords: $
37  *---------------------------------------------------------------------------*/
38 
39 #include <revolution.h>
40 #include <revolution/mem.h>
41 #include <revolution/kpad.h>
42 #include <revolution/nand.h>
43 #include <revolution/vf.h>
44 #include <revolution/nwc24.h>
45 #include <string.h>
46 
47 #define DEMO_USE_MEMLIB 1
48 #include <demo.h>
49 
50 #include "MsgViewer.h"
51 #include "MsgViewerRender.h"
52 #include "MsgViewerUpdate.h"
53 
54 /*---------------------------------------------------------------------------*
55    Global constants
56  *---------------------------------------------------------------------------*/
57 const GXColor   CLR_DARKBLUE                        = {   0,   0,  40, 255 };
58 const GXColor   CLR_WHITE                           = { 255, 255, 255, 255 };
59 const GXColor   CLR_YELLOW                          = { 255, 255,   0, 255 };
60 const char*     HIDDEN_MESSAGE                      = "(Cannot read.)";
61 
62 /*---------------------------------------------------------------------------*
63    Global variables
64  *---------------------------------------------------------------------------*/
65 s16             g_screenWidth;
66 s16             g_screenHeight;
67 OSFontHeader*   g_fontData                                      = NULL;
68 u32             g_longHold                                      = 0;                // Button held down
69 MsgBoxState     g_state                                         = MB_STATE_MENU;
70 MsgBoxMenu      g_selectedMenu                                  = MB_MENU_RECV_BOX;
71 u32*            g_idListBuf[NUM_MSG_BOX_TYPES]                  = { NULL };
72 u32             g_numMsgs[NUM_MSG_BOX_TYPES]                    = { 0 };
73 u32             g_idxSelectedId[NUM_MSG_BOX_TYPES]              = { 0 };
74 u32             g_idxIdTopOfList[NUM_MSG_BOX_TYPES]             = { 0 };
75 u32             g_lineTopOfBodyText                             = 0;
76 u32             g_numLinesBodyText                              = 1;
77 char*           g_subjectBuf[NUM_MSG_BOX_TYPES][LIST_BOX_ROWS]  = { { NULL }, { NULL } };
78 u32             g_idxSubjectBufStart[NUM_MSG_BOX_TYPES]         = { 0 };
79 MsgData         g_msgData;
80 
81 /*---------------------------------------------------------------------------*
82    Static constants
83  *---------------------------------------------------------------------------*/
84 static const    u32     HOLD_THRESHOLD      =   10;
85 #define                 NUM_KPAD_BUTTONS        16
86 
87 /*---------------------------------------------------------------------------*
88    Static variables
89  *---------------------------------------------------------------------------*/
90 static  char*   s_libWorkMem                        = NULL;
91 static  u32     s_holdCount[NUM_KPAD_BUTTONS]       = { 0 };
92 
93 /*---------------------------------------------------------------------------*
94    Local functions
95  *---------------------------------------------------------------------------*/
96 static void     OpenLib         ( void );
97 static void     CloseLib        ( void );
98 static void*    AllocFromPadHeap( u32 size );
99 static u8       FreeToPadHeap   ( void* ptr );
100 static void     SampleInitialize( void );
101 static void     SampleFinalize  ( void );
102 
103 /*---------------------------------------------------------------------------*
104    App entry point
105  *---------------------------------------------------------------------------*/
main(void)106 int main( void )
107 {
108     KPADStatus  input;
109     u8          iButton;
110 
111     SampleInitialize();
112     (void)memset( &input, 0, sizeof(KPADStatus) );
113 
114     /* App main loop */
115     while ( TRUE )
116     {
117         (void)KPADRead( WPAD_CHAN0, &input, 1 );
118 
119         /* Button hold detect */
120         for ( iButton = 0; iButton < NUM_KPAD_BUTTONS; ++iButton )
121         {
122             if ( (input.hold >> iButton) & 0x1 )
123             {
124                 ++s_holdCount[iButton];
125             }
126             else
127             {
128                 s_holdCount[iButton] = 0;
129             }
130 
131             if ( HOLD_THRESHOLD < s_holdCount[iButton] )
132             {
133                 g_longHold |= 0x1 << iButton;
134             }
135             else
136             {
137                 g_longHold &= ~(0x1 << iButton);
138             }
139         }
140 
141         OpenLib();
142 
143         /* Update processing other than rendering */
144         Update( &input );
145 
146         /* Render */
147         DEMOBeforeRender();
148         Render();
149         DEMODoneRender();
150 
151         CloseLib();
152     }
153 
154     SampleFinalize();
155 
156     OSHalt( "All done." );
157     return 0;
158 }
159 
160 /*---------------------------------------------------------------------------*
161   Name: CheckError
162   Description: Check the error code of NWC24Err type, and if not NWC24_OK, display the error details.
163 
164   Arguments   : strFunc     - Function name that returned an error code.
165                 err         - NWC24Err type error code.
166   Returns: NWC24Err    -Same value as err.
167  *---------------------------------------------------------------------------*/
CheckError(const char * strFunc,NWC24Err err)168 void CheckError( const char* strFunc, NWC24Err err )
169 {
170     if ( err != NWC24_OK )
171     {
172         OSReport( "%s: error %d\n", strFunc, err );
173         OSHalt( "Failed.\n" );
174     }
175 
176     return;
177 }
178 
179 /*---------------------------------------------------------------------------*
180   Name: GetMsgIdList
181   Description: Obtain the total message count and message ID list in the specified message box.
182 
183   Arguments: mBoxId  - Message box type.
184   Returns: None.
185  *---------------------------------------------------------------------------*/
GetMsgIdList(NWC24MsgBoxId mBoxId)186 void GetMsgIdList( NWC24MsgBoxId mBoxId )
187 {
188     NWC24Err    err;
189     u32         bufSize;
190     MsgBoxType  mbType  = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
191 
192     err = NWC24GetNumMsgs( mBoxId, &g_numMsgs[mbType] );
193     CheckError( "NWC24GetNumMsgs()", err );
194 
195     if ( g_numMsgs[mbType] == 0 )
196     {
197         g_idListBuf[mbType] = NULL;
198         return;
199     }
200 
201     bufSize = OSRoundUp32B( g_numMsgs[mbType] * sizeof(u32) );
202     g_idListBuf[mbType] = (u32*)MEMAllocFromAllocator( &DemoAllocator1, bufSize );
203     err = NWC24GetMsgIdList( mBoxId, g_idListBuf[mbType], g_numMsgs[mbType] );
204     CheckError( "NWC24GetMsgIdList()", err );
205 
206     return;
207 }
208 
209 /*---------------------------------------------------------------------------*
210   Name: ReleaseMsgIdList
211   Description: Frees the memory used for the message ID list in the specified message box.
212 
213   Arguments: mBoxId  - Message box type.
214   Returns: None.
215  *---------------------------------------------------------------------------*/
ReleaseMsgIdList(NWC24MsgBoxId mBoxId)216 void ReleaseMsgIdList( NWC24MsgBoxId mBoxId )
217 {
218     MsgBoxType  mbType  = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
219 
220     if ( g_idListBuf[mbType] )
221     {
222         MEMFreeToAllocator( &DemoAllocator1, g_idListBuf[mbType] );
223         g_idListBuf[mbType] = NULL;
224     }
225 
226     return;
227 }
228 
229 /*---------------------------------------------------------------------------*
230   Name: GetListedSubjects
231   Description: Obtains the title of the message displayed onscreen for the specified message box.
232 
233   Arguments: mBoxId  - Message box type.
234   Returns: None.
235  *---------------------------------------------------------------------------*/
GetListedSubjects(NWC24MsgBoxId mBoxId)236 void GetListedSubjects( NWC24MsgBoxId mBoxId )
237 {
238     NWC24Err    err;
239     u32         subjectSize;
240     NWC24MsgObj msgObj;
241     u32         i;
242     MsgBoxType  mbType  = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
243 
244     g_idxSubjectBufStart[mbType] = 0;
245 
246     for ( i = 0; i < LIST_BOX_ROWS; ++i )
247     {
248         u32     idxIdListBuf    = (u32)(g_idxIdTopOfList[mbType] + i);
249 
250         if ( g_numMsgs[mbType] <= idxIdListBuf )
251         {
252             break;
253         }
254 
255         err = NWC24GetMsgObj( &msgObj, mBoxId, g_idListBuf[mbType][idxIdListBuf] );
256         if ( err == NWC24_ERR_HIDDEN )
257         {
258             subjectSize = strlen( HIDDEN_MESSAGE ) + 1;
259             g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, subjectSize );
260             (void)memcpy( g_subjectBuf[mbType][i], HIDDEN_MESSAGE, subjectSize );
261         }
262         else
263         {
264             CheckError( "NWC24GetMsgObj()", err );
265 
266             err = NWC24GetMsgSubjectSize( &msgObj, &subjectSize );
267             CheckError( "NWC24GetMsgSubjectSize()", err );
268 
269             if ( subjectSize < 1 )
270             {
271                 subjectSize = 1;
272             }
273 
274             g_subjectBuf[mbType][i] = MEMAllocFromAllocator( &DemoAllocator1, subjectSize );
275             err = NWC24ReadMsgSubject( &msgObj, g_subjectBuf[mbType][i], subjectSize );
276             if ( err != NWC24_OK )
277             {
278                 g_subjectBuf[mbType][i][0] = '\0';
279             }
280         }
281     }
282 
283     return;
284 }
285 
286 /*---------------------------------------------------------------------------*
287   Name: ReleaseListedSubjects
288   Description: Obtains the title of the message displayed onscreen for the specified message box.
289 
290   Arguments: mBoxId  - Message box type.
291   Returns: None.
292  *---------------------------------------------------------------------------*/
ReleaseListedSubjects(NWC24MsgBoxId mBoxId)293 void ReleaseListedSubjects( NWC24MsgBoxId mBoxId )
294 {
295     u32         i;
296     MsgBoxType  mbType  = (mBoxId == NWC24_RECV_BOX) ? MB_TYPE_RECV : MB_TYPE_SEND;
297 
298     for ( i = 0; i < LIST_BOX_ROWS; ++i )
299     {
300         if ( g_subjectBuf[mbType][i] )
301         {
302             MEMFreeToAllocator( &DemoAllocator1, g_subjectBuf[mbType][i] );
303             g_subjectBuf[mbType][i] = NULL;
304         }
305     }
306 
307     return;
308 }
309 
310 /*---------------------------------------------------------------------------*
311   Name: OpenLib
312   Description: Calls NWC24OpenLib().
313   Arguments: None.
314   Returns: None.
315  *---------------------------------------------------------------------------*/
OpenLib(void)316 static void OpenLib( void )
317 {
318     NWC24Err    err;
319 
320     err = NWC24OpenLib( s_libWorkMem );
321     while ( err == NWC24_ERR_BUSY )
322     {
323         OSSleepSeconds( 1 );
324         err = NWC24OpenLib( s_libWorkMem );
325     }
326     CheckError( "NWC24OpenLib()", err );
327 }
328 
329 /*---------------------------------------------------------------------------*
330   Name: CloseLib
331   Description: Calls NWC24CloseLib().
332   Arguments: None.
333   Returns: None.
334  *---------------------------------------------------------------------------*/
CloseLib(void)335 static void CloseLib( void )
336 {
337     NWC24Err    err;
338 
339     err = NWC24CloseLib();
340     CheckError( "NWC24CloseLib()", err );
341 }
342 
343 /*---------------------------------------------------------------------------*
344   Name: AllocFromPadHeap
345   Description: Dynamically allocates memory for the WPAD library.
346   Arguments: size    -   Specifies the size of memory to be allocated (in bytes).
347   Returns: void*   - Start address of the allocated memory.
348  *---------------------------------------------------------------------------*/
AllocFromPadHeap(u32 size)349 static void* AllocFromPadHeap( u32 size )
350 {
351     return MEMAllocFromAllocator( &DemoAllocator2, size );
352 }
353 
354 /*---------------------------------------------------------------------------*
355   Name: FreeToPadHeap
356   Description: Frees memory dynamically allocated for the WPAD library.
357   Arguments: ptr - Start address of the memory to be freed.
358   Returns: u8      -   Returns 0 if the attempt to free memory fails.
359  *---------------------------------------------------------------------------*/
FreeToPadHeap(void * ptr)360 static u8 FreeToPadHeap( void* ptr )
361 {
362     if ( !ptr )
363     {
364         return 0;
365     }
366 
367     MEMFreeToAllocator( &DemoAllocator2, ptr );
368     ptr = NULL;
369 
370     return 1;
371 }
372 
373 /*---------------------------------------------------------------------------*
374   Name: SampleInitialize
375   Description: Initializes the sample program.
376   Arguments: None.
377   Returns: None.
378  *---------------------------------------------------------------------------*/
SampleInitialize(void)379 static void SampleInitialize( void )
380 {
381     OSInit();
382 
383     /* Initialize DEMO and GX */
384     {
385         GXRenderModeObj*    renderMode  = NULL;
386 
387         DEMOInit( NULL );
388         g_fontData = DEMOInitROMFont();
389         DEMOSetROMFontSize( FONT_SIZE, 0 );
390         renderMode = DEMOGetRenderModeObj();
391         g_screenWidth = (s16)renderMode->fbWidth;
392         g_screenHeight = (s16)renderMode->efbHeight;
393         DEMOInitCaption( DM_FT_XLU, g_screenWidth, g_screenHeight );
394         GXSetCopyClear( CLR_DARKBLUE, GX_MAX_Z24 );
395         GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO );
396         GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV );
397         GXSetTevColor( GX_TEVREG0, CLR_WHITE );
398     }
399 
400     /* Initialize NAND */
401     {
402         s32     result;
403 
404         result = NANDInit();
405         if ( result != NAND_RESULT_OK )
406         {
407             OSHalt("NANDInit() failed.\n");
408         }
409     }
410 
411     /* Initialize VF */
412     {
413         VFInit();
414     }
415 
416     /* Initialize KPAD */
417     {
418         WPADRegisterAllocator( AllocFromPadHeap, FreeToPadHeap );
419         KPADInit();
420     }
421 
422     /* Initialize other applications */
423     {
424         s_libWorkMem = MEMAllocFromAllocator( &DemoAllocator1, NWC24_WORK_MEM_SIZE );
425 
426         OpenLib();
427 
428         /* Initialize message ID list */
429         GetMsgIdList( NWC24_RECV_BOX );
430         GetMsgIdList( NWC24_SEND_BOX );
431 
432         /* Initialize the title buffer of displayed message */
433         GetListedSubjects( NWC24_RECV_BOX );
434         GetListedSubjects( NWC24_SEND_BOX );
435 
436         CloseLib();
437     }
438 
439     return;
440 }
441 
442 /*---------------------------------------------------------------------------*
443   Name: SampleFinalize
444   Description: Finalizes the sample program.
445   Arguments: None.
446   Returns: None.
447  *---------------------------------------------------------------------------*/
SampleFinalize(void)448 static void SampleFinalize( void )
449 {
450     MEMFreeToAllocator( &DemoAllocator1, s_libWorkMem );
451     ReleaseMsgIdList( NWC24_RECV_BOX );
452     ReleaseMsgIdList( NWC24_SEND_BOX );
453     ReleaseListedSubjects( NWC24_RECV_BOX );
454     ReleaseListedSubjects( NWC24_SEND_BOX );
455     return;
456 }
457 
458 /*======== End of MsgViewer.c ========*/
459