1 /*---------------------------------------------------------------------------*
2 Project: WPAD Demo Program
3 File: mplus.c
4
5 Copyright (C) 2008 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 *---------------------------------------------------------------------------*/
14 #include <string.h>
15 #include <revolution.h>
16 #include <revolution/wpad.h>
17 #include <revolution/sc.h>
18
19 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
20 #include <demo.h>
21
22 /*---------------------------------------------------------------------------*
23 * Local Definitions
24 *---------------------------------------------------------------------------*/
25 // screen size
26 #define SCREEN_WIDTH 640
27 #define SCREEN_HEIGHT 480
28 // font size
29 #define FONT_HEIGHT 12
30 #define FONT_SPACE 1
31 // draw screen
32 #define COL_WIDTH 140
33 #define X0_START 0
34 #define X1_START 70
35 #define Y0_START 38
36 #define Y1_START 400
37 // sampling buffer
38 #define SMPBUF_SIZE 100
39 // print buffer
40 #define BUFFER_SIZE_BYTES 128
41 #define BUFFER_SIZE_LINES 6
42
43 #define CMD_MPLS_OFF WPAD_MPLS_OFF
44 #define CMD_MPLS_STD WPAD_MPLS_STD
45 #define CMD_MPLS_FS WPAD_MPLS_FS
46 #define CMD_MPLS_CL WPAD_MPLS_CL
47 #define CMD_MPLS_HW_RST WPAD_MPLS_ZRST
48 #define CMD_MPLS_SW_RST (WPAD_MPLS_ZRST+1) // temporary defined
49
50 /*---------------------------------------------------------------------------*
51 * Local Data
52 *---------------------------------------------------------------------------*/
53 // sampling buffers
54 static WPADMPStatus mp_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE];
55 static WPADCLStatus cl_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE];
56 static WPADFSStatus fs_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE];
57 static WPADStatus co_ringbuffer[WPAD_MAX_CONTROLLERS][SMPBUF_SIZE];
58 // reset flag
59 static u8 reset = 1;
60 // print buffer
61 static char __buffer[BUFFER_SIZE_LINES][BUFFER_SIZE_BYTES];
62 static u32 __curr_line = 0;
63 // device strings
64 static u8 str_dev_core [] = " CORE ";
65 static u8 str_dev_extn [] = " FREE ";
66 static u8 str_dev_cl [] = " CLAC ";
67 static u8 str_dev_mp [] = " MPLS ";
68 static u8 str_dev_mpfs [] = " MP+FS";
69 static u8 str_dev_mpcl [] = " MP+CL";
70 static u8 str_dev_mpft [] = " MP+FT";
71 static u8 str_dev_future [] = " FTRE ";
72 static u8 str_dev_notsup [] = " NOSP ";
73 static u8 str_dev_unknown[] = " UNKW ";
74 // status strings
75 static u8 str_status_ok [] = " NONE ";
76 static u8 str_status_none[] = " NCNT ";
77 static u8 str_status_busy[] = " BUSY ";
78 static u8 str_status_xfer[] = " TRNS ";
79 static u8 str_status_inv [] = " INVD ";
80 static u8 str_status_crpt[] = " CRPT ";
81 static u8 str_status_unk [] = " UNKW ";
82 // dpd format strings
83 static u8 dpd_fmt_off [] = "OFF ";
84 static u8 dpd_fmt_std [] = "STD ";
85 static u8 dpd_fmt_exp [] = "EXP ";
86 static u8 dpd_fmt_full[] = "FULL";
87 // data format strings
88 static u8 fmt_core1[] = "CO ";
89 static u8 fmt_core2[] = "CO+A ";
90 static u8 fmt_core3[] = "CO+AD ";
91 static u8 fmt_nun1 [] = "FS ";
92 static u8 fmt_nun2 [] = "FS+A ";
93 static u8 fmt_nun3 [] = "FS+AD ";
94 static u8 fmt_clas1[] = "CL ";
95 static u8 fmt_clas2[] = "CL+A ";
96 static u8 fmt_clas3[] = "CL+AD ";
97 static u8 fmt_full [] = "CO+ADF";
98 static u8 fmt_mpls [] = "MPLS ";
99
100 static const GXColor BLACK= { 20, 20, 20, 255 };
101
102 static u8 mpls[WPAD_MAX_CONTROLLERS] = {0,0,0,0};
103 static u8 hcnt[WPAD_MAX_CONTROLLERS] = {0,0,0,0};
104
105 /*---------------------------------------------------------------------------*
106 * Function prototypes
107 *---------------------------------------------------------------------------*/
108
109 static void *myAlloc ( u32 size );
110 static u8 myFree ( void *ptr );
111 static void myPrint ( int x, int y, int z, char *fmt, ... );
112
113 // callbacks
114 void connectCallback ( s32 chan, s32 reason );
115 void extensionCallback ( s32 chan, s32 result );
116 void samplingCallback ( s32 chan );
117 void mplsCallback ( s32 chan, s32 result );
118
119 // Internal functions
120 static void initialize ( void );
121 static void renderStatus ( void );
122 static void renderAimings ( void );
123 static void recalibrate ( s32 chan, u32 type );
124 static void printBuffer ( char *string, ... );
125 static u8 *getDevName ( u32 type );
126 static u8 *getErrName ( s32 status );
127 static u8 *getFmtString ( u8 fmt );
128 static u8 *getDpdFmt ( u8 type );
129
130 /*---------------------------------------------------------------------------*
131 Name: Main
132
133 Description: None.
134
135 Arguments: None.
136
137 Returns: None.
138 *---------------------------------------------------------------------------*/
main(void)139 void main( void )
140 {
141 s32 i;
142 u16 prev[4];
143 u16 curr[4];
144
145 initialize();
146
147 while(reset)
148 {
149 for(i=WPAD_CHAN0; i<WPAD_MAX_CONTROLLERS; i++)
150 {
151 WPADStatusEx wpad;
152 u16 trig=0;
153 u16 hold=0;
154 u32 type;
155 u8 cmd = 0xff;
156
157 if (WPADProbe(i, &type) == WPAD_ERR_NONE)
158 {
159 WPADRead(i, &wpad);
160 curr[i] = wpad.button;
161 trig = WPADButtonDown(prev[i], curr[i]);
162 hold = curr[i];
163 prev[i] = curr[i];
164 }
165
166 // Determine command input
167 if (trig & WPAD_BUTTON_A ) { cmd = CMD_MPLS_STD; }
168 if (trig & WPAD_BUTTON_B ) { cmd = CMD_MPLS_OFF; }
169 if (trig & WPAD_BUTTON_1 ) { cmd = CMD_MPLS_FS; }
170 if (trig & WPAD_BUTTON_2 ) { cmd = CMD_MPLS_CL; }
171 if (trig & WPAD_BUTTON_HOME) { cmd = CMD_MPLS_HW_RST; }
172
173 // If a button is held down for some time, consider it to be a command
174 if (hold == (WPAD_BUTTON_PLUS | WPAD_BUTTON_MINUS))
175 {
176 if (++hcnt[i] > 100)
177 {
178 cmd = CMD_MPLS_SW_RST;
179 hcnt[i] = 0;
180 }
181 }
182
183 // Check the command
184 if (cmd == 0xff)
185 {
186 continue;
187 }
188
189 // Display a message for each command
190 switch(cmd)
191 {
192 case CMD_MPLS_OFF: printBuffer("Try to turn off motion plus."); break;
193 case CMD_MPLS_STD: printBuffer("Try to turn on motion plus."); break;
194 case CMD_MPLS_FS : printBuffer("Try to turn on nunchaku + motion plus."); break;
195 case CMD_MPLS_CL : printBuffer("Try to turn on classic + motion plus."); break;
196 case CMD_MPLS_HW_RST: printBuffer("Try to do the hardware re-calibration."); break;
197 case CMD_MPLS_SW_RST: printBuffer("Try to do the software re-calibration."); break;
198 }
199
200 if (cmd != CMD_MPLS_SW_RST)
201 {
202 // Issue a command
203 WPADControlMpls(i, cmd, mplsCallback);
204 }
205 else
206 {
207 recalibrate(i, type);
208 }
209 }
210
211 DEMOBeforeRender();
212 renderStatus();
213 renderAimings();
214 DEMODoneRender();
215 }
216
217 OSRestart(0);
218
219 } // End main()
220
221 /*---------------------------------------------------------------------------*
222 Name: connectCallback
223
224 Description: Function to be called when a controller is connected or
225 disconnected.
226
227 Arguments: chan: Specified channel to be connected/disconnected.
228 reason: Reason of calling this.
229 if WPAD_ERR_NONE, connected.
230 if WPAD_ERR_NO_CONTROLLER, disconnected.
231
232 Returns: None.
233 *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)234 void connectCallback( s32 chan, s32 reason )
235 {
236 // Wii Remote is connected.
237 if (reason == WPAD_ERR_NONE)
238 {
239 WPADSetExtensionCallback(chan, extensionCallback);
240 WPADSetSamplingCallback(chan, samplingCallback);
241
242 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
243 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
244 WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[chan][0]), SMPBUF_SIZE);
245
246 mpls[chan] = 0;
247 }
248 }
249
250 /*---------------------------------------------------------------------------*
251 Name: extensionCallback
252
253 Description: Function to be called when an extension is attached or
254 detached.
255
256 Arguments: chan: specified channel to be attached/detached.
257 result: new device type.
258
259 / ----------------------------------------------------------------------- /
260 the meaning of result is below.
261 if WPAD_DEV_CORE, an extension is detached.
262 if WPAD_DEV_FUTURE, an extension is undefined.
263 if WPAD_DEV_NOT_SUPPORTED, an extension is not supported.
264 if WPAD_DEV_FREESTYLE, Nunchuk extension is attached.
265 if WPAD_DEV_CLASSIC, Classic Controller extension is attached.
266 if WPAD_DEV_MPLS, MotionPlus extension is turned on in standard mode
267 and extension is detached from the Wii MotionPlus.
268 if WPAD_DEV_MPLS_FREESTYLE, MotionPlus extension is turned on in expansion mode
269 and Nunchuk extension is installed into the Wii MotionPlus.
270 if WPAD_DEV_MPLS_CLASSIC, MotionPlus extension is turned on in expansion mode
271 and Classic Controller extension is installed into the Wii MotionPlus.
272 if WPAD_DEV_MPLS_FUTURE, MotionPlus extension is turned on in expansion mode
273 and other extension is installed into the Wii MotionPlus.
274 if WPAD_DEV_UNKNOWN, an extension is attached but it is not known yet.
275
276 An extension cannot be recognized shortly when it is attached and
277 WPAD_DEV_UNKOWN is returned at first. After a while, the host recognizes
278 the correct device type and the type is returned.
279
280 Note: If WPAD_DEV_FUTURE or WPAD_DEV_NOT_SUPPORTED is returned,
281 Wii Remote at least has to work.
282 / ----------------------------------------------------------------------- /
283
284 Returns: None.
285 *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)286 void extensionCallback( s32 chan, s32 result )
287 {
288 if ( result != WPAD_DEV_MPLS
289 && result != WPAD_DEV_MPLS_FREESTYLE
290 && result != WPAD_DEV_MPLS_CLASSIC
291 && result != WPAD_DEV_MPLS_FUTURE)
292 {
293 mpls[chan] = 0;
294 }
295
296 switch(result)
297 {
298 case WPAD_DEV_UNKNOWN:
299 printBuffer("Initializing extension on chan %1d...", chan);
300 break;
301
302 case WPAD_DEV_CORE:
303 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
304 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
305 WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[chan][0]), SMPBUF_SIZE);
306 printBuffer("Extension removed on chan %1d.", chan);
307 break;
308
309 case WPAD_DEV_FREESTYLE:
310 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
311 WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
312 WPADSetAutoSamplingBuf(chan, (void *)(&fs_ringbuffer[chan][0]), SMPBUF_SIZE);
313 printBuffer("Freestyle initialized on chan %1d.", chan);
314 break;
315
316 case WPAD_DEV_CLASSIC:
317 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
318 WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
319 WPADSetAutoSamplingBuf(chan, (void *)(&cl_ringbuffer[chan][0]), SMPBUF_SIZE);
320 printBuffer("Classic initialized on chan %1d.", chan);
321 break;
322
323 case WPAD_DEV_MPLS:
324 // Started the Wii MotionPlus
325 if (mpls[chan] == 0)
326 {
327 mpls[chan] = 1;
328 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
329 WPADSetDataFormat(chan, WPAD_FMT_MPLS);
330 WPADSetAutoSamplingBuf(chan, (void *)(&mp_ringbuffer[chan][0]), SMPBUF_SIZE);
331 printBuffer("MotionPlus initialized on chan %1d.", chan);
332 }
333 // An external extension controller was disconnected from the Wii MotionPlus
334 else
335 {
336 printBuffer("Detached Extenion from MotionPlus on chan %1d.", chan);
337 }
338 break;
339
340 case WPAD_DEV_MPLS_FREESTYLE:
341 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
342 WPADSetDataFormat(chan, WPAD_FMT_MPLS);
343 WPADSetAutoSamplingBuf(chan, (void *)(&mp_ringbuffer[chan][0]), SMPBUF_SIZE);
344 printBuffer("Attached Freestyle into MotionPlus on chan %1d.", chan);
345 break;
346
347 case WPAD_DEV_MPLS_CLASSIC:
348 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
349 WPADSetDataFormat(chan, WPAD_FMT_MPLS);
350 WPADSetAutoSamplingBuf(chan, (void *)(&mp_ringbuffer[chan][0]), SMPBUF_SIZE);
351 printBuffer("Attached Classic into MotionPlus on chan %1d.", chan);
352 break;
353
354 case WPAD_DEV_MPLS_FUTURE:
355 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
356 WPADSetDataFormat(chan, WPAD_FMT_MPLS);
357 WPADSetAutoSamplingBuf(chan, (void *)(&mp_ringbuffer[chan][0]), SMPBUF_SIZE);
358 printBuffer("Attached Future device into MotionPlus on chan %1d.", chan);
359 break;
360
361 case WPAD_DEV_FUTURE:
362 case WPAD_DEV_NOT_SUPPORTED:
363 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
364 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
365 WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[chan][0]), SMPBUF_SIZE);
366 printBuffer("Unknown device [%d] on chan %1d.", result, chan);
367 break;
368
369 default:
370 break;
371
372 }
373 }
374
375 /*---------------------------------------------------------------------------*
376 Name: samplingCallback
377
378 Description: Function to be called whenever controller data is received.
379
380 Arguments: chan: specified channel.
381
382 Returns: None.
383 *---------------------------------------------------------------------------*/
samplingCallback(s32 chan)384 void samplingCallback( s32 chan )
385 {
386 (void)chan;
387 }
388
389 /*---------------------------------------------------------------------------*
390 Name: mplsCallback
391
392 Description: Function to be called whenever the result for WPADControlMpls
393 is received.
394
395 Arguments: chan: specified channel.
396 result: result.
397
398 Returns: None.
399 *---------------------------------------------------------------------------*/
mplsCallback(s32 chan,s32 result)400 void mplsCallback( s32 chan, s32 result )
401 {
402 printBuffer("Result = %d on chan %1d.", result, chan);
403 }
404
405 /*---------------------------------------------------------------------------*
406 Name: myAlloc
407
408 Description: Allocate memory from MEM2.
409
410 Arguments: size: Memory size
411
412 Returns: Point to the head address of the allocated memory.
413 *---------------------------------------------------------------------------*/
myAlloc(u32 size)414 static void *myAlloc( u32 size )
415 {
416 return MEMAllocFromAllocator(&DemoAllocator2, size);
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 return(1);
432 }
433
myPrint(int x,int y,int z,char * fmt,...)434 static void myPrint( int x, int y, int z, char *fmt, ... )
435 {
436 va_list vlist;
437 char string[256];
438
439 va_start(vlist, fmt);
440 vsprintf(string, fmt, vlist);
441 va_end(vlist);
442
443 if (SCGetLanguage() == SC_LANG_JAPANESE)
444 {
445 DEMORFPrintf((s16)x, (s16)y, (s16)z, "%s", string);
446 }
447 else
448 {
449 DEMOPrintf((s16)x, (s16)y, (s16)z, "%s", string);
450 }
451
452 }
453
454 /*---------------------------------------------------------------------------*
455 Name: printBuffer
456
457 Description: Stored message to be drawn on screen.
458
459 Arguments: string: message like printf().
460
461 Returns: None.
462 *---------------------------------------------------------------------------*/
printBuffer(char * string,...)463 static void printBuffer( char *string, ... )
464 {
465 va_list vlist;
466
467 memset(&__buffer[__curr_line][0], 0, BUFFER_SIZE_BYTES);
468
469 va_start(vlist, string);
470 vsprintf((char *)(&__buffer[__curr_line][0]), string, vlist);
471 va_end(vlist);
472
473 __curr_line = (__curr_line + 1) % BUFFER_SIZE_LINES;
474
475 }
476
477 /*---------------------------------------------------------------------------*
478 Name: getDevName
479
480 Description: Got the device name string.
481
482 Arguments: type: device type.
483
484 Returns: Device name string.
485 *---------------------------------------------------------------------------*/
getDevName(u32 type)486 static u8 *getDevName( u32 type )
487 {
488
489 u8 *ptr;
490
491 switch(type)
492 {
493 case WPAD_DEV_CORE: ptr = &str_dev_core[0]; break;
494 case WPAD_DEV_FREESTYLE: ptr = &str_dev_extn[0]; break;
495 case WPAD_DEV_CLASSIC: ptr = &str_dev_cl[0]; break;
496 case WPAD_DEV_MPLS: ptr = &str_dev_mp[0]; break;
497 case WPAD_DEV_MPLS_FREESTYLE: ptr = &str_dev_mpfs[0]; break;
498 case WPAD_DEV_MPLS_CLASSIC: ptr = &str_dev_mpcl[0]; break;
499 case WPAD_DEV_MPLS_FUTURE: ptr = &str_dev_mpft[0]; break;
500 case WPAD_DEV_FUTURE: ptr = &str_dev_future[0]; break;
501 case WPAD_DEV_NOT_SUPPORTED: ptr = &str_dev_notsup[0]; break;
502 case WPAD_DEV_UNKNOWN:
503 default: ptr = &str_dev_unknown[0]; break;
504 }
505
506 return(ptr);
507
508 }
509
510 /*---------------------------------------------------------------------------*
511 Name: getErrName
512
513 Description: Got the error name string.
514
515 Arguments: status: error type.
516
517 Returns: Error name string.
518 *---------------------------------------------------------------------------*/
getErrName(s32 status)519 static u8 *getErrName( s32 status )
520 {
521
522 u8 *ptr;
523
524 switch(status)
525 {
526 case WPAD_ERR_NONE: ptr = &str_status_ok[0]; break;
527 case WPAD_ERR_NO_CONTROLLER: ptr = &str_status_none[0]; break;
528 case WPAD_ERR_BUSY: ptr = &str_status_busy[0]; break;
529 case WPAD_ERR_TRANSFER: ptr = &str_status_xfer[0]; break;
530 case WPAD_ERR_INVALID: ptr = &str_status_inv[0]; break;
531 case WPAD_ERR_CORRUPTED: ptr = &str_status_crpt[0]; break;
532 default: ptr = &str_status_unk[0]; break;
533 }
534
535 return(ptr);
536
537 }
538
539 /*---------------------------------------------------------------------------*
540 Name: getDpdFmt
541
542 Description: Got the DPD format name string.
543
544 Arguments: fmt: dpd format type.
545
546 Returns: DPD format name string.
547 *---------------------------------------------------------------------------*/
getDpdFmt(u8 fmt)548 static u8 *getDpdFmt(u8 fmt)
549 {
550 u8 *ptr;
551
552 switch(fmt)
553 {
554 case WPAD_DPD_OFF: ptr = &dpd_fmt_off[0]; break;
555 case WPAD_DPD_STD: ptr = &dpd_fmt_std[0]; break;
556 case WPAD_DPD_EXP: ptr = &dpd_fmt_exp[0]; break;
557 case WPAD_DPD_FULL: ptr = &dpd_fmt_full[0]; break;
558 }
559
560 return (ptr);
561 }
562
563 /*---------------------------------------------------------------------------*
564 Name: getFmtString
565
566 Description: Got the data format name string.
567
568 Arguments: type: device type.
569
570 Returns: Data format name string.
571 *---------------------------------------------------------------------------*/
getFmtString(u8 fmt)572 static u8 *getFmtString( u8 fmt )
573 {
574 u8 *ptr;
575
576 switch(fmt)
577 {
578 case WPAD_FMT_CORE: ptr = &fmt_core1[0]; break;
579 case WPAD_FMT_CORE_ACC: ptr = &fmt_core2[0]; break;
580 case WPAD_FMT_CORE_ACC_DPD: ptr = &fmt_core3[0]; break;
581 case WPAD_FMT_FREESTYLE: ptr = &fmt_nun1[0]; break;
582 case WPAD_FMT_FREESTYLE_ACC: ptr = &fmt_nun2[0]; break;
583 case WPAD_FMT_FREESTYLE_ACC_DPD: ptr = &fmt_nun3[0]; break;
584 case WPAD_FMT_CLASSIC: ptr = &fmt_clas1[0]; break;
585 case WPAD_FMT_CLASSIC_ACC: ptr = &fmt_clas2[0]; break;
586 case WPAD_FMT_CLASSIC_ACC_DPD: ptr = &fmt_clas3[0]; break;
587 case WPAD_FMT_CORE_ACC_DPD_FULL: ptr = &fmt_full[0]; break;
588 case WPAD_FMT_MPLS: ptr = &fmt_mpls[0]; break;
589 default: ptr = &fmt_core1[0]; break;
590 }
591
592 return (ptr);
593 }
594
595 /*---------------------------------------------------------------------------*
596 Name: renderStatus
597
598 Description: Draw controller status.
599
600 Arguments: None.
601
602 Returns: None.
603 *---------------------------------------------------------------------------*/
renderStatus(void)604 static void renderStatus( void )
605 {
606 s16 x = X0_START;
607 s16 y = Y0_START;
608
609 int i;
610
611 myPrint(30, 20, 0, "WPAD Demo -- Mplus");
612 myPrint(x, y, 0, "------------------------------"); y+=FONT_HEIGHT;
613 myPrint(x, y, 0, "Status :"); y+=FONT_HEIGHT;
614 myPrint(x, y, 0, "Type :"); y+=FONT_HEIGHT;
615 myPrint(x, y, 0, "Err :"); y+=FONT_HEIGHT;
616 myPrint(x, y, 0, "Buttons:"); y+=FONT_HEIGHT;
617 myPrint(x, y, 0, "DPD0-xy:"); y+=FONT_HEIGHT;
618 myPrint(x, y, 0, "DPD1-xy:"); y+=FONT_HEIGHT;
619 myPrint(x, y, 0, "ACC-XYZ:"); y+=FONT_HEIGHT;
620 myPrint(x, y, 0, "---------"); y+=FONT_HEIGHT;
621 myPrint(x, y, 0, "YAW :"); y+=FONT_HEIGHT;
622 myPrint(x, y, 0, "ROLL :"); y+=FONT_HEIGHT;
623 myPrint(x, y, 0, "PITCH :"); y+=FONT_HEIGHT;
624 myPrint(x, y, 0, "STATUS :"); y+=FONT_HEIGHT;
625 myPrint(x, y, 0, "---------"); y+=FONT_HEIGHT;
626 myPrint(x, y, 0, "EXT :"); y+=FONT_HEIGHT;
627 myPrint(x, y, 0, " :"); y+=FONT_HEIGHT;
628 myPrint(x, y, 0, " :"); y+=FONT_HEIGHT;
629 myPrint(x, y, 0, " :"); y+=FONT_HEIGHT;
630 myPrint(x, y, 0, "---------"); y+=FONT_HEIGHT;
631 myPrint(x, y, 0, "YAWCL H:"); y+=FONT_HEIGHT;
632 myPrint(x, y, 0, "ROLCL H:"); y+=FONT_HEIGHT;
633 myPrint(x, y, 0, "PITCL H:"); y+=FONT_HEIGHT;
634 myPrint(x, y, 0, "YAWCL L:"); y+=FONT_HEIGHT;
635 myPrint(x, y, 0, "ROLCL L:"); y+=FONT_HEIGHT;
636 myPrint(x, y, 0, "PITCL L:"); y+=FONT_HEIGHT;
637 myPrint(x, y, 0, "DPS :"); y+=FONT_HEIGHT;
638 myPrint(x, y, 0, "---------"); y+=FONT_HEIGHT;
639
640 for(i=WPAD_CHAN0; i<WPAD_MAX_CONTROLLERS; i++)
641 {
642 char buf1[] = "____";
643 char buf2[] = "____";
644 char buf3[] = "___";
645 char buf4[] = "__";
646 char buf5[] = "____";
647 char buf6[] = "____";
648 char buf7[] = "____";
649 char buf8[] = "___";
650 s32 status;
651 u32 type;
652 WPADMPStatus tmp;
653
654 x = (s16)(X1_START + COL_WIDTH * (i));
655 y = (s16)(Y0_START + FONT_HEIGHT);
656
657 status = WPADProbe(i, &type);
658 myPrint(x, y, 0, " %s", getErrName(status)); y+= FONT_HEIGHT;
659 myPrint(x, y, 0, " %s", getDevName(type)); y+= FONT_HEIGHT;
660
661 if (WPAD_ERR_NO_CONTROLLER != status)
662 {
663 WPADRead(i, &tmp);
664 myPrint(x, y, 0, " %s", getErrName(tmp.err)); y+=FONT_HEIGHT;
665
666 {
667 WPADStatus *ptr = (WPADStatus*)(&tmp);
668
669 if( ptr->button & WPAD_BUTTON_LEFT ) buf1[ 0] = '<';
670 if( ptr->button & WPAD_BUTTON_UP ) buf1[ 1] = '^';
671 if( ptr->button & WPAD_BUTTON_DOWN ) buf1[ 2] = 'v';
672 if( ptr->button & WPAD_BUTTON_RIGHT ) buf1[ 3] = '>';
673 if( ptr->button & WPAD_BUTTON_A ) buf2[ 0] = 'A';
674 if( ptr->button & WPAD_BUTTON_B ) buf2[ 1] = 'B';
675 if( ptr->button & WPAD_BUTTON_1 ) buf2[ 2] = '1';
676 if( ptr->button & WPAD_BUTTON_2 ) buf2[ 3] = '2';
677 if( ptr->button & WPAD_BUTTON_MINUS ) buf3[ 0] = '-';
678 if( ptr->button & WPAD_BUTTON_HOME ) buf3[ 1] = 'H';
679 if( ptr->button & WPAD_BUTTON_PLUS ) buf3[ 2] = '+';
680 myPrint(x, y, 0, " %s%s%s", buf1,buf2,buf3); y+= FONT_HEIGHT;
681 myPrint(x, y, 0, " %4d", (s16)(ptr->obj[0].x));
682 myPrint(x+35, y, 0, " %4d", (s16)(ptr->obj[0].y)); y+= FONT_HEIGHT;
683 myPrint(x, y, 0, " %4d", (s16)(ptr->obj[1].x));
684 myPrint(x+35, y, 0, " %4d", (s16)(ptr->obj[1].y)); y+= FONT_HEIGHT;
685 myPrint(x, y, 0, " %+3d", (s16)(ptr->accX));
686 myPrint(x+35, y, 0, " %+3d", (s16)(ptr->accY));
687 myPrint(x+70, y, 0, " %+3d", (s16)(ptr->accZ)); y+= FONT_HEIGHT; y+=FONT_HEIGHT;
688 }
689
690 if (type == WPAD_DEV_MPLS
691 || type == WPAD_DEV_MPLS_FREESTYLE
692 || type == WPAD_DEV_MPLS_CLASSIC
693 || type == WPAD_DEV_MPLS_FUTURE)
694 {
695 WPADMPStatus *ptr = (WPADMPStatus*)(&tmp);
696 WPADMpls high;
697 WPADMpls low;
698 f32 dps;
699
700 WPADGetMplsCalibration(i, &high, &low);
701
702 // Yaw
703 if (ptr->stat & WPAD_MPLS_STAT_YAWSEL) { dps = (ptr->yaw - low.yaw_zero) / low.yaw_scale * low.degrees ; }
704 else { dps = (ptr->yaw - high.yaw_zero) / high.yaw_scale * high.degrees; }
705 // which src? raw data, dps
706 myPrint(x, y, 0, "[%s] %5d%+8.2f", (ptr->stat & WPAD_MPLS_STAT_YAWSEL) ? "L" : "H", (s16)(ptr->yaw), dps);
707 y+= FONT_HEIGHT;
708
709 // Roll
710 if (ptr->stat & WPAD_MPLS_STAT_ROLSEL) { dps = (ptr->roll - low.roll_zero) / low.roll_scale * low.degrees ; }
711 else { dps = (ptr->roll - high.roll_zero) / high.roll_scale * high.degrees; }
712 // which src? raw data, dps
713 myPrint(x, y, 0, "[%s] %5d%+8.2f", (ptr->stat & WPAD_MPLS_STAT_ROLSEL) ? "L" : "H", (s16)(ptr->roll), dps);
714 y+= FONT_HEIGHT;
715
716 // Pitch
717 if (ptr->stat & WPAD_MPLS_STAT_PITSEL) { dps = (ptr->pitch - low.pitch_zero) / low.pitch_scale * low.degrees ; }
718 else { dps = (ptr->pitch - high.pitch_zero) / high.pitch_scale * high.degrees; }
719 // which src? raw data, dps
720 myPrint(x, y, 0, "[%s] %5d%+8.2f", (ptr->stat & WPAD_MPLS_STAT_PITSEL) ? "L" : "H", (s16)(ptr->pitch), dps);
721 y+= FONT_HEIGHT;
722
723 // MPLS Status
724 myPrint(x, y, 0, " %s %s %s",
725 (ptr->stat & WPAD_MPLS_STAT_ATTACH) ? "A" : "-", // Extra extension is attached or detached?
726 (ptr->stat & WPAD_MPLS_STAT_PLSVLD) ? "M" : "-", // MotionPlus data is valid or corrupted?
727 (ptr->stat & WPAD_MPLS_STAT_EXTVLD) ? "E" : "-"); // Extra extension data is valid or corrupted?
728 y+= FONT_HEIGHT;
729 y+= FONT_HEIGHT;
730
731 if (ptr->stat & WPAD_MPLS_STAT_ATTACH
732 && ptr->stat & WPAD_MPLS_STAT_EXTVLD)
733 {
734 if (type == WPAD_DEV_MPLS_FREESTYLE)
735 {
736 if ( ptr->button & WPAD_BUTTON_C ) buf4[ 0] = 'C';
737 if ( ptr->button & WPAD_BUTTON_Z ) buf4[ 1] = 'Z';
738
739 myPrint(x, y, 0, " %s", buf4); y+= FONT_HEIGHT;
740 myPrint(x, y, 0, " %d", (s16)(ptr->ext.fs.fsStickX));
741 myPrint(x+35, y, 0, " %d", (s16)(ptr->ext.fs.fsStickY)); y+= FONT_HEIGHT;
742 myPrint(x, y, 0, " %d", (s16)(ptr->ext.fs.fsAccX));
743 myPrint(x+35, y, 0, " %d", (s16)(ptr->ext.fs.fsAccY));
744 myPrint(x+70, y, 0, " %d", (s16)(ptr->ext.fs.fsAccZ)); y+= FONT_HEIGHT;
745 y += FONT_HEIGHT;
746 }
747 if (type == WPAD_DEV_MPLS_CLASSIC)
748 {
749 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_LEFT ) buf5[ 0] = '<';
750 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_UP ) buf5[ 1] = '^';
751 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_DOWN ) buf5[ 2] = 'v';
752 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_RIGHT ) buf5[ 3] = '>';
753 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_A ) buf6[ 0] = 'A';
754 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_B ) buf6[ 1] = 'B';
755 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_X ) buf6[ 2] = 'X';
756 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_Y ) buf6[ 3] = 'Y';
757 if ( ptr->ext.cl.clButton & WPAD_CL_TRIGGER_L ) buf7[ 0] = 'L';
758 if ( ptr->ext.cl.clButton & WPAD_CL_TRIGGER_R ) buf7[ 1] = 'R';
759 if ( ptr->ext.cl.clButton & WPAD_CL_TRIGGER_ZL ) buf7[ 2] = 'z';
760 if ( ptr->ext.cl.clButton & WPAD_CL_TRIGGER_ZR ) buf7[ 3] = 'Z';
761 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_MINUS ) buf8[ 0] = '-';
762 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_HOME ) buf8[ 1] = 'H';
763 if ( ptr->ext.cl.clButton & WPAD_CL_BUTTON_PLUS ) buf8[ 2] = '+';
764 myPrint(x, y, 0, " %s%s%s%s", buf5,buf6,buf7,buf8); y+= FONT_HEIGHT;
765 myPrint(x, y, 0, " %d", (s16)(ptr->ext.cl.clLStickX));
766 myPrint(x+35, y, 0, " %d", (s16)(ptr->ext.cl.clLStickY)); y+= FONT_HEIGHT;
767 myPrint(x, y, 0, " %d", (s16)(ptr->ext.cl.clRStickX));
768 myPrint(x+35, y, 0, " %d", (s16)(ptr->ext.cl.clRStickY)); y+= FONT_HEIGHT;
769 myPrint(x, y, 0, " %d", (s16)(ptr->ext.cl.clTriggerL));
770 myPrint(x+35, y, 0, " %d", (s16)(ptr->ext.cl.clTriggerR)); y+= FONT_HEIGHT;
771 }
772 }
773
774 y = (s16)(Y0_START + FONT_HEIGHT * 19);
775 myPrint(x, y, 0, " %.1f %.1f", high.yaw_zero, high.yaw_scale); y+=FONT_HEIGHT;
776 myPrint(x, y, 0, " %.1f %.1f", high.roll_zero, high.roll_scale); y+=FONT_HEIGHT;
777 myPrint(x, y, 0, " %.1f %.1f", high.pitch_zero, high.pitch_scale); y+=FONT_HEIGHT;
778 myPrint(x, y, 0, " %.1f %.1f", low.yaw_zero, low.yaw_scale); y+=FONT_HEIGHT;
779 myPrint(x, y, 0, " %.1f %.1f", low.roll_zero, low.roll_scale); y+=FONT_HEIGHT;
780 myPrint(x, y, 0, " %.1f %.1f", low.pitch_zero, low.pitch_scale); y+=FONT_HEIGHT;
781 myPrint(x, y, 0, " %d %d", high.degrees, low.degrees); y+=FONT_HEIGHT;
782 }
783 else
784 {
785 y+= FONT_HEIGHT * 5;
786 }
787
788 if (WPAD_DEV_FREESTYLE == type)
789 {
790 WPADFSStatus *ptr = (WPADFSStatus*)(&tmp);
791
792 if ( ptr->button & WPAD_BUTTON_C ) buf4[ 0] = 'C';
793 if ( ptr->button & WPAD_BUTTON_Z ) buf4[ 1] = 'Z';
794
795 myPrint(x, y, 0, " %s", buf4); y+= FONT_HEIGHT;
796 myPrint(x, y, 0, " %d", (s16)(ptr->fsStickX));
797 myPrint(x+35, y, 0, " %d", (s16)(ptr->fsStickY)); y+= FONT_HEIGHT;
798 myPrint(x, y, 0, " %d", (s16)(ptr->fsAccX));
799 myPrint(x+35, y, 0, " %d", (s16)(ptr->fsAccY));
800 myPrint(x+70, y, 0, " %d", (s16)(ptr->fsAccZ)); y+= FONT_HEIGHT;
801 y += FONT_HEIGHT;
802 }
803 if (WPAD_DEV_CLASSIC == type)
804 {
805 WPADCLStatus *ptr = (WPADCLStatus*)(&tmp);
806
807 if ( ptr->clButton & WPAD_CL_BUTTON_LEFT ) buf5[ 0] = '<';
808 if ( ptr->clButton & WPAD_CL_BUTTON_UP ) buf5[ 1] = '^';
809 if ( ptr->clButton & WPAD_CL_BUTTON_DOWN ) buf5[ 2] = 'v';
810 if ( ptr->clButton & WPAD_CL_BUTTON_RIGHT ) buf5[ 3] = '>';
811 if ( ptr->clButton & WPAD_CL_BUTTON_A ) buf6[ 0] = 'A';
812 if ( ptr->clButton & WPAD_CL_BUTTON_B ) buf6[ 1] = 'B';
813 if ( ptr->clButton & WPAD_CL_BUTTON_X ) buf6[ 2] = 'X';
814 if ( ptr->clButton & WPAD_CL_BUTTON_Y ) buf6[ 3] = 'Y';
815 if ( ptr->clButton & WPAD_CL_TRIGGER_L ) buf7[ 0] = 'L';
816 if ( ptr->clButton & WPAD_CL_TRIGGER_R ) buf7[ 1] = 'R';
817 if ( ptr->clButton & WPAD_CL_TRIGGER_ZL ) buf7[ 2] = 'z';
818 if ( ptr->clButton & WPAD_CL_TRIGGER_ZR ) buf7[ 3] = 'Z';
819 if ( ptr->clButton & WPAD_CL_BUTTON_MINUS ) buf8[ 0] = '-';
820 if ( ptr->clButton & WPAD_CL_BUTTON_HOME ) buf8[ 1] = 'H';
821 if ( ptr->clButton & WPAD_CL_BUTTON_PLUS ) buf8[ 2] = '+';
822 myPrint(x, y, 0, " %s%s%s%s", buf5,buf6,buf7,buf8); y+= FONT_HEIGHT;
823 myPrint(x, y, 0, " %d", (s16)(ptr->clLStickX));
824 myPrint(x+35, y, 0, " %d", (s16)(ptr->clLStickY)); y+= FONT_HEIGHT;
825 myPrint(x, y, 0, " %d", (s16)(ptr->clRStickX));
826 myPrint(x+35, y, 0, " %d", (s16)(ptr->clRStickY)); y+= FONT_HEIGHT;
827 myPrint(x, y, 0, " %d", (s16)(ptr->clTriggerL));
828 myPrint(x+35, y, 0, " %d", (s16)(ptr->clTriggerR)); y+= FONT_HEIGHT;
829 }
830
831 }
832 }
833
834 // print stored messages on screen
835 x = X0_START;
836 y = Y1_START;
837 {
838 u32 line = __curr_line;
839 int i;
840
841 for (i=0; i<BUFFER_SIZE_LINES; i++)
842 {
843 myPrint(x, y, 0, ">> %s", &__buffer[line][0]);
844 line = (line + 1) % BUFFER_SIZE_LINES;
845 y+= FONT_HEIGHT;
846 }
847 }
848 }
849
850 /*---------------------------------------------------------------------------*
851 Name: renderAimings
852
853 Description: Draw dots using sampled controller data.
854
855 Arguments: None.
856
857 Returns: None.
858 *---------------------------------------------------------------------------*/
renderAimings(void)859 static void renderAimings( void )
860 {
861 WPADStatus *ptr;
862 int i,j;
863 u32 latest = WPADGetLatestIndexInBuf(WPAD_CHAN0);
864 u32 index = ((latest - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
865 u32 type;
866
867 for(j=0; j<WPAD_MAX_CONTROLLERS; j++)
868 {
869 if (WPADProbe(j, &type) == WPAD_ERR_NO_CONTROLLER)
870 {
871 continue;
872 }
873
874 for (i=0; i<SMPBUF_SIZE-1; i++)
875 {
876 switch(type)
877 {
878 case WPAD_DEV_MPLS:
879 case WPAD_DEV_MPLS_FREESTYLE:
880 case WPAD_DEV_MPLS_CLASSIC:
881 case WPAD_DEV_MPLS_FUTURE: ptr = (WPADStatus*)(&mp_ringbuffer[j][index]); break;
882 case WPAD_DEV_FREESTYLE: ptr = (WPADStatus*)(&fs_ringbuffer[j][index]); break;
883 case WPAD_DEV_CLASSIC: ptr = (WPADStatus*)(&cl_ringbuffer[j][index]); break;
884 default: ptr = (WPADStatus*)(&co_ringbuffer[j][index]); break;
885 }
886
887 if (WPAD_ERR_NONE == ptr->err
888 || WPAD_ERR_CORRUPTED == ptr->err)
889 {
890 s16 x=(s16)(SCREEN_WIDTH -(ptr->obj[0].x+ptr->obj[1].x)/2*SCREEN_WIDTH /WPAD_DPD_IMG_RESO_WX);
891 s16 y=(s16)(SCREEN_HEIGHT-(ptr->obj[0].y+ptr->obj[1].y)/2*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY);
892 myPrint(x, y, 0, ".");
893 }
894 index = ((index - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
895 }
896 }
897 }
898
899 /*---------------------------------------------------------------------------*
900 Name: resetCallback
901
902 Description: Function to be called when RESET button is pressed.
903
904 Arguments: None.
905
906 Returns: None.
907 *---------------------------------------------------------------------------*/
resetCallback(void)908 static void resetCallback( void )
909 {
910 reset = 0;
911 }
912
913 /*---------------------------------------------------------------------------*
914 Name: initialize
915
916 Description: Initialized this application.
917
918 Arguments: None.
919
920 Returns: None.
921 *---------------------------------------------------------------------------*/
initialize(void)922 static void initialize( void )
923 {
924 int i;
925 s32 wpad_state;
926
927 DEMOInit( &GXNtsc480IntDf );
928 DEMOPadInit();
929 DEMOInitROMFont();
930 DEMOSetROMFontSize(FONT_HEIGHT, FONT_SPACE);
931
932 GXSetCopyClear( BLACK, GX_MAX_Z24 );
933 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
934 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
935 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode
936 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode
937
938 memset(__buffer, 0, BUFFER_SIZE_BYTES*BUFFER_SIZE_LINES);
939
940 WPADRegisterAllocator(myAlloc, myFree);
941 WPADInit();
942 for (i=0; i<WPAD_MAX_CONTROLLERS; i++)
943 {
944 WPADSetConnectCallback(i, connectCallback);
945 }
946
947 do {
948 wpad_state = WPADGetStatus();
949 } while (WPAD_STATE_SETUP != wpad_state);
950
951 OSSetResetCallback( resetCallback );
952 }
953
954 /*---------------------------------------------------------------------------*
955 Name: recalibrate
956
957 Description: Recalibrated the zero points by the current data.
958
959 Arguments: chan: Specified channel.
960 type: Device type.
961
962 Returns: None.
963 *---------------------------------------------------------------------------*/
recalibrate(s32 chan,u32 type)964 static void recalibrate( s32 chan, u32 type )
965 {
966 WPADMPStatus status;
967 s32 result = -1;
968
969 if (type == WPAD_DEV_MPLS ||
970 type == WPAD_DEV_MPLS_FREESTYLE ||
971 type == WPAD_DEV_MPLS_CLASSIC ||
972 type == WPAD_DEV_MPLS_FUTURE)
973 {
974 WPADRead(chan, &status);
975 if (status.err == WPAD_ERR_NONE)
976 {
977 WPADSetMplsCalibration(chan, &status);
978 result = 1;
979 }
980 }
981 printBuffer("Result = %d on chan %1d.", result, chan);
982 }
983