1 /*-------------------------------------------------------------
3 wpad.c -- Wiimote Application Programmers Interface
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
10 This software is provided 'as-is', without any express or implied
11 warranty. In no event will the authors be held liable for any
12 damages arising from the use of this software.
14 Permission is granted to anyone to use this software for any
15 purpose, including commercial applications, and to alter it and
16 redistribute it freely, subject to the following restrictions:
18 1. The origin of this software must not be misrepresented; you
19 must not claim that you wrote the original software. If you use
20 this software in a product, an acknowledgment in the product
21 documentation would be appreciated but is not required.
23 2. Altered source versions must be plainly marked as such, and
24 must not be misrepresented as being the original software.
26 3. This notice may not be removed or altered from any source
29 -------------------------------------------------------------*/
38 #include "processor.h"
44 #include "guitar_hero_3.h"
46 #include "wiiuse_internal.h"
47 #include "wiiuse/wpad.h"
48 #include "lwp_threads.h"
51 #define MAX_STREAMDATA_LEN 20
52 #define EVENTQUEUE_LENGTH 16
54 #define DISCONNECT_BATTERY_DIED 0x14
55 #define DISCONNECT_POWER_OFF 0x15
76 struct _wpad_thresh thresh
;
85 WPADData queue_int
[EVENTQUEUE_LENGTH
];
88 static syswd_t __wpad_timer
;
89 static vu32 __wpads_inited
= 0;
90 static vs32 __wpads_ponded
= 0;
91 static u32 __wpad_idletimeout
= 300;
92 static vu32 __wpads_active
= 0;
93 static vu32 __wpads_used
= 0;
94 static wiimote
**__wpads
= NULL
;
95 static wiimote_listen __wpads_listen
[CONF_PAD_MAX_REGISTERED
];
96 static WPADData wpaddata
[WPAD_MAX_WIIMOTES
];
97 static struct _wpad_cb __wpdcb
[WPAD_MAX_WIIMOTES
];
98 static conf_pads __wpad_devs
;
99 static struct linkkey_info __wpad_keys
[WPAD_MAX_WIIMOTES
];
101 static s32
__wpad_onreset(s32 final
);
102 static s32
__wpad_disconnect(struct _wpad_cb
*wpdcb
);
103 static void __wpad_eventCB(struct wiimote_t
*wm
,s32 event
);
105 static void __wpad_def_powcb(s32 chan
);
106 static WPADShutdownCallback __wpad_batcb
= NULL
;
107 static WPADShutdownCallback __wpad_powcb
= __wpad_def_powcb
;
109 extern void __wiiuse_sensorbar_enable(int enable
);
110 extern void __SYS_DoPowerCB(void);
112 static sys_resetinfo __wpad_resetinfo
= {
118 static s32
__wpad_onreset(s32 final
)
120 //printf("__wpad_onreset(%d)\n",final);
127 static void __wpad_def_powcb(s32 chan
)
132 static void __wpad_timeouthandler(syswd_t alarm
,void *cbarg
)
135 struct wiimote_t
*wm
= NULL
;
136 struct _wpad_cb
*wpdcb
= NULL
;
138 if(!__wpads_active
) return;
140 __lwp_thread_dispatchdisable();
141 for(i
=0;i
<WPAD_MAX_WIIMOTES
;i
++) {
144 if(wm
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
146 if(wpdcb
->idle_time
>=__wpad_idletimeout
) {
147 wpdcb
->idle_time
= 0;
148 wiiuse_disconnect(wm
);
152 __lwp_thread_dispatchunnest();
155 static void __wpad_sounddata_alarmhandler(syswd_t alarm
,void *cbarg
)
159 struct wiimote_t
*wm
;
160 struct _wpad_cb
*wpdcb
= (struct _wpad_cb
*)cbarg
;
164 if(wpdcb
->sound_off
>=wpdcb
->sound_len
) {
165 wpdcb
->sound_data
= NULL
;
166 wpdcb
->sound_len
= 0;
167 wpdcb
->sound_off
= 0;
168 SYS_CancelAlarm(wpdcb
->sound_alarm
);
173 snd_data
= wpdcb
->sound_data
;
174 snd_off
= wpdcb
->sound_off
;
175 wpdcb
->sound_off
+= MAX_STREAMDATA_LEN
;
176 wiiuse_write_streamdata(wm
,(snd_data
+snd_off
),MAX_STREAMDATA_LEN
,NULL
);
179 static void __wpad_setfmt(s32 chan
)
181 switch(__wpdcb
[chan
].data_fmt
) {
183 wiiuse_set_flags(__wpads
[chan
], 0, WIIUSE_CONTINUOUS
);
184 wiiuse_motion_sensing(__wpads
[chan
],0);
185 if(chan
!= WPAD_BALANCE_BOARD
) wiiuse_set_ir(__wpads
[chan
],0);
187 case WPAD_FMT_BTNS_ACC
:
188 wiiuse_set_flags(__wpads
[chan
], WIIUSE_CONTINUOUS
, 0);
189 wiiuse_motion_sensing(__wpads
[chan
],1);
190 if(chan
!= WPAD_BALANCE_BOARD
) wiiuse_set_ir(__wpads
[chan
],0);
192 case WPAD_FMT_BTNS_ACC_IR
:
193 wiiuse_set_flags(__wpads
[chan
], WIIUSE_CONTINUOUS
, 0);
194 wiiuse_motion_sensing(__wpads
[chan
],1);
195 if(chan
!= WPAD_BALANCE_BOARD
) wiiuse_set_ir(__wpads
[chan
],1);
202 wiimote
*__wpad_assign_slot(struct bd_addr
*pad_addr
)
205 struct bd_addr bdaddr
;
206 //printf("WPAD Assigning slot (active: 0x%02x)\n", __wpads_used);
207 _CPU_ISR_Disable(level
);
209 // check for balance board
210 BD_ADDR(&(bdaddr
),__wpad_devs
.balance_board
.bdaddr
[5],__wpad_devs
.balance_board
.bdaddr
[4],__wpad_devs
.balance_board
.bdaddr
[3],__wpad_devs
.balance_board
.bdaddr
[2],__wpad_devs
.balance_board
.bdaddr
[1],__wpad_devs
.balance_board
.bdaddr
[0]);
211 if(bd_addr_cmp(pad_addr
,&bdaddr
)) {
212 if(!(__wpads_used
&(1<<WPAD_BALANCE_BOARD
))) {
213 __wpads_used
|= (0x01<<WPAD_BALANCE_BOARD
);
214 _CPU_ISR_Restore(level
);
215 return __wpads
[WPAD_BALANCE_BOARD
];
217 _CPU_ISR_Restore(level
);
222 // Try preassigned slots
223 for(i
=0; i
<CONF_PAD_MAX_ACTIVE
/*&& i<WPAD_MAX_WIIMOTES*/; i
++) {
224 BD_ADDR(&(bdaddr
),__wpad_devs
.active
[i
].bdaddr
[5],__wpad_devs
.active
[i
].bdaddr
[4],__wpad_devs
.active
[i
].bdaddr
[3],__wpad_devs
.active
[i
].bdaddr
[2],__wpad_devs
.active
[i
].bdaddr
[1],__wpad_devs
.active
[i
].bdaddr
[0]);
225 if(bd_addr_cmp(pad_addr
,&bdaddr
) && !(__wpads_used
& (1<<i
))) {
226 //printf("WPAD Got Preassigned Slot %d\n", i);
227 __wpads_used
|= (0x01<<i
);
228 _CPU_ISR_Restore(level
);
233 // No match, pick the first free slot
234 for(i
=0; i
<WPAD_MAX_WIIMOTES
; i
++) {
235 if(!(__wpads_used
& (1<<i
))) {
236 //printf("WPAD Got Free Slot %d\n", i);
237 __wpads_used
|= (0x01<<i
);
238 _CPU_ISR_Restore(level
);
242 //printf("WPAD All Slots Used\n");
243 _CPU_ISR_Restore(level
);
247 static s32
__wpad_init_finished(s32 result
,void *usrdata
)
250 struct bd_addr bdaddr
;
252 //printf("__wpad_init_finished(%d)\n",result);
255 for(i
=0;/*__wpads[i] && */i
<__wpad_devs
.num_registered
;i
++) {
256 BD_ADDR(&(bdaddr
),__wpad_devs
.registered
[i
].bdaddr
[5],__wpad_devs
.registered
[i
].bdaddr
[4],__wpad_devs
.registered
[i
].bdaddr
[3],__wpad_devs
.registered
[i
].bdaddr
[2],__wpad_devs
.registered
[i
].bdaddr
[1],__wpad_devs
.registered
[i
].bdaddr
[0]);
257 wiiuse_register(&__wpads_listen
[i
],&(bdaddr
),__wpad_assign_slot
);
260 BD_ADDR(&(bdaddr
),__wpad_devs
.balance_board
.bdaddr
[5],__wpad_devs
.balance_board
.bdaddr
[4],__wpad_devs
.balance_board
.bdaddr
[3],__wpad_devs
.balance_board
.bdaddr
[2],__wpad_devs
.balance_board
.bdaddr
[1],__wpad_devs
.balance_board
.bdaddr
[0]);
261 if(i
<CONF_PAD_MAX_REGISTERED
&& !bd_addr_cmp(&bdaddr
,BD_ADDR_ANY
)) {
262 wiiuse_register(&__wpads_listen
[i
],&(bdaddr
),__wpad_assign_slot
);
264 __wpads_inited
= WPAD_STATE_ENABLED
;
269 static s32
__wpad_patch_finished(s32 result
,void *usrdata
)
271 //printf("__wpad_patch_finished(%d)\n",result);
272 BTE_InitSub(__wpad_init_finished
);
276 static s32
__readlinkkey_finished(s32 result
,void *usrdata
)
278 //printf("__readlinkkey_finished(%d)\n",result);
280 __wpads_ponded
= result
;
281 BTE_ApplyPatch(__wpad_patch_finished
);
286 static s32
__initcore_finished(s32 result
,void *usrdata
)
288 //printf("__initcore_finished(%d)\n",result);
291 BTE_ReadStoredLinkKey(__wpad_keys
,WPAD_MAX_WIIMOTES
,__readlinkkey_finished
);
296 static s32
__wpad_disconnect(struct _wpad_cb
*wpdcb
)
298 struct wiimote_t
*wm
;
300 if(wpdcb
==NULL
) return 0;
303 if(wm
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
304 wiiuse_disconnect(wm
);
310 static void __wpad_calc_data(WPADData
*data
,WPADData
*lstate
,struct accel_t
*accel_calib
,u32 smoothed
)
312 if(data
->err
!=WPAD_ERR_NONE
) return;
314 data
->orient
= lstate
->orient
;
316 data
->ir
.state
= lstate
->ir
.state
;
317 data
->ir
.sensorbar
= lstate
->ir
.sensorbar
;
318 data
->ir
.x
= lstate
->ir
.x
;
319 data
->ir
.y
= lstate
->ir
.y
;
320 data
->ir
.sx
= lstate
->ir
.sx
;
321 data
->ir
.sy
= lstate
->ir
.sy
;
322 data
->ir
.ax
= lstate
->ir
.ax
;
323 data
->ir
.ay
= lstate
->ir
.ay
;
324 data
->ir
.distance
= lstate
->ir
.distance
;
325 data
->ir
.z
= lstate
->ir
.z
;
326 data
->ir
.angle
= lstate
->ir
.angle
;
327 data
->ir
.error_cnt
= lstate
->ir
.error_cnt
;
328 data
->ir
.glitch_cnt
= lstate
->ir
.glitch_cnt
;
330 data
->btns_l
= lstate
->btns_h
;
331 if(data
->data_present
& WPAD_DATA_ACCEL
) {
332 calculate_orientation(accel_calib
, &data
->accel
, &data
->orient
, smoothed
);
333 calculate_gforce(accel_calib
, &data
->accel
, &data
->gforce
);
335 if(data
->data_present
& WPAD_DATA_IR
) {
336 interpret_ir_data(&data
->ir
,&data
->orient
);
338 if(data
->data_present
& WPAD_DATA_EXPANSION
) {
339 switch(data
->exp
.type
) {
342 struct nunchuk_t
*nc
= &data
->exp
.nunchuk
;
344 nc
->orient
= lstate
->exp
.nunchuk
.orient
;
345 calc_joystick_state(&nc
->js
,nc
->js
.pos
.x
,nc
->js
.pos
.y
);
346 calculate_orientation(&nc
->accel_calib
,&nc
->accel
,&nc
->orient
,smoothed
);
347 calculate_gforce(&nc
->accel_calib
,&nc
->accel
,&nc
->gforce
);
348 data
->btns_h
|= (data
->exp
.nunchuk
.btns
<<16);
354 struct classic_ctrl_t
*cc
= &data
->exp
.classic
;
356 cc
->r_shoulder
= ((f32
)cc
->rs_raw
/0x1F);
357 cc
->l_shoulder
= ((f32
)cc
->ls_raw
/0x1F);
358 calc_joystick_state(&cc
->ljs
, cc
->ljs
.pos
.x
, cc
->ljs
.pos
.y
);
359 calc_joystick_state(&cc
->rjs
, cc
->rjs
.pos
.x
, cc
->rjs
.pos
.y
);
360 data
->btns_h
|= (data
->exp
.classic
.btns
<<16);
364 case EXP_GUITAR_HERO_3
:
366 struct guitar_hero_3_t
*gh3
= &data
->exp
.gh3
;
369 if (gh3
->tb_raw
> 0x1B)
370 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_ORANGE
;
371 else if (gh3
->tb_raw
> 0x18)
372 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_ORANGE
| GUITAR_HERO_3_TOUCH_BLUE
;
373 else if (gh3
->tb_raw
> 0x15)
374 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_BLUE
;
375 else if (gh3
->tb_raw
> 0x13)
376 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_BLUE
| GUITAR_HERO_3_TOUCH_YELLOW
;
377 else if (gh3
->tb_raw
> 0x10)
378 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_YELLOW
;
379 else if (gh3
->tb_raw
> 0x0D)
380 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_AVAILABLE
;
381 else if (gh3
->tb_raw
> 0x0B)
382 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_YELLOW
| GUITAR_HERO_3_TOUCH_RED
;
383 else if (gh3
->tb_raw
> 0x08)
384 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_RED
;
385 else if (gh3
->tb_raw
> 0x05)
386 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_RED
| GUITAR_HERO_3_TOUCH_GREEN
;
387 else if (gh3
->tb_raw
> 0x02)
388 gh3
->touch_bar
= GUITAR_HERO_3_TOUCH_GREEN
;
390 gh3
->whammy_bar
= (gh3
->wb_raw
- GUITAR_HERO_3_WHAMMY_BAR_MIN
) / (float)(GUITAR_HERO_3_WHAMMY_BAR_MAX
- GUITAR_HERO_3_WHAMMY_BAR_MIN
);
391 calc_joystick_state(&gh3
->js
, gh3
->js
.pos
.x
, gh3
->js
.pos
.y
);
392 data
->btns_h
|= (data
->exp
.gh3
.btns
<<16);
398 struct wii_board_t
*wb
= &data
->exp
.wb
;
399 calc_balanceboard_state(wb
);
407 data
->btns_d
= data
->btns_h
& ~data
->btns_l
;
408 data
->btns_u
= ~data
->btns_h
& data
->btns_l
;
412 static void __save_state(struct wiimote_t
* wm
) {
414 wm
->lstate
.btns
= wm
->btns
;
415 wm
->lstate
.accel
= wm
->accel
;
418 wm
->lstate
.ir
= wm
->ir
;
421 switch (wm
->exp
.type
) {
423 wm
->lstate
.exp
.nunchuk
= wm
->exp
.nunchuk
;
426 wm
->lstate
.exp
.classic
= wm
->exp
.classic
;
428 case EXP_GUITAR_HERO_3
:
429 wm
->lstate
.exp
.gh3
= wm
->exp
.gh3
;
432 wm
->lstate
.exp
.wb
= wm
->exp
.wb
;
434 case EXP_MOTION_PLUS
:
435 wm
->lstate
.exp
.mp
= wm
->exp
.mp
;
440 #define ABS(x) ((s32)(x)>0?(s32)(x):-((s32)(x)))
442 #define STATE_CHECK(thresh, a, b) \
443 if(((thresh) > WPAD_THRESH_IGNORE) && (ABS((a)-(b)) > (thresh))) \
446 #define STATE_CHECK_SIMPLE(thresh, a, b) \
447 if(((thresh) > WPAD_THRESH_IGNORE) && ((a) != (b))) \
450 static u32
__wpad_read_expansion(struct wiimote_t
*wm
,WPADData
*data
, struct _wpad_thresh
*thresh
)
452 int state_changed
= 0;
453 switch(data
->exp
.type
) {
455 data
->exp
.nunchuk
= wm
->exp
.nunchuk
;
456 STATE_CHECK_SIMPLE(thresh
->btns
, wm
->exp
.nunchuk
.btns
, wm
->lstate
.exp
.nunchuk
.btns
);
457 STATE_CHECK(thresh
->acc
, wm
->exp
.nunchuk
.accel
.x
, wm
->lstate
.exp
.nunchuk
.accel
.x
);
458 STATE_CHECK(thresh
->acc
, wm
->exp
.nunchuk
.accel
.y
, wm
->lstate
.exp
.nunchuk
.accel
.y
);
459 STATE_CHECK(thresh
->acc
, wm
->exp
.nunchuk
.accel
.z
, wm
->lstate
.exp
.nunchuk
.accel
.z
);
460 STATE_CHECK(thresh
->js
, wm
->exp
.nunchuk
.js
.pos
.x
, wm
->lstate
.exp
.nunchuk
.js
.pos
.x
);
461 STATE_CHECK(thresh
->js
, wm
->exp
.nunchuk
.js
.pos
.y
, wm
->lstate
.exp
.nunchuk
.js
.pos
.y
);
464 data
->exp
.classic
= wm
->exp
.classic
;
465 STATE_CHECK_SIMPLE(thresh
->btns
, wm
->exp
.classic
.btns
, wm
->lstate
.exp
.classic
.btns
);
466 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.rs_raw
, wm
->lstate
.exp
.classic
.rs_raw
);
467 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.ls_raw
, wm
->lstate
.exp
.classic
.ls_raw
);
468 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.ljs
.pos
.x
, wm
->lstate
.exp
.classic
.ljs
.pos
.x
);
469 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.ljs
.pos
.y
, wm
->lstate
.exp
.classic
.ljs
.pos
.y
);
470 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.rjs
.pos
.x
, wm
->lstate
.exp
.classic
.rjs
.pos
.x
);
471 STATE_CHECK(thresh
->js
, wm
->exp
.classic
.rjs
.pos
.y
, wm
->lstate
.exp
.classic
.rjs
.pos
.y
);
473 case EXP_GUITAR_HERO_3
:
474 data
->exp
.gh3
= wm
->exp
.gh3
;
475 STATE_CHECK_SIMPLE(thresh
->btns
, wm
->exp
.gh3
.btns
, wm
->lstate
.exp
.gh3
.btns
);
476 STATE_CHECK(thresh
->js
, wm
->exp
.gh3
.wb_raw
, wm
->lstate
.exp
.gh3
.wb_raw
);
477 STATE_CHECK(thresh
->js
, wm
->exp
.gh3
.js
.pos
.x
, wm
->lstate
.exp
.gh3
.js
.pos
.x
);
478 STATE_CHECK(thresh
->js
, wm
->exp
.gh3
.js
.pos
.y
, wm
->lstate
.exp
.gh3
.js
.pos
.y
);
481 data
->exp
.wb
= wm
->exp
.wb
;
482 STATE_CHECK(thresh
->wb
,wm
->exp
.wb
.rtl
,wm
->lstate
.exp
.wb
.rtl
);
483 STATE_CHECK(thresh
->wb
,wm
->exp
.wb
.rtr
,wm
->lstate
.exp
.wb
.rtr
);
484 STATE_CHECK(thresh
->wb
,wm
->exp
.wb
.rbl
,wm
->lstate
.exp
.wb
.rbl
);
485 STATE_CHECK(thresh
->wb
,wm
->exp
.wb
.rbr
,wm
->lstate
.exp
.wb
.rbr
);
487 case EXP_MOTION_PLUS
:
488 data
->exp
.mp
= wm
->exp
.mp
;
489 STATE_CHECK(thresh
->mp
,wm
->exp
.mp
.rx
,wm
->lstate
.exp
.mp
.rx
);
490 STATE_CHECK(thresh
->mp
,wm
->exp
.mp
.ry
,wm
->lstate
.exp
.mp
.ry
);
491 STATE_CHECK(thresh
->mp
,wm
->exp
.mp
.rz
,wm
->lstate
.exp
.mp
.rz
);
494 return state_changed
;
497 static void __wpad_read_wiimote(struct wiimote_t
*wm
, WPADData
*data
, s32
*idle_time
, struct _wpad_thresh
*thresh
)
500 int state_changed
= 0;
501 data
->err
= WPAD_ERR_TRANSFER
;
502 data
->data_present
= 0;
503 data
->battery_level
= wm
->battery_level
;
504 data
->exp
.type
= wm
->exp
.type
;
505 if(wm
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
506 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) {
507 switch(wm
->event_buf
[0]) {
510 case WM_RPT_BTN_ACC_IR
:
512 case WM_RPT_BTN_ACC_EXP
:
513 case WM_RPT_BTN_IR_EXP
:
514 case WM_RPT_BTN_ACC_IR_EXP
:
515 data
->btns_h
= (wm
->btns
&0xffff);
516 data
->data_present
|= WPAD_DATA_BUTTONS
;
517 STATE_CHECK_SIMPLE(thresh
->btns
, wm
->btns
, wm
->lstate
.btns
);
519 switch(wm
->event_buf
[0]) {
521 case WM_RPT_BTN_ACC_IR
:
522 case WM_RPT_BTN_ACC_EXP
:
523 case WM_RPT_BTN_ACC_IR_EXP
:
524 data
->accel
= wm
->accel
;
525 data
->data_present
|= WPAD_DATA_ACCEL
;
526 STATE_CHECK(thresh
->acc
, wm
->accel
.x
, wm
->lstate
.accel
.x
);
527 STATE_CHECK(thresh
->acc
, wm
->accel
.y
, wm
->lstate
.accel
.y
);
528 STATE_CHECK(thresh
->acc
, wm
->accel
.z
, wm
->lstate
.accel
.z
);
530 switch(wm
->event_buf
[0]) {
531 //IR requires acceleration
532 //case WM_RPT_BTN_IR_EXP:
533 case WM_RPT_BTN_ACC_IR
:
534 case WM_RPT_BTN_ACC_IR_EXP
:
536 data
->data_present
|= WPAD_DATA_IR
;
537 for(i
=0; i
<WPAD_MAX_IR_DOTS
; i
++) {
538 STATE_CHECK_SIMPLE(thresh
->ir
, wm
->ir
.dot
[i
].visible
, wm
->lstate
.ir
.dot
[i
].visible
);
539 STATE_CHECK(thresh
->ir
, wm
->ir
.dot
[i
].rx
, wm
->lstate
.ir
.dot
[i
].rx
);
540 STATE_CHECK(thresh
->ir
, wm
->ir
.dot
[i
].ry
, wm
->lstate
.ir
.dot
[i
].ry
);
543 switch(wm
->event_buf
[0]) {
545 case WM_RPT_BTN_ACC_EXP
:
546 case WM_RPT_BTN_IR_EXP
:
547 case WM_RPT_BTN_ACC_IR_EXP
:
548 state_changed
|= __wpad_read_expansion(wm
,data
,thresh
);
549 data
->data_present
|= WPAD_DATA_EXPANSION
;
551 data
->err
= WPAD_ERR_NONE
;
557 data
->err
= WPAD_ERR_NOT_READY
;
559 data
->err
= WPAD_ERR_NO_CONTROLLER
;
562 static void __wpad_eventCB(struct wiimote_t
*wm
,s32 event
)
566 WPADData
*wpadd
= NULL
;
567 struct _wpad_cb
*wpdcb
= NULL
;
572 wpdcb
= &__wpdcb
[chan
];
574 if(wpdcb
->queue_ext
!=NULL
) {
575 maxbufs
= wpdcb
->queue_length
;
576 wpadd
= &(wpdcb
->queue_ext
[wpdcb
->queue_tail
]);
578 maxbufs
= EVENTQUEUE_LENGTH
;
579 wpadd
= &(wpdcb
->queue_int
[wpdcb
->queue_tail
]);
581 if(wpdcb
->queue_full
== maxbufs
) {
583 wpdcb
->queue_head
%= maxbufs
;
584 wpdcb
->dropped_events
++;
589 __wpad_read_wiimote(wm
, wpadd
, &wpdcb
->idle_time
, &wpdcb
->thresh
);
592 wpdcb
->queue_tail
%= maxbufs
;
599 wpdcb
= &__wpdcb
[chan
];
601 wpdcb
->queue_head
= 0;
602 wpdcb
->queue_tail
= 0;
603 wpdcb
->queue_full
= 0;
604 wpdcb
->idle_time
= 0;
605 memset(&wpdcb
->lstate
,0,sizeof(WPADData
));
606 memset(&wpaddata
[chan
],0,sizeof(WPADData
));
607 memset(wpdcb
->queue_int
,0,(sizeof(WPADData
)*EVENTQUEUE_LENGTH
));
608 wiiuse_set_ir_position(wm
,(CONF_GetSensorBarPosition()^1));
609 wiiuse_set_ir_sensitivity(wm
,CONF_GetIRSensitivity());
610 wiiuse_set_leds(wm
,(WIIMOTE_LED_1
<<(chan
%WPAD_BALANCE_BOARD
)),NULL
);
611 wiiuse_set_speaker(wm
,wpdcb
->speaker_enabled
);
613 __wpads_active
|= (0x01<<chan
);
615 case WIIUSE_DISCONNECT
:
617 wpdcb
= &__wpdcb
[chan
];
619 wpdcb
->queue_head
= 0;
620 wpdcb
->queue_tail
= 0;
621 wpdcb
->queue_full
= 0;
622 wpdcb
->queue_length
= 0;
623 wpdcb
->queue_ext
= NULL
;
624 wpdcb
->idle_time
= -1;
625 memset(&wpdcb
->lstate
,0,sizeof(WPADData
));
626 memset(&wpaddata
[chan
],0,sizeof(WPADData
));
627 memset(wpdcb
->queue_int
,0,(sizeof(WPADData
)*EVENTQUEUE_LENGTH
));
628 __wpads_active
&= ~(0x01<<chan
);
629 __wpads_used
&= ~(0x01<<chan
);
636 void __wpad_disconnectCB(struct bd_addr
*offaddr
, u8 reason
)
638 struct bd_addr bdaddr
;
641 if(__wpads_inited
== WPAD_STATE_ENABLED
) {
642 for(i
=0;i
<__wpad_devs
.num_registered
;i
++) {
643 BD_ADDR(&(bdaddr
),__wpad_devs
.registered
[i
].bdaddr
[5],__wpad_devs
.registered
[i
].bdaddr
[4],__wpad_devs
.registered
[i
].bdaddr
[3],__wpad_devs
.registered
[i
].bdaddr
[2],__wpad_devs
.registered
[i
].bdaddr
[1],__wpad_devs
.registered
[i
].bdaddr
[0]);
644 if(bd_addr_cmp(offaddr
,&bdaddr
)) {
645 if(reason
== DISCONNECT_BATTERY_DIED
) {
646 if(__wpad_batcb
) __wpad_batcb(i
); //sanity check since this pointer can be NULL.
647 } else if(reason
== DISCONNECT_POWER_OFF
)
648 __wpad_powcb(i
); //no sanity check because there's a default callback iff not otherwise set.
661 _CPU_ISR_Disable(level
);
662 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
666 memset(__wpdcb
,0,sizeof(struct _wpad_cb
)*WPAD_MAX_WIIMOTES
);
667 memset(&__wpad_devs
,0,sizeof(conf_pads
));
668 memset(__wpad_keys
,0,sizeof(struct linkkey_info
)*WPAD_MAX_WIIMOTES
);
670 for(i
=0;i
<WPAD_MAX_WIIMOTES
;i
++) {
671 __wpdcb
[i
].thresh
.btns
= WPAD_THRESH_DEFAULT_BUTTONS
;
672 __wpdcb
[i
].thresh
.ir
= WPAD_THRESH_DEFAULT_IR
;
673 __wpdcb
[i
].thresh
.acc
= WPAD_THRESH_DEFAULT_ACCEL
;
674 __wpdcb
[i
].thresh
.js
= WPAD_THRESH_DEFAULT_JOYSTICK
;
675 __wpdcb
[i
].thresh
.wb
= WPAD_THRESH_DEFAULT_BALANCEBOARD
;
676 __wpdcb
[i
].thresh
.mp
= WPAD_THRESH_DEFAULT_MOTION_PLUS
;
678 if (SYS_CreateAlarm(&__wpdcb
[i
].sound_alarm
) < 0)
681 _CPU_ISR_Restore(level
);
682 return WPAD_ERR_UNKNOWN
;
686 if(CONF_GetPadDevices(&__wpad_devs
) < 0) {
688 _CPU_ISR_Restore(level
);
689 return WPAD_ERR_BADCONF
;
692 if(__wpad_devs
.num_registered
== 0) {
694 _CPU_ISR_Restore(level
);
695 return WPAD_ERR_NONEREGISTERED
;
698 if(__wpad_devs
.num_registered
> CONF_PAD_MAX_REGISTERED
) {
700 _CPU_ISR_Restore(level
);
701 return WPAD_ERR_BADCONF
;
704 __wpads
= wiiuse_init(WPAD_MAX_WIIMOTES
,__wpad_eventCB
);
707 _CPU_ISR_Restore(level
);
708 return WPAD_ERR_UNKNOWN
;
711 __wiiuse_sensorbar_enable(1);
714 BTE_SetDisconnectCallback(__wpad_disconnectCB
);
715 BTE_InitCore(__initcore_finished
);
717 if (SYS_CreateAlarm(&__wpad_timer
) < 0)
720 _CPU_ISR_Restore(level
);
721 return WPAD_ERR_UNKNOWN
;
724 SYS_RegisterResetFunc(&__wpad_resetinfo
);
728 SYS_SetPeriodicAlarm(__wpad_timer
,&tb
,&tb
,__wpad_timeouthandler
,NULL
);
729 __wpads_inited
= WPAD_STATE_ENABLING
;
731 _CPU_ISR_Restore(level
);
732 return WPAD_ERR_NONE
;
735 s32
WPAD_ReadEvent(s32 chan
, WPADData
*data
)
738 u32 maxbufs
,smoothed
= 0;
739 struct accel_t
*accel_calib
= NULL
;
740 struct _wpad_cb
*wpdcb
= NULL
;
741 WPADData
*lstate
= NULL
,*wpadd
= NULL
;
743 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
745 _CPU_ISR_Disable(level
);
746 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
747 _CPU_ISR_Restore(level
);
748 return WPAD_ERR_NOT_READY
;
751 if(__wpads
[chan
] && WIIMOTE_IS_SET(__wpads
[chan
],WIIMOTE_STATE_CONNECTED
)) {
752 if(WIIMOTE_IS_SET(__wpads
[chan
],WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) {
753 wpdcb
= &__wpdcb
[chan
];
754 if(wpdcb
->queue_ext
!=NULL
) {
755 maxbufs
= wpdcb
->queue_length
;
756 wpadd
= wpdcb
->queue_ext
;
758 maxbufs
= EVENTQUEUE_LENGTH
;
759 wpadd
= wpdcb
->queue_int
;
761 if(wpdcb
->queue_full
== 0) {
762 _CPU_ISR_Restore(level
);
763 return WPAD_ERR_QUEUE_EMPTY
;
766 *data
= wpadd
[wpdcb
->queue_head
];
768 wpdcb
->queue_head
%= maxbufs
;
770 lstate
= &wpdcb
->lstate
;
771 accel_calib
= &__wpads
[chan
]->accel_calib
;
772 smoothed
= WIIMOTE_IS_FLAG_SET(__wpads
[chan
], WIIUSE_SMOOTHING
);
774 _CPU_ISR_Restore(level
);
775 return WPAD_ERR_NOT_READY
;
778 _CPU_ISR_Restore(level
);
779 return WPAD_ERR_NO_CONTROLLER
;
782 _CPU_ISR_Restore(level
);
784 __wpad_calc_data(data
,lstate
,accel_calib
,smoothed
);
788 s32
WPAD_DroppedEvents(s32 chan
)
795 if(chan
== WPAD_CHAN_ALL
) {
796 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
797 if((ret
= WPAD_DroppedEvents(i
)) < WPAD_ERR_NONE
)
804 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
806 _CPU_ISR_Disable(level
);
807 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
808 _CPU_ISR_Restore(level
);
809 return WPAD_ERR_NOT_READY
;
812 if(__wpads
[chan
]!=NULL
) {
813 dropped
= __wpdcb
[chan
].dropped_events
;
814 __wpdcb
[chan
].dropped_events
= 0;
816 _CPU_ISR_Restore(level
);
820 s32
WPAD_Flush(s32 chan
)
825 if(chan
== WPAD_CHAN_ALL
) {
826 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
827 if((ret
= WPAD_Flush(i
)) < WPAD_ERR_NONE
)
834 while((ret
= WPAD_ReadEvent(chan
, NULL
)) >= 0)
836 if(ret
== WPAD_ERR_QUEUE_EMPTY
) return count
;
840 s32
WPAD_ReadPending(s32 chan
, WPADDataCallback datacb
)
852 if(chan
== WPAD_CHAN_ALL
) {
853 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
854 if((ret
= WPAD_ReadPending(i
, datacb
)) >= WPAD_ERR_NONE
)
859 btns_p
= btns_nh
= btns_l
= wpaddata
[chan
].btns_h
;
861 ret
= WPAD_ReadEvent(chan
,&wpaddata
[chan
]);
862 if(ret
< WPAD_ERR_NONE
) break;
864 datacb(chan
, &wpaddata
[chan
]);
866 // we ignore everything except _h, since we have our
867 // own "fake" _l and everything gets recalculated at
868 // the end of the function
869 btns_h
= wpaddata
[chan
].btns_h
;
871 /* Button event coalescing:
872 * What we're doing here is get the very first button event
873 * (press or release) for each button. This gets propagated
874 * to the output. Held will therefore report an "old" state
875 * for every button that has changed more than once. This is
876 * intentional: next call to WPAD_ReadPending, if this button
877 * hasn't again changed, the opposite event will fire. This
878 * is the behavior that preserves the most information,
879 * within the limitations of trying to coalesce multiple events
880 * into one. It also keeps the output consistent, if possibly
881 * not fully up to date.
884 // buttons that changed that haven't changed before
885 btns_ch
= (btns_h
^ btns_p
) & ~btns_ev
;
887 // propagate changes in btns_ch to btns_nd
888 btns_nh
= (btns_nh
& ~btns_ch
) | (btns_h
& btns_ch
);
889 // store these new changes to btns_ev
894 wpaddata
[chan
].btns_h
= btns_nh
;
895 wpaddata
[chan
].btns_l
= btns_l
;
896 wpaddata
[chan
].btns_d
= btns_nh
& ~btns_l
;
897 wpaddata
[chan
].btns_u
= ~btns_nh
& btns_l
;
898 if(ret
== WPAD_ERR_QUEUE_EMPTY
) return count
;
902 s32
WPAD_SetDataFormat(s32 chan
, s32 fmt
)
908 if(chan
== WPAD_CHAN_ALL
) {
909 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
910 if((ret
= WPAD_SetDataFormat(i
, fmt
)) < WPAD_ERR_NONE
)
912 return WPAD_ERR_NONE
;
915 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
917 _CPU_ISR_Disable(level
);
918 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
919 _CPU_ISR_Restore(level
);
920 return WPAD_ERR_NOT_READY
;
923 if(__wpads
[chan
]!=NULL
) {
926 case WPAD_FMT_BTNS_ACC
:
927 case WPAD_FMT_BTNS_ACC_IR
:
928 __wpdcb
[chan
].data_fmt
= fmt
;
932 _CPU_ISR_Restore(level
);
933 return WPAD_ERR_BADVALUE
;
936 _CPU_ISR_Restore(level
);
937 return WPAD_ERR_NONE
;
940 s32
WPAD_SetMotionPlus(s32 chan
, u8 enable
)
946 if(chan
== WPAD_CHAN_ALL
) {
947 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
948 if((ret
= WPAD_SetMotionPlus(i
, enable
)) < WPAD_ERR_NONE
)
950 return WPAD_ERR_NONE
;
953 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
955 _CPU_ISR_Disable(level
);
956 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
957 _CPU_ISR_Restore(level
);
958 return WPAD_ERR_NOT_READY
;
961 if(__wpads
[chan
]!=NULL
) {
962 wiiuse_set_motion_plus(__wpads
[chan
], enable
);
964 _CPU_ISR_Restore(level
);
965 return WPAD_ERR_NONE
;
968 s32
WPAD_SetVRes(s32 chan
,u32 xres
,u32 yres
)
974 if(chan
== WPAD_CHAN_ALL
) {
975 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
976 if((ret
= WPAD_SetVRes(i
, xres
, yres
)) < WPAD_ERR_NONE
)
978 return WPAD_ERR_NONE
;
981 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
983 _CPU_ISR_Disable(level
);
984 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
985 _CPU_ISR_Restore(level
);
986 return WPAD_ERR_NOT_READY
;
989 if(__wpads
[chan
]!=NULL
)
990 wiiuse_set_ir_vres(__wpads
[chan
],xres
,yres
);
992 _CPU_ISR_Restore(level
);
993 return WPAD_ERR_NONE
;
1001 _CPU_ISR_Disable(level
);
1002 ret
= __wpads_inited
;
1003 _CPU_ISR_Restore(level
);
1008 s32
WPAD_Probe(s32 chan
,u32
*type
)
1014 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1016 _CPU_ISR_Disable(level
);
1017 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1018 _CPU_ISR_Restore(level
);
1019 return WPAD_ERR_NOT_READY
;
1023 if(wm
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
1024 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)) {
1025 dev
= WPAD_EXP_NONE
;
1026 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_EXP
)) {
1027 switch(wm
->exp
.type
) {
1028 case WPAD_EXP_NUNCHUK
:
1029 case WPAD_EXP_CLASSIC
:
1030 case WPAD_EXP_GUITARHERO3
:
1031 case WPAD_EXP_WIIBOARD
:
1036 if(type
!=NULL
) *type
= dev
;
1037 ret
= WPAD_ERR_NONE
;
1039 ret
= WPAD_ERR_NOT_READY
;
1041 ret
= WPAD_ERR_NO_CONTROLLER
;
1042 _CPU_ISR_Restore(level
);
1047 s32
WPAD_SetEventBufs(s32 chan
, WPADData
*bufs
, u32 cnt
)
1050 struct _wpad_cb
*wpdcb
= NULL
;
1052 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1054 _CPU_ISR_Disable(level
);
1055 wpdcb
= &__wpdcb
[chan
];
1056 wpdcb
->queue_head
= 0;
1057 wpdcb
->queue_tail
= 0;
1058 wpdcb
->queue_full
= 0;
1059 wpdcb
->queue_length
= cnt
;
1060 wpdcb
->queue_ext
= bufs
;
1061 _CPU_ISR_Restore(level
);
1062 return WPAD_ERR_NONE
;
1065 void WPAD_SetPowerButtonCallback(WPADShutdownCallback cb
)
1069 _CPU_ISR_Disable(level
);
1073 __wpad_powcb
= __wpad_def_powcb
;
1074 _CPU_ISR_Restore(level
);
1077 void WPAD_SetBatteryDeadCallback(WPADShutdownCallback cb
)
1081 _CPU_ISR_Disable(level
);
1083 _CPU_ISR_Restore(level
);
1086 s32
WPAD_Disconnect(s32 chan
)
1089 struct _wpad_cb
*wpdcb
= NULL
;
1091 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1093 _CPU_ISR_Disable(level
);
1094 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1095 _CPU_ISR_Restore(level
);
1096 return WPAD_ERR_NOT_READY
;
1099 wpdcb
= &__wpdcb
[chan
];
1100 __wpad_disconnect(wpdcb
);
1102 _CPU_ISR_Restore(level
);
1104 while(__wpads_active
&(0x01<<chan
)) {
1106 if(++cnt
> 3000) break;
1109 return WPAD_ERR_NONE
;
1112 void WPAD_Shutdown()
1117 struct _wpad_cb
*wpdcb
= NULL
;
1119 _CPU_ISR_Disable(level
);
1121 __wpads_inited
= WPAD_STATE_DISABLED
;
1122 SYS_RemoveAlarm(__wpad_timer
);
1123 for(i
=0;i
<WPAD_MAX_WIIMOTES
;i
++) {
1124 wpdcb
= &__wpdcb
[i
];
1125 SYS_RemoveAlarm(wpdcb
->sound_alarm
);
1126 __wpad_disconnect(wpdcb
);
1129 __wiiuse_sensorbar_enable(0);
1130 _CPU_ISR_Restore(level
);
1132 while(__wpads_active
) {
1134 if(++cnt
> 3000) break;
1140 void WPAD_SetIdleTimeout(u32 seconds
)
1144 _CPU_ISR_Disable(level
);
1145 __wpad_idletimeout
= seconds
;
1146 _CPU_ISR_Restore(level
);
1151 return WPAD_ReadPending(WPAD_CHAN_ALL
, NULL
);
1154 s32
WPAD_Rumble(s32 chan
, int status
)
1160 if(chan
== WPAD_CHAN_ALL
) {
1161 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
1162 if((ret
= WPAD_Rumble(i
,status
)) < WPAD_ERR_NONE
)
1164 return WPAD_ERR_NONE
;
1167 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1169 _CPU_ISR_Disable(level
);
1170 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1171 _CPU_ISR_Restore(level
);
1172 return WPAD_ERR_NOT_READY
;
1175 if(__wpads
[chan
]!=NULL
)
1176 wiiuse_rumble(__wpads
[chan
],status
);
1178 _CPU_ISR_Restore(level
);
1179 return WPAD_ERR_NONE
;
1182 s32
WPAD_SetIdleThresholds(s32 chan
, s32 btns
, s32 ir
, s32 accel
, s32 js
, s32 wb
, s32 mp
)
1188 if(chan
== WPAD_CHAN_ALL
) {
1189 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
1190 if((ret
= WPAD_SetIdleThresholds(i
,btns
,ir
,accel
,js
,wb
,mp
)) < WPAD_ERR_NONE
)
1192 return WPAD_ERR_NONE
;
1195 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1197 _CPU_ISR_Disable(level
);
1198 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1199 _CPU_ISR_Restore(level
);
1200 return WPAD_ERR_NOT_READY
;
1203 __wpdcb
[chan
].thresh
.btns
= (btns
<0) ? -1 : 0;
1204 __wpdcb
[chan
].thresh
.ir
= ir
;
1205 __wpdcb
[chan
].thresh
.acc
= accel
;
1206 __wpdcb
[chan
].thresh
.js
= js
;
1207 __wpdcb
[chan
].thresh
.wb
= wb
;
1208 __wpdcb
[chan
].thresh
.mp
= mp
;
1211 _CPU_ISR_Restore(level
);
1212 return WPAD_ERR_NONE
;
1215 s32
WPAD_ControlSpeaker(s32 chan
,s32 enable
)
1221 if(chan
== WPAD_CHAN_ALL
) {
1222 for(i
=WPAD_CHAN_0
; i
<WPAD_MAX_WIIMOTES
; i
++)
1223 if((ret
= WPAD_ControlSpeaker(i
,enable
)) < WPAD_ERR_NONE
)
1225 return WPAD_ERR_NONE
;
1228 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1230 _CPU_ISR_Disable(level
);
1231 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1232 _CPU_ISR_Restore(level
);
1233 return WPAD_ERR_NOT_READY
;
1236 if(__wpads
[chan
]!=NULL
) {
1237 __wpdcb
[chan
].speaker_enabled
= enable
;
1238 wiiuse_set_speaker(__wpads
[chan
],enable
);
1241 _CPU_ISR_Restore(level
);
1242 return WPAD_ERR_NONE
;
1245 s32
WPAD_IsSpeakerEnabled(s32 chan
)
1251 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1253 _CPU_ISR_Disable(level
);
1254 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1255 _CPU_ISR_Restore(level
);
1256 return WPAD_ERR_NOT_READY
;
1260 ret
= WPAD_ERR_NOT_READY
;
1261 if(wm
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
1262 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)
1263 && WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_SPEAKER
)) ret
= WPAD_ERR_NONE
;
1266 _CPU_ISR_Restore(level
);
1270 s32
WPAD_SendStreamData(s32 chan
,void *buf
,u32 len
)
1276 if(chan
<WPAD_CHAN_0
|| chan
>=WPAD_MAX_WIIMOTES
) return WPAD_ERR_BAD_CHANNEL
;
1278 _CPU_ISR_Disable(level
);
1279 if(__wpads_inited
==WPAD_STATE_DISABLED
) {
1280 _CPU_ISR_Restore(level
);
1281 return WPAD_ERR_NOT_READY
;
1285 if(wm
!=NULL
&& WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_CONNECTED
)) {
1286 if(WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_HANDSHAKE_COMPLETE
)
1287 && WIIMOTE_IS_SET(wm
,WIIMOTE_STATE_SPEAKER
)) {
1288 __wpdcb
[chan
].sound_data
= buf
;
1289 __wpdcb
[chan
].sound_len
= len
;
1290 __wpdcb
[chan
].sound_off
= 0;
1293 tb
.tv_nsec
= 6666667;
1294 SYS_SetPeriodicAlarm(__wpdcb
[chan
].sound_alarm
,&tb
,&tb
,__wpad_sounddata_alarmhandler
, &__wpdcb
[chan
]);
1298 _CPU_ISR_Restore(level
);
1299 return WPAD_ERR_NONE
;
1302 void WPAD_EncodeData(WPADEncStatus
*info
,u32 flag
,const s16
*pcmSamples
,s32 numSamples
,u8
*encData
)
1305 short *samples
= (short*)pcmSamples
;
1306 WENCStatus
*status
= (WENCStatus
*)info
;
1308 if(!(flag
&WPAD_ENC_CONT
)) status
->step
= 0;
1310 n
= (numSamples
+1)/2;
1313 nibble
= (wencdata(status
,samples
[0]))<<4;
1314 nibble
|= (wencdata(status
,samples
[1]));
1315 *encData
++ = nibble
;
1320 WPADData
*WPAD_Data(int chan
)
1322 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
) return NULL
;
1323 return &wpaddata
[chan
];
1326 u8
WPAD_BatteryLevel(int chan
)
1328 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
) return 0;
1329 return wpaddata
[chan
].battery_level
;
1332 u32
WPAD_ButtonsUp(int chan
)
1334 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
) return 0;
1335 return wpaddata
[chan
].btns_u
;
1338 u32
WPAD_ButtonsDown(int chan
)
1340 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
) return 0;
1341 return wpaddata
[chan
].btns_d
;
1344 u32
WPAD_ButtonsHeld(int chan
)
1346 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
) return 0;
1347 return wpaddata
[chan
].btns_h
;
1350 void WPAD_IR(int chan
, struct ir_t
*ir
)
1352 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
|| ir
==NULL
) return;
1353 *ir
= wpaddata
[chan
].ir
;
1356 void WPAD_Orientation(int chan
, struct orient_t
*orient
)
1358 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
|| orient
==NULL
) return;
1359 *orient
= wpaddata
[chan
].orient
;
1362 void WPAD_GForce(int chan
, struct gforce_t
*gforce
)
1364 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
|| gforce
==NULL
) return;
1365 *gforce
= wpaddata
[chan
].gforce
;
1368 void WPAD_Accel(int chan
, struct vec3w_t
*accel
)
1370 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
|| accel
==NULL
) return;
1371 *accel
= wpaddata
[chan
].accel
;
1374 void WPAD_Expansion(int chan
, struct expansion_t
*exp
)
1376 if(chan
<0 || chan
>=WPAD_MAX_WIIMOTES
|| exp
==NULL
) return;
1377 *exp
= wpaddata
[chan
].exp
;