1 /*--------------------------------------------------------------------------*
2   Project:    WPAD demo program
3   File:       wpadsample.c
4 
5   Copyright (C) 2007 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: wpadsample.c,v $
14   Revision 1.7.2.1  2009/12/08 02:14:42  yasuda_shumpei
15   Updated wpaddemo. Soleved the warnings.
16 
17   Revision 1.7  2009/07/06 02:06:17  tojo
18   *** empty log message ***
19 
20   Revision 1.6  2008/12/26 03:16:27  tojo
21   (none)
22 
23   Revision 1.5  2008/12/24 06:28:38  tojo
24   Modified the error handling of controller data.
25 
26   Revision 1.4  2008/04/17 09:27:40  tojo
27   Supported special extensions.
28 
29   Revision 1.3  2007/07/19 08:59:54  tojo
30   Cleared string buffer before getting the game title.
31 
32   Revision 1.2  2007/07/11 11:42:55  tojo
33   Added the distance calculation and introduction on serial output.
34 
35   Revision 1.1  2007/07/11 09:06:40  tojo
36   Initial check-in.
37 
38 
39  *---------------------------------------------------------------------------*/
40 
41 #include <revolution.h>
42 #include <revolution/wpad.h>
43 #include <revolution/wpadGuitar.h>
44 #include <revolution/wpadDrum.h>
45 #include <revolution/wpadTaiko.h>
46 #include <revolution/wpadTrain.h>
47 #include <revolution/wpadBalance.h>
48 #include <revolution/wbc.h>
49 #include <revolution/enc.h>
50 #include <revolution/sc.h>
51 #include <string.h>
52 #include <math.h>
53 
54 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
55 #include <demo.h>
56 
57 /*---------------------------------------------------------------------------*
58  * Local Definitions
59  *---------------------------------------------------------------------------*/
60 #define SCRN_WIDTH      640
61 #define SCRN_HEIGHT     480
62 #define FONT_HEIGHT     10
63 #define CLMN_WIDTH      20 * FONT_HEIGHT
64 #define CHAN_INDENT     140
65 #define ITEM_WIDTH      80
66 
67 #define X_START         10
68 #define Y_START         16
69 
70 enum {
71     MNU_RUMBLE = 0,
72     MNU_INFO,
73     MNU_DISCN,
74     MNU_ACC,
75     MNU_DPD,
76     MNU_DPD_FULL,
77     MNU_EXTGMK,
78     MNU_RDMEM,
79     MNU_WRMEM,
80     MNU_DMEXT,
81     MNU_MPLS,
82     MNU_MAX
83 };
84 
85 #define SMPBUF_SIZE     120
86 
87 #define SEPARATION      0.20f   // Meter unit.
88                                 // You must modify this value according to your environment.
89 
90 /*---------------------------------------------------------------------------*
91  * Local Data
92  *---------------------------------------------------------------------------*/
93 static WPADCLStatus cl_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
94 static WPADFSStatus fs_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
95 static WPADTRStatus tr_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
96 static WPADBLStatus bl_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
97 static WPADMPStatus mp_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
98 static WPADStatus   co_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
99 static WPADStatusEx ex_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE+4];
100 static WPADInfo     infos[WPAD_MAX_CONTROLLERS];
101 
102 static u8 myWorkarea[ WPAD_BLCINT_WORK_LEN ] ATTRIBUTE_ALIGN( 32 ) ;
103 
104 static int rb      [WPAD_MAX_CONTROLLERS];
105 static int rbCount [WPAD_MAX_CONTROLLERS];
106 static int acc     [WPAD_MAX_CONTROLLERS];
107 static int dpd     [WPAD_MAX_CONTROLLERS];
108 static int dpd_full[WPAD_MAX_CONTROLLERS];
109 static int extGmk  [WPAD_MAX_CONTROLLERS];
110 static int dummyExt[WPAD_MAX_CONTROLLERS];
111 
112 static u8  readBuf [WPAD_MAX_CONTROLLERS][4096];
113 static u8  writeBuf[WPAD_MAX_CONTROLLERS][4096];
114 
115 static int col;
116 static int row;
117 
118 static u8  smp_pair;
119 static u8  std_pair;
120 static u8  reset;
121 static u8  power;
122 
123 static u8 rbPattern[64] = {1,1,1,1,1,1,1,1,
124                            1,1,1,1,1,1,1,1,
125                            1,1,1,1,1,1,1,1,
126                            0,0,0,0,0,0,0,0,
127                            0,0,0,0,0,0,0,0,
128                            0,0,0,0,0,0,0,0,
129                            0,0,0,0,0,0,0,0,
130                            0,0,0,0,0,0,0,0};
131 
132 
133 u8 fmt_core1[] = "CORE             ";
134 u8 fmt_core2[] = "CORE_ACC         ";
135 u8 fmt_core3[] = "CORE_ACC_DPD     ";
136 u8 fmt_nun1[]  = "FREESTYLE        ";
137 u8 fmt_nun2[]  = "FREESTYLE_ACC    ";
138 u8 fmt_nun3[]  = "FREESTYLE_ACC_DPD";
139 u8 fmt_clas1[] = "CLASSIC          ";
140 u8 fmt_clas2[] = "CLASSIC_ACC      ";
141 u8 fmt_clas3[] = "CLASSIC_ACC_DPD  ";
142 u8 fmt_full[]  = "CORE_ACC_DPD_FULL";
143 u8 fmt_gtr[]   = "GUITAR           ";
144 u8 fmt_trn[]   = "TRAIN            ";
145 u8 fmt_blc[]   = "BALANCE_CHECKER  ";
146 u8 fmt_drm[]   = "DRUM             ";
147 u8 fmt_tko[]   = "TAIKO            ";
148 u8 fmt_mpls[]  = "MPLS             ";
149 
150 u8 str_dev_core   [] = "CORE ";
151 u8 str_dev_extn   [] = "NCHKU";
152 u8 str_dev_cl     [] = "CLSIC";
153 u8 str_dev_gt     [] = "GUITR";
154 u8 str_dev_tr     [] = "TRAIN";
155 u8 str_dev_bl     [] = "BLANC";
156 u8 str_dev_dr     [] = "DRUM ";
157 u8 str_dev_tk     [] = "TAIKO";
158 u8 str_dev_mp     [] = "MPLS ";
159 u8 str_dev_mf     [] = "MP+FS";
160 u8 str_dev_mc     [] = "MP+CL";
161 u8 str_dev_me     [] = "MP+FT";
162 u8 str_dev_future [] = "FTURE";
163 u8 str_dev_notsup [] = "UNSPT";
164 u8 str_dev_unknown[] = "UNKWN";
165 u8 str_dev_notfound[]= "NTFND";
166 
167 u8 str_status_ok  [] = "OK   ";
168 u8 str_status_none[] = "NONE ";
169 u8 str_status_busy[] = "BUSY ";
170 u8 str_status_xfer[] = "TRANS";
171 u8 str_status_inv [] = "INVLD";
172 u8 str_status_crpt[] = "CRPTD";
173 u8 str_status_unk [] = "UNKWN";
174 
175 u8 dpd_fmt_off  [] = "OFF ";
176 u8 dpd_fmt_std  [] = "STD ";
177 u8 dpd_fmt_exp  [] = "EXP ";
178 u8 dpd_fmt_full [] = "FULL";
179 
180 u8 sync_std[] = "STD";
181 u8 sync_smp[] = "SMP";
182 u8 sync_unk[] = "NONE";
183 
184 
185 /*---------------------------------------------------------------------------*
186  * Function prototypes
187  *---------------------------------------------------------------------------*/
188 static void *myAlloc                ( u32  size );
189 static u8    myFree                 ( void *ptr );
190 
191 static void  sysInit                ( void );
192 static void  sysShutdown            ( void );
193 static void  appInit                ( void );
194 static void  wpadInit               ( void );
195 
196 static void  resetCallback          ( void );
197 static void  powerCallback          ( void );
198 
199 static void  samplingCallback       ( s32 chan );
200 static void  connectCallback        ( s32 chan, s32 reason );
201 static void  extensionCallback      ( s32 chan, s32 result );
202 static void  syncButtonCallback     ( s32 result, s32 num  );
203 static void  syncSimpleCallback     ( s32 result, s32 num  );
204 
205 static void  update                 ( void );
206 static void  operate                ( void );
207 static void  moveCursor             ( void );
208 static void  resetController        ( s32 chan, u32 type );
209 static void  renderScreen           ( void );
210 static void  renderAimings          ( void );
211 static void  renderStatus           ( void );
212 static void  renderDots             ( void *ptr );
213 
214 static u8   *getDevName             ( u32 type );
215 static u8   *getErrName             ( s8  err  );
216 static u8   *getDpdFmt              ( u8  fmt  );
217 static u8   *getSyncName            ( u8  sync );
218 static u8   *getFormat              ( u32 fmt  );
219 static f32   getDistance            ( const WPADStatus *stat );
220 
221 static void  printIntro             ( void );
222 
223 /*===========================================================================*
224  *                   F U N C T I O N    D E F I N I T I O N S
225  *===========================================================================*/
226 /*---------------------------------------------------------------------------*
227     Name:           main
228 
229     Description:    None.
230 
231     Arguments:      None.
232 
233     Returns:        None.
234  *---------------------------------------------------------------------------*/
main(void)235 void main( void )
236 {
237     sysInit();
238     appInit();
239     wpadInit();
240 
241     printIntro();
242 
243     // main loop
244     while( reset && power )
245     {
246         DEMOBeforeRender();
247         renderScreen();
248         renderStatus();
249         renderAimings();
250         DEMODoneRender();
251 
252         DEMOPadRead();
253         update();
254         operate();
255         moveCursor();
256     }
257 
258     sysShutdown();
259 }
260 
261 /*---------------------------------------------------------------------------*
262     Name:           sysInit
263 
264     Description:    Initializes system.
265 
266     Arguments:      None.
267 
268     Returns:        None.
269  *---------------------------------------------------------------------------*/
sysInit(void)270 static void sysInit( void )
271 {
272     const GXColor DARKBLUE  = { 0, 0, 80, 255 };
273 
274     // Initialize OS
275     OSInit();
276     // Initialize reset and power process.
277     reset = power = 1;
278     OSSetResetCallback(resetCallback);
279     OSSetPowerCallback(powerCallback);
280     // Initialize DEMO
281     DEMOInit( &GXNtsc480IntDf );
282     DEMOPadInit();
283     // Initialize screen setting
284     GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
285     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
286     DEMOInitCaption( DM_FT_XLU, SCRN_WIDTH, SCRN_HEIGHT );
287     GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );                       // Set pixel processing mode
288     GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );    // Translucent mode
289 
290 }
291 
292 /*---------------------------------------------------------------------------*
293     Name:           sysShutdown
294 
295     Description:    Shutdown system.
296 
297     Arguments:      None.
298 
299     Returns:        None.
300  *---------------------------------------------------------------------------*/
sysShutdown(void)301 static void sysShutdown( void )
302 {
303     int i;
304 
305     // Make screen black.
306     VISetBlack(TRUE);
307     VIFlush();
308     for(i=0; i<8; i++)
309     {
310         VIWaitForRetrace();
311     }
312 
313     // reset or shutdown.
314     if (!reset)
315     {
316         OSRestart(0);
317     }
318     if (!power)
319     {
320         OSShutdownSystem();
321     }
322 }
323 
324 /*---------------------------------------------------------------------------*
325     Name:           resetCallback
326 
327     Description:    Function to be called when reset button is pressed.
328 
329     Arguments:      None.
330 
331     Returns:        None.
332  *---------------------------------------------------------------------------*/
resetCallback(void)333 static void resetCallback( void )
334 {
335     reset = 0;
336 }
337 
338 /*---------------------------------------------------------------------------*
339     Name:           powerCallback
340 
341     Description:    Function to be called when power button on wii console
342                     is pressed or power button on wii remote registered by
343                     standard pairing.
344 
345     Arguments:      None.
346 
347     Returns:        None.
348  *---------------------------------------------------------------------------*/
powerCallback(void)349 static void powerCallback( void )
350 {
351     power = 0;
352 }
353 
354 /*---------------------------------------------------------------------------*
355     Name:           appInit
356 
357     Description:    Initializes application.
358 
359     Arguments:      None.
360 
361     Returns:        None.
362  *---------------------------------------------------------------------------*/
appInit(void)363 static void appInit( void )
364 {
365     int i;
366 
367     col = 0;
368     row = 0;
369 
370     for(i=0; i<WPAD_MAX_CONTROLLERS; i++)
371     {
372         rb[i]       = 0;
373         rbCount[i]  = 0;
374         acc[i]      = 0;
375         dpd[i]      = 0;
376         dpd_full[i] = 0;
377         extGmk[i]   = 0;
378         dummyExt[i] = 0;
379     }
380 }
381 
382 /*---------------------------------------------------------------------------*
383     Name:           wpadInit
384 
385     Description:    Initializes WPAD library.
386 
387     Arguments:      None.
388 
389     Returns:        None.
390  *---------------------------------------------------------------------------*/
wpadInit(void)391 static void wpadInit( void )
392 {
393     int   i;
394     s32   len;
395     u16   utf16_title[16];
396     const char game_title[] = "wpad_sample";
397 
398     // - We must now register memory allocation/free functions for MEM2.
399     // - WPAD requires some memory in MEM2 for data transfers
400     //   between the controller and WPAD driver stack.
401     // - Memory allocation only occurs once, at the initialization.
402     // - Memory usage is on the order of 1KB.
403     // - NOTE: We are using the MEM library allocators defined by
404     //   the DEMO library.
405     //
406     WPADRegisterAllocator(myAlloc, myFree);
407 
408     // If application uses Wii balance board on JP platform,
409     // it must give work buffer aligned 32bytes for initialization.
410     // This work buffer can be freed after WPADGetStatus() returns WPAD_STATE_SETUP.
411     if (SCGetLanguage() == SC_LANG_JAPANESE)
412     {
413         WPADRegisterBLCWorkarea(myWorkarea);
414     }
415     // Initialize WPAD!
416     WPADInit();
417     // Register callback to be called when a controller is connected or disconnected.
418     for (i=0; i<WPAD_MAX_CONTROLLERS; i++)
419     {
420         WPADSetConnectCallback(i, connectCallback);
421     }
422 
423     // Register callback to be called when sync event occurs.
424     smp_pair = 0;
425     std_pair = 0;
426     WPADSetSyncDeviceCallback(syncButtonCallback);
427     WPADSetSimpleSyncCallback(syncSimpleCallback);
428 
429     // Set the game title that is written when an application writes
430     // the game data into wii remote memory.
431     memset(utf16_title, 0, sizeof(utf16_title));
432     len = (s32)strlen(game_title);
433     ENCConvertStringUtf8ToUtf16(utf16_title, &len, (const u8*)game_title, &len);
434     WPADSetGameTitleUtf16(utf16_title);
435 
436     // The WPAD initialization process is asynchronous.
437     // So we should wait until it's completed.
438     while (WPAD_STATE_SETUP != WPADGetStatus())
439     {
440         ;
441     }
442 
443     // From here, workarea can be freed if necessary.
444 
445 }
446 
447 /*---------------------------------------------------------------------------*
448     Name:           myAlloc
449 
450     Description:    Allocate memory from MEM2.
451 
452     Arguments:      size        Memory size
453 
454     Returns:        Point to the head address of the allocated memory.
455  *---------------------------------------------------------------------------*/
myAlloc(u32 size)456 static void *myAlloc( u32 size )
457 {
458     void *ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
459     ASSERTMSG(ptr, "Memory allocation failed\n");
460 
461     return(ptr);
462 
463 }
464 
465 /*---------------------------------------------------------------------------*
466     Name:           myFree
467 
468     Description:    Free memory.
469 
470     Arguments:      ptr         Point to head of the memory address to be freed.
471 
472     Returns:        Result, but unused now.
473  *---------------------------------------------------------------------------*/
myFree(void * ptr)474 static u8 myFree( void *ptr )
475 {
476     MEMFreeToAllocator(&DemoAllocator2, ptr);
477 
478     return(1);
479 
480 }
481 
482 /*---------------------------------------------------------------------------*
483     Name:           resetController
484 
485     Description:    Reset the controller settings such as data foramt,
486                     dpd format, and sampling buffer.
487 
488     Arguments:      chan        specified channel.
489                     type        device type.
490 
491     Returns:        None.
492  *---------------------------------------------------------------------------*/
resetController(s32 chan,u32 type)493 static void resetController( s32 chan, u32 type )
494 {
495     void *buffer;
496     u32   datfmt;
497     u8    dpdfmt;
498 
499     if (type == WPAD_DEV_UNKNOWN || type == WPAD_DEV_NOT_FOUND)
500     {
501         return;
502     }
503 
504     if (dpd_full[chan])
505     {
506         if (acc[chan])
507         {
508             datfmt = WPAD_FMT_CORE_ACC_DPD_FULL;
509         }
510         else
511         {
512             datfmt = WPAD_FMT_CORE;
513         }
514         buffer = (void *)&ex_ringbuffer[chan][0];
515         dpdfmt = WPAD_DPD_FULL;
516     }
517     else
518     {
519         switch(type)
520         {
521             case WPAD_DEV_CORE:
522             case WPAD_DEV_FUTURE:
523             case WPAD_DEV_NOT_SUPPORTED:
524                 buffer = (void *)&co_ringbuffer[chan][0];
525                 datfmt = (u32)((!acc[chan]) ? WPAD_FMT_CORE :
526                                (!dpd[chan]) ? WPAD_FMT_CORE_ACC :
527                                               WPAD_FMT_CORE_ACC_DPD);
528                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_EXP : WPAD_DPD_OFF);
529                 break;
530             case WPAD_DEV_FREESTYLE:
531                 buffer = (void *)&fs_ringbuffer[chan][0];
532                 datfmt = (u32)((!acc[chan]) ? WPAD_FMT_FREESTYLE :
533                                (!dpd[chan]) ? WPAD_FMT_FREESTYLE_ACC :
534                                               WPAD_FMT_FREESTYLE_ACC_DPD);
535                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
536                 break;
537 
538             case WPAD_DEV_CLASSIC:
539                 buffer = (void *)&cl_ringbuffer[chan][0];
540                 datfmt = (u32)((!acc[chan]) ? WPAD_FMT_CLASSIC :
541                                (!dpd[chan]) ? WPAD_FMT_CLASSIC_ACC :
542                                               WPAD_FMT_CLASSIC_ACC_DPD);
543                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
544                 break;
545 
546             case WPAD_DEV_GUITAR:
547                 buffer = (void *)&cl_ringbuffer[chan][0];
548                 datfmt = WPAD_FMT_GUITAR;
549                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
550                 break;
551 
552             case WPAD_DEV_DRUM:
553                 buffer = (void *)&cl_ringbuffer[chan][0];
554                 datfmt = WPAD_FMT_DRUM;
555                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
556                 break;
557 
558             case WPAD_DEV_TAIKO:
559                 buffer = (void *)&cl_ringbuffer[chan][0];
560                 datfmt = WPAD_FMT_TAIKO;
561                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
562                 break;
563 
564             case WPAD_DEV_TRAIN:
565                 buffer = (void *)&tr_ringbuffer[chan][0];
566                 datfmt = WPAD_FMT_TRAIN;
567                 dpdfmt = WPAD_DPD_OFF;
568                 break;
569 
570             case WPAD_DEV_BALANCE_CHECKER:
571                 buffer = (void *)&bl_ringbuffer[chan][0];
572                 datfmt = WPAD_FMT_BALANCE_CHECKER;
573                 dpdfmt = WPAD_DPD_OFF;
574                 break;
575 
576             case WPAD_DEV_MPLS:
577             case WPAD_DEV_MPLS_FREESTYLE:
578             case WPAD_DEV_MPLS_CLASSIC:
579             case WPAD_DEV_MPLS_FUTURE:
580                 buffer = (void *)&mp_ringbuffer[chan][0];
581                 datfmt = WPAD_FMT_MPLS;
582                 dpdfmt = (u8)((dpd[chan])   ? WPAD_DPD_STD : WPAD_DPD_OFF);
583                 break;
584 
585         }
586     }
587 
588     WPADControlDpd(chan, dpdfmt, NULL);
589     WPADSetDataFormat(chan, datfmt);
590     WPADSetAutoSamplingBuf(chan, buffer, SMPBUF_SIZE);
591 }
592 
593 /*---------------------------------------------------------------------------*
594     Name:           connectCallback
595 
596     Description:    Function to be called when a controller is connected or
597                     disconnected.
598 
599     Arguments:      chan        Specified channel to be connected/disconnected.
600                     reason      Reason of calling this.
601                                   if WPAD_ERR_NONE, connected.
602                                   if WPAD_ERR_NO_CONTROLLER, disconnected.
603 
604     Returns:        None.
605  *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)606 static void connectCallback( s32 chan, s32 reason )
607 {
608     u32 type;
609 
610     // connected!
611     if (reason == WPAD_ERR_NONE)
612     {
613         WPADProbe(chan, &type);
614 
615         // If WPAD_DEV_BALANCE_CHECKER, wii balance board is connected.
616         // If WPAD_DEV_CORE, wii remote is connected.
617         // Set the data format, turn on/off DPD and register auto sampling buffer
618         resetController( chan, type );
619 
620         // Register callbacks which are deregistered in disconnection.
621         WPADSetExtensionCallback(chan, extensionCallback);
622         WPADSetSamplingCallback(chan, samplingCallback);
623 
624         if (dummyExt[chan])
625         {
626             WPADAttachDummyExtension(chan, WPAD_DEV_FUTURE);
627         }
628     }
629 }
630 
631 /*---------------------------------------------------------------------------*
632     Name:           extensionCallback
633 
634     Description:    Function to be called when an extension is attached or
635                     detached.
636 
637     Arguments:      chan        specified channel to be attached/detached.
638                     result      new device type.
639 
640    / ----------------------------------------------------------------------- /
641      the meaning of result is below.
642       if WPAD_DEV_CORE, an extension is detached.
643       if WPAD_DEV_FUTURE, an extension is undefined.
644       if WPAD_DEV_NOT_SUPPORTED, an extension is not supported.
645       if WPAD_DEV_FREESTYLE, nunchaku extension is attached.
646       if WPAD_DEV_CLASSIC, classic controller extension is attached.
647       if WPAD_DEV_GUITAR, guitar extension is attached.
648       if WPAD_DEV_DRUM, drum extension is attached.
649       if WPAD_DEV_TAIKO, taiko extension is attached.
650       if WPAD_DEV_TRAIN, master controller for train game is attached.
651       if WPAD_DEV_MPLS, Wii MotionPlus extension is attached or someting is detached from Wii MotionPlus.
652       if WPAD_DEV_MPLS_FREESTYLE, nunchaku extension is attached with Wii MotionPlus.
653       if WPAD_DEV_MPLS_CLASSIC, classic controller extension is attached with Wii MotionPlus.
654       if WPAD_DEV_MPLS_FUTURE, an extension except nunchaku and classic controller is attached with Wii MotionPlus.
655       if WPAD_DEV_UNKNOWN, an extension is attached but it is not known yet.
656 
657       An extension cannot be recognized shortly when it is attached and
658       WPAD_DEV_UNKOWN is returned at first. After a while, the host recognizes
659       the currect deveice type and the type is returned.
660 
661       Note: if WPAD_DEV_FUTRUE and WPAD_DEV_NOT_SUPPORTED is returned,
662             wii remote at least has to work.
663    / ----------------------------------------------------------------------- /
664 
665     Returns:        None.
666  *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)667 static void extensionCallback( s32 chan, s32 result )
668 {
669     resetController( chan, (u32)result );
670 }
671 
672 /*---------------------------------------------------------------------------*
673     Name:           samplingCallback
674 
675     Description:    Function to be called whenever controler data is received.
676 
677     Arguments:      chan        specified channel.
678 
679     Returns:        None.
680  *---------------------------------------------------------------------------*/
samplingCallback(s32 chan)681 static void samplingCallback( s32 chan )
682 {
683 #pragma unused(chan)
684 
685 }
686 
687 /*---------------------------------------------------------------------------*
688     Name:           syncButtonCallback
689 
690     Description:    Function to be called when SYNC button on wii console
691                     is pressed.
692 
693     Arguments:      result      Sync event
694                     num         Number of the registered device in this try.
695 
696     Returns:        None.
697  *---------------------------------------------------------------------------*/
syncButtonCallback(s32 result,s32 num)698 static void syncButtonCallback( s32 result, s32 num )
699 {
700     BOOL ret;
701 
702     if (result == WPAD_SYNC_EVT_START)
703     {
704         ret = WPADStartSyncDevice();
705         if (ret)
706         {
707             std_pair = 1;
708         }
709         OSReport("SYNC is pressed.\n");
710     }
711     else
712     {
713         std_pair = 0;
714         OSReport("sync is done. %d device(s) registered.\n", num);
715     }
716 }
717 
718 /*---------------------------------------------------------------------------*
719     Name:           syncSimpleCallback
720 
721     Description:    Function to be called when an application stops
722                     simple pairing.
723 
724     Arguments:      result      Sync event
725                     num         Number of the registered device in this try.
726 
727     Returns:        None.
728  *---------------------------------------------------------------------------*/
syncSimpleCallback(s32 result,s32 num)729 static void syncSimpleCallback( s32 result, s32 num )
730 {
731     if (result == WPAD_SYNC_EVT_DONE)
732     {
733         smp_pair = 0;
734         OSReport("sync is done. %d device(s) registered.\n", num);
735     }
736 }
737 
738 /*---------------------------------------------------------------------------*
739     Name:           update
740 
741     Description:    None.
742 
743     Arguments:      None.
744 
745     Returns:        None.
746  *---------------------------------------------------------------------------*/
update(void)747 static void update( void )
748 {
749     int chan;
750 
751     for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
752     {
753         if (rb[chan])
754         {
755             if (rbPattern[rbCount[chan]])
756             {
757                 WPADStartMotor(chan);
758             }
759             else
760             {
761                 WPADStopMotor(chan);
762             }
763 
764             if (++rbCount[chan] == sizeof(rbPattern))
765             {
766                 rbCount[chan] = 0;
767             }
768         }
769         else
770         {
771             WPADStopMotor(chan);
772             rbCount[chan] = 0;
773         }
774     }
775 }
776 
777 /*---------------------------------------------------------------------------*
778     Name:           moveCursor
779 
780     Description:
781 
782     Arguments:      trig        triggered button bit mask.
783 
784     Returns:        None.
785  *---------------------------------------------------------------------------*/
moveCursor(void)786 static void moveCursor( void )
787 {
788     u32 trig = DEMOPadGetButtonDown(0);
789 
790     if (trig & PAD_BUTTON_UP)
791     {
792         col = (col > 0) ? col - 1 : 0;
793     }
794     if (trig & PAD_BUTTON_DOWN)
795     {
796         col = (col < MNU_MAX - 1) ? col + 1 : col;
797     }
798     if (trig & PAD_BUTTON_LEFT)
799     {
800         row = (row > 0) ? row - 1 : 0;;
801     }
802     if (trig & PAD_BUTTON_RIGHT)
803     {
804         row = (row < WPAD_MAX_CONTROLLERS) ? row + 1 : row;
805     }
806 }
807 
808 /*---------------------------------------------------------------------------*
809     Name:           operate
810 
811     Description:    None.
812 
813     Arguments:      None.
814 
815     Returns:        None.
816  *---------------------------------------------------------------------------*/
operate()817 static void operate()
818 {
819     int i;
820     u32 trig = DEMOPadGetButtonDown(0);
821     u32 type;
822     u8  chan[4] = {0,0,0,0};
823 
824     if (trig & PAD_BUTTON_A)
825     {
826         if (row == 4)
827         {
828             chan[0] = chan[1] = chan[2] = chan[3] = 1;
829         }
830         else
831         {
832             chan[row] = 1;
833         }
834 
835         for(i=0; i<WPAD_MAX_CONTROLLERS; i++)
836         {
837             if (!chan[i])
838             {
839                 continue;
840             }
841 
842             WPADProbe(i, &type);
843 
844             switch(col)
845             {
846                 case MNU_RUMBLE:
847                     rb[i] = (rb[i]) ? 0 : 1;
848                     rbCount[i] = 0;
849                     break;
850                 case MNU_INFO:
851                     WPADGetInfoAsync(i, &infos[i], NULL);
852                     break;
853                 case MNU_DISCN:
854                     WPADDisconnect(i);
855                     break;
856                 case MNU_RDMEM:
857                     WPADReadGameData(i, readBuf[i],  3000, 0, NULL);
858                     break;
859                 case MNU_WRMEM:
860                     WPADWriteGameData(i, writeBuf[i], 3000, 0, NULL);
861                     break;
862                 case MNU_ACC:
863                     acc[i] = (acc[i]) ? 0 : 1;
864                     resetController(i, type);
865                     break;
866                 case MNU_DPD:
867                     dpd[i] = (dpd[i]) ? 0 : 1;
868                     resetController(i, type);
869                     break;
870                 case MNU_DPD_FULL:
871                     dpd_full[i] = (dpd_full[i]) ? 0 : 1;
872                     resetController(i, type);
873                     break;
874                 case MNU_EXTGMK:
875                     extGmk[i] = (extGmk[i]) ? 0 : 1;
876                     WPADControlExtGimmick(i, (u32)((extGmk[i]) ? WPAD_EXTGMK_ON : WPAD_EXTGMK_OFF), NULL);
877                     break;
878                 case MNU_DMEXT:
879                     dummyExt[i] = (dummyExt[i]) ? 0 : 1;
880                     if (dummyExt[i])
881                     {
882                         WPADAttachDummyExtension(i, WPAD_DEV_FUTURE);
883                     }
884                     else
885                     {
886                         WPADDetachDummyExtension(i);
887                     }
888                     break;
889                 case MNU_MPLS:
890                     if (WPADGetMplsStatus(i) != WPAD_MPLS_OFF)
891                     {
892                         WPADControlMpls(i, WPAD_MPLS_OFF, NULL);
893                     }
894                     else
895                     {
896                         WPADControlMpls(i, WPAD_MPLS_STD, NULL);
897                     }
898                     break;
899             }
900         }
901     }
902     if (trig & PAD_TRIGGER_Z)
903     {
904         if (!smp_pair && !std_pair)
905         {
906             smp_pair = 1;
907             WPADStartSimpleSync();
908         }
909         else if (smp_pair)
910         {
911             WPADStopSimpleSync();
912         }
913     }
914     if (trig & PAD_BUTTON_B)
915     {
916         WPADSetAcceptConnection((WPADGetAcceptConnection()) ? FALSE : TRUE);
917     }
918 }
919 
920 /*---------------------------------------------------------------------------*
921     Name:           getDevName
922 
923     Description:    Get the device name from the device type.
924 
925     Arguments:      type        device type.
926 
927     Returns:        Point to the device name string.
928  *---------------------------------------------------------------------------*/
getDevName(u32 type)929 static u8 *getDevName( u32 type )
930 {
931     u8 *ptr;
932 
933     switch(type)
934     {
935         case WPAD_DEV_CORE:                 ptr = &str_dev_core[0];                break;
936         case WPAD_DEV_FREESTYLE:            ptr = &str_dev_extn[0];                break;
937         case WPAD_DEV_CLASSIC:              ptr = &str_dev_cl[0];                  break;
938         case WPAD_DEV_GUITAR:               ptr = &str_dev_gt[0];                  break;
939         case WPAD_DEV_TRAIN:                ptr = &str_dev_tr[0];                  break;
940         case WPAD_DEV_DRUM:                 ptr = &str_dev_dr[0];                  break;
941         case WPAD_DEV_TAIKO:                ptr = &str_dev_tk[0];                  break;
942         case WPAD_DEV_MPLS:                 ptr = &str_dev_mp[0];                  break;
943         case WPAD_DEV_MPLS_FREESTYLE:       ptr = &str_dev_mf[0];                  break;
944         case WPAD_DEV_MPLS_CLASSIC:         ptr = &str_dev_mc[0];                  break;
945         case WPAD_DEV_MPLS_FUTURE:          ptr = &str_dev_me[0];                  break;
946         case WPAD_DEV_BALANCE_CHECKER:      ptr = &str_dev_bl[0];                  break;
947         case WPAD_DEV_FUTURE:               ptr = &str_dev_future[0];              break;
948         case WPAD_DEV_NOT_SUPPORTED:        ptr = &str_dev_notsup[0];              break;
949         case WPAD_DEV_UNKNOWN:              ptr = &str_dev_unknown[0];             break;
950         default:                            ptr = &str_dev_notfound[0];            break;
951     }
952 
953     return ptr;
954 
955 }
956 
957 /*---------------------------------------------------------------------------*
958     Name:           getErrName
959 
960     Description:    Get the error name from the error type.
961 
962     Arguments:      err         error type.
963 
964     Returns:        Point to the error name string.
965  *---------------------------------------------------------------------------*/
getErrName(s8 err)966 static u8 *getErrName( s8 err )
967 {
968     u8 *ptr;
969 
970     switch(err)
971     {
972         case WPAD_ERR_NONE:            ptr = &str_status_ok[0];            break;
973         case WPAD_ERR_NO_CONTROLLER:   ptr = &str_status_none[0];          break;
974         case WPAD_ERR_BUSY:            ptr = &str_status_busy[0];          break;
975         case WPAD_ERR_TRANSFER:        ptr = &str_status_xfer[0];          break;
976         case WPAD_ERR_INVALID:         ptr = &str_status_inv[0];           break;
977         case WPAD_ERR_CORRUPTED:       ptr = &str_status_crpt[0];          break;
978         default:                       ptr = &str_status_unk[0];           break;
979     }
980 
981     return ptr;
982 
983 }
984 
985 /*---------------------------------------------------------------------------*
986     Name:           getDpdFmt
987 
988     Description:    Get the dpd format name from the format type.
989 
990     Arguments:      fmt         dpd format type.
991 
992     Returns:        Point to the dpd format name string.
993  *---------------------------------------------------------------------------*/
getDpdFmt(u8 fmt)994 static u8 *getDpdFmt( u8 fmt )
995 {
996     u8 *ptr;
997 
998     switch(fmt)
999     {
1000         case WPAD_DPD_OFF:  ptr = &dpd_fmt_off[0];  break;
1001         case WPAD_DPD_STD:  ptr = &dpd_fmt_std[0];  break;
1002         case WPAD_DPD_EXP:  ptr = &dpd_fmt_exp[0];  break;
1003         case WPAD_DPD_FULL: ptr = &dpd_fmt_full[0]; break;
1004     }
1005 
1006     return ptr;
1007 }
1008 
1009 /*---------------------------------------------------------------------------*
1010     Name:           getSyncName
1011 
1012     Description:    Get the connection type name from the sync type.
1013 
1014     Arguments:      sync        sync type.
1015 
1016     Returns:        Point to the connection type name string.
1017  *---------------------------------------------------------------------------*/
getSyncName(u8 sync)1018 static u8 *getSyncName( u8 sync )
1019 {
1020     u8 *ptr;
1021 
1022     switch(sync)
1023     {
1024         case WPAD_SYNC_TYPE_STD: ptr = &sync_std[0];  break;
1025         case WPAD_SYNC_TYPE_SMP: ptr = &sync_smp[0];  break;
1026         default:                 ptr = &sync_unk[0];  break;
1027     }
1028 
1029     return ptr;
1030 }
1031 
1032 /*---------------------------------------------------------------------------*
1033     Name:           getFormat
1034 
1035     Description:    Get the data format name from the format type.
1036 
1037     Arguments:      fmt         data format type.
1038 
1039     Returns:        Point to the data format name string.
1040  *---------------------------------------------------------------------------*/
getFormat(u32 fmt)1041 static u8 *getFormat( u32 fmt )
1042 {
1043     u8 *ptr;
1044 
1045     switch(fmt)
1046     {
1047         case WPAD_FMT_CORE:                 ptr = &fmt_core1[0];  break;
1048         case WPAD_FMT_CORE_ACC:             ptr = &fmt_core2[0];  break;
1049         case WPAD_FMT_CORE_ACC_DPD:         ptr = &fmt_core3[0];  break;
1050         case WPAD_FMT_FREESTYLE:            ptr = &fmt_nun1[0];   break;
1051         case WPAD_FMT_FREESTYLE_ACC:        ptr = &fmt_nun2[0];   break;
1052         case WPAD_FMT_FREESTYLE_ACC_DPD:    ptr = &fmt_nun3[0];   break;
1053         case WPAD_FMT_CLASSIC:              ptr = &fmt_clas1[0];  break;
1054         case WPAD_FMT_CLASSIC_ACC:          ptr = &fmt_clas2[0];  break;
1055         case WPAD_FMT_CLASSIC_ACC_DPD:      ptr = &fmt_clas3[0];  break;
1056         case WPAD_FMT_CORE_ACC_DPD_FULL:    ptr = &fmt_full[0];   break;
1057         case WPAD_FMT_GUITAR:               ptr = &fmt_gtr[0];    break;
1058         case WPAD_FMT_TRAIN:                ptr = &fmt_trn[0];    break;
1059         case WPAD_FMT_DRUM:                 ptr = &fmt_drm[0];    break;
1060         case WPAD_FMT_TAIKO:                ptr = &fmt_tko[0];    break;
1061         case WPAD_FMT_MPLS:                 ptr = &fmt_mpls[0];   break;
1062         case WPAD_FMT_BALANCE_CHECKER:      ptr = &fmt_blc[0];    break;
1063         default:                            ptr = &fmt_core1[0];  break;
1064     }
1065 
1066     return ptr;
1067 }
1068 
1069 /*---------------------------------------------------------------------------*
1070     Name:           getDistance
1071 
1072     Description:    Get the approx distance between wii remote and sensor bar.
1073 
1074     Arguments:      wpad         controller data.
1075 
1076     Returns:        Distance.
1077  *---------------------------------------------------------------------------*/
getDistance(const WPADStatus * wpad)1078 static f32 getDistance( const WPADStatus *wpad )
1079 {
1080     const f32 PI = 3.141592f;
1081     const f32 TH = WPAD_DPD_ANGLE / 2 * PI / 180;
1082     f32 xDiff;
1083     f32 yDiff;
1084     f32 dpdDist;
1085 
1086     xDiff   = (f32)(wpad->obj[0].x - wpad->obj[1].x);
1087     yDiff   = (f32)(wpad->obj[0].y - wpad->obj[1].y);
1088     dpdDist = (f32)sqrt(xDiff * xDiff + yDiff * yDiff);
1089 
1090     if ((wpad->obj[0].size > 0) && (wpad->obj[1].size > 0))
1091     {
1092         return (f32)(SEPARATION / 2 / tan(TH) * WPAD_DPD_IMG_RESO_WX / dpdDist);
1093     }
1094     else
1095     {
1096         return -1.0f;
1097     }
1098 }
1099 
1100 /*---------------------------------------------------------------------------*
1101     Name:           renderScreen
1102 
1103     Description:    Draw the items of controller status and menu.
1104 
1105     Arguments:      None.
1106 
1107     Returns:        None.
1108  *---------------------------------------------------------------------------*/
renderScreen(void)1109 static void renderScreen( void )
1110 {
1111     s16 x = X_START;
1112     s16 y = Y_START;
1113     s16 i;
1114 
1115     DEMOPrintf(x, y, 0, "WPAD Demo -- WPADSAMPLE");
1116 
1117     y+=FONT_HEIGHT*2;
1118 
1119     for(i=0; i<WPAD_MAX_CONTROLLERS; i++)
1120     {
1121         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y, 0, "Ch%d", i);
1122     }
1123 
1124     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "ADDR      ");
1125     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "TX-STAT   ");
1126     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "TYPE      ");
1127     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "FORMAT    ");
1128     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "RATE      ");
1129     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "BUTTON    ");
1130     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "ACC       ");
1131     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-0     ");
1132     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-1     ");
1133     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-2     ");
1134     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-3     ");
1135     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-ST/FT ");
1136     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DISTANCE  ");
1137     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DEV       ");
1138     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DATA-ERR  ");
1139     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "BAT/LED   ");
1140     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "MEM-NM    ");
1141     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "MEM-TM    ");
1142     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "EXTENSION ");
1143 
1144     y+=FONT_HEIGHT*4;
1145 
1146     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "WORKMEM   ");
1147     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "STD/SMP   ");
1148     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "BAR-POS   ");
1149     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "MOTOR     ");
1150     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "ACCEPT    ");
1151     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "STD PAIR  ");
1152     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "SMP PAIR  ");
1153 
1154     x = X_START + 200;
1155     y = Y_START + FONT_HEIGHT * 25;
1156 
1157     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Rumble            1     2     3     4     A");
1158     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Info              1     2     3     4     A");
1159     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Disconnect        1     2     3     4     A");
1160     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "ACC               1     2     3     4     A");
1161     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD               1     2     3     4     A");
1162     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "DPD-FULL          1     2     3     4     A");
1163     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "ExtGimmick        1     2     3     4     A");
1164     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Read  mem         1     2     3     4     A");
1165     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Write mem         1     2     3     4     A");
1166     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "Dummy Ext         1     2     3     4     A");
1167     DEMOPrintf(x, y+=FONT_HEIGHT, 0, "MotionPlus        1     2     3     4     A");
1168 
1169     x = (s16)(X_START + 335 + row * 48);
1170     y = (s16)(Y_START + FONT_HEIGHT * (26 + col));
1171 
1172     DEMOPrintf(x, y, 0, "*");
1173 
1174 }
1175 
1176 /*---------------------------------------------------------------------------*
1177     Name:           renderStatus
1178 
1179     Description:    Draw each controller status.
1180 
1181     Arguments:      None.
1182 
1183     Returns:        None.
1184  *---------------------------------------------------------------------------*/
renderStatus(void)1185 static void renderStatus( void )
1186 {
1187     WPADStatusEx wpad;
1188     WPADAcc      acc;
1189     u8           addr[6];
1190     u8           game[4][17];
1191     s32          len = 16;
1192     OSTime       time;
1193     OSCalendarTime ct;
1194     char btn[] = "___________";
1195     char led[] = "____";
1196 
1197     s32  stat;
1198     u32  type;
1199     u8   sync;
1200 
1201     s32  i, j;
1202     s16  x;
1203     s16  y;
1204 
1205     const u16 *title;
1206 
1207 
1208     for (i=0; i<WPAD_MAX_CONTROLLERS; i++)
1209     {
1210         stat = WPADProbe(i, &type);
1211 
1212         WPADGetAddress(i, addr);
1213 
1214         x = X_START;
1215         y = Y_START + FONT_HEIGHT * 2;
1216 
1217         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%02x%02x:%02x%02x:%02x%02x",
1218             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
1219 
1220         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s", getErrName((s8)stat));
1221         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s", getDevName(type));
1222 
1223         if (stat == WPAD_ERR_NO_CONTROLLER)
1224         {
1225             continue;
1226         }
1227 
1228         // Read the latest controller data.
1229         WPADRead(i, &wpad);
1230         // Get the connection type.
1231         WPADGetSyncType(i, &sync);
1232         // Get the acc calibration for each axis on wii remote.
1233         WPADGetAccGravityUnit(i, WPAD_DEV_CORE, &acc);
1234 
1235         // Show controller status
1236         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 40), (s16)(y-FONT_HEIGHT*3), 0, "[%s]", getSyncName(sync));
1237         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),      y+=FONT_HEIGHT,         0, "%s",   getFormat(WPADGetDataFormat(i)));
1238         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),      y+=FONT_HEIGHT,         0, "%d",   WPADGetRadioSensitivity(i));
1239 
1240         // button on wii remote.
1241         btn[0] = (char)((wpad.button & WPAD_BUTTON_LEFT) ? '<' : '_');
1242         btn[1] = (char)((wpad.button & WPAD_BUTTON_UP)   ? '^' : '_');
1243         btn[2] = (char)((wpad.button & WPAD_BUTTON_DOWN) ? 'v' : '_');
1244         btn[3] = (char)((wpad.button & WPAD_BUTTON_RIGHT)? '>' : '_');
1245         btn[4] = (char)((wpad.button & WPAD_BUTTON_A)    ? 'A' : '_');
1246         btn[5] = (char)((wpad.button & WPAD_BUTTON_B)    ? 'B' : '_');
1247         btn[6] = (char)((wpad.button & WPAD_BUTTON_1)    ? '1' : '_');
1248         btn[7] = (char)((wpad.button & WPAD_BUTTON_2)    ? '2' : '_');
1249         btn[8] = (char)((wpad.button & WPAD_BUTTON_PLUS) ? '+' : '_');
1250         btn[9] = (char)((wpad.button & WPAD_BUTTON_MINUS)? '-' : '_');
1251         btn[10]= (char)((wpad.button & WPAD_BUTTON_HOME) ? 'H' : '_');
1252         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%s", btn);
1253         // acc on wii remote.
1254         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),      (s16)(y+FONT_HEIGHT), 0, "%1.2lf", (f32)((f32)wpad.accX/(f32)acc.x));
1255         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45), (s16)(y+FONT_HEIGHT), 0, "%1.2lf", (f32)((f32)wpad.accY/(f32)acc.y));
1256         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 90),       y+=FONT_HEIGHT, 0, "%1.2lf", (f32)((f32)wpad.accZ/(f32)acc.z));
1257         // dpd.
1258         for(j=0; j<WPAD_DPD_MAX_OBJECTS; j++)
1259         {
1260             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%04d, %04d, %d", wpad.obj[j].x, wpad.obj[j].y, wpad.obj[j].size);
1261         }
1262         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s / %s", WPADIsDpdEnabled(i) ? "ON " : "OFF", getDpdFmt(WPADGetDpdFormat(i)));
1263         // distance.
1264         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%.02f", getDistance((const WPADStatus*)&wpad));
1265         // controller data infomation.
1266         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s", getDevName(wpad.dev));
1267         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s", getErrName(wpad.err));     // This probes whether the data is available or not.
1268 
1269         memset(led, '_', sizeof(led)-1);
1270         for(j=0; j<WPAD_MAX_CONTROLLERS; j++)
1271         {
1272             if ((infos[i].led >> j) & 0x1u)
1273             {
1274                 led[j] = 'o';
1275             }
1276         }
1277         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%d, %s", infos[i].battery, led);
1278 
1279         // Clear string buffer for game title.
1280         memset(game[i], 0, 17);
1281         len = 16;
1282         // Get the file info on wii remote memory.
1283         if (WPADGetGameTitleUtf16(i, &title) == WPAD_ERR_INVALID)
1284         {
1285             memcpy(game[i], "----", 5);
1286         }
1287         else
1288         {
1289             ENCConvertStringUtf16ToUtf8(game[i], &len, title, &len);
1290         }
1291         DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s", game[i]);
1292         if (WPADGetGameDataTimeStamp(i, &time) == WPAD_ERR_INVALID)
1293         {
1294             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "--/-- --:--");
1295         }
1296         else
1297         {
1298             OSTicksToCalendarTime(time, &ct);
1299             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%02d/%02d %02d:%02d", ct.mon+1, ct.mday, ct.hour, ct.min);
1300         }
1301 
1302         switch(type)
1303         {
1304             case WPAD_DEV_FREESTYLE:
1305                 {
1306                     WPADFSStatus *fs = (WPADFSStatus*)&wpad;
1307                     char cz[] = "__";
1308 
1309                     // Get the acc calibration for each axis on nunchaku.
1310                     WPADGetAccGravityUnit(i, WPAD_DEV_FREESTYLE, &acc);
1311                     // button.
1312                     cz[0] = (char)((fs->button & WPAD_BUTTON_C) ? 'C' : '_');
1313                     cz[1] = (char)((fs->button & WPAD_BUTTON_Z) ? 'Z' : '_');
1314                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%s", cz);
1315                     // stick
1316                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", fs->fsStickX);
1317                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", fs->fsStickY);
1318                     // acc on nunchaku.
1319                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),      (s16)(y+FONT_HEIGHT), 0, "%1.2lf", (f32)((f32)fs->fsAccX/(f32)acc.x));
1320                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45), (s16)(y+FONT_HEIGHT), 0, "%1.2lf", (f32)((f32)fs->fsAccY/(f32)acc.y));
1321                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 90),       y+=FONT_HEIGHT, 0, "%1.2lf", (f32)((f32)fs->fsAccZ/(f32)acc.z));
1322                 }
1323                 y+=FONT_HEIGHT;
1324                 break;
1325 
1326             case WPAD_DEV_CLASSIC:
1327             case WPAD_DEV_GUITAR:
1328             case WPAD_DEV_DRUM:
1329             case WPAD_DEV_TAIKO:
1330                 {
1331                     WPADCLStatus *cl = (WPADCLStatus*)&wpad;
1332                     char clb[] = "_______________";
1333 
1334                     // button.
1335                     clb[0] = (char)((cl->clButton & WPAD_CL_BUTTON_LEFT) ? '<' : '_');
1336                     clb[1] = (char)((cl->clButton & WPAD_CL_BUTTON_UP)   ? '^' : '_');
1337                     clb[2] = (char)((cl->clButton & WPAD_CL_BUTTON_DOWN) ? 'v' : '_');
1338                     clb[3] = (char)((cl->clButton & WPAD_CL_BUTTON_RIGHT)? '>' : '_');
1339                     clb[4] = (char)((cl->clButton & WPAD_CL_BUTTON_A)    ? 'A' : '_');
1340                     clb[5] = (char)((cl->clButton & WPAD_CL_BUTTON_B)    ? 'B' : '_');
1341                     clb[6] = (char)((cl->clButton & WPAD_CL_BUTTON_X)    ? 'X' : '_');
1342                     clb[7] = (char)((cl->clButton & WPAD_CL_BUTTON_Y)    ? 'Y' : '_');
1343                     clb[8] = (char)((cl->clButton & WPAD_CL_TRIGGER_L)   ? 'L' : '_');
1344                     clb[9] = (char)((cl->clButton & WPAD_CL_TRIGGER_R)   ? 'R' : '_');
1345                     clb[10]= (char)((cl->clButton & WPAD_CL_TRIGGER_ZL)  ? 'z' : '_');
1346                     clb[11]= (char)((cl->clButton & WPAD_CL_TRIGGER_ZR)  ? 'Z' : '_');
1347                     clb[12]= (char)((cl->clButton & WPAD_CL_BUTTON_PLUS) ? '+' : '_');
1348                     clb[13]= (char)((cl->clButton & WPAD_CL_BUTTON_MINUS)? '-' : '_');
1349                     clb[14]= (char)((cl->clButton & WPAD_CL_BUTTON_HOME) ? 'H' : '_');
1350                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%s",   clb);
1351                     // stick.
1352                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", cl->clLStickX);
1353                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", cl->clLStickY);
1354                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", cl->clRStickX);
1355                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", cl->clRStickY);
1356                     // trigger.
1357                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", cl->clTriggerL);
1358                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", cl->clTriggerR);
1359                 }
1360                 break;
1361 
1362             case WPAD_DEV_TRAIN:
1363                 {
1364                     WPADTRStatus *tr = (WPADTRStatus*)&wpad;
1365                     char trb[] = "__________";
1366 
1367                     // button.
1368                     trb[0] = (char)((tr->trButton & WPAD_CL_BUTTON_LEFT) ? '<' : '_');
1369                     trb[1] = (char)((tr->trButton & WPAD_CL_BUTTON_UP)   ? '^' : '_');
1370                     trb[2] = (char)((tr->trButton & WPAD_CL_BUTTON_DOWN) ? 'v' : '_');
1371                     trb[3] = (char)((tr->trButton & WPAD_CL_BUTTON_RIGHT)? '>' : '_');
1372                     trb[4] = (char)((tr->trButton & WPAD_CL_BUTTON_Y)    ? 'A' : '_');
1373                     trb[5] = (char)((tr->trButton & WPAD_CL_BUTTON_B)    ? 'B' : '_');
1374                     trb[6] = (char)((tr->trButton & WPAD_CL_BUTTON_A)    ? 'C' : '_');
1375                     trb[7] = (char)((tr->trButton & WPAD_CL_BUTTON_X)    ? 'D' : '_');
1376                     trb[8] = (char)((tr->trButton & WPAD_CL_BUTTON_PLUS) ? '+' : '_');
1377                     trb[9] = (char)((tr->trButton & WPAD_CL_BUTTON_MINUS)? '-' : '_');
1378                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%s",   trb);
1379                     // trigger.
1380                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", tr->brake);
1381                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", tr->mascon);
1382                 }
1383                 break;
1384 
1385             case WPAD_DEV_BALANCE_CHECKER:
1386                 {
1387                     WPADBLStatus *bl = (WPADBLStatus*)&wpad;
1388 
1389                     // press.
1390                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", bl->press[0]);
1391                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", bl->press[1]);
1392                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH)     , (s16)(y+FONT_HEIGHT), 0, "%04d", bl->press[2]);
1393                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH + 45),       y+=FONT_HEIGHT, 0, "%04d", bl->press[3]);
1394                     // battery.
1395                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%04d", bl->battery);
1396                     // temperature.
1397                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),            y+=FONT_HEIGHT, 0, "%04d", bl->temp);
1398                 }
1399                 break;
1400 
1401             case WPAD_DEV_MPLS:
1402             case WPAD_DEV_MPLS_FREESTYLE:
1403             case WPAD_DEV_MPLS_CLASSIC:
1404             case WPAD_DEV_MPLS_FUTURE:
1405                 {
1406                     WPADMPStatus *mp = (WPADMPStatus*)&wpad;
1407                     WPADMpls     high;
1408                     WPADMpls     low;
1409                     f32          dps;
1410 
1411                     WPADGetMplsCalibration(i, &high, &low);
1412 
1413                     // Yaw
1414                     if (mp->stat & WPAD_MPLS_STAT_YAWSEL) { dps = (mp->yaw - low.yaw_zero)  / low.yaw_scale  * low.degrees ; }
1415                     else                                  { dps = (mp->yaw - high.yaw_zero) / high.yaw_scale * high.degrees; }
1416                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "[%s] %5d%+8.2f", (mp->stat & WPAD_MPLS_STAT_YAWSEL) ? "L" : "H", (s16)(mp->yaw),   dps);
1417                     // Roll
1418                     if (mp->stat & WPAD_MPLS_STAT_ROLSEL) { dps = (mp->roll - low.roll_zero)  / low.roll_scale  * low.degrees ; }
1419                     else                                  { dps = (mp->roll - high.roll_zero) / high.roll_scale * high.degrees; }
1420                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "[%s] %5d%+8.2f", (mp->stat & WPAD_MPLS_STAT_ROLSEL) ? "L" : "H", (s16)(mp->roll),  dps);
1421                     // Pitch
1422                     if (mp->stat & WPAD_MPLS_STAT_PITSEL) { dps = (mp->pitch - low.pitch_zero)  / low.pitch_scale  * low.degrees ; }
1423                     else                                  { dps = (mp->pitch - high.pitch_zero) / high.pitch_scale * high.degrees; }
1424                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "[%s] %5d%+8.2f", (mp->stat & WPAD_MPLS_STAT_PITSEL) ? "L" : "H", (s16)(mp->pitch), dps);
1425                     // MPLS Status
1426                     DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "  %s %s %s",
1427                         (mp->stat & WPAD_MPLS_STAT_ATTACH) ? "A" : "-",  // Extra extension is attached or detached?
1428                         (mp->stat & WPAD_MPLS_STAT_PLSVLD) ? "M" : "-",  // MotionPlus data is valid or corrupted?
1429                         (mp->stat & WPAD_MPLS_STAT_EXTVLD) ? "E" : "-"); // Extra extension data is valid or corrupted?
1430                     y+= FONT_HEIGHT;
1431 
1432                     if (mp->stat & WPAD_MPLS_STAT_ATTACH
1433                     &&  mp->stat & WPAD_MPLS_STAT_EXTVLD)
1434                     {
1435                         if (type == WPAD_DEV_MPLS_FREESTYLE)
1436                         {
1437                             char cz[] = "__";
1438 
1439                             cz[0] = (char)((mp->button & WPAD_BUTTON_C) ? 'C' : '_');
1440                             cz[1] = (char)((mp->button & WPAD_BUTTON_Z) ? 'Z' : '_');
1441 
1442                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %s", cz);                          y+= FONT_HEIGHT;
1443                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %d", (s16)(mp->ext.fs.fsStickX));
1444                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+35), y, 0, "  %d", (s16)(mp->ext.fs.fsStickY));  y+= FONT_HEIGHT;
1445                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %d", (s16)(mp->ext.fs.fsAccX));
1446                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+35), y, 0, "  %d", (s16)(mp->ext.fs.fsAccY));
1447                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+70), y, 0, "  %d", (s16)(mp->ext.fs.fsAccZ));    y+= FONT_HEIGHT;
1448                             y += FONT_HEIGHT;
1449                         }
1450                         if (type == WPAD_DEV_MPLS_CLASSIC)
1451                         {
1452                             char clb[] = "_______________";
1453 
1454                             // button.
1455                             clb[0] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_LEFT) ? '<' : '_');
1456                             clb[1] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_UP)   ? '^' : '_');
1457                             clb[2] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_DOWN) ? 'v' : '_');
1458                             clb[3] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_RIGHT)? '>' : '_');
1459                             clb[4] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_A)    ? 'A' : '_');
1460                             clb[5] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_B)    ? 'B' : '_');
1461                             clb[6] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_X)    ? 'X' : '_');
1462                             clb[7] = (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_Y)    ? 'Y' : '_');
1463                             clb[8] = (char)((mp->ext.cl.clButton & WPAD_CL_TRIGGER_L)   ? 'L' : '_');
1464                             clb[9] = (char)((mp->ext.cl.clButton & WPAD_CL_TRIGGER_R)   ? 'R' : '_');
1465                             clb[10]= (char)((mp->ext.cl.clButton & WPAD_CL_TRIGGER_ZL)  ? 'z' : '_');
1466                             clb[11]= (char)((mp->ext.cl.clButton & WPAD_CL_TRIGGER_ZR)  ? 'Z' : '_');
1467                             clb[12]= (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_PLUS) ? '+' : '_');
1468                             clb[13]= (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_MINUS)? '-' : '_');
1469                             clb[14]= (char)((mp->ext.cl.clButton & WPAD_CL_BUTTON_HOME) ? 'H' : '_');
1470                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %s", clb);                          y+= FONT_HEIGHT;
1471                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %d", (s16)(mp->ext.cl.clLStickX));
1472                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+35), y, 0, "  %d", (s16)(mp->ext.cl.clLStickY));  y+= FONT_HEIGHT;
1473                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %d", (s16)(mp->ext.cl.clRStickX));
1474                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+35), y, 0, "  %d", (s16)(mp->ext.cl.clRStickY));  y+= FONT_HEIGHT;
1475                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH),    y, 0, "  %d", (s16)(mp->ext.cl.clTriggerL));
1476                             DEMOPrintf((s16)(x + CHAN_INDENT * i + ITEM_WIDTH+35), y, 0, "  %d", (s16)(mp->ext.cl.clTriggerR)); y+= FONT_HEIGHT;
1477                         }
1478                     }
1479                 }
1480                 break;
1481 
1482             default:
1483                 y+=FONT_HEIGHT*3;
1484                 break;
1485         }
1486     }
1487 
1488     y = Y_START + FONT_HEIGHT * 25;
1489 
1490     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%d",         WPADGetWorkMemorySize());
1491     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%02d, %02d", WPADGetRegisteredDevNum(), WPADGetTemporaryDevNum());
1492     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s",         WPADGetSensorBarPosition() ? "TOP" : "BOTTOM");
1493     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s",         WPADIsMotorEnabled()       ? "ENABLE" : "DISABLE");
1494     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s",         WPADGetAcceptConnection()  ? "OK" : "NG");
1495     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s",         (std_pair)                 ? "STOP" : "START");
1496     DEMOPrintf((s16)(x + ITEM_WIDTH), y+=FONT_HEIGHT, 0, "%s",         (smp_pair)                 ? "STOP" : "START");
1497 }
1498 
1499 /*---------------------------------------------------------------------------*
1500     Name:           renderDots
1501 
1502     Description:    Draw a dot at the center of the coordinates of two objects.
1503 
1504     Arguments:      ptr         point to the controller data.
1505 
1506     Returns:        None.
1507  *---------------------------------------------------------------------------*/
renderDots(void * ptr)1508 static void renderDots( void *ptr )
1509 {
1510     s16 x;
1511     s16 y;
1512     WPADStatus *wpad = (WPADStatus*)ptr;
1513 
1514     // Check the error type of the controller data.
1515     // The data from dpd is available if the type is WPAD_ERR_NONE or WPAD_ERR_CORRUPTED.
1516     if (wpad->err == WPAD_ERR_NONE || wpad->err == WPAD_ERR_CORRUPTED)
1517     {
1518         x = (s16)(SCRN_WIDTH  - (wpad->obj[0].x + wpad->obj[1].x) / 2 * SCRN_WIDTH  / WPAD_DPD_IMG_RESO_WX);
1519         y = (s16)(SCRN_HEIGHT - (wpad->obj[0].y + wpad->obj[1].y) / 2 * SCRN_HEIGHT / WPAD_DPD_IMG_RESO_WY);
1520         DEMOPrintf(x, y, 0, ".");
1521     }
1522 }
1523 
1524 /*---------------------------------------------------------------------------*
1525     Name:           renderAimings
1526 
1527     Description:    Draw dots using sampled controller data.
1528 
1529     Arguments:      None.
1530 
1531     Returns:        None.
1532  *---------------------------------------------------------------------------*/
renderAimings(void)1533 static void renderAimings( void )
1534 {
1535     u32 latest;
1536     u32 index;
1537 
1538     int i;
1539     int j;
1540 
1541     u8  *ptr;
1542     u32 size;
1543 
1544     for (j=0; j<WPAD_MAX_CONTROLLERS; j++)
1545     {
1546         if (WPADProbe(j, NULL) == WPAD_ERR_NO_CONTROLLER)
1547         {
1548             continue;
1549         }
1550 
1551         // Ignore if dpd is disabled.
1552         if (!WPADIsDpdEnabled(j))
1553         {
1554             continue;
1555         }
1556         // Get the index of the latest data in sampling buffer.
1557         latest = WPADGetLatestIndexInBuf(j);
1558         index  = ((latest - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
1559 
1560         switch (WPADGetDataFormat(j))
1561         {
1562             case WPAD_FMT_CORE:
1563             case WPAD_FMT_CORE_ACC:
1564             case WPAD_FMT_CORE_ACC_DPD:
1565                 ptr  = (u8 *)(&co_ringbuffer[j][0]);
1566                 size = sizeof(WPADStatus);
1567                 break;
1568 
1569             case WPAD_FMT_CORE_ACC_DPD_FULL:
1570                 ptr  = (u8 *)(&ex_ringbuffer[j][0]);
1571                 size = sizeof(WPADStatusEx);
1572                 break;
1573 
1574             case WPAD_FMT_FREESTYLE:
1575             case WPAD_FMT_FREESTYLE_ACC:
1576             case WPAD_FMT_FREESTYLE_ACC_DPD:
1577                 ptr  = (u8 *)(&fs_ringbuffer[j][0]);
1578                 size = sizeof(WPADFSStatus);
1579                 break;
1580 
1581             case WPAD_FMT_CLASSIC:
1582             case WPAD_FMT_CLASSIC_ACC:
1583             case WPAD_FMT_CLASSIC_ACC_DPD:
1584             case WPAD_FMT_GUITAR:
1585             case WPAD_FMT_DRUM:
1586             case WPAD_FMT_TAIKO:
1587                 ptr  = (u8 *)(&cl_ringbuffer[j][0]);
1588                 size = sizeof(WPADCLStatus);
1589                 break;
1590 
1591             case WPAD_FMT_MPLS:
1592                 ptr  = (u8 *)(&mp_ringbuffer[j][0]);
1593                 size = sizeof(WPADMPStatus);
1594                 break;
1595 
1596             // not reached here.
1597             default:
1598                 ptr  = NULL;
1599                 size = 0;
1600                 break;
1601         }
1602 
1603         for (i=0; i<SMPBUF_SIZE-1; i++)
1604         {
1605             renderDots(ptr + size * index);
1606             index  = ((index - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
1607         }
1608     }
1609 }
1610 
1611 /*---------------------------------------------------------------------------*
1612     Name:           printIntro
1613 
1614     Description:    None.
1615 
1616     Arguments:      None.
1617 
1618     Returns:        None.
1619  *---------------------------------------------------------------------------*/
printIntro(void)1620 static void printIntro( void )
1621 {
1622     OSReport("========================================\n");
1623     OSReport(" WPADSAMPLE demo                        \n");
1624     OSReport("========================================\n");
1625     OSReport(" Please connect GC controller to Port1. \n");
1626     OSReport("                                        \n");
1627     OSReport(" -- Menu --                             \n");
1628     OSReport(" cursor key: move cursor                \n");
1629     OSReport("          A: issue command              \n");
1630     OSReport("          B: accept/reject connection   \n");
1631     OSReport("          Z: start/stop simple sync     \n");
1632     OSReport("========================================\n");
1633 }
1634