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.&#xa0;
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