diff --git a/src/events.c b/src/events.c index 6fe9621..116075e 100644 --- a/src/events.c +++ b/src/events.c @@ -44,6 +44,7 @@ #include "nunchuk.h" /* for nunchuk_disconnected, etc */ #include "wiiboard.h" /* for wii_board_disconnected, etc */ #include "io.h" /* for wiiuse_io_read on Windows, etc */ +#include "motion_plus.h" #ifndef WIIUSE_WIN32 #include /* for timeval */ diff --git a/src/io.c b/src/io.c index d3a956c..0fbb7ea 100644 --- a/src/io.c +++ b/src/io.c @@ -68,6 +68,7 @@ void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) { break; } + case 1: { struct read_req_t* req = wm->read_req; @@ -90,10 +91,10 @@ void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) { accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z, accel->cal_g.x, accel->cal_g.y, accel->cal_g.z); + wiiuse_set_motion_plus(wm, 0); - /* request the status of the wiimote to see if there is an expansion */ + /* request the status of the wiimote to check for any expansion */ wiiuse_status(wm); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); wm->handshake_state++; @@ -106,10 +107,12 @@ void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) { } wm->event = WIIUSE_CONNECT; + wm->expansion_state = 0; wiiuse_status(wm); break; } + default: { break; diff --git a/src/motion_plus.c b/src/motion_plus.c index 3371f97..d79208c 100644 --- a/src/motion_plus.c +++ b/src/motion_plus.c @@ -41,19 +41,21 @@ static void wiiuse_calibrate_motion_plus(struct motion_plus_t *mp); static void calculate_gyro_rates(struct motion_plus_t* mp); -void wiiuse_motion_plus_check(struct wiimote_t *wm,byte *data,unsigned short len) + +void wiiuse_motion_plus_handshake(struct wiimote_t *wm,byte *data,unsigned short len) { uint32_t val; if(data == NULL) { - wiiuse_read_data_cb(wm, wiiuse_motion_plus_check, wm->motion_plus_id, WM_EXP_ID, 6); + wiiuse_read_data_cb(wm, wiiuse_motion_plus_handshake, wm->motion_plus_id, WM_EXP_ID, 6); } else { - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); + val = from_big_endian_uint32_t(data + 2); + if(val == EXP_ID_CODE_MOTION_PLUS || val == EXP_ID_CODE_MOTION_PLUS_NUNCHUK || val == EXP_ID_CODE_MOTION_PLUS_CLASSIC) @@ -83,7 +85,6 @@ void wiiuse_motion_plus_check(struct wiimote_t *wm,byte *data,unsigned short len } WIIUSE_DEBUG("Motion plus connected"); - WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP); /* Init gyroscopes */ wm->exp.mp.cal_gyro.r = 0; @@ -98,6 +99,9 @@ void wiiuse_motion_plus_check(struct wiimote_t *wm,byte *data,unsigned short len wm->exp.mp.classic = &(wm->exp.classic); wm->exp.nunchuk.flags = &wm->flags; + wm->exp.mp.ext = 0; + wm->exp.mp.ext_initialized = 0; + wiiuse_set_ir_mode(wm); } } @@ -105,7 +109,6 @@ void wiiuse_motion_plus_check(struct wiimote_t *wm,byte *data,unsigned short len static void wiiuse_set_motion_plus_clear2(struct wiimote_t *wm,byte *data,unsigned short len) { - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); wiiuse_set_ir_mode(wm); @@ -122,13 +125,10 @@ void wiiuse_set_motion_plus(struct wiimote_t *wm, int status) { byte val; - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE)) - return; - - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); - if(status) + if(status && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE)) { - val = 0x04; + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); + val = (status == 1) ? 0x04 : 0x05; wiiuse_write_data_cb(wm, WM_EXP_MOTION_PLUS_ENABLE, &val, 1, wiiuse_motion_plus_check); } else @@ -145,7 +145,7 @@ void motion_plus_disconnected(struct motion_plus_t* mp) memset(mp, 0, sizeof(struct motion_plus_t)); } -void motion_plus_event(struct motion_plus_t* mp, byte* msg) +void motion_plus_event(struct motion_plus_t* mp, int exp_type, byte* msg) { /* * Pass-through modes interleave data from the gyro @@ -178,9 +178,9 @@ void motion_plus_event(struct motion_plus_t* mp, byte* msg) } else - { /* expansion frame */ - /* FIXME: Handle pass-through modes */ -/* if (mp->mode == WIIUSE_MP_NUNCHUK) */ + { + /* expansion frame */ + if (exp_type == EXP_MOTION_PLUS_NUNCHUK) { /* ok, this is nunchuck, re-encode it as regular nunchuck packet */ @@ -205,10 +205,16 @@ void motion_plus_event(struct motion_plus_t* mp, byte* msg) &(mp->nc->gforce)); } -/* else if (mp->mode == WIIUSE_MP_CLASSIC) */ -/* { */ -/* WIIUSE_ERROR("Classic controller pass-through is not implemented!\n"); */ -/* } */ + + else if (exp_type == EXP_MOTION_PLUS_CLASSIC) + { + WIIUSE_ERROR("Classic controller pass-through is not implemented!\n"); + } + + else + { + WIIUSE_ERROR("Unsupported mode passed to motion_plus_event() !\n"); + } } } diff --git a/src/motion_plus.h b/src/motion_plus.h index 9b05cce..88cdba7 100644 --- a/src/motion_plus.h +++ b/src/motion_plus.h @@ -45,7 +45,10 @@ extern "C" { /** @{ */ void motion_plus_disconnected(struct motion_plus_t* mp); -void motion_plus_event(struct motion_plus_t* mp, byte* msg); +void motion_plus_event(struct motion_plus_t* mp, int exp_type, byte* msg); + +void wiiuse_motion_plus_handshake(struct wiimote_t *wm, byte *data,unsigned short len); + /** @} */ #ifdef __cplusplus diff --git a/src/wiiuse.h b/src/wiiuse.h index 6279a07..b1a003d 100644 --- a/src/wiiuse.h +++ b/src/wiiuse.h @@ -534,6 +534,7 @@ typedef struct guitar_hero_3_t { */ typedef struct motion_plus_t { + int ext_initialized; /* is the pass-through device initialized? */ unsigned char ext; struct ang3s_t raw_gyro; /**< current raw gyroscope data */ diff --git a/src/wiiuse_internal.h b/src/wiiuse_internal.h index af342aa..ef05501 100644 --- a/src/wiiuse_internal.h +++ b/src/wiiuse_internal.h @@ -135,6 +135,7 @@ #define WM_EXP_MEM_ENABLE2 0x04A400FB #define WM_EXP_MEM_CALIBR 0x04A40020 #define WM_EXP_MOTION_PLUS_ENABLE 0x04A600FE +#define WM_EXP_MOTION_PLUS_INIT 0x04A600F0 #define WM_REG_IR 0x04B00030 #define WM_REG_IR_BLOCK1 0x04B00000 #define WM_REG_IR_BLOCK2 0x04B0001A @@ -197,8 +198,10 @@ #define WIIMOTE_STATE_IR_SENS_LVL3 0x0800 #define WIIMOTE_STATE_IR_SENS_LVL4 0x1000 #define WIIMOTE_STATE_IR_SENS_LVL5 0x2000 -#define WIIMOTE_STATE_EXP_HANDSHAKE 0x40000 /* actual M+ connection exists but no handshake yet */ -#define WIIMOTE_STATE_EXP_FAILED 0x80000 /* actual M+ connection exists but handshake failed */ +#define WIIMOTE_STATE_EXP_HANDSHAKE 0x10000 /* actual M+ connection exists but no handshake yet */ +#define WIIMOTE_STATE_EXP_EXTERN 0x20000 /* actual M+ connection exists but handshake failed */ +#define WIIMOTE_STATE_EXP_FAILED 0x40000 /* actual M+ connection exists but handshake failed */ + #define WIIMOTE_INIT_STATES (WIIMOTE_STATE_IR_SENS_LVL3)