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