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