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

Add in support for using PS3 Guitars as PS2 Guitars in PADEMU #896

Merged
merged 8 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 64 additions & 4 deletions include/ds34common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#define USB_SUBCLASS_RF_CONTROLLER 0x01
#define USB_PROTOCOL_BLUETOOTH_PROG 0x01

#define DS34_VID 0x054C // Sony Corporation
#define DS3_PID 0x0268 // PS3 Controller
#define DS4_PID 0x05C4 // PS4 Controller
#define DS4_PID_SLIM 0x09CC // PS4 Slim Controller
#define SONY_VID 0x12ba // Sony
#define DS34_VID 0x054C // Sony Corporation
#define DS3_PID 0x0268 // PS3 Controller
#define DS4_PID 0x05C4 // PS4 Controller
#define DS4_PID_SLIM 0x09CC // PS4 Slim Controller
#define GUITAR_HERO_PS3_PID 0x0100 // PS3 Guitar Hero Guitar
#define ROCK_BAND_PS3_PID 0x0200 // PS3 Rock Band Guitar

// NOTE: struct member prefixed with "n" means it's active-low (i.e. value of 0 indicates button is pressed, value 1 is released)
enum DS2ButtonBitNumber {
Expand Down Expand Up @@ -164,6 +167,55 @@ struct ds3report

} __attribute__((packed));

struct ds3guitarreport
{
union
{
uint16_t ButtonState;
struct
{
uint8_t ButtonStateL; // Main buttons low byte
uint8_t ButtonStateH; // Main buttons high byte
};
struct
{
uint16_t Blue : 1;
uint16_t Green : 1;
uint16_t Red : 1;
uint16_t Yellow : 1;
uint16_t Orange : 1;
uint16_t StarPower : 1;
uint16_t : 1;
uint16_t : 1;
uint16_t Select : 1;
uint16_t Start : 1;
uint16_t : 1;
uint16_t : 1;
uint16_t PSButton : 1;
uint16_t : 1;
uint16_t : 1;
uint16_t : 1;
};
};
uint8_t Dpad; // hat format, 0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW
uint8_t : 8;
uint8_t : 8;
uint8_t Whammy; // Whammy axis 0 - 255, 128 is mid
uint8_t : 8;
uint8_t PressureRightYellow; // digital Pad Right + Yellow button Pressure 0 - 255 (if both are pressed, then they cancel eachother out)
uint8_t PressureLeft; // digital Pad Left button Pressure 0 - 255
uint8_t PressureUpGreen; // digital Pad Up + Green button Pressure 0 - 255 (if both are pressed, then they cancel eachother out)
uint8_t PressureDownOrange; // digital Pad Down + Orange button Pressure 0 - 255 (if both are pressed, then they cancel eachother out)
uint8_t PressureBlue; // digital Pad Blue button Pressure 0 - 255
uint8_t PressureRed; // digital Pad Red button Pressure 0 - 255
uint8_t Reserved3[6]; // Unknown
int16_t AccelX;
int16_t AccelZ;
int16_t AccelY;
int16_t GyroZ;

} __attribute__((packed));

