1 /*---------------------------------------------------------------------------*
2   Project:  WiiConnect24 API demos
3   File:     FLViewerUpdate.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: FLViewerUpdate.c,v $
14   Revision 1.3  2007/01/24 06:25:42  torigoe_nobutaka
15   Added processing for when the Home Button is pressed.
16 
17   Revision 1.2  2006/10/26 10:42:56  hirose_kazuki
18   Modification to accept user ID of the console itself. (due to library changes)
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/nwc24.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34 
35 #include "FLViewer.h"
36 #include "FLViewerUpdate.h"
37 
38 /*---------------------------------------------------------------------------*
39    Static constants
40  *---------------------------------------------------------------------------*/
41 static const char*  STR_SAMPLE_WII_ID       =   "4016576553504409";
42 
43 /*---------------------------------------------------------------------------*
44    Local functions
45  *---------------------------------------------------------------------------*/
46 static u32          GetSelectedNameIdx  ( void );
47 static void         UpdateSelectFriend  ( const KPADStatus* input );
48 static void         UpdateSelectEditItem( const KPADStatus* input );
49 static void         UpdateEditType      ( const KPADStatus* input );
50 static void         UpdateEditStatus    ( const KPADStatus* input );
51 static void         UpdateEditFdId      ( const KPADStatus* input );
52 static void         UpdateEditName      ( const KPADStatus* input );
53 static void         UpdateEditWiiId     ( const KPADStatus* input );
54 static void         UpdateEditMailAddr  ( const KPADStatus* input );
55 static void         UpdateDeleteFriend  ( const KPADStatus* input );
56 static void         InputAlpha          ( char* dst, const KPADStatus* input, BOOL bCaps, BOOL bStart );
57 static void         InputNumber         ( char* dst, const KPADStatus* input, BOOL bStart );
58 static void         InputHexNumber      ( char* dst, const KPADStatus* input, BOOL bStart );
59 static void         InputSymbol         ( char* dst, const KPADStatus* input, BOOL bStart );
60 static void         InputMailSymbol     ( char* dst, const KPADStatus* input, BOOL bStart );
61 static char         GetInputChar        ( u8* idxChar, const KPADStatus* input, const char* charList, u8 listLen, BOOL bStart );
62 
63 /*---------------------------------------------------------------------------*
64    Scene update processing besides rendering
65  *---------------------------------------------------------------------------*/
Update(const KPADStatus * input)66 void Update( const KPADStatus* input )
67 {
68     /* (1) button */
69     if ( input->trig & KPAD_BUTTON_1 )
70     {
71         g_bHelp = !g_bHelp;
72     }
73 
74     /* (Home) button */
75     if ( input->trig & KPAD_BUTTON_HOME )
76     {
77         OSReturnToMenu();
78     }
79 
80     switch ( g_state )
81     {
82         case STATE_SELECT_FRIEND:    UpdateSelectFriend( input );   break;
83         case STATE_SELECT_EDIT_ITEM: UpdateSelectEditItem( input ); break;
84         case STATE_EDIT_TYPE:        UpdateEditType( input );       break;
85         case STATE_EDIT_STATUS:      UpdateEditStatus( input );     break;
86         case STATE_EDIT_FD_ID:       UpdateEditFdId( input );       break;
87         case STATE_EDIT_NAME:        UpdateEditName( input );       break;
88         case STATE_EDIT_WII_ID:      UpdateEditWiiId( input );      break;
89         case STATE_EDIT_MAIL_ADDR:   UpdateEditMailAddr( input );   break;
90         case STATE_DELETE_FRIEND:    UpdateDeleteFriend( input );   break;
91     }
92     return;
93 }
94 
95 /*---------------------------------------------------------------------------*/
GetSelectedNameIdx(void)96 static u32 GetSelectedNameIdx( void )
97 {
98     return (u32)((g_idxNameBufStart + g_idxSelectedFriend - g_idxTopOfFriendList) % LIST_BOX_ROWS);
99 }
100 
101 /*---------------------------------------------------------------------------*
102    Selection of friend
103  *---------------------------------------------------------------------------*/
UpdateSelectFriend(const KPADStatus * input)104 static void UpdateSelectFriend( const KPADStatus* input )
105 {
106     NWC24Err    err;
107 
108     /* (Up) button */
109     if ( (input->trig & KPAD_BUTTON_UP) || (g_longHold & KPAD_BUTTON_UP) )
110     {
111         /* Selection of friend */
112         if ( 0 < g_idxSelectedFriend )
113         {
114             if ( g_idxSelectedFriend == g_idxTopOfFriendList )
115             {
116                 --g_idxTopOfFriendList;
117                 g_idxNameBufStart = (g_idxNameBufStart + LIST_BOX_ROWS - 1) % LIST_BOX_ROWS;
118                 if ( TRUE == NWC24IsFriendInfoThere( g_idxTopOfFriendList ) )
119                 {
120                     err = NWC24ReadFriendInfo( g_tempInfo, g_idxTopOfFriendList );
121                     CheckError( "NWC24ReadFriendInfo()", err );
122 
123                     ConvNameUtf16ToSjis( g_nameBuf[g_idxNameBufStart], g_tempInfo->attr.name );
124                 }
125                 else
126                 {
127                     (void)sprintf( g_nameBuf[g_idxNameBufStart], "%s", STR_NOT_REGISTERED );
128                 }
129             }
130             --g_idxSelectedFriend;
131         }
132     }
133 
134     /* (Down) button */
135     if ( (input->trig & KPAD_BUTTON_DOWN) || (g_longHold & KPAD_BUTTON_DOWN) )
136     {
137         /* Selection of friend */
138         if ( g_idxSelectedFriend < g_numFriendInfos - 1 )
139         {
140             u32     idxBottomOfFriendList   = g_idxTopOfFriendList + LIST_BOX_ROWS - 1;
141 
142             if ( g_idxSelectedFriend == idxBottomOfFriendList )
143             {
144                 ++g_idxTopOfFriendList;
145                 ++idxBottomOfFriendList;
146                 if ( TRUE == NWC24IsFriendInfoThere( idxBottomOfFriendList ) )
147                 {
148                     err = NWC24ReadFriendInfo( g_tempInfo, idxBottomOfFriendList );
149                     CheckError( "NWC24ReadFriendInfo()", err );
150 
151                     ConvNameUtf16ToSjis( g_nameBuf[g_idxNameBufStart], g_tempInfo->attr.name );
152                 }
153                 else
154                 {
155                     (void)sprintf( g_nameBuf[g_idxNameBufStart], "%s", STR_NOT_REGISTERED );
156                 }
157                 g_idxNameBufStart = (g_idxNameBufStart + 1) % LIST_BOX_ROWS;
158             }
159             ++g_idxSelectedFriend;
160         }
161     }
162 
163     /* (A) button */
164     if ( input->trig & KPAD_BUTTON_A )
165     {
166         /* Determination of friend */
167         g_state = STATE_SELECT_EDIT_ITEM;
168         if ( TRUE == NWC24IsFriendInfoThere( g_idxSelectedFriend ) )
169         {
170             NWC24Err    err;
171             u8          i;
172 
173             err = NWC24ReadFriendInfo( g_tempInfo, g_idxSelectedFriend );
174             CheckError( "NWC24ReadFriendInfo()", err );
175 
176             InitEditFriendInfo( g_tempInfo );
177             for ( i = 0; i < NUM_EDIT_ITEMS; ++i )
178             {
179                 if ( UPDATABLE_ITEM_TABLE[i] )
180                 {
181                     g_selectedEditItem = i;
182                     break;
183                 }
184             }
185         }
186         else
187         {
188             InitEditFriendInfo( NULL );
189             g_selectedEditItem = EDIT_ITEM_TYPE;
190         }
191     }
192 
193     /* (B) button */
194     if ( input->trig & KPAD_BUTTON_B )
195     {
196         /* Delete friend information */
197         if ( TRUE == NWC24IsFriendInfoThere( g_idxSelectedFriend ) )
198         {
199             g_state = STATE_DELETE_FRIEND;
200         }
201     }
202     return;
203 }
204 
205 /*---------------------------------------------------------------------------*
206    Select friend information item to edit
207  *---------------------------------------------------------------------------*/
UpdateSelectEditItem(const KPADStatus * input)208 static void UpdateSelectEditItem( const KPADStatus* input )
209 {
210     BOOL    bRegistered = (BOOL)(TRUE == NWC24IsFriendInfoThere( g_idxSelectedFriend ));
211 
212     /* (Up) button */
213     if ( (input->trig & KPAD_BUTTON_UP) || (g_longHold & KPAD_BUTTON_UP) )
214     {
215         /* Selection of edit item */
216         if ( bRegistered )
217         {
218             s32     i;
219             for ( i = g_selectedEditItem - 1; 0 <= i; --i )
220             {
221                 if ( UPDATABLE_ITEM_TABLE[i] )
222                 {
223                     g_selectedEditItem = (u8)i;
224                     break;
225                 }
226             }
227         }
228         else if ( 0 < g_selectedEditItem )
229         {
230             --g_selectedEditItem;
231         }
232     }
233 
234     /* (Down) button */
235     if ( (input->trig & KPAD_BUTTON_DOWN) || (g_longHold & KPAD_BUTTON_DOWN) )
236     {
237         /* Selection of edit item */
238         if ( bRegistered )
239         {
240             s32     i;
241             for ( i = g_selectedEditItem + 1; i < (s32)NUM_EDIT_ITEMS; ++i )
242             {
243                 if ( UPDATABLE_ITEM_TABLE[i] )
244                 {
245                     g_selectedEditItem = (u8)i;
246                     break;
247                 }
248             }
249         }
250         else if ( g_selectedEditItem < NUM_EDIT_ITEMS - 1 )
251         {
252             ++g_selectedEditItem;
253         }
254     }
255 
256     /* (A) button */
257     if ( input->trig & KPAD_BUTTON_A )
258     {
259         /* Determination of edit item */
260         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
261         switch ( g_selectedEditItem )
262         {
263             case EDIT_ITEM_TYPE:     g_state = STATE_EDIT_TYPE;     break;
264             case EDIT_ITEM_STATUS:   g_state = STATE_EDIT_STATUS;   break;
265             case EDIT_ITEM_FD_ID:    g_state = STATE_EDIT_FD_ID;    break;
266             case EDIT_ITEM_NAME:     g_state = STATE_EDIT_NAME;     break;
267             case EDIT_ITEM_ADDRESS:
268             {
269                 if ( g_editFriendInfo.type == NWC24_FI_TYPE_WII )
270                 {
271                     g_state = STATE_EDIT_WII_ID;
272                 }
273                 else if ( g_editFriendInfo.type == NWC24_FI_TYPE_PUBLIC )
274                 {
275                     g_state = STATE_EDIT_MAIL_ADDR;
276                 }
277                 break;
278             }
279         }
280     }
281 
282     /* (B) button */
283     if ( input->trig & KPAD_BUTTON_B )
284     {
285         /* Cancel change and return to friend selection */
286         g_state = STATE_SELECT_FRIEND;
287     }
288 
289     /* (Plus) button */
290     if ( input->trig & KPAD_BUTTON_PLUS )
291     {
292         /* Register friend information and return to friend selection */
293         while ( TRUE )
294         {
295             if ( g_editFriendInfo.type == NWC24_FI_TYPE_WII )
296             {
297                 NWC24UserId     userId  = ConvStringTo16Digits( g_editFriendInfo.wiiId );
298                 NWC24Err        err;
299 
300                 err = NWC24CheckUserId( userId );
301                 /* Valid ID or your own ID */
302                 if ( err != NWC24_OK && err != NWC24_ERR_ID_GENERATED )
303                 {
304                     /* Don't register if the Wii number is invalid */
305                     g_selectedEditItem = EDIT_ITEM_ADDRESS;
306                     (void)memset( g_editFriendInfo.wiiId, 0, WII_ID_BUF_SIZE );
307                     break;
308                 }
309             }
310 
311             g_state = STATE_SELECT_FRIEND;
312             RegisterFriendInfo( g_idxSelectedFriend );
313             (void)sprintf( g_nameBuf[ GetSelectedNameIdx() ], "%s", g_editFriendInfo.name );
314             break;
315         }
316     }
317     return;
318 }
319 
320 /*---------------------------------------------------------------------------*
321    Edit address type
322  *---------------------------------------------------------------------------*/
UpdateEditType(const KPADStatus * input)323 static void UpdateEditType( const KPADStatus* input )
324 {
325     /* (Up) or (Down) button */
326     if ( input->trig & (KPAD_BUTTON_UP | KPAD_BUTTON_DOWN) )
327     {
328         /* Selection of address type*/
329         g_editFriendInfo.type = (u32)((g_editFriendInfo.type == NWC24_FI_TYPE_WII)
330                                       ? NWC24_FI_TYPE_PUBLIC : NWC24_FI_TYPE_WII);
331     }
332 
333     /* (A) button */
334     if ( input->trig & KPAD_BUTTON_A )
335     {
336         /* Change address type and return to edit item selection. */
337         g_state = STATE_SELECT_EDIT_ITEM;
338         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
339     }
340 
341     /* (B) button */
342     if ( input->trig & KPAD_BUTTON_B )
343     {
344         /* Cancel change and return to edit item selection */
345         g_state = STATE_SELECT_EDIT_ITEM;
346         (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
347     }
348     return;
349 }
350 
351 /*---------------------------------------------------------------------------*
352    Edit communication capable/incapable information
353  *---------------------------------------------------------------------------*/
UpdateEditStatus(const KPADStatus * input)354 static void UpdateEditStatus( const KPADStatus* input )
355 {
356     /* (Up) or (Down) button */
357     if ( input->trig & (KPAD_BUTTON_UP | KPAD_BUTTON_DOWN) )
358     {
359         /* Selection of communication capable/incapable */
360         g_editFriendInfo.status = (u32)((g_editFriendInfo.status == NWC24_FI_STAT_PENDING)
361                                         ? NWC24_FI_STAT_ESTABLISHED : NWC24_FI_STAT_PENDING);
362         /* This is forcibly changed to Pending when registering to friend list */
363     }
364 
365     /* (A) button */
366     if ( input->trig & KPAD_BUTTON_A )
367     {
368         /* Change communication capable/incapable information and return to edit item selection */
369         g_state = STATE_SELECT_EDIT_ITEM;
370         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
371     }
372 
373     /* (B) button */
374     if ( input->trig & KPAD_BUTTON_B )
375     {
376         /* Cancel change and return to edit item selection */
377         g_state = STATE_SELECT_EDIT_ITEM;
378         (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
379     }
380     return;
381 }
382 
383 /*---------------------------------------------------------------------------*
384    Editing FDID
385  *---------------------------------------------------------------------------*/
UpdateEditFdId(const KPADStatus * input)386 static void UpdateEditFdId( const KPADStatus* input )
387 {
388     static BOOL     bStart      = TRUE;
389     u8              idxEdit;
390     char*           pChar       = NULL;
391 
392     if ( bStart )
393     {
394         idxEdit = 0;
395         (void)memset( g_editFriendInfo.fdId, 0, FD_ID_BUF_SIZE );
396     }
397     else
398     {
399         idxEdit = (u8)(strlen( g_editFriendInfo.fdId ) - 1);
400     }
401 
402     pChar = &g_editFriendInfo.fdId[idxEdit];
403 
404     /* Input character selection*/
405     InputNumber( pChar, input, bStart );
406     bStart = FALSE;
407 
408     /* (A) button */
409     if ( input->trig & KPAD_BUTTON_A )
410     {
411         /* Character input*/
412         if ( FD_ID_BUF_SIZE - 2 <= idxEdit )
413         {
414             /* If the character count has reached the maximum value, change FDID and return to the edit item selection */
415             g_state = STATE_SELECT_EDIT_ITEM;
416             bStart = TRUE;
417             g_editFriendInfo.fdId[FD_ID_BUF_SIZE - 1] = '\0';
418             (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
419         }
420         else
421         {
422             *(pChar + 1) = *pChar;
423             *(pChar + 2) = '\0';
424         }
425     }
426 
427     /* (B) button */
428     if ( (input->trig & KPAD_BUTTON_B) || (g_longHold & KPAD_BUTTON_B) )
429     {
430         /* Delete one character*/
431         if ( idxEdit < 1 )
432         {
433             /* Cancel change and return to edit item selection if all characters are deleted */
434             g_state = STATE_SELECT_EDIT_ITEM;
435             bStart = TRUE;
436             (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
437         }
438         else
439         {
440             *pChar = '\0';
441         }
442     }
443 
444     return;
445 }
446 
447 /*---------------------------------------------------------------------------*
448    Edit nickname
449  *---------------------------------------------------------------------------*/
UpdateEditName(const KPADStatus * input)450 static void UpdateEditName( const KPADStatus* input )
451 {
452     static const u8     NUM_INPUT_MODES         =   4;
453     static const u8     INPUT_LOWER             =   0;
454     static const u8     INPUT_UPPER             =   1;
455     static const u8     INPUT_NUMBER            =   2;
456     static const u8     INPUT_SYMBOL            =   3;
457     static BOOL         bStart                  =   TRUE;
458     static BOOL         bHexMode                =   FALSE;
459     static u8           inputMode;
460     u8                  idxEdit;
461     u8                  idxHex;
462     char*               pChar                   =   NULL;
463 
464     if ( bStart )
465     {
466         inputMode = INPUT_LOWER;
467         bHexMode = FALSE;
468         (void)memset( g_hexBuf, 0, HEX_BUF_SIZE );
469 
470         if ( NAME_LEN <= SjisStrLen( g_editFriendInfo.name ) )
471         {
472             u8      i;
473 
474             idxEdit = 0;
475             for ( i = 0; i < NAME_LEN - 1; ++i )
476             {
477                 idxEdit += SjisIsMultibyte( &g_editFriendInfo.name[idxEdit] ) ? 2 : 1;
478             }
479 
480             g_editFriendInfo.name[idxEdit + 1] = '\0';
481         }
482         else
483         {
484             idxEdit = (u8)strlen( g_editFriendInfo.name );
485         }
486     }
487     else
488     {
489         idxEdit = (u8)(strlen( g_editFriendInfo.name ) - 1);
490     }
491 
492     pChar = &g_editFriendInfo.name[idxEdit];
493 
494     /* Input character selection*/
495     if ( bHexMode )
496     {
497         u32     hexLen      = strlen( g_hexBuf );
498         BOOL    bHexStart   = (hexLen == 0);
499 
500         idxHex = (u8)(bHexStart ? hexLen : hexLen - 1);
501         InputHexNumber( &g_hexBuf[idxHex], input, bHexStart );
502     }
503     else
504     {
505         switch ( inputMode )
506         {
507             case INPUT_LOWER:  InputAlpha( pChar, input, FALSE, bStart ); break;
508             case INPUT_UPPER:  InputAlpha( pChar, input, TRUE, bStart );  break;
509             case INPUT_NUMBER: InputNumber( pChar, input, bStart );       break;
510             case INPUT_SYMBOL: InputSymbol( pChar, input, bStart );       break;
511         }
512     }
513 
514     bStart = FALSE;
515 
516     /* (Right) button */
517     if ( (input->trig & KPAD_BUTTON_RIGHT) || (g_longHold & KPAD_BUTTON_RIGHT) )
518     {
519         /* Change character type */
520         inputMode = (u8)((inputMode + 1) % NUM_INPUT_MODES);
521     }
522 
523     /* (Left) button */
524     if ( (input->trig & KPAD_BUTTON_LEFT) || (g_longHold & KPAD_BUTTON_LEFT) )
525     {
526         /* Change character type */
527         inputMode = (u8)((inputMode + NUM_INPUT_MODES - 1) % NUM_INPUT_MODES);
528     }
529 
530     /* (A) button */
531     if ( input->trig & KPAD_BUTTON_A )
532     {
533         /* Character input*/
534         char    temp    = *pChar;
535 
536         if ( bHexMode )
537         {
538             if ( HEX_BUF_SIZE - 2 <= idxHex )
539             {
540                 s32     code;
541 
542                 g_hexBuf[HEX_BUF_SIZE - 1] = '\0';
543                 code = strtol( g_hexBuf, NULL, 16 );
544                 *pChar = (char)(code / 0x100);
545 
546                 if ( SjisIsMultibyte( pChar ) )
547                 {
548                     *(pChar + 1) = (char)(code % 0x100);
549                     *(pChar + 2) = '\0';
550                 }
551                 else
552                 {
553                     if ( *pChar == 0x00 )
554                     {
555                         *pChar = (char)(code % 0x100);
556                     }
557 
558                     if ( !isprint( *pChar ) )
559                     {
560                         *pChar = ' ';
561                     }
562 
563                     *(pChar + 1) = '\0';
564                 }
565 
566                 bHexMode = FALSE;
567                 (void)memset( g_hexBuf, 0, HEX_BUF_SIZE );
568             }
569             else
570             {
571                 g_hexBuf[idxHex + 1] = g_hexBuf[idxHex];
572             }
573         }
574 
575         if ( !bHexMode )
576         {
577             if ( NAME_LEN <= SjisStrLen( g_editFriendInfo.name ) )
578             {
579                 /* If the character count has reached the maximum value, change nickname and return to the edit item selection */
580                 g_state = STATE_SELECT_EDIT_ITEM;
581                 bStart = TRUE;
582                 *(pChar + 1) = '\0';
583                 (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
584             }
585             else
586             {
587                 if ( SjisIsMultibyte( pChar ) )
588                 {
589                     *(pChar + 2) = temp;
590                     *(pChar + 3) = '\0';
591                 }
592                 else
593                 {
594                     *(pChar + 1) = temp;
595                     *(pChar + 2) = '\0';
596                 }
597             }
598         }
599     }
600 
601     /* (B) button */
602     if ( (input->trig & KPAD_BUTTON_B) || (g_longHold & KPAD_BUTTON_B) )
603     {
604         /* Delete one character*/
605         if ( bHexMode )
606         {
607             g_hexBuf[idxHex] = '\0';
608         }
609         else if ( idxEdit < 1 )
610         {
611             /* Cancel change and return to edit item selection if all characters are deleted */
612             g_state = STATE_SELECT_EDIT_ITEM;
613             bStart = TRUE;
614             (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
615         }
616         else
617         {
618             *pChar = '\0';
619             if ( 1 < idxEdit )
620             {
621                 char*   curr    = g_editFriendInfo.name;
622                 char*   next    = g_editFriendInfo.name;
623                 while ( next != pChar )
624                 {
625                     curr = next;
626                     next = (char*)(curr + (SjisIsMultibyte( curr ) ? 2 : 1));
627                 }
628 
629                 if ( next - curr == 2 )
630                 {
631                     *(pChar - 1) = '\0';
632                 }
633             }
634         }
635     }
636 
637     /* (Plus) */
638     if ( input->trig & KPAD_BUTTON_PLUS )
639     {
640         /* Change the nickname and return to edit item selection.*/
641         g_state = STATE_SELECT_EDIT_ITEM;
642         *pChar = '\0';
643         bStart = TRUE;
644         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
645     }
646 
647     /* (Minus) */
648     if ( input->trig & KPAD_BUTTON_MINUS )
649     {
650         /* Hexadecimal character code input mode switch */
651         bHexMode = !bHexMode;
652         (void)memset( g_hexBuf, 0, HEX_BUF_SIZE );
653     }
654     return;
655 }
656 
657 /*---------------------------------------------------------------------------*
658    Edit Wii number
659  *---------------------------------------------------------------------------*/
UpdateEditWiiId(const KPADStatus * input)660 static void UpdateEditWiiId( const KPADStatus* input )
661 {
662     static BOOL     bStart      = TRUE;
663     u8              idxEdit;
664     char*           pChar       = NULL;
665 
666     if ( bStart )
667     {
668         idxEdit = 0;
669         (void)memset( g_editFriendInfo.wiiId, 0, WII_ID_BUF_SIZE );
670     }
671     else
672     {
673         idxEdit = (u8)(strlen( g_editFriendInfo.wiiId ) - 1);
674     }
675 
676     pChar = &g_editFriendInfo.wiiId[idxEdit];
677 
678     /* Input character selection*/
679     InputNumber( pChar, input, bStart );
680     bStart = FALSE;
681 
682     /* (A) button */
683     if ( input->trig & KPAD_BUTTON_A )
684     {
685         /* Character input*/
686         if ( WII_ID_BUF_SIZE - 2 <= idxEdit )
687         {
688             /* If the character count has reached the maximum value, change Wii number and return to the edit item selection */
689             g_state = STATE_SELECT_EDIT_ITEM;
690             bStart = TRUE;
691             g_editFriendInfo.wiiId[WII_ID_BUF_SIZE - 1] = '\0';
692             (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
693         }
694         else
695         {
696             *(pChar + 1) = *pChar;
697             *(pChar + 2) = '\0';
698         }
699     }
700 
701     /* (B) button */
702     if ( (input->trig & KPAD_BUTTON_B) || (g_longHold & KPAD_BUTTON_B) )
703     {
704         /* Delete one character*/
705         if ( idxEdit < 1 )
706         {
707             /* Cancel change and return to edit item selection if all characters are deleted */
708             g_state = STATE_SELECT_EDIT_ITEM;
709             bStart = TRUE;
710             (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
711         }
712         else
713         {
714             *pChar = '\0';
715         }
716     }
717 
718     /* (Plus) button */
719     if ( input->trig & KPAD_BUTTON_PLUS )
720     {
721         /* Input the sample Wii number */
722         g_state = STATE_SELECT_EDIT_ITEM;
723         bStart = TRUE;
724         (void)sprintf( g_editFriendInfo.wiiId, "%s", STR_SAMPLE_WII_ID );
725         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
726     }
727     return;
728 }
729 
730 /*---------------------------------------------------------------------------*
731    Edit e-mail address
732  *---------------------------------------------------------------------------*/
UpdateEditMailAddr(const KPADStatus * input)733 static void UpdateEditMailAddr( const KPADStatus* input )
734 {
735     static const u8     NUM_INPUT_MODES = 4;
736     static const u8     INPUT_LOWER     = 0;
737     static const u8     INPUT_UPPER     = 1;
738     static const u8     INPUT_NUMBER    = 2;
739     static const u8     INPUT_SYMBOL    = 3;
740     static BOOL         bStart          = TRUE;
741     static u8           inputMode;
742     u8                  idxEdit;
743     char*               pChar           = NULL;
744 
745     if ( bStart )
746     {
747         inputMode = INPUT_LOWER;
748         idxEdit = (u8)strlen( g_editFriendInfo.mailAddr );
749         if ( MAIL_ADDR_BUF_SIZE - 1 <= idxEdit )
750         {
751             idxEdit = MAIL_ADDR_BUF_SIZE - 2;
752         }
753     }
754     else
755     {
756         idxEdit = (u8)(strlen( g_editFriendInfo.mailAddr ) - 1);
757     }
758 
759     pChar = &g_editFriendInfo.mailAddr[idxEdit];
760 
761     /* Input character selection*/
762     switch ( inputMode )
763     {
764         case INPUT_LOWER:  InputAlpha( pChar, input, FALSE, bStart ); break;
765         case INPUT_UPPER:  InputAlpha( pChar, input, TRUE, bStart );  break;
766         case INPUT_NUMBER: InputNumber( pChar, input, bStart );       break;
767         case INPUT_SYMBOL: InputMailSymbol( pChar, input, bStart );   break;
768     }
769 
770     bStart = FALSE;
771 
772     /* (Right) button */
773     if ( (input->trig & KPAD_BUTTON_RIGHT) || (g_longHold & KPAD_BUTTON_RIGHT) )
774     {
775         /* Change character type */
776         inputMode = (u8)((inputMode + 1) % NUM_INPUT_MODES);
777     }
778 
779     /* (Left) button */
780     if ( (input->trig & KPAD_BUTTON_LEFT) || (g_longHold & KPAD_BUTTON_LEFT) )
781     {
782         /* Change character type */
783         inputMode = (u8)((inputMode + NUM_INPUT_MODES - 1) % NUM_INPUT_MODES);
784     }
785 
786     /* (A) button */
787     if ( input->trig & KPAD_BUTTON_A )
788     {
789         /* Character input*/
790         if ( MAIL_ADDR_BUF_SIZE - 2 <= idxEdit )
791         {
792             /* If the character count has reached the maximum value, change e-mail address and return to the edit item selection */
793             g_state = STATE_SELECT_EDIT_ITEM;
794             bStart = TRUE;
795             g_editFriendInfo.mailAddr[MAIL_ADDR_BUF_SIZE - 1] = '\0';
796             (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
797         }
798         else
799         {
800             *(pChar + 1) = *pChar;
801             *(pChar + 2) = '\0';
802         }
803     }
804 
805     /* (B) button */
806     if ( (input->trig & KPAD_BUTTON_B) || (g_longHold & KPAD_BUTTON_B) )
807     {
808         /* Delete one character*/
809         if ( idxEdit < 1 )
810         {
811             /* Cancel change and return to edit item selection if all characters are deleted */
812             g_state = STATE_SELECT_EDIT_ITEM;
813             bStart = TRUE;
814             (void)memcpy( &g_editFriendInfo, &g_backupFriendInfo, sizeof(EditFriendInfo) );
815         }
816         else
817         {
818             *pChar = '\0';
819         }
820     }
821 
822     /* (Plus) */
823     if ( input->trig & KPAD_BUTTON_PLUS )
824     {
825         /* Change e-mail address and return to edit item selection. */
826         g_state = STATE_SELECT_EDIT_ITEM;
827         *pChar = '\0';
828         bStart = TRUE;
829         (void)memcpy( &g_backupFriendInfo, &g_editFriendInfo, sizeof(EditFriendInfo) );
830     }
831     return;
832 }
833 
834 /*---------------------------------------------------------------------------*
835    Delete friend information
836  *---------------------------------------------------------------------------*/
UpdateDeleteFriend(const KPADStatus * input)837 static void UpdateDeleteFriend( const KPADStatus* input )
838 {
839     /* (A) button */
840     if ( input->trig & KPAD_BUTTON_A )
841     {
842         /* Execute deletion of friend information */
843         NWC24Err    err;
844 
845         g_state = STATE_SELECT_FRIEND;
846         err = NWC24DeleteFriendInfo( g_idxSelectedFriend );
847         CheckError( "NWC24DeleteFriendInfo()", err );
848         (void)sprintf( g_nameBuf[ GetSelectedNameIdx() ], "%s", STR_NOT_REGISTERED );
849     }
850 
851     /* (B) button */
852     if ( input->trig & KPAD_BUTTON_B )
853     {
854         /* Return to friend selection without deleting friend information */
855         g_state = STATE_SELECT_FRIEND;
856     }
857     return;
858 }
859 
860 /*---------------------------------------------------------------------------*/
InputAlpha(char * dst,const KPADStatus * input,BOOL bCaps,BOOL bStart)861 static void InputAlpha( char* dst, const KPADStatus* input, BOOL bCaps, BOOL bStart )
862 {
863     static const char*  ALPHA_LIST  = "abcdefghijklmnopqrstuvwxyz";
864     static u8           idxAlphas   = 0;
865     u8                  numAlphas   = (u8)strlen( ALPHA_LIST );
866 
867     *dst = GetInputChar( &idxAlphas, input, ALPHA_LIST, numAlphas, bStart );
868 
869     if ( bCaps )
870     {
871         *dst = (char)(*dst - 'a' + 'A');
872     }
873     return;
874 }
875 
876 /*---------------------------------------------------------------------------*/
InputNumber(char * dst,const KPADStatus * input,BOOL bStart)877 static void InputNumber( char* dst, const KPADStatus* input, BOOL bStart )
878 {
879     static const char*  NUMBER_LIST = "0123456789";
880     static u8           idxNumber   = 0;
881     u8                  numNumbers  = (u8)strlen( NUMBER_LIST );
882 
883     *dst = GetInputChar( &idxNumber, input, NUMBER_LIST, numNumbers, bStart );
884     return;
885 }
886 
887 /*---------------------------------------------------------------------------*/
InputHexNumber(char * dst,const KPADStatus * input,BOOL bStart)888 static void InputHexNumber( char* dst, const KPADStatus* input, BOOL bStart )
889 {
890     static const char*  NUMBER_LIST = "0123456789ABCDEF";
891     static u8           idxNumber   = 0;
892     u8                  numNumbers  = (u8)strlen( NUMBER_LIST );
893 
894     *dst = GetInputChar( &idxNumber, input, NUMBER_LIST, numNumbers, bStart );
895     return;
896 }
897 
898 /*---------------------------------------------------------------------------*/
InputSymbol(char * dst,const KPADStatus * input,BOOL bStart)899 static void InputSymbol( char* dst, const KPADStatus* input, BOOL bStart )
900 {
901     static const char*  SYMBOL_LIST = "!\"#$%&\'()*+,-./:;<=>\?@[\\]^_`{|}~ ";
902     static u8           idxSymbol   = 0;
903     u8                  numSymbols  = (u8)strlen( SYMBOL_LIST );
904 
905     *dst = GetInputChar( &idxSymbol, input, SYMBOL_LIST, numSymbols, bStart );
906     return;
907 }
908 
909 /*---------------------------------------------------------------------------*/
InputMailSymbol(char * dst,const KPADStatus * input,BOOL bStart)910 static void InputMailSymbol( char* dst, const KPADStatus* input, BOOL bStart )
911 {
912     static const char*  SYMBOL_LIST = "@.-_";
913     static u8           idxSymbol   = 0;
914     u8                  numSymbols  = (u8)strlen( SYMBOL_LIST );
915 
916     *dst = GetInputChar( &idxSymbol, input, SYMBOL_LIST, numSymbols, bStart );
917     return;
918 }
919 
920 /*---------------------------------------------------------------------------*/
GetInputChar(u8 * idxChar,const KPADStatus * input,const char * charList,u8 listLen,BOOL bStart)921 static char GetInputChar
922 (
923     u8*                 idxChar,
924     const KPADStatus*   input,
925     const char*         charList,
926     u8                  listLen,
927     BOOL                bStart
928 )
929 {
930     if ( bStart )
931     {
932         *idxChar = 0;
933     }
934 
935     /* (Up) button */
936     if ( (input->trig & KPAD_BUTTON_UP) || (g_longHold & KPAD_BUTTON_UP) )
937     {
938         *idxChar = (u8)((*idxChar == listLen - 1) ? 0 : *idxChar + 1);
939     }
940 
941     /* (Down) button */
942     if ( (input->trig & KPAD_BUTTON_DOWN) || (g_longHold & KPAD_BUTTON_DOWN) )
943     {
944         *idxChar = (u8)((*idxChar == 0) ? listLen - 1 : *idxChar - 1);
945     }
946 
947     return charList[*idxChar];
948 }
949 
950 /*======== End of FLViewerUpdate.c ========*/
951