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