1 /*---------------------------------------------------------------------------*
2 Project: WiiConnect24 API demos
3 File: FLViewer.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: FLViewer.c,v $
14 Revision 1.2 2007/01/24 06:25:22 torigoe_nobutaka
15 Added processing for when the POWER and RESET Buttons are pressed.
16
17 Revision 1.1 2006/09/27 08:56:17 torigoe_nobutaka
18 Moved from nwc24demo/src.
19
20 Revision 1.1 2006/09/13 10:07:05 torigoe_nobutaka
21 Initial check in.
22
23 $NoKeywords: $
24 *---------------------------------------------------------------------------*/
25 #include <revolution.h>
26 #include <revolution/mem.h>
27 #include <revolution/kpad.h>
28 #include <revolution/nand.h>
29 #include <revolution/vf.h>
30 #include <revolution/nwc24.h>
31 #include <revolution/enc.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #define DEMO_USE_MEMLIB 1
36 #include <demo.h>
37
38 #include "FLViewer.h"
39 #include "FLViewerUpdate.h"
40 #include "FLViewerRender.h"
41
42 /*---------------------------------------------------------------------------*
43 Global constants
44 *---------------------------------------------------------------------------*/
45 const GXColor CLR_DARKBLUE = { 0, 0, 40, 255 };
46 const GXColor CLR_WHITE = { 255, 255, 255, 255 };
47 const GXColor CLR_GRAY = { 63, 63, 63, 255 };
48 const GXColor CLR_YELLOW = { 255, 255, 0, 255 };
49 const GXColor CLR_DARKYELLOW = { 127, 127, 0, 255 };
50 const GXColor CLR_GREEN = { 0, 255, 0, 255 };
51 const char* STR_NOT_REGISTERED = "----------";
52 const BOOL UPDATABLE_ITEM_TABLE[] =
53 {
54 FALSE,
55 FALSE,
56 TRUE,
57 TRUE,
58 FALSE
59 };
60
61 /*---------------------------------------------------------------------------*
62 Static constants
63 *---------------------------------------------------------------------------*/
64 #define NUM_KPAD_BUTTONS 16
65 static const u32 HOLD_THRESHOLD = 25;
66 static const u32 HOLD_WAIT = 3;
67
68 /*---------------------------------------------------------------------------*
69 Global variables
70 *---------------------------------------------------------------------------*/
71 s16 g_screenWidth;
72 s16 g_screenHeight;
73 u32 g_longHold = 0; // Button held down
74 AppState g_state = STATE_SELECT_FRIEND;
75 u32 g_numFriendInfos = 0;
76 u32 g_idxSelectedFriend = 0;
77 u32 g_idxTopOfFriendList = 0;
78 u8 g_selectedEditItem = EDIT_ITEM_TYPE;
79 NWC24FriendInfo* g_tempInfo = NULL;
80 EditFriendInfo g_editFriendInfo; // Friend information being edited
81 EditFriendInfo g_backupFriendInfo; // Friend information for Undo
82 char g_nameBuf[LIST_BOX_ROWS][NAME_BUF_SIZE];
83 u32 g_idxNameBufStart = 0;
84 char g_hexBuf[HEX_BUF_SIZE] = "";
85 BOOL g_bHelp = TRUE;
86
87 /*---------------------------------------------------------------------------*
88 Static variables
89 *---------------------------------------------------------------------------*/
90 static u32 s_holdCount[NUM_KPAD_BUTTONS] = { 0 };
91 static char* s_libWorkMem = NULL;
92 static BOOL s_shutdown = FALSE;
93
94 /*---------------------------------------------------------------------------*
95 Local functions
96 *---------------------------------------------------------------------------*/
97 static void Initialize ( void );
98 static void Finalize ( void );
99 static void* AllocFromPadHeap( u32 size );
100 static u8 FreeToPadHeap ( void* ptr );
101 static void PowerCallback();
102 static void CheckSystemButton();
103
104 /*---------------------------------------------------------------------------*
105 App entry point
106 *---------------------------------------------------------------------------*/
main(void)107 int main( void )
108 {
109 NWC24Err err;
110 KPADStatus input;
111 u8 iButton;
112
113 Initialize();
114
115 /* App main loop */
116 while ( TRUE )
117 {
118 (void)memset( &input, 0, sizeof(KPADStatus) );
119 (void)KPADRead( WPAD_CHAN0, &input, 1 );
120 CheckSystemButton();
121
122 /* Button hold detect */
123 for ( iButton = 0; iButton < NUM_KPAD_BUTTONS; ++iButton )
124 {
125 if ( (input.hold >> iButton) & 0x1 )
126 {
127 ++s_holdCount[iButton];
128 }
129 else
130 {
131 s_holdCount[iButton] = 0;
132 }
133
134 if ( HOLD_THRESHOLD < s_holdCount[iButton] )
135 {
136 g_longHold |= 0x1 << iButton;
137 s_holdCount[iButton] -= HOLD_WAIT;
138 }
139 else
140 {
141 g_longHold &= ~(0x1 << iButton);
142 }
143 }
144
145 do
146 {
147 err = NWC24OpenLib( s_libWorkMem );
148 } while ( err == NWC24_ERR_BUSY );
149 CheckError( "NWC24OpenLib()", err );
150
151 /* Update processing other than rendering */
152 Update( &input );
153
154 /* Render */
155 DEMOBeforeRender();
156 Render();
157 DEMODoneRender();
158
159 err = NWC24CloseMsgLib();
160 CheckError( "NWC24CloseMsgLib()", err );
161 }
162
163 Finalize();
164
165 OSHalt( "All done." );
166 return 0;
167 }
168
169 /*---------------------------------------------------------------------------*
170 Callback function that is called when the POWER Button is pressed
171 *---------------------------------------------------------------------------*/
PowerCallback()172 static void PowerCallback()
173 {
174 s_shutdown = TRUE;
175 }
176
177 /*---------------------------------------------------------------------------*
178 Processing for when the POWER and RESET Buttons are pressed
179 *---------------------------------------------------------------------------*/
CheckSystemButton()180 static void CheckSystemButton()
181 {
182 if( s_shutdown )
183 {
184 OSReport("Power button was pushed.\n");
185 OSShutdownSystem();
186 }
187 if (OSGetResetButtonState())
188 {
189 OSReport("Reset button was pushed.\n");
190 OSRebootSystem();
191 }
192 }
193
194 /*---------------------------------------------------------------------------*/
CheckError(const char * strFunc,NWC24Err err)195 void CheckError( const char* strFunc, NWC24Err err )
196 {
197 if ( err != NWC24_OK )
198 {
199 OSReport( "%s: error %d\n", strFunc, err );
200 OSHalt( "Failed.\n" );
201 }
202 return;
203 }
204
205 /*---------------------------------------------------------------------------*/
ConvStringTo16Digits(const char * str)206 u64 ConvStringTo16Digits( const char* str )
207 {
208 s32 i;
209 u64 scale = 1;
210 u64 ret = 0;
211
212 for ( i = 15; 0 <= i; --i, scale *= 10 )
213 {
214 ret += (u64)(str[i] - '0') * scale;
215 }
216
217 return ret;
218 }
219
220 /*---------------------------------------------------------------------------*
221 NWC24FriendInfo::attr::name -> EditFriendInfo::name
222 *---------------------------------------------------------------------------*/
ConvNameUtf16ToSjis(char * dst,const u16 * src)223 void ConvNameUtf16ToSjis( char* dst, const u16* src )
224 {
225 ENCResult encResult;
226 s32 srclen = 2 * NAME_LEN + 2;
227 s32 dstlen = NAME_BUF_SIZE;
228
229 encResult = ENCConvertStringUnicodeToSjis( (u8*)dst, &dstlen, src, &srclen );
230 if ( encResult != ENC_OK )
231 {
232 (void)sprintf( dst, "ENC ERROR!" );
233 return;
234 }
235 dst[dstlen] = '\0';
236 return;
237 }
238
239 /*---------------------------------------------------------------------------*
240 EditFriendInfo::name -> NWC24FriendInfo::attr::name
241 *---------------------------------------------------------------------------*/
ConvNameSjisToUtf16(u16 * dst,const char * src)242 void ConvNameSjisToUtf16( u16* dst, const char* src )
243 {
244 ENCResult encResult;
245 s32 srclen = NAME_BUF_SIZE;
246 s32 dstlen = 2 * NAME_LEN + 2;
247
248 encResult = ENCConvertStringSjisToUnicode( dst, &dstlen, (u8*)src, &srclen );
249 if ( encResult != ENC_OK )
250 {
251 const u16 ENC_ERROR[] = { (u16)'E', (u16)'N', (u16)'C', (u16)' ', (u16)'E', (u16)'R',
252 (u16)'R', (u16)'O', (u16)'R', (u16)'!', (u16)'\0' };
253 (void)memcpy( dst, ENC_ERROR, 11 * sizeof(u16) );
254 }
255 dst[NAME_LEN] = 0x0000;
256 return;
257 }
258
259 /*---------------------------------------------------------------------------*
260 Calculate Shift_JIS string character count
261 *---------------------------------------------------------------------------*/
SjisStrLen(const char * str)262 u32 SjisStrLen( const char* str )
263 {
264 u32 count = 0;
265
266 while ( *str != '\0' )
267 {
268 ++count;
269 str += SjisIsMultibyte( str ) ? 2 : 1;
270 }
271 return count;
272 /* Simply return the byte count if the font encoding format is not Shift_JIS. */
273 }
274
275 /*---------------------------------------------------------------------------*
276 Determine if the first character of the Shift_JIS string is a two-byte character.
277 *---------------------------------------------------------------------------*/
SjisIsMultibyte(const char * str)278 BOOL SjisIsMultibyte( const char* str )
279 {
280 u8 code = (u8)*str;
281
282 if ( OS_FONT_ENCODE_SJIS != OSGetFontEncode() )
283 {
284 return FALSE;
285 /* Always return false if the font encoding format is not Shift_JIS. */
286 }
287 else
288 {
289 return (0x81 <= code && code <= 0x9f) || (0xe0 <= code && code <= 0xef);
290 }
291 }
292
293 /*---------------------------------------------------------------------------*
294 Name: InitEditFriendInfo
295 Description: Copy the NWC24FriendInfo type friend information to a EditFriendInfo type structure, g_editFriendInfo. 
296
297 Arguments: info - Pointer to the copy source NWC24FriendInfo type structure.
298
299 If NULL, the default value will be stored in the edit friend information structure.
300
301 Returns: None.
302 *---------------------------------------------------------------------------*/
InitEditFriendInfo(NWC24FriendInfo * info)303 void InitEditFriendInfo( NWC24FriendInfo* info )
304 {
305 (void)memset( &g_editFriendInfo, 0, sizeof(EditFriendInfo) );
306 if ( info )
307 {
308 g_editFriendInfo.type = info->attr.type;
309 g_editFriendInfo.status = info->attr.status;
310 (void)sprintf( g_editFriendInfo.fdId, "%016llu", info->attr.fdId );
311 ConvNameUtf16ToSjis( g_editFriendInfo.name, info->attr.name );
312
313 if ( info->attr.type == NWC24_FI_TYPE_WII )
314 {
315 (void)sprintf( g_editFriendInfo.wiiId, "%016llu", info->addr.wiiId );
316 }
317 else if ( info->attr.type == NWC24_FI_TYPE_PUBLIC )
318 {
319 (void)memcpy( g_editFriendInfo.mailAddr, info->addr.mailAddr, MAIL_ADDR_BUF_SIZE );
320 g_editFriendInfo.mailAddr[MAIL_ADDR_BUF_SIZE - 1] = '\0';
321 }
322 }
323 else
324 {
325 g_editFriendInfo.type = NWC24_FI_TYPE_WII;
326 g_editFriendInfo.status = NWC24_FI_STAT_PENDING;
327 (void)sprintf( g_editFriendInfo.fdId, "0000000000000000" );
328 (void)sprintf( g_editFriendInfo.wiiId, "0000000000000000" );
329 }
330 return;
331 }
332
333 /*---------------------------------------------------------------------------*
334 Name: RegisterFriendInfo
335 Description: Register the friend information stored in the current EditFriendInfo type structure, g_editFriendInfo, to the 'index' position of the friend roster.
336
337 If an information already exist in the 'index' position, overwrite the information.
338 Arguments: index - Index in the friend list.
339 Returns: None.
340 *---------------------------------------------------------------------------*/
RegisterFriendInfo(u32 index)341 void RegisterFriendInfo( u32 index )
342 {
343 NWC24Err err;
344
345 (void)memset( g_tempInfo, 0, sizeof(NWC24FriendInfo) );
346 g_tempInfo->attr.type = g_editFriendInfo.type;
347 g_tempInfo->attr.status = g_editFriendInfo.status;
348 g_tempInfo->attr.fdId = ConvStringTo16Digits( g_editFriendInfo.fdId );
349 ConvNameSjisToUtf16( g_tempInfo->attr.name, g_editFriendInfo.name );
350
351 if ( g_editFriendInfo.type == NWC24_FI_TYPE_WII )
352 {
353 g_tempInfo->addr.wiiId = ConvStringTo16Digits( g_editFriendInfo.wiiId );
354 }
355 else if ( g_editFriendInfo.type == NWC24_FI_TYPE_PUBLIC )
356 {
357 (void)memcpy( g_tempInfo->addr.mailAddr, g_editFriendInfo.mailAddr, MAIL_ADDR_BUF_SIZE );
358 g_tempInfo->addr.mailAddr[MAIL_ADDR_BUF_SIZE - 1] = '\0';
359 }
360
361 if ( TRUE == NWC24IsFriendInfoThere( index ) )
362 {
363 /* Overwrite */
364 err = NWC24UpdateFriendInfo( g_tempInfo, index );
365 CheckError( "NWC24UpdateFriendInfo()", err );
366 }
367 else
368 {
369 /* New registration */
370 err = NWC24WriteFriendInfo( g_tempInfo, index );
371 CheckError( "NWC24WriteFriendInfo()", err );
372 }
373 return;
374 }
375
376 /*---------------------------------------------------------------------------*
377 Initialize animation
378 *---------------------------------------------------------------------------*/
Initialize(void)379 static void Initialize( void )
380 {
381 OSInit();
382
383 /* Initialize DEMO and GX */
384 {
385 GXRenderModeObj* renderMode = NULL;
386
387 DEMOInit( NULL );
388 (void)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 OSReport( "NANDInit(): error %d\n", result);
408 OSHalt( "Failed.\n" );
409 }
410 }
411
412 /* Initialize KPAD */
413 {
414 WPADRegisterAllocator( AllocFromPadHeap, FreeToPadHeap );
415 KPADInit();
416 }
417
418 /* Initialize VF */
419 {
420 VFInit();
421 }
422
423 /* initialization related to the POWER button*/
424 {
425 (void)OSSetPowerCallback( PowerCallback );
426 }
427
428 /* Other */
429 {
430 NWC24Err err;
431 NWC24FriendInfo* info = NULL;
432 u32 idxBuf;
433
434 s_libWorkMem = MEMAllocFromAllocator( &DemoAllocator1, NWC24_WORK_MEM_SIZE );
435 g_tempInfo = MEMAllocFromAllocator( &DemoAllocator1, sizeof(NWC24FriendInfo) );
436
437 do
438 {
439 err = NWC24OpenLib( s_libWorkMem );
440 } while ( err == NWC24_ERR_BUSY );
441 CheckError( "NWC24OpenLib()", err );
442
443 err = NWC24GetNumFriendInfos( &g_numFriendInfos );
444 CheckError( "NWC24GetNumFriendInfos()", err );
445
446 InitEditFriendInfo( NULL );
447
448 /* Obtain the friend information to be displayed on-screen at application startup. */
449 for ( idxBuf = 0; idxBuf < LIST_BOX_ROWS && idxBuf < g_numFriendInfos; ++idxBuf )
450 {
451 if ( TRUE == NWC24IsFriendInfoThere( idxBuf ) )
452 {
453 err = NWC24ReadFriendInfo( g_tempInfo, idxBuf );
454 CheckError( "NWC24ReadFriendInfo()", err );
455
456 ConvNameUtf16ToSjis( g_nameBuf[idxBuf], g_tempInfo->attr.name );
457 }
458 else
459 {
460 (void)sprintf( g_nameBuf[idxBuf], "%s", STR_NOT_REGISTERED );
461 }
462 }
463
464 err = NWC24CloseMsgLib();
465 CheckError( "NWC24CloseMsgLib()", err );
466 }
467 return;
468 }
469
470 /*---------------------------------------------------------------------------*
471 Cleanup after application
472 *---------------------------------------------------------------------------*/
Finalize(void)473 static void Finalize( void )
474 {
475 MEMFreeToAllocator( &DemoAllocator1, s_libWorkMem );
476 MEMFreeToAllocator( &DemoAllocator1, g_tempInfo );
477 return;
478 }
479
480 /*---------------------------------------------------------------------------*/
AllocFromPadHeap(u32 size)481 static void* AllocFromPadHeap( u32 size )
482 {
483 return MEMAllocFromAllocator( &DemoAllocator2, size );
484 }
485
486 /*---------------------------------------------------------------------------*/
FreeToPadHeap(void * ptr)487 static u8 FreeToPadHeap( void* ptr )
488 {
489 if ( !ptr )
490 {
491 return 0;
492 }
493
494 MEMFreeToAllocator( &DemoAllocator2, ptr );
495 ptr = NULL;
496 return 1;
497 }
498
499 /*======== End of FLViewer.c ========*/
500