enum DS4DpadDirections {
DS4DpadDirectionN = 0,
DS4DpadDirectionNE,
Expand Down Expand Up @@ -239,6 +291,14 @@ struct ds4report
*/
void translate_pad_ds3(const struct ds3report *in, struct ds2report *out, uint8_t pressure_emu);

/**
* Translate PS3 Guitar pad data into DS2 Guitar pad data.
* @param in PS3 Guitar report
* @param out PS2 Guitar report
* @param guitar_hero_format set to 1 if this is a guitar hero guitar, set to 0 if this is a rock band guitar
*/
void translate_pad_guitar(const struct ds3guitarreport *in, struct ds2report *out, uint8_t guitar_hero_format);

/**
* Translate DS3 pad data into DS2 pad data.
* @param in DS4 report
Expand Down
38 changes: 38 additions & 0 deletions modules/pademu/ds34common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,44 @@
#include "loadcore.h"
#include "sysclib.h"

void translate_pad_guitar(const struct ds3guitarreport *in, struct ds2report *out, uint8_t guitar_hero_format)
{
out->RightStickX = 0x7F;
out->RightStickY = 0x7F;
out->LeftStickX = 0x7F;
out->LeftStickY = -(in->Whammy);

static const u8 dpad_mapping[] = {
(DS2ButtonUp),
(DS2ButtonUp | DS2ButtonRight),
(DS2ButtonRight),
(DS2ButtonDown | DS2ButtonRight),
(DS2ButtonDown),
(DS2ButtonDown | DS2ButtonLeft),
(DS2ButtonLeft),
(DS2ButtonUp | DS2ButtonLeft),
0,
};

u8 dpad = in->Dpad > DS4DpadDirectionReleased ? DS4DpadDirectionReleased : in->Dpad;

out->nButtonStateL = ~(in->Select | in->Start << 3 | dpad_mapping[dpad]);

out->nLeft = 0;
out->nL2 = 1;

if (guitar_hero_format) {
// GH PS3 Guitars swap Yellow and Blue
// Interestingly, it is only GH PS3 Guitars that do this, all the other instruments including GH Drums don't have this swapped.
out->nButtonStateH = ~(in->Green << 1 | in->Blue << 4 | in->Red << 5 | in->Yellow << 6 | in->Orange << 7);
if (in->AccelX > 512 || in->AccelX < 432) {
out->nL2 = 0;
}
} else {
out->nButtonStateH = ~(in->StarPower | in->Green << 1 | in->Yellow << 4 | in->Red << 5 | in->Blue << 6 | in->Orange << 7);
}
}

void translate_pad_ds3(const struct ds3report *in, struct ds2report *out, u8 pressure_emu)
{
out->nButtonStateL = ~in->ButtonStateL;
Expand Down
36 changes: 34 additions & 2 deletions modules/pademu/ds34usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "sys_utils.h"
#include "padmacro.h"

//#define DPRINTF(x...) printf(x)
// #define DPRINTF(x...) printf(x)
#define DPRINTF(x...)

#define REQ_USB_OUT (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
Expand Down Expand Up @@ -83,6 +83,10 @@ int usb_probe(int devId)
return 0;
}

if (device->idVendor == SONY_VID && (device->idProduct == GUITAR_HERO_PS3_PID || device->idProduct == ROCK_BAND_PS3_PID)) {
return 1;
}

if (device->idVendor == DS34_VID && (device->idProduct == DS3_PID || device->idProduct == DS4_PID || device->idProduct == DS4_PID_SLIM))
return 1;

Expand Down Expand Up @@ -124,6 +128,12 @@ int usb_connect(int devId)
if (device->idProduct == DS3_PID) {
ds34pad[pad].type = DS3;
epCount = interface->bNumEndpoints - 1;
} else if (device->idProduct == GUITAR_HERO_PS3_PID) {
ds34pad[pad].type = GUITAR_GH;
epCount = interface->bNumEndpoints - 1;
} else if (device->idProduct == ROCK_BAND_PS3_PID) {
ds34pad[pad].type = GUITAR_RB;
epCount = interface->bNumEndpoints - 1;
} else {
ds34pad[pad].type = DS4;
epCount = 20; // ds4 v2 returns interface->bNumEndpoints as 0
Expand Down Expand Up @@ -261,6 +271,14 @@ static void DS3USB_init(int pad)
static void readReport(u8 *data, int pad_idx)
{
ds34usb_device *pad = &ds34pad[pad_idx];
if (pad->type == GUITAR_GH || pad->type == GUITAR_RB) {
struct ds3guitarreport *report;

report = (struct ds3guitarreport *)data;

translate_pad_guitar(report, &pad->ds2, pad->type == GUITAR_GH);
padMacroPerform(&pad->ds2, report->PSButton);
}
if (data[0]) {

if (pad->type == DS3) {
Expand All @@ -276,7 +294,6 @@ static void readReport(u8 *data, int pad_idx)

translate_pad_ds3(report, &pad->ds2, 0);
padMacroPerform(&pad->ds2, report->PSButton);

if (report->PSButton) { // display battery level
if (report->Select && (pad->btn_delay == MAX_DELAY)) { // PS + SELECT
if (pad->analog_btn < 2) // unlocked mode
Expand Down Expand Up @@ -497,6 +514,21 @@ int ds34usb_get_status(int port)
return ret;
}

int ds34usb_get_model(int port)
{
int ret;

WaitSema(ds34pad[port].sema);
if (ds34pad[port].type == GUITAR_GH || ds34pad[port].type == GUITAR_RB) {
ret = MODEL_GUITAR;
} else {
ret = MODEL_PS2;
}
SignalSema(ds34pad[port].sema);

return ret;
}

int ds34usb_init(u8 pads, u8 options)
{
int pad;
Expand Down
12 changes: 9 additions & 3 deletions modules/pademu/ds34usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@

#include <ds34common.h>

#define DS3 0
#define DS4 1
#define DS3 0
#define DS4 1
#define GUITAR_GH 2
#define GUITAR_RB 3

#define MODEL_GUITAR 1
#define MODEL_PS2 3

#define MAX_BUFFER_SIZE 64 // Size of general purpose data buffer

Expand All @@ -20,7 +25,7 @@ typedef struct _usb_ds34
int outEndp;
u8 enabled;
u8 status;
u8 type; // 0 - ds3, 1 - ds4
u8 type; // 0 - ds3, 1 - ds4, 2 - guitar hero guitar, 3 - rock band guitar
u8 oldled[4]; // rgb for ds4 and blink
u8 lrum;
u8 rrum;
Expand Down Expand Up @@ -70,6 +75,7 @@ enum eHID {

int ds34usb_init(u8 pads, u8 options);
int ds34usb_get_status(int port);
int ds34usb_get_model(int port);
void ds34usb_reset();
int ds34usb_get_data(u8 *dst, int size, int port);
void ds34usb_set_rumble(u8 lrum, u8 rrum, int port);
Expand Down
15 changes: 9 additions & 6 deletions modules/pademu/pademu.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@

#include "ds34bt.h"

#define PAD_INIT ds34bt_init
#define PAD_GET_STATUS ds34bt_get_status
#define PAD_RESET ds34bt_reset
#define PAD_GET_DATA ds34bt_get_data
#define PAD_SET_RUMBLE ds34bt_set_rumble
#define PAD_SET_MODE ds34bt_set_mode
#define PAD_INIT ds34bt_init
#define PAD_GET_STATUS ds34bt_get_status
#define PAD_RESET ds34bt_reset
#define PAD_GET_DATA ds34bt_get_data
#define PAD_SET_RUMBLE ds34bt_set_rumble
#define PAD_SET_MODE ds34bt_set_mode
#define PAD_GET_MODEL(port) 3

#elif defined(USB)

Expand All @@ -28,6 +29,7 @@
#define PAD_GET_STATUS ds34usb_get_status
#define PAD_RESET ds34usb_reset
#define PAD_GET_DATA ds34usb_get_data
#define PAD_GET_MODEL ds34usb_get_model
#define PAD_SET_RUMBLE ds34usb_set_rumble
#define PAD_SET_MODE ds34usb_set_mode

Expand Down Expand Up @@ -463,6 +465,7 @@ void pademu_cmd(int port, u8 *in, u8 *out, u8 out_size)
case 0x45: // query model and mode
mips_memcpy(&out[3], &pademu_data[1], 6);
out[5] = pad[port].mode;
out[3] = PAD_GET_MODEL(port);
break;

case 0x46: // query act
Expand Down