diff --git a/gc/wiiuse/wiiuse.h b/gc/wiiuse/wiiuse.h index 49ed06282..b394485bf 100644 --- a/gc/wiiuse/wiiuse.h +++ b/gc/wiiuse/wiiuse.h @@ -67,6 +67,17 @@ #define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 #define CLASSIC_CTRL_BUTTON_ALL 0xFEFF +/* wii u pro controller extra button codes */ +#define WII_U_PRO_CTRL_BUTTON_RSTICK 0x00010000 +#define WII_U_PRO_CTRL_BUTTON_LSTICK 0x00020000 +#define WII_U_PRO_CTRL_BUTTON_EXTRA 0x00030000 +#define WII_U_PRO_CTRL_BUTTON_ALL (WII_U_PRO_CTRL_BUTTON_EXTRA | CLASSIC_CTRL_BUTTON_ALL) + +/* wii u pro controller extra data */ +#define WII_U_PRO_CTRL_CHARGING 0x04 +#define WII_U_PRO_CTRL_WIRED 0x08 +#define WII_U_PRO_CTRL_BATTERY 0x70 + /* guitar hero 3 button codes */ #define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001 #define GUITAR_HERO_3_BUTTON_YELLOW 0x0008 @@ -105,6 +116,11 @@ #define EXP_WII_BOARD 4 #define EXP_MOTION_PLUS 5 +/* classic controller types */ +#define CLASSIC_TYPE_ORIG 0 /* original classic controller (analog triggers) */ +#define CLASSIC_TYPE_PRO 1 /* classic controller pro (no analog triggers) */ +#define CLASSIC_TYPE_WIIU 2 + /* IR correction types */ typedef enum ir_position_t { WIIUSE_IR_ABOVE, @@ -458,10 +474,10 @@ typedef struct nunchuk_t { * @brief Classic controller expansion device. */ typedef struct classic_ctrl_t { - short btns; /**< what buttons have just been pressed */ - short btns_last; /**< what buttons have just been pressed */ - short btns_held; /**< what buttons are being held down */ - short btns_released; /**< what buttons were just released this */ + u32 btns; /**< what buttons have just been pressed */ + u32 btns_last; /**< what buttons have just been pressed */ + u32 btns_held; /**< what buttons are being held down */ + u32 btns_released; /**< what buttons were just released this */ ubyte rs_raw; ubyte ls_raw; @@ -471,7 +487,12 @@ typedef struct classic_ctrl_t { struct joystick_t ljs; /**< left joystick calibration */ struct joystick_t rjs; /**< right joystick calibration */ - ubyte type; /**< original, pro, wiiu pro */ + ubyte type; /**< original, pro, wiiu pro */ + + ubyte charging; + ubyte wired; + ubyte battery; + } classic_ctrl_t; diff --git a/gc/wiiuse/wpad.h b/gc/wiiuse/wpad.h index daddd9a2d..8fb317510 100644 --- a/gc/wiiuse/wpad.h +++ b/gc/wiiuse/wpad.h @@ -81,6 +81,9 @@ enum { #define WPAD_CLASSIC_BUTTON_DOWN (0x4000u<<16) #define WPAD_CLASSIC_BUTTON_RIGHT (0x8000u<<16) +#define WPAD_WII_U_PRO_BUTTON_RSTICK 0x0001 +#define WPAD_WII_U_PRO_BUTTON_LSTICK 0x0002 + #define WPAD_GUITAR_HERO_3_BUTTON_STRUM_UP (0x0001<<16) #define WPAD_GUITAR_HERO_3_BUTTON_YELLOW (0x0008<<16) #define WPAD_GUITAR_HERO_3_BUTTON_GREEN (0x0010<<16) diff --git a/wiiuse/classic.c b/wiiuse/classic.c index 2e9aaa5d3..2a308b457 100644 --- a/wiiuse/classic.c +++ b/wiiuse/classic.c @@ -48,7 +48,7 @@ #include "io.h" static void fix_bad_calibration_values(struct joystick_t* js, short right_stick); -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now); +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, ubyte *now); /** * @brief Handle the handshake data from the classic controller. @@ -81,7 +81,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt cc->rjs = cc->ljs; - cc->type = 2; + cc->type = CLASSIC_TYPE_WIIU; } else { if (data[offset] == 0xFF) { @@ -102,9 +102,9 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt } if (len > 218 && data[218]) - cc->type = 1; /* classic controller pro (no analog triggers) */ + cc->type = CLASSIC_TYPE_PRO; else - cc->type = 0; /* original classic controller (analog triggers) */ + cc->type = CLASSIC_TYPE_ORIG; /* joystick stuff */ cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4; @@ -124,6 +124,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt fix_bad_calibration_values(&cc->ljs, 0); fix_bad_calibration_values(&cc->rjs, 1); } + /* handshake done */ wm->event = WIIUSE_CLASSIC_CTRL_INSERTED; wm->exp.type = EXP_CLASSIC; @@ -162,8 +163,8 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) { for (i = 0; i < 6; ++i) msg[i] = (msg[i] ^ 0x17) + 0x17; */ - if (cc->type==2) { - classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 8))); + if (cc->type==CLASSIC_TYPE_WIIU) { + classic_ctrl_pressed_buttons(cc, msg + 8); /* 12-bit little endian values adjusted to 8-bit */ cc->ljs.pos.x = (msg[0] >> 4) | (msg[1] << 4); @@ -173,11 +174,16 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) { cc->ls_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_L ? 0x1F : 0; cc->rs_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_R ? 0x1F : 0; + + /* Wii U pro controller specific data */ + cc->charging = !(((msg[10] & WII_U_PRO_CTRL_CHARGING) >> 2) & 1); + cc->wired = !(((msg[10] & WII_U_PRO_CTRL_WIRED) >> 3) & 1); + cc->battery = ((msg[10] & WII_U_PRO_CTRL_BATTERY) >> 4) & 7; } else { - classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); + classic_ctrl_pressed_buttons(cc, msg + 4); - /* left/right buttons */ + /* left/right triggers */ cc->ls_raw = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5)); cc->rs_raw = (msg[3] & 0x1F); @@ -194,6 +200,11 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) { cc->ljs.pos.y = (msg[1] & 0x3F); cc->rjs.pos.x = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7); cc->rjs.pos.y = (msg[2] & 0x1F); + + /* wipe Wii U pro controller specific data */ + cc->charging = 0; + cc->wired = 0; + cc->battery = 0; } #ifndef GEKKO @@ -221,19 +232,29 @@ static void fix_bad_calibration_values(struct joystick_t* js, short right_stick) * @param cc A pointer to a classic_ctrl_t structure. * @param msg The message byte specified in the event packet. */ -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) { - /* message is inverted (0 is active, 1 is inactive) */ - now = ~now & CLASSIC_CTRL_BUTTON_ALL; +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, ubyte *now) { + u32 buttons = (now[0] << 0x8) | now[1]; + + if (cc->type==CLASSIC_TYPE_WIIU) { + /* append Wii U Pro Controller stick buttons to top 16 bits */ + buttons |= (now[2] << 0x10); + + /* message is inverted (0 is active, 1 is inactive) */ + buttons = ~buttons & WII_U_PRO_CTRL_BUTTON_ALL; + } else { + /* message is inverted (0 is active, 1 is inactive) */ + buttons = ~buttons & CLASSIC_CTRL_BUTTON_ALL; + } /* preserve old btns pressed */ cc->btns_last = cc->btns; /* pressed now & were pressed, then held */ - cc->btns_held = (now & cc->btns); + cc->btns_held = (buttons & cc->btns); /* were pressed or were held & not pressed now, then released */ - cc->btns_released = ((cc->btns | cc->btns_held) & ~now); + cc->btns_released = ((cc->btns | cc->btns_held) & ~buttons); /* buttons pressed now */ - cc->btns = now; + cc->btns = buttons; } diff --git a/wiiuse/io.c b/wiiuse/io.c index a01074795..4b73ee16d 100644 --- a/wiiuse/io.c +++ b/wiiuse/io.c @@ -102,7 +102,6 @@ void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len) case 3: if(!data || !len) return; id = BIG_ENDIAN_LONG(*(int*)(&data[220])); - //printf("New exp type: %d\n", id); switch(id) { case EXP_ID_CODE_NUNCHUK: diff --git a/wiiuse/wpad.c b/wiiuse/wpad.c index a9c5a98eb..734fe9acf 100644 --- a/wiiuse/wpad.c +++ b/wiiuse/wpad.c @@ -492,7 +492,12 @@ static void __wpad_calc_data(WPADData *data,WPADData *lstate,struct accel_t *acc cc->l_shoulder = ((f32)cc->ls_raw/0x1F); calc_joystick_state(&cc->ljs, cc->ljs.pos.x, cc->ljs.pos.y); calc_joystick_state(&cc->rjs, cc->rjs.pos.x, cc->rjs.pos.y); - data->btns_h |= (data->exp.classic.btns<<16); + + // overwrite Wiimote buttons (unused) with extra Wii U Pro Controller stick buttons + if (data->exp.classic.type == CLASSIC_TYPE_WIIU) + data->btns_h = (data->exp.classic.btns & WII_U_PRO_CTRL_BUTTON_EXTRA) >> 16; + + data->btns_h |= ((data->exp.classic.btns & CLASSIC_CTRL_BUTTON_ALL)<<16); } break; @@ -765,9 +770,9 @@ static void __wpad_eventCB(struct wiimote_t *wm,s32 event) case WIIUSE_ACK: break; default: - WIIUSE_DEBUG("__wpad_eventCB(%02x)", event); + WIIUSE_DEBUG("__wpad_eventCB(%02x)\n", event); break; - } + } } void __wpad_disconnectCB(struct bd_addr *pad_addr, u8 reason)