Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PS3 Guitar Hero instruments (Guitar, Drums, Turntable) #28

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ add_executable(fakemote
source/usb_hid.c
source/usb_drivers/sony_ds3.c
source/usb_drivers/sony_ds4.c
source/usb_drivers/dj_hero_turntable.c
source/usb_drivers/guitar_hero_drums.c
source/usb_drivers/guitar_hero_guitar.c
)

target_include_directories(fakemote PRIVATE
Expand Down
119 changes: 116 additions & 3 deletions include/button_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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];
Expand All @@ -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;
Expand All @@ -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;
Expand Down
13 changes: 12 additions & 1 deletion include/usb_device_drivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
#include "usb_hid.h"

/* List of Vendor IDs */
#define SONY_VID 0x054c
#define SONY_VID 0x054c
#define SONY_INST_VID 0x12ba
#define SANTROLLER_VID 0x1209

/* List of Product IDs */
#define GH_GUITAR_PID 0x0100
#define GH_DRUM_PID 0x0120
#define DJ_TURNTABLE_PID 0x0140
#define SANTROLLER_PID 0x2882

struct device_id_t {
u16 vid;
Expand All @@ -23,5 +31,8 @@ static inline bool usb_driver_is_comaptible(u16 vid, u16 pid, const struct devic

extern const usb_device_driver_t ds3_usb_device_driver;
extern const usb_device_driver_t ds4_usb_device_driver;
extern const usb_device_driver_t gh_guitar_usb_device_driver;
extern const usb_device_driver_t gh_drum_usb_device_driver;
extern const usb_device_driver_t turntable_usb_device_driver;

#endif
2 changes: 2 additions & 0 deletions include/usb_hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ typedef struct {
/* VID and PID */
u16 vid;
u16 pid;
u16 max_packet_len;
u8 endpoint_address;
/* Used to communicate with Wii's USB module */
int host_fd;
u32 dev_id;
Expand Down
159 changes: 159 additions & 0 deletions include/wiimote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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 */
Expand Down
Loading