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