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