diff --git a/include/button_map.h b/include/button_map.h index 7655823..59fe985 100644 --- a/include/button_map.h +++ b/include/button_map.h @@ -22,6 +22,35 @@ enum bm_classic_analog_axis_e { BM_CLASSIC_ANALOG_AXIS__NUM = BM_CLASSIC_ANALOG_AXIS_RIGHT_Y }; +/* Guitar controller */ +enum bm_guitar_analog_axis_e { + BM_GUITAR_ANALOG_AXIS_STICK_X = 1, + BM_GUITAR_ANALOG_AXIS_STICK_Y, + BM_GUITAR_ANALOG_AXIS_TAP_BAR, + BM_GUITAR_ANALOG_AXIS_WHAMMY_BAR, + BM_GUITAR_ANALOG_AXIS__NUM = BM_GUITAR_ANALOG_AXIS_WHAMMY_BAR +}; + +/* Turntable controller */ +enum bm_turntable_analog_axis_e { + BM_TURNTABLE_ANALOG_AXIS_STICK_X = 1, + BM_TURNTABLE_ANALOG_AXIS_STICK_Y, + BM_TURNTABLE_ANALOG_LEFT_TURNTABLE_VELOCITY, + BM_TURNTABLE_ANALOG_RIGHT_TURNTABLE_VELOCITY, + BM_TURNTABLE_ANALOG_CROSS_FADER, + BM_TURNTABLE_ANALOG_EFFECTS_DIAL, + BM_TURNTABLE_ANALOG_AXIS__NUM = BM_TURNTABLE_ANALOG_EFFECTS_DIAL +}; + +/* Drum controller */ +enum bm_drum_analog_axis_e { + BM_DRUM_ANALOG_AXIS_STICK_X = 1, + BM_DRUM_ANALOG_AXIS_STICK_Y, + BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR, + BM_DRUM_ANALOG_AXIS_VELOCITY, + BM_DRUM_ANALOG_AXIS__NUM = BM_DRUM_ANALOG_AXIS_VELOCITY +}; + /* IR pointer emulation */ enum bm_ir_emulation_mode_e { BM_IR_EMULATION_MODE_NONE, @@ -70,6 +99,35 @@ void bm_map_classic( /* Outputs */ struct wiimote_extension_data_format_classic_t *classic); +void bm_map_guitar( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *guitar_button_map, + const u8 *guitar_analog_axis_map, + /* Outputs */ + struct wiimote_extension_data_format_guitar_t *guitar); + +void bm_map_turntable( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *turntable_button_map, + const u8 *turntable_analog_axis_map, + /* Outputs */ + struct wiimote_extension_data_format_turntable_t *guitar); + +void bm_map_drum( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *drum_button_map, + /* Outputs */ + struct wiimote_extension_data_format_drum_t *drum); + void bm_map_ir_direct( /* Inputs */ int num_coordinates, const u16 *x, const u16 *y, @@ -99,8 +157,8 @@ static inline bool bm_check_switch_mapping(u32 buttons, bool *switch_mapping, u3 } static inline void bm_nunchuk_format(struct wiimote_extension_data_format_nunchuk_t *out, - u8 buttons, u8 analog_axis[static BM_NUNCHUK_ANALOG_AXIS__NUM], - u16 ax, u16 ay, u16 az) + u8 buttons, u8 analog_axis[static BM_NUNCHUK_ANALOG_AXIS__NUM], + u16 ax, u16 ay, u16 az) { out->jx = analog_axis[BM_NUNCHUK_ANALOG_AXIS_X - 1]; out->jy = analog_axis[BM_NUNCHUK_ANALOG_AXIS_Y - 1]; @@ -115,7 +173,7 @@ static inline void bm_nunchuk_format(struct wiimote_extension_data_format_nunchu } static inline void bm_classic_format(struct wiimote_extension_data_format_classic_t *out, - u16 buttons, u8 analog_axis[static BM_CLASSIC_ANALOG_AXIS__NUM]) + u16 buttons, u8 analog_axis[static BM_CLASSIC_ANALOG_AXIS__NUM]) { u8 lx = analog_axis[BM_CLASSIC_ANALOG_AXIS_LEFT_X - 1] >> 2; u8 ly = analog_axis[BM_CLASSIC_ANALOG_AXIS_LEFT_Y - 1] >> 2; @@ -136,6 +194,61 @@ static inline void bm_classic_format(struct wiimote_extension_data_format_classi out->bt.hex = (~buttons) & CLASSIC_CTRL_BUTTON_ALL; } + + +static inline void bm_turntable_format(struct wiimote_extension_data_format_turntable_t *out, + u16 buttons, u8 analog_axis[static BM_TURNTABLE_ANALOG_AXIS__NUM]) +{ + u8 sx = analog_axis[BM_TURNTABLE_ANALOG_AXIS_STICK_X - 1] >> 2; + u8 sy = analog_axis[BM_TURNTABLE_ANALOG_AXIS_STICK_Y - 1] >> 2; + u8 ltt = analog_axis[BM_TURNTABLE_ANALOG_LEFT_TURNTABLE_VELOCITY - 1] >> 3; + u8 rtt = analog_axis[BM_TURNTABLE_ANALOG_RIGHT_TURNTABLE_VELOCITY - 1] >> 3; + u8 cross_fader = analog_axis[BM_TURNTABLE_ANALOG_CROSS_FADER - 1] >> 4; + u8 effects_dial = analog_axis[BM_TURNTABLE_ANALOG_EFFECTS_DIAL - 1] >> 3; + + out->sx = sx & 0x3F; + out->sy = sy & 0x3F; + out->rtt1 = rtt & 1; + out->rtt2 = (rtt >> 1) & 3; + out->rtt3 = (rtt >> 3) & 3; + out->rtt5 = rtt & (1<<5); + out->effects2 = (effects_dial >> 3) & 3; + out->effects1 = effects_dial & 0x7; + out->ltt1 = ltt & 0x20; + out->crossfade = cross_fader; + out->bt.hex = (~buttons) & TURNTABLE_CTRL_BUTTON_ALL; + out->bt.ltt5 = ltt & (1<<5); +} + +static inline void bm_guitar_format(struct wiimote_extension_data_format_guitar_t *out, + u16 buttons, const u8 analog_axis[static BM_GUITAR_ANALOG_AXIS__NUM]) +{ + u8 sx = analog_axis[BM_GUITAR_ANALOG_AXIS_STICK_X - 1] >> 2; + u8 sy = analog_axis[BM_GUITAR_ANALOG_AXIS_STICK_Y - 1] >> 2; + u8 tb = analog_axis[BM_GUITAR_ANALOG_AXIS_TAP_BAR - 1] >> 3; + u8 wb = analog_axis[BM_GUITAR_ANALOG_AXIS_WHAMMY_BAR - 1] >> 3; + out->sx = sx & 0x3F; + out->sy = sy & 0x3F; + out->tb = tb & 0x1F; + out->wb = wb & 0x1F; + out->bt.hex = (~buttons) & GUITAR_CTRL_BUTTON_ALL; +} + +static inline void bm_drum_format(struct wiimote_extension_data_format_drum_t *out, + u16 buttons, const u8 analog_axis[static BM_DRUM_ANALOG_AXIS__NUM]) +{ + u8 sx = analog_axis[BM_DRUM_ANALOG_AXIS_STICK_X - 1] >> 2; + u8 sy = analog_axis[BM_DRUM_ANALOG_AXIS_STICK_Y - 1] >> 2; + u8 type = analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1]; + u8 velocity = analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] >> 5; + out->sx = sx & 0x3F; + out->sy = sy & 0x3F; + out->velocity_type = type & 0x1f; + out->velocity = velocity & 0x07; + out->bt.hex = (~buttons) & DRUM_CTRL_BUTTON_ALL; + out->extra = 0b0110; +} + static inline void bm_ir_emulation_state_reset(struct bm_ir_emulation_state_t *state) { state->position[BM_IR_AXIS_X - 1] = IR_CENTER_X; diff --git a/include/usb_device_drivers.h b/include/usb_device_drivers.h index 7f5139b..57aeb3c 100644 --- a/include/usb_device_drivers.h +++ b/include/usb_device_drivers.h @@ -3,7 +3,11 @@ #include "usb_hid.h" -#define SONY_VID 0x054c +#define SONY_VID 0x054c +#define SONY_INST_VID 0x12ba +#define GH_GUITAR_PID 0x0100 +#define GH_DRUM_PID 0x0120 +#define DJ_TURNTABLE_PID 0x0140 struct device_id_t { u16 vid; diff --git a/include/wiimote.h b/include/wiimote.h index 8b7a42d..8098d6f 100644 --- a/include/wiimote.h +++ b/include/wiimote.h @@ -121,6 +121,44 @@ #define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 #define CLASSIC_CTRL_BUTTON_ALL 0xFEFF +/* Guitar button codes */ +#define GUITAR_CTRL_BUTTON_STRUM_UP 0x0001 +#define GUITAR_CTRL_BUTTON_YELLOW 0x0008 +#define GUITAR_CTRL_BUTTON_GREEN 0x0010 +#define GUITAR_CTRL_BUTTON_BLUE 0x0020 +#define GUITAR_CTRL_BUTTON_RED 0x0040 +#define GUITAR_CTRL_BUTTON_ORANGE 0x0080 +#define GUITAR_CTRL_BUTTON_PLUS 0x0400 +#define GUITAR_CTRL_BUTTON_MINUS 0x1000 +#define GUITAR_CTRL_BUTTON_STRUM_DOWN 0x4000 +#define GUITAR_CTRL_BUTTON_ALL 0xFEFF + +/* Drum button codes */ +#define DRUM_CTRL_BUTTON_UP 0x0001 +#define DRUM_CTRL_BUTTON_LEFT 0x0002 +#define DRUM_CTRL_BUTTON_YELLOW 0x0008 +#define DRUM_CTRL_BUTTON_GREEN 0x0010 +#define DRUM_CTRL_BUTTON_BLUE 0x0020 +#define DRUM_CTRL_BUTTON_RED 0x0040 +#define DRUM_CTRL_BUTTON_ORANGE 0x0080 +#define DRUM_CTRL_BUTTON_PLUS 0x0400 +#define DRUM_CTRL_BUTTON_MINUS 0x1000 +#define DRUM_CTRL_BUTTON_DOWN 0x4000 +#define DRUM_CTRL_BUTTON_RIGHT 0x8000 +#define DRUM_CTRL_BUTTON_ALL 0xFEFF + +/* Turntable button codes */ +#define TURNTABLE_CTRL_BUTTON_LEFT_GREEN 0x0008 +#define TURNTABLE_CTRL_BUTTON_LEFT_RED 0x2000 +#define TURNTABLE_CTRL_BUTTON_LEFT_BLUE 0x0080 +#define TURNTABLE_CTRL_BUTTON_RIGHT_GREEN 0x0020 +#define TURNTABLE_CTRL_BUTTON_RIGHT_RED 0x0200 +#define TURNTABLE_CTRL_BUTTON_RIGHT_BLUE 0x0004 +#define TURNTABLE_CTRL_BUTTON_EUPHORIA 0x0010 +#define TURNTABLE_CTRL_BUTTON_PLUS 0x0400 +#define TURNTABLE_CTRL_BUTTON_MINUS 0x1000 +#define TURNTABLE_CTRL_BUTTON_ALL 0xFEFF + /* Acceleromter configuration */ #define ACCEL_ZERO_G (0x80 << 2) #define ACCEL_ONE_G (0x9A << 2) @@ -152,6 +190,8 @@ enum wiimote_ext_e { WIIMOTE_EXT_CLASSIC, WIIMOTE_EXT_CLASSIC_WIIU_PRO, WIIMOTE_EXT_GUITAR, + WIIMOTE_EXT_DRUM, + WIIMOTE_EXT_TURNTABLE, WIIMOTE_EXT_MOTION_PLUS, }; @@ -334,9 +374,126 @@ struct wiimote_extension_data_format_classic_t { } bt; }; +struct wiimote_extension_data_format_turntable_t { + u8 rtt3 : 2; // byte 0 + u8 sx : 6; + + u8 rtt2 : 2; // byte 1 + u8 sy : 6; + + u8 rtt1 : 1; + u8 effects1 : 2; + u8 crossfade : 4; + u8 rtt5 : 1; + + u8 effects2 : 3; + u8 ltt1 : 5; + + union { // byte 4, 5 + u16 hex; + struct { + u8 : 1; + u8 : 1; + u8 left_red : 1; + u8 minus : 1; + u8 : 1; + u8 plus : 1; + u8 right_red : 1; + u8 ltt5 : 1; + + u8 left_blue : 1; + u8 : 1; + u8 right_green : 1; + u8 euphoria : 1; + u8 left_green : 1; + u8 right_blue : 1; + u8 : 1; + u8 : 1; + }; + } bt; +}; + +struct wiimote_extension_data_format_guitar_t { + u8 : 2; // byte 0 + u8 sx : 6; + + u8 : 2; + u8 sy : 6; // byte 1 + + u8 : 3; // byte 2 + u8 tb : 5; + + u8 : 3; // byte 3 + u8 wb : 5; + + union { // byte 4, 5 + u16 hex; + struct { + u8 : 1; + u8 strum_down : 1; + u8 : 1; + u8 minus : 1; + u8 : 1; + u8 plus : 1; + u8 : 1; + u8 : 1; + + u8 orange : 1; + u8 red : 1; + u8 blue : 1; + u8 green : 1; + u8 yellow : 1; + u8 : 1; + u8 : 1; + u8 strum_up : 1; + }; + } bt; +}; + +struct wiimote_extension_data_format_drum_t { + bool : 1; // byte 0 + bool : 1; + u8 sx : 6; + + bool : 1; // byte 1 + bool : 1; + u8 sy : 6; + + bool hhp : 1; // byte 2 + bool has_velocity : 1; + u8 velocity_type : 5; + u8 : 1; + + u8 velocity : 3; // byte 3 + u8 extra : 4; // needs to be set to 0b0110 + u8 : 1; + + union { // byte 4, 5 + u16 hex; + struct { + u8 : 3; + u8 minus : 1; + u8 : 1; + u8 plus : 1; + u8 : 2; + + u8 orange : 1; + u8 red : 1; + u8 blue : 1; + u8 green : 1; + u8 yellow : 1; + u8 kick : 1; + u8 : 2; + }; + } bt; +}; + union wiimote_extension_data_t { struct wiimote_extension_data_format_nunchuk_t nunchuk; struct wiimote_extension_data_format_classic_t classic; + struct wiimote_extension_data_format_guitar_t guitar; + struct wiimote_extension_data_format_drum_t drum; + struct wiimote_extension_data_format_turntable_t turntable; }; static_assert(sizeof(union wiimote_extension_data_t) <= CONTROLLER_DATA_BYTES); @@ -373,6 +530,8 @@ static const u8 EXT_ID_CODE_NUNCHUNK[6] = {0x00, 0x00, 0xa4, 0x20, 0x00, 0x00} static const u8 EXP_ID_CODE_CLASSIC_CONTROLLER[6] = {0x00, 0x00, 0xa4, 0x20, 0x01, 0x01}; static const u8 EXP_ID_CODE_CLASSIC_WIIU_PRO[6] = {0x00, 0x00, 0xa4, 0x20, 0x01, 0x20}; static const u8 EXP_ID_CODE_GUITAR[6] = {0x00, 0x00, 0xa4, 0x20, 0x01, 0x03}; +static const u8 EXP_ID_CODE_DRUM[6] = {0x01, 0x00, 0xa4, 0x20, 0x01, 0x03}; +static const u8 EXP_ID_CODE_TURNTABLE[6] = {0x03, 0x00, 0xa4, 0x20, 0x01, 0x03}; static const u8 EXP_ID_CODE_MOTION_PLUS[6] = {0x00, 0x00, 0xA6, 0x20, 0x00, 0x05}; /* EEPROM */ diff --git a/source/button_map.c b/source/button_map.c index 6af66ea..6c52b00 100644 --- a/source/button_map.c +++ b/source/button_map.c @@ -71,6 +71,80 @@ void bm_map_classic( bm_classic_format(classic, classic_buttons, classic_analog_axis); } +void bm_map_guitar( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *guitar_button_map, + const u8 *guitar_analog_axis_map, + /* Outputs */ + struct wiimote_extension_data_format_guitar_t *guitar) +{ + u16 guitar_buttons = 0; + u8 guitar_analog_axis[BM_GUITAR_ANALOG_AXIS__NUM] = {0}; + + for (int i = 0; i < num_buttons; i++) { + if (buttons & 1) + guitar_buttons |= guitar_button_map[i]; + buttons >>= 1; + } + + for (int i = 0; i < num_analog_axis; i++) { + if (guitar_analog_axis_map[i]) + guitar_analog_axis[guitar_analog_axis_map[i] - 1] = analog_axis[i]; + } + + bm_guitar_format(guitar, guitar_buttons, guitar_analog_axis); +} + +void bm_map_turntable( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *turntable_button_map, + const u8 *turntable_analog_axis_map, + /* Outputs */ + struct wiimote_extension_data_format_turntable_t *turntable) +{ + u16 turntable_buttons = 0; + u8 turntable_analog_axis[BM_TURNTABLE_ANALOG_AXIS__NUM] = {0}; + + for (int i = 0; i < num_buttons; i++) { + if (buttons & 1) + turntable_buttons |= turntable_button_map[i]; + buttons >>= 1; + } + + for (int i = 0; i < num_analog_axis; i++) { + if (turntable_analog_axis_map[i]) + turntable_analog_axis[turntable_analog_axis_map[i] - 1] = analog_axis[i]; + } + + bm_turntable_format(turntable, turntable_buttons, turntable_analog_axis); +} + +void bm_map_drum( + /* Inputs */ + int num_buttons, u32 buttons, + int num_analog_axis, const u8 *analog_axis, + /* Mapping tables */ + const u16 *drum_button_map, + /* Outputs */ + struct wiimote_extension_data_format_drum_t *guitar) +{ + u16 drum_buttons = 0; + + for (int i = 0; i < num_buttons; i++) { + if (buttons & 1) + drum_buttons |= drum_button_map[i]; + buttons >>= 1; + } + + bm_drum_format(guitar, drum_buttons, analog_axis); +} + static inline void map_ir_dot(struct ir_dot_t ir_dots[static IR_MAX_DOTS], const struct ir_dot_t *dot) { s16 vert_offset = g_sensor_bar_position_top ? IR_VERTICAL_OFFSET : -IR_VERTICAL_OFFSET; diff --git a/source/fake_wiimote.c b/source/fake_wiimote.c index aba90ab..6d3d56c 100644 --- a/source/fake_wiimote.c +++ b/source/fake_wiimote.c @@ -205,6 +205,12 @@ static inline void fake_wiimote_reset_extension_state(fake_wiimote_t *wiimote) case WIIMOTE_EXT_GUITAR: id_code = EXP_ID_CODE_GUITAR; break; + case WIIMOTE_EXT_DRUM: + id_code = EXP_ID_CODE_DRUM; + break; + case WIIMOTE_EXT_TURNTABLE: + id_code = EXP_ID_CODE_TURNTABLE; + break; case WIIMOTE_EXT_MOTION_PLUS: id_code = EXP_ID_CODE_MOTION_PLUS; break; diff --git a/source/input_device.c b/source/input_device.c index c42ed01..692acaa 100644 --- a/source/input_device.c +++ b/source/input_device.c @@ -50,7 +50,7 @@ void input_devices_remove(input_device_t *input_device) fake_wiimote_release_input_device(wiimote); fake_wiimote_disconnect(wiimote); } - input_devices->valid = false; + input_device->valid = false; } void input_devices_tick(void) diff --git a/source/usb_driver_ds3.c b/source/usb_driver_ds3.c index 3591a0c..1cbb4ae 100644 --- a/source/usb_driver_ds3.c +++ b/source/usb_driver_ds3.c @@ -72,6 +72,112 @@ struct ds3_input_report { u16 z_gyro; } ATTRIBUTE_PACKED; +struct guitar_input_report { + u8 : 2; + u8 pedal : 1; + u8 orange : 1; + u8 blue : 1; + u8 red : 1; + u8 green : 1; + u8 yellow : 1; + + u8 : 3; + u8 ps : 1; + u8 : 2; + u8 start : 1; + u8 select : 1; + + u8 hat; + + u8 unused0; + u8 unused1; + u8 whammy_bar; + u8 tap_bar; + + u8 pressure_dpadRight_yellow; + u8 pressure_dpadLeft; + u8 pressure_dpadUp_green; + u8 pressure_dpadDown_orange; + u8 pressure_blue; + u8 pressure_red; + u8 unused2[6]; + + // Reminder that these values are 10-bit in range + u16 acc_x; + u16 acc_z; + u16 acc_y; + u16 z_gyro; + +} ATTRIBUTE_PACKED; +struct drum_input_report { + u8 : 2; + u8 kick : 1; + u8 orange : 1; + u8 yellow : 1; + u8 red : 1; + u8 green : 1; + u8 blue : 1; + + u8 : 3; + u8 ps : 1; + u8 : 2; + u8 start : 1; + u8 select : 1; + + u8 hat; + u8 unused; + u8 unused2; + u8 whammy_bar; + u8 tap_bar; + u8 pressure_yellow; + u8 pressure_red; + u8 pressure_green; + u8 pressure_blue; + u8 pressure_kick; + u8 pressure_orange; + u8 unused3[2]; + u16 unused4[4]; + +} ATTRIBUTE_PACKED; +struct turntable_input_report { + u8 : 4; + u8 triangle_euphoria : 1; + u8 circle : 1; + u8 cross : 1; + u8 square : 1; + + u8 : 3; + u8 ps : 1; + u8 : 2; + u8 start : 1; + u8 select : 1; + + u8 hat; + u8 unused; + u8 unused2; + u8 left_turn_table_velocity; + u8 right_turn_table_velocity; + u8 pressure_yellow; + u8 pressure_red; + u8 pressure_green; + u8 pressure_blue; + u8 pressure_kick; + u8 pressure_orange; + u8 unused3[2]; + u16 effects_knob; + u16 cross_fader; + u16 right_green : 1; + u16 right_red : 1; + u16 right_blue : 1; + u16 left_green : 1; + u16 left_red : 1; + u16 left_blue : 1; + u16 : 3; + u16 table_neutral : 1; + u16 : 6; + u16 : 16; + +} ATTRIBUTE_PACKED; struct ds3_rumble { u8 duration_right; u8 power_right; @@ -100,6 +206,61 @@ enum ds3_buttons_e { DS3_BUTTON__NUM }; +enum guitar_buttons_e { + GUITAR_BUTTON_YELLOW, + GUITAR_BUTTON_GREEN, + GUITAR_BUTTON_RED, + GUITAR_BUTTON_BLUE, + GUITAR_BUTTON_ORANGE, + GUITAR_BUTTON_UP, + GUITAR_BUTTON_DOWN, + GUITAR_BUTTON_LEFT, + GUITAR_BUTTON_RIGHT, + GUITAR_BUTTON_SP_PEDAL, + GUITAR_BUTTON_SELECT, + GUITAR_BUTTON_START, + GUITAR_BUTTON_PS, + GUITAR_BUTTON__NUM +}; + +enum turntable_buttons_e { + TURNTABLE_BUTTON_SQUARE, + TURNTABLE_BUTTON_CROSS, + TURNTABLE_BUTTON_CIRCLE, + TURNTABLE_BUTTON_TRIANGLE_EUPHORIA, + TURNTABLE_BUTTON_SELECT, + TURNTABLE_BUTTON_START, + TURNTABLE_BUTTON_LEFT_GREEN, + TURNTABLE_BUTTON_LEFT_RED, + TURNTABLE_BUTTON_LEFT_BLUE, + TURNTABLE_BUTTON_RIGHT_GREEN, + TURNTABLE_BUTTON_RIGHT_RED, + TURNTABLE_BUTTON_RIGHT_BLUE, + TURNTABLE_BUTTON_UP, + TURNTABLE_BUTTON_DOWN, + TURNTABLE_BUTTON_LEFT, + TURNTABLE_BUTTON_RIGHT, + TURNTABLE_BUTTON_PS, + TURNTABLE_BUTTON__NUM +}; + +enum drum_buttons_e { + DRUM_BUTTON_YELLOW, + DRUM_BUTTON_GREEN, + DRUM_BUTTON_RED, + DRUM_BUTTON_BLUE, + DRUM_BUTTON_ORANGE, + DRUM_BUTTON_UP, + DRUM_BUTTON_DOWN, + DRUM_BUTTON_LEFT, + DRUM_BUTTON_RIGHT, + DRUM_BUTTON_KICK, + DRUM_BUTTON_SELECT, + DRUM_BUTTON_START, + DRUM_BUTTON_PS, + DRUM_BUTTON__NUM +}; + enum ds3_analog_axis_e { DS3_ANALOG_AXIS_LEFT_X, DS3_ANALOG_AXIS_LEFT_Y, @@ -108,10 +269,36 @@ enum ds3_analog_axis_e { DS3_ANALOG_AXIS__NUM }; +enum guitar_analog_axis_e { + GUITAR_ANALOG_AXIS_TAP_BAR, + GUITAR_ANALOG_AXIS_WHAMMY_BAR, + GUITAR_ANALOG_AXIS__NUM +}; + +enum drum_analog_axis_e { + DRUM_ANALOG_AXIS_GREEN, + DRUM_ANALOG_AXIS_RED, + DRUM_ANALOG_AXIS_YELLOW, + DRUM_ANALOG_AXIS_BLUE, + DRUM_ANALOG_AXIS_ORANGE, + DRUM_ANALOG_AXIS_KICK, + DRUM_ANALOG_AXIS__NUM +}; + +enum turntable_analog_axis_e { + TURNTABLE_ANALOG_AXIS_LEFT_VELOCITY, + TURNTABLE_ANALOG_AXIS_RIGHT_VELOCITY, + TURNTABLE_ANALOG_AXIS_CROSS_FADER, + TURNTABLE_ANALOG_AXIS_EFFECTS_KNOB, + TURNTABLE_ANALOG_AXIS__NUM +}; + +#define MAX_ANALOG_AXIS DRUM_ANALOG_AXIS__NUM + struct ds3_private_data_t { struct { u32 buttons; - u8 analog_axis[DS3_ANALOG_AXIS__NUM]; + u8 analog_axis[MAX_ANALOG_AXIS]; s16 acc_x, acc_y, acc_z; } input; enum bm_ir_emulation_mode_e ir_emu_mode; @@ -188,6 +375,82 @@ static const struct { }, }; +static const struct { + u16 wiimote_button_map[TURNTABLE_BUTTON__NUM]; + u16 turntable_button_map[TURNTABLE_BUTTON__NUM]; + u8 turntable_analog_axis_map[TURNTABLE_ANALOG_AXIS__NUM]; +} turntable_mapping = + { + .wiimote_button_map = { + [TURNTABLE_BUTTON_PS] = WIIMOTE_BUTTON_HOME, + }, + .turntable_analog_axis_map = { + [TURNTABLE_ANALOG_AXIS_LEFT_VELOCITY] = BM_TURNTABLE_ANALOG_LEFT_TURNTABLE_VELOCITY, + [TURNTABLE_ANALOG_AXIS_RIGHT_VELOCITY] = BM_TURNTABLE_ANALOG_RIGHT_TURNTABLE_VELOCITY, + [TURNTABLE_ANALOG_AXIS_CROSS_FADER] = BM_TURNTABLE_ANALOG_CROSS_FADER, + [TURNTABLE_ANALOG_AXIS_EFFECTS_KNOB] = BM_TURNTABLE_ANALOG_EFFECTS_DIAL, + }, + .turntable_button_map = { + [TURNTABLE_BUTTON_LEFT_GREEN] = TURNTABLE_CTRL_BUTTON_LEFT_GREEN, + [TURNTABLE_BUTTON_LEFT_RED] = TURNTABLE_CTRL_BUTTON_LEFT_RED, + [TURNTABLE_BUTTON_LEFT_BLUE] = TURNTABLE_CTRL_BUTTON_LEFT_BLUE, + [TURNTABLE_BUTTON_RIGHT_GREEN] = TURNTABLE_CTRL_BUTTON_RIGHT_GREEN, + [TURNTABLE_BUTTON_RIGHT_RED] = TURNTABLE_CTRL_BUTTON_RIGHT_RED, + [TURNTABLE_BUTTON_RIGHT_BLUE] = TURNTABLE_CTRL_BUTTON_RIGHT_BLUE, + [TURNTABLE_BUTTON_CROSS] = TURNTABLE_CTRL_BUTTON_LEFT_GREEN | TURNTABLE_CTRL_BUTTON_RIGHT_GREEN, + [TURNTABLE_BUTTON_CIRCLE] = TURNTABLE_CTRL_BUTTON_LEFT_RED | TURNTABLE_CTRL_BUTTON_RIGHT_RED, + [TURNTABLE_BUTTON_SQUARE] = TURNTABLE_CTRL_BUTTON_LEFT_BLUE | TURNTABLE_CTRL_BUTTON_RIGHT_BLUE, + [TURNTABLE_BUTTON_START] = TURNTABLE_CTRL_BUTTON_PLUS, + [TURNTABLE_BUTTON_SELECT] = TURNTABLE_CTRL_BUTTON_MINUS, + }}; + +static const struct { + u16 wiimote_button_map[GUITAR_BUTTON__NUM]; + u16 guitar_button_map[GUITAR_BUTTON__NUM]; + u8 guitar_analog_axis_map[GUITAR_ANALOG_AXIS__NUM]; +} guitar_mapping = + { + .wiimote_button_map = { + [GUITAR_BUTTON_PS] = WIIMOTE_BUTTON_HOME, + }, + .guitar_analog_axis_map = { + [GUITAR_ANALOG_AXIS_TAP_BAR] = BM_GUITAR_ANALOG_AXIS_TAP_BAR, + [GUITAR_ANALOG_AXIS_WHAMMY_BAR] = BM_GUITAR_ANALOG_AXIS_WHAMMY_BAR, + }, + .guitar_button_map = { + [GUITAR_BUTTON_YELLOW] = GUITAR_CTRL_BUTTON_YELLOW, + [GUITAR_BUTTON_RED] = GUITAR_CTRL_BUTTON_RED, + [GUITAR_BUTTON_GREEN] = GUITAR_CTRL_BUTTON_GREEN, + [GUITAR_BUTTON_BLUE] = GUITAR_CTRL_BUTTON_BLUE, + [GUITAR_BUTTON_ORANGE] = GUITAR_CTRL_BUTTON_ORANGE, + [GUITAR_BUTTON_UP] = GUITAR_CTRL_BUTTON_STRUM_UP, + [GUITAR_BUTTON_DOWN] = GUITAR_CTRL_BUTTON_STRUM_DOWN, + [GUITAR_BUTTON_START] = GUITAR_CTRL_BUTTON_PLUS, + [GUITAR_BUTTON_SELECT] = GUITAR_CTRL_BUTTON_MINUS, + }}; + +static const struct { + u16 wiimote_button_map[DRUM_BUTTON__NUM]; + u16 drum_button_map[DRUM_BUTTON__NUM]; +} drum_mapping = + { + .wiimote_button_map = { + [DRUM_BUTTON_PS] = WIIMOTE_BUTTON_HOME, + }, + .drum_button_map = { + [DRUM_BUTTON_YELLOW] = DRUM_CTRL_BUTTON_YELLOW, + [DRUM_BUTTON_RED] = DRUM_CTRL_BUTTON_RED, + [DRUM_BUTTON_GREEN] = DRUM_CTRL_BUTTON_GREEN, + [DRUM_BUTTON_BLUE] = DRUM_CTRL_BUTTON_BLUE, + [DRUM_BUTTON_ORANGE] = DRUM_CTRL_BUTTON_ORANGE, + [DRUM_BUTTON_UP] = DRUM_CTRL_BUTTON_UP, + [DRUM_BUTTON_DOWN] = DRUM_CTRL_BUTTON_DOWN, + [DRUM_BUTTON_LEFT] = DRUM_CTRL_BUTTON_LEFT, + [DRUM_BUTTON_RIGHT] = DRUM_CTRL_BUTTON_RIGHT, + [DRUM_BUTTON_START] = DRUM_CTRL_BUTTON_PLUS, + [DRUM_BUTTON_SELECT] = DRUM_CTRL_BUTTON_MINUS, + }}; + static const u8 ir_analog_axis_map[DS3_ANALOG_AXIS__NUM] = { [DS3_ANALOG_AXIS_RIGHT_X] = BM_IR_AXIS_X, [DS3_ANALOG_AXIS_RIGHT_Y] = BM_IR_AXIS_Y, @@ -229,6 +492,109 @@ static inline void ds3_get_buttons(const struct ds3_input_report *report, u32 *b *buttons = mask; } +static inline void guitar_get_buttons(const struct guitar_input_report *report, u32 *buttons) { + u32 mask = 0; + +#define MAP(field, button) \ + if (report->field) \ + mask |= BIT(button); + + MAP(green, GUITAR_BUTTON_GREEN) + MAP(red, GUITAR_BUTTON_RED) + MAP(yellow, GUITAR_BUTTON_YELLOW) + MAP(blue, GUITAR_BUTTON_BLUE) + MAP(orange, GUITAR_BUTTON_ORANGE) + MAP(start, GUITAR_BUTTON_START) + MAP(select, GUITAR_BUTTON_SELECT) + MAP(pedal, GUITAR_BUTTON_SP_PEDAL) + MAP(ps, GUITAR_BUTTON_PS) +#undef MAP + if (report->hat == 0 || report->hat == 1 || report->hat == 7) { + mask |= BIT(GUITAR_BUTTON_UP); + } + if (report->hat == 1 || report->hat == 2 || report->hat == 3) { + mask |= BIT(GUITAR_BUTTON_LEFT); + } + if (report->hat == 3 || report->hat == 4 || report->hat == 5) { + mask |= BIT(GUITAR_BUTTON_DOWN); + } + if (report->hat == 5 || report->hat == 6 || report->hat == 7) { + mask |= BIT(GUITAR_BUTTON_RIGHT); + } + + *buttons = mask; +} + +static inline void drum_get_buttons(const struct drum_input_report *report, u32 *buttons) { + u32 mask = 0; + +#define MAP(field, button) \ + if (report->field) \ + mask |= BIT(button); + + MAP(green, DRUM_BUTTON_GREEN) + MAP(red, DRUM_BUTTON_RED) + MAP(yellow, DRUM_BUTTON_YELLOW) + MAP(blue, DRUM_BUTTON_BLUE) + MAP(orange, DRUM_BUTTON_ORANGE) + MAP(start, DRUM_BUTTON_START) + MAP(select, DRUM_BUTTON_SELECT) + MAP(kick, DRUM_BUTTON_KICK) + MAP(ps, DRUM_BUTTON_PS) +#undef MAP + if (report->hat == 0 || report->hat == 1 || report->hat == 7) { + mask |= BIT(DRUM_BUTTON_UP); + } + if (report->hat == 1 || report->hat == 2 || report->hat == 3) { + mask |= BIT(DRUM_BUTTON_LEFT); + } + if (report->hat == 3 || report->hat == 4 || report->hat == 5) { + mask |= BIT(DRUM_BUTTON_DOWN); + } + if (report->hat == 5 || report->hat == 6 || report->hat == 7) { + mask |= BIT(DRUM_BUTTON_RIGHT); + } + + *buttons = mask; +} + +static inline void turntable_get_buttons(const struct turntable_input_report *report, u32 *buttons) { + u32 mask = 0; + +#define MAP(field, button) \ + if (report->field) \ + mask |= BIT(button); + + MAP(left_green, TURNTABLE_BUTTON_LEFT_GREEN) + MAP(left_red, TURNTABLE_BUTTON_LEFT_RED) + MAP(left_blue, TURNTABLE_BUTTON_LEFT_BLUE) + MAP(right_green, TURNTABLE_BUTTON_RIGHT_GREEN) + MAP(right_red, TURNTABLE_BUTTON_RIGHT_RED) + MAP(right_blue, TURNTABLE_BUTTON_RIGHT_BLUE) + MAP(cross, TURNTABLE_BUTTON_CROSS) + MAP(circle, TURNTABLE_BUTTON_CIRCLE) + MAP(square, TURNTABLE_BUTTON_SQUARE) + MAP(triangle_euphoria, TURNTABLE_BUTTON_TRIANGLE_EUPHORIA) + MAP(select, TURNTABLE_BUTTON_SELECT) + MAP(ps, TURNTABLE_BUTTON_PS) +#undef MAP + if (report->hat == 0 || report->hat == 1 || report->hat == 7) { + mask |= BIT(TURNTABLE_BUTTON_UP); + } + if (report->hat == 1 || report->hat == 2 || report->hat == 3) { + mask |= BIT(TURNTABLE_BUTTON_LEFT); + } + if (report->hat == 3 || report->hat == 4 || report->hat == 5) { + mask |= BIT(TURNTABLE_BUTTON_DOWN); + } + if (report->hat == 5 || report->hat == 6 || report->hat == 7) { + mask |= BIT(TURNTABLE_BUTTON_RIGHT); + } + + *buttons = mask; +} + + static inline void ds3_get_analog_axis(const struct ds3_input_report *report, u8 analog_axis[static DS3_ANALOG_AXIS__NUM]) { @@ -238,6 +604,30 @@ static inline void ds3_get_analog_axis(const struct ds3_input_report *report, analog_axis[DS3_ANALOG_AXIS_RIGHT_Y] = 255 - report->right_y; } +static inline void guitar_get_analog_axis(const struct guitar_input_report *report, + u8 analog_axis[static MAX_ANALOG_AXIS]) { + analog_axis[GUITAR_ANALOG_AXIS_TAP_BAR] = report->tap_bar; + analog_axis[GUITAR_ANALOG_AXIS_WHAMMY_BAR] = report->whammy_bar; +} + +static inline void drum_get_analog_axis(const struct drum_input_report *report, + u8 analog_axis[static MAX_ANALOG_AXIS]) { + analog_axis[DRUM_ANALOG_AXIS_GREEN] = report->pressure_green; + analog_axis[DRUM_ANALOG_AXIS_RED] = report->pressure_red; + analog_axis[DRUM_ANALOG_AXIS_YELLOW] = report->pressure_yellow; + analog_axis[DRUM_ANALOG_AXIS_BLUE] = report->pressure_blue; + analog_axis[DRUM_ANALOG_AXIS_ORANGE] = report->pressure_orange; + analog_axis[DRUM_ANALOG_AXIS_KICK] = report->pressure_kick; +} + +static inline void turntable_get_analog_axis(const struct turntable_input_report *report, + u8 analog_axis[static MAX_ANALOG_AXIS]) { + analog_axis[TURNTABLE_ANALOG_AXIS_CROSS_FADER] = report->cross_fader; + analog_axis[TURNTABLE_ANALOG_AXIS_EFFECTS_KNOB] = report->effects_knob; + analog_axis[TURNTABLE_ANALOG_AXIS_LEFT_VELOCITY] = report->left_turn_table_velocity; + analog_axis[TURNTABLE_ANALOG_AXIS_RIGHT_VELOCITY] = report->right_turn_table_velocity; +} + static int ds3_set_operational(usb_input_device_t *device) { u8 buf[17] ATTRIBUTE_ALIGN(32); @@ -368,9 +758,122 @@ int ds3_driver_ops_set_rumble(usb_input_device_t *device, bool rumble_on) return ds3_driver_update_leds_rumble(device); } +bool guitar_report_input(usb_input_device_t *device) { + struct ds3_private_data_t *priv = (void *)device->private_data; + u16 wiimote_buttons = 0; + u16 acc_x, acc_y, acc_z; + union wiimote_extension_data_t extension_data; + + bm_map_wiimote(GUITAR_BUTTON__NUM, priv->input.buttons, + guitar_mapping.wiimote_button_map, + &wiimote_buttons); + /* Normalize to accelerometer calibration configuration */ + acc_x = ACCEL_ZERO_G - ((s32)priv->input.acc_x * (ACCEL_ONE_G - ACCEL_ZERO_G)) / DS3_ACC_RES_PER_G; + acc_y = ACCEL_ZERO_G + ((s32)priv->input.acc_y * (ACCEL_ONE_G - ACCEL_ZERO_G)) / DS3_ACC_RES_PER_G; + acc_z = ACCEL_ZERO_G + ((s32)priv->input.acc_z * (ACCEL_ONE_G - ACCEL_ZERO_G)) / DS3_ACC_RES_PER_G; + + fake_wiimote_report_accelerometer(device->wiimote, acc_x, acc_y, acc_z); + + bm_map_guitar(GUITAR_BUTTON__NUM, priv->input.buttons, + GUITAR_ANALOG_AXIS__NUM, priv->input.analog_axis, + guitar_mapping.guitar_button_map, + guitar_mapping.guitar_analog_axis_map, + &extension_data.guitar); + fake_wiimote_report_input_ext(device->wiimote, wiimote_buttons, + &extension_data, sizeof(extension_data.guitar)); + + return true; +} + +bool drum_report_input(usb_input_device_t *device) { + struct ds3_private_data_t *priv = (void *)device->private_data; + u16 wiimote_buttons = 0; + u16 acc_x, acc_y, acc_z; + union wiimote_extension_data_t extension_data; + + bm_map_wiimote(DRUM_BUTTON__NUM, priv->input.buttons, + drum_mapping.wiimote_button_map, + &wiimote_buttons); + + /* Normalize to accelerometer calibration configuration */ + acc_x = ACCEL_ZERO_G; + acc_y = ACCEL_ZERO_G; + acc_z = ACCEL_ZERO_G; + + fake_wiimote_report_accelerometer(device->wiimote, acc_x, acc_y, acc_z); + + u8 drum_analog_axis[BM_DRUM_ANALOG_AXIS__NUM] = {0}; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_STICK_X - 1] = 128; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_STICK_Y - 1] = 128; + // Manually handle velocity here, as its pretty different between the wii and ps3 formats + if (priv->input.analog_axis[DRUM_ANALOG_AXIS_GREEN]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b10010; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_GREEN]; + } else if (priv->input.analog_axis[DRUM_ANALOG_AXIS_RED]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b11001; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_RED]; + } else if (priv->input.analog_axis[DRUM_ANALOG_AXIS_YELLOW]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b10001; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_YELLOW]; + } else if (priv->input.analog_axis[DRUM_ANALOG_AXIS_BLUE]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b01111; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_BLUE]; + } else if (priv->input.analog_axis[DRUM_ANALOG_AXIS_ORANGE]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b01110; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_ORANGE]; + } else if (priv->input.analog_axis[DRUM_ANALOG_AXIS_KICK]) { + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY_SELECTOR - 1] = 0b11011; + drum_analog_axis[BM_DRUM_ANALOG_AXIS_VELOCITY - 1] = priv->input.analog_axis[DRUM_ANALOG_AXIS_KICK]; + } + + bm_map_drum(DRUM_BUTTON__NUM, priv->input.buttons, + BM_GUITAR_ANALOG_AXIS__NUM, drum_analog_axis, + drum_mapping.drum_button_map, + &extension_data.drum); + fake_wiimote_report_input_ext(device->wiimote, wiimote_buttons, + &extension_data, sizeof(extension_data.drum)); + + return true; +} + +bool turntable_report_input(usb_input_device_t *device) { + struct ds3_private_data_t *priv = (void *)device->private_data; + u16 wiimote_buttons = 0; + u16 acc_x, acc_y, acc_z; + union wiimote_extension_data_t extension_data; + + bm_map_wiimote(TURNTABLE_BUTTON__NUM, priv->input.buttons, + guitar_mapping.wiimote_button_map, + &wiimote_buttons); + acc_x = ACCEL_ZERO_G; + acc_y = ACCEL_ZERO_G; + acc_z = ACCEL_ZERO_G; + + fake_wiimote_report_accelerometer(device->wiimote, acc_x, acc_y, acc_z); + + bm_map_turntable(TURNTABLE_BUTTON__NUM, priv->input.buttons, + TURNTABLE_ANALOG_AXIS__NUM, priv->input.analog_axis, + turntable_mapping.turntable_button_map, + turntable_mapping.turntable_analog_axis_map, + &extension_data.turntable); + fake_wiimote_report_input_ext(device->wiimote, wiimote_buttons, + &extension_data, sizeof(extension_data.turntable)); + + return true; +} + bool ds3_report_input(usb_input_device_t *device) { - struct ds3_private_data_t *priv = (void *)device->private_data; + if (device->vid == SONY_INST_VID && device->pid == GH_GUITAR_PID) { + return guitar_report_input(device); + } + if (device->vid == SONY_INST_VID && device->pid == GH_DRUM_PID) { + return drum_report_input(device); + } + if (device->vid == SONY_INST_VID && device->pid == DJ_TURNTABLE_PID) { + return turntable_report_input(device); + } + struct ds3_private_data_t *priv = (void *)device->private_data; u16 wiimote_buttons = 0; u16 acc_x, acc_y, acc_z; union wiimote_extension_data_t extension_data; @@ -435,14 +938,31 @@ bool ds3_report_input(usb_input_device_t *device) int ds3_driver_ops_usb_async_resp(usb_input_device_t *device) { struct ds3_private_data_t *priv = (void *)device->private_data; - struct ds3_input_report *report = (void *)device->usb_async_resp; - - ds3_get_buttons(report, &priv->input.buttons); - ds3_get_analog_axis(report, priv->input.analog_axis); + if (device->vid == SONY_INST_VID && device->pid == GH_GUITAR_PID) { + struct guitar_input_report *report = (void *)device->usb_async_resp; + guitar_get_buttons(report, &priv->input.buttons); + guitar_get_analog_axis(report, priv->input.analog_axis); + + priv->input.acc_x = (s16)report->acc_x - 511; + priv->input.acc_y = 511 - (s16)report->acc_y; + priv->input.acc_z = 511 - (s16)report->acc_z; + } else if (device->vid == SONY_INST_VID && device->pid == GH_DRUM_PID) { + struct drum_input_report *report = (void *)device->usb_async_resp; + drum_get_buttons(report, &priv->input.buttons); + drum_get_analog_axis(report, priv->input.analog_axis); + } else if (device->vid == SONY_INST_VID && device->pid == DJ_TURNTABLE_PID) { + struct turntable_input_report *report = (void *)device->usb_async_resp; + turntable_get_buttons(report, &priv->input.buttons); + turntable_get_analog_axis(report, priv->input.analog_axis); + } else { + struct ds3_input_report *report = (void *)device->usb_async_resp; + ds3_get_buttons(report, &priv->input.buttons); + ds3_get_analog_axis(report, priv->input.analog_axis); - priv->input.acc_x = (s16)report->acc_x - 511; - priv->input.acc_y = 511 - (s16)report->acc_y; - priv->input.acc_z = 511 - (s16)report->acc_z; + priv->input.acc_x = (s16)report->acc_x - 511; + priv->input.acc_y = 511 - (s16)report->acc_y; + priv->input.acc_z = 511 - (s16)report->acc_z; + } return ds3_request_data(device); } diff --git a/source/usb_hid.c b/source/usb_hid.c index 1e9d6ad..665ef86 100644 --- a/source/usb_hid.c +++ b/source/usb_hid.c @@ -281,7 +281,7 @@ static int usb_device_ops_resume(void *usrdata, fake_wiimote_t *wiimote) device->wiimote = wiimote; if (device->driver->init) - return device->driver->init(device, device->pid, device->vid); + return device->driver->init(device, device->vid, device->pid); return 0; }