bluetooth-mitm: store mapped controller state per-controller

This commit is contained in:
ndeadly 2020-10-03 17:22:21 +02:00
parent 7685b4024e
commit b21806c8c5
26 changed files with 542 additions and 539 deletions

View file

@ -19,48 +19,54 @@
namespace ams::controller {
void EightBitDoController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto eightbitdo_report = reinterpret_cast<const EightBitDoReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void EightBitDoController::UpdateControllerState(const bluetooth::HidReport *report) {
auto eightbitdo_report = reinterpret_cast<const EightBitDoReportData *>(&report->data);
switch(eightbitdo_report->id) {
case 0x01:
this->HandleInputReport0x01(eightbitdo_report, switch_report);
this->HandleInputReport0x01(eightbitdo_report);
break;
case 0x03:
this->HandleInputReport0x03(eightbitdo_report, switch_report);
this->HandleInputReport0x03(eightbitdo_report);
break;
default:
break;
}
}
void EightBitDoController::HandleInputReport0x01(const EightBitDoReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.dpad_down = (src->input0x01.dpad == EightBitDoDPad_S) ||
void EightBitDoController::HandleInputReport0x01(const EightBitDoReportData *src) {
m_buttons.dpad_down = (src->input0x01.dpad == EightBitDoDPad_S) ||
(src->input0x01.dpad == EightBitDoDPad_SE) ||
(src->input0x01.dpad == EightBitDoDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x01.dpad == EightBitDoDPad_N) ||
m_buttons.dpad_up = (src->input0x01.dpad == EightBitDoDPad_N) ||
(src->input0x01.dpad == EightBitDoDPad_NE) ||
(src->input0x01.dpad == EightBitDoDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x01.dpad == EightBitDoDPad_E) ||
m_buttons.dpad_right = (src->input0x01.dpad == EightBitDoDPad_E) ||
(src->input0x01.dpad == EightBitDoDPad_NE) ||
(src->input0x01.dpad == EightBitDoDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x01.dpad == EightBitDoDPad_W) ||
m_buttons.dpad_left = (src->input0x01.dpad == EightBitDoDPad_W) ||
(src->input0x01.dpad == EightBitDoDPad_NW) ||
(src->input0x01.dpad == EightBitDoDPad_SW);
}
void EightBitDoController::HandleInputReport0x03(const EightBitDoReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.A = src->input0x03.buttons.B;
dst->input0x30.buttons.B = src->input0x03.buttons.A;
dst->input0x30.buttons.X = src->input0x03.buttons.Y;
dst->input0x30.buttons.Y = src->input0x03.buttons.X;
void EightBitDoController::HandleInputReport0x03(const EightBitDoReportData *src) {
m_buttons.A = src->input0x03.buttons.B;
m_buttons.B = src->input0x03.buttons.A;
m_buttons.X = src->input0x03.buttons.Y;
m_buttons.Y = src->input0x03.buttons.X;
dst->input0x30.buttons.R = src->input0x03.buttons.R;
dst->input0x30.buttons.L = src->input0x03.buttons.L;
m_buttons.R = src->input0x03.buttons.R;
m_buttons.L = src->input0x03.buttons.L;
dst->input0x30.buttons.minus = src->input0x03.buttons.select;
dst->input0x30.buttons.plus = src->input0x03.buttons.start;
m_buttons.minus = src->input0x03.buttons.select;
m_buttons.plus = src->input0x03.buttons.start;
// Home combo
m_buttons.home = m_buttons.minus && m_buttons.dpad_down;
if (m_buttons.home) {
m_buttons.minus = 0;
m_buttons.dpad_down = 0;
}
}
}

View file

@ -84,11 +84,11 @@ namespace ams::controller {
EightBitDoController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const EightBitDoReportData *src, SwitchReportData *dst);
void HandleInputReport0x03(const EightBitDoReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const EightBitDoReportData *src);
void HandleInputReport0x03(const EightBitDoReportData *src);
};

View file

@ -53,36 +53,35 @@ namespace ams::controller {
return this->UpdateControllerState();
}
void Dualshock4Controller::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto ds4_report = reinterpret_cast<const Dualshock4ReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void Dualshock4Controller::UpdateControllerState(const bluetooth::HidReport *report) {
auto ds4_report = reinterpret_cast<const Dualshock4ReportData *>(&report->data);
switch(ds4_report->id) {
case 0x01:
this->HandleInputReport0x01(ds4_report, switch_report);
this->HandleInputReport0x01(ds4_report);
break;
case 0x11:
this->HandleInputReport0x11(ds4_report, switch_report);
this->HandleInputReport0x11(ds4_report);
break;
default:
break;
}
}
void Dualshock4Controller::HandleInputReport0x01(const Dualshock4ReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void Dualshock4Controller::HandleInputReport0x01(const Dualshock4ReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
);
this->MapButtons(&src->input0x01.buttons, dst);
this->MapButtons(&src->input0x01.buttons);
}
void Dualshock4Controller::HandleInputReport0x11(const Dualshock4ReportData *src, SwitchReportData *dst) {
void Dualshock4Controller::HandleInputReport0x11(const Dualshock4ReportData *src) {
if (!src->input0x11.usb || src->input0x11.battery_level > 10)
m_charging = false;
else
@ -96,50 +95,50 @@ namespace ams::controller {
m_battery = static_cast<uint8_t>(8 * (battery_level + 1) / 10) & 0x0e;
this->PackStickData(&dst->input0x30.left_stick,
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x11.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x11.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x11.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x11.right_stick.y)) & 0xfff
);
this->MapButtons(&src->input0x11.buttons, dst);
this->MapButtons(&src->input0x11.buttons);
}
void Dualshock4Controller::MapButtons(const Dualshock4ButtonData *buttons, SwitchReportData *dst) {
dst->input0x30.buttons.dpad_down = (buttons->dpad == Dualshock4DPad_S) ||
void Dualshock4Controller::MapButtons(const Dualshock4ButtonData *buttons) {
m_buttons.dpad_down = (buttons->dpad == Dualshock4DPad_S) ||
(buttons->dpad == Dualshock4DPad_SE) ||
(buttons->dpad == Dualshock4DPad_SW);
dst->input0x30.buttons.dpad_up = (buttons->dpad == Dualshock4DPad_N) ||
m_buttons.dpad_up = (buttons->dpad == Dualshock4DPad_N) ||
(buttons->dpad == Dualshock4DPad_NE) ||
(buttons->dpad == Dualshock4DPad_NW);
dst->input0x30.buttons.dpad_right = (buttons->dpad == Dualshock4DPad_E) ||
m_buttons.dpad_right = (buttons->dpad == Dualshock4DPad_E) ||
(buttons->dpad == Dualshock4DPad_NE) ||
(buttons->dpad == Dualshock4DPad_SE);
dst->input0x30.buttons.dpad_left = (buttons->dpad == Dualshock4DPad_W) ||
m_buttons.dpad_left = (buttons->dpad == Dualshock4DPad_W) ||
(buttons->dpad == Dualshock4DPad_NW) ||
(buttons->dpad == Dualshock4DPad_SW);
dst->input0x30.buttons.A = buttons->circle;
dst->input0x30.buttons.B = buttons->cross;
dst->input0x30.buttons.X = buttons->triangle;
dst->input0x30.buttons.Y = buttons->square;
m_buttons.A = buttons->circle;
m_buttons.B = buttons->cross;
m_buttons.X = buttons->triangle;
m_buttons.Y = buttons->square;
dst->input0x30.buttons.R = buttons->R1;
dst->input0x30.buttons.ZR = buttons->R2;
dst->input0x30.buttons.L = buttons->L1;
dst->input0x30.buttons.ZL = buttons->L2;
m_buttons.R = buttons->R1;
m_buttons.ZR = buttons->R2;
m_buttons.L = buttons->L1;
m_buttons.ZL = buttons->L2;
dst->input0x30.buttons.minus = buttons->share;
dst->input0x30.buttons.plus = buttons->options;
m_buttons.minus = buttons->share;
m_buttons.plus = buttons->options;
dst->input0x30.buttons.lstick_press = buttons->L3;
dst->input0x30.buttons.rstick_press = buttons->R3;
m_buttons.lstick_press = buttons->L3;
m_buttons.rstick_press = buttons->R3;
dst->input0x30.buttons.capture = buttons->tpad;
dst->input0x30.buttons.home = buttons->ps;
m_buttons.capture = buttons->tpad;
m_buttons.home = buttons->ps;
}
Result Dualshock4Controller::UpdateControllerState(void) {
@ -149,9 +148,7 @@ namespace ams::controller {
s_output_report.size = sizeof(report) - 1;
std::memcpy(s_output_report.data, &report.data[1], s_output_report.size);
R_TRY(bluetooth::hid::report::SendHidReport(&m_address, &s_output_report));
return ams::ResultSuccess();
return bluetooth::hid::report::SendHidReport(&m_address, &s_output_report);
}
}

View file

@ -137,13 +137,13 @@ namespace ams::controller {
Result SetPlayerLed(uint8_t led_mask);
Result SetLightbarColour(Dualshock4LedColour colour);
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const Dualshock4ReportData *src, SwitchReportData *dst);
void HandleInputReport0x11(const Dualshock4ReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const Dualshock4ReportData *src);
void HandleInputReport0x11(const Dualshock4ReportData *src);
void MapButtons(const Dualshock4ButtonData *buttons, SwitchReportData *dst);
void MapButtons(const Dualshock4ButtonData *buttons);
Result UpdateControllerState(void);
Dualshock4LedColour m_led_colour;

View file

@ -22,17 +22,30 @@ namespace ams::controller {
bluetooth::HidReport EmulatedSwitchController::s_input_report;
bluetooth::HidReport EmulatedSwitchController::s_output_report;
EmulatedSwitchController::EmulatedSwitchController(const bluetooth::Address *address)
: SwitchController(address)
, m_charging(false)
, m_battery(BATTERY_MAX) {
std::memset(&m_buttons, 0, sizeof(m_buttons));
this->PackStickData(&m_left_stick, STICK_ZERO, STICK_ZERO);
this->PackStickData(&m_right_stick, STICK_ZERO, STICK_ZERO);
std::memset(&m_motion_data, 0, sizeof(m_motion_data));
};
Result EmulatedSwitchController::HandleIncomingReport(const bluetooth::HidReport *report) {
// Update controller state
this->UpdateControllerState(report);
// Prepare Switch report
auto switch_report = reinterpret_cast<SwitchReportData *>(s_input_report.data);
s_input_report.size = sizeof(SwitchInputReport0x30) + 1;
switch_report->id = 0x30;
switch_report->input0x30.conn_info = 0x0;
switch_report->input0x30.battery = m_battery | m_charging;
std::memset(&switch_report->input0x30.buttons, 0, sizeof(switch_report->input0x30.buttons));
this->PackStickData(&switch_report->input0x30.left_stick, STICK_ZERO, STICK_ZERO);
this->PackStickData(&switch_report->input0x30.right_stick, STICK_ZERO, STICK_ZERO);
std::memset(&switch_report->input0x30.motion, 0, sizeof(switch_report->input0x30.motion));
this->ConvertReportFormat(report, &s_input_report);
switch_report->input0x30.buttons = m_buttons;
switch_report->input0x30.left_stick = m_left_stick;
switch_report->input0x30.right_stick = m_right_stick;
std::memcpy(&switch_report->input0x30.motion, &m_motion_data, sizeof(m_motion_data));
switch_report->input0x30.timer = os::ConvertToTimeSpan(os::GetSystemTick()).GetMilliSeconds() & 0xff;
return bluetooth::hid::report::WriteHidReportBuffer(&m_address, &s_input_report);

View file

@ -22,16 +22,13 @@ namespace ams::controller {
class EmulatedSwitchController : public SwitchController {
public:
EmulatedSwitchController(const bluetooth::Address *address)
: SwitchController(address)
, m_charging(false)
, m_battery(BATTERY_MAX) { };
EmulatedSwitchController(const bluetooth::Address *address);
Result HandleIncomingReport(const bluetooth::HidReport *report);
Result HandleOutgoingReport(const bluetooth::HidReport *report);
protected:
virtual void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {};
virtual void UpdateControllerState(const bluetooth::HidReport *report) {};
virtual Result SetVibration(void) { return ams::ResultSuccess(); };
virtual Result SetPlayerLed(uint8_t led_mask) { return ams::ResultSuccess(); };
@ -63,6 +60,10 @@ namespace ams::controller {
bool m_charging;
uint8_t m_battery;
SwitchButtonData m_buttons;
SwitchStickData m_left_stick;
SwitchStickData m_right_stick;
Switch6AxisData m_motion_data[3];
static bluetooth::HidReport s_input_report;
static bluetooth::HidReport s_output_report;

View file

@ -25,64 +25,63 @@ namespace ams::controller {
}
void GamesirController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto gamesir_report = reinterpret_cast<const GamesirReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void GamesirController::UpdateControllerState(const bluetooth::HidReport *report) {
auto gamesir_report = reinterpret_cast<const GamesirReportData *>(&report->data);
switch(gamesir_report->id) {
case 0x12:
this->HandleInputReport0x12(gamesir_report, switch_report);
this->HandleInputReport0x12(gamesir_report);
break;
case 0xc4:
this->HandleInputReport0xc4(gamesir_report, switch_report);
this->HandleInputReport0xc4(gamesir_report);
break;
default:
break;
}
}
void GamesirController::HandleInputReport0x12(const GamesirReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.home = src->input0x12.home;
void GamesirController::HandleInputReport0x12(const GamesirReportData *src) {
m_buttons.home = src->input0x12.home;
}
void GamesirController::HandleInputReport0xc4(const GamesirReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void GamesirController::HandleInputReport0xc4(const GamesirReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0xc4.buttons.dpad == GamesirDpad_S) ||
m_buttons.dpad_down = (src->input0xc4.buttons.dpad == GamesirDpad_S) ||
(src->input0xc4.buttons.dpad == GamesirDpad_SE) ||
(src->input0xc4.buttons.dpad == GamesirDpad_SW);
dst->input0x30.buttons.dpad_up = (src->input0xc4.buttons.dpad == GamesirDpad_N) ||
m_buttons.dpad_up = (src->input0xc4.buttons.dpad == GamesirDpad_N) ||
(src->input0xc4.buttons.dpad == GamesirDpad_NE) ||
(src->input0xc4.buttons.dpad == GamesirDpad_NW);
dst->input0x30.buttons.dpad_right = (src->input0xc4.buttons.dpad == GamesirDpad_E) ||
m_buttons.dpad_right = (src->input0xc4.buttons.dpad == GamesirDpad_E) ||
(src->input0xc4.buttons.dpad == GamesirDpad_NE) ||
(src->input0xc4.buttons.dpad == GamesirDpad_SE);
dst->input0x30.buttons.dpad_left = (src->input0xc4.buttons.dpad == GamesirDpad_W) ||
m_buttons.dpad_left = (src->input0xc4.buttons.dpad == GamesirDpad_W) ||
(src->input0xc4.buttons.dpad == GamesirDpad_NW) ||
(src->input0xc4.buttons.dpad == GamesirDpad_SW);
dst->input0x30.buttons.A = src->input0xc4.buttons.B;
dst->input0x30.buttons.B = src->input0xc4.buttons.A;
dst->input0x30.buttons.X = src->input0xc4.buttons.Y;
dst->input0x30.buttons.Y = src->input0xc4.buttons.X;
m_buttons.A = src->input0xc4.buttons.B;
m_buttons.B = src->input0xc4.buttons.A;
m_buttons.X = src->input0xc4.buttons.Y;
m_buttons.Y = src->input0xc4.buttons.X;
dst->input0x30.buttons.R = src->input0xc4.buttons.RB;
dst->input0x30.buttons.ZR = src->input0xc4.buttons.RT;
dst->input0x30.buttons.L = src->input0xc4.buttons.LB;
dst->input0x30.buttons.ZL = src->input0xc4.buttons.LT;
m_buttons.R = src->input0xc4.buttons.RB;
m_buttons.ZR = src->input0xc4.buttons.RT;
m_buttons.L = src->input0xc4.buttons.LB;
m_buttons.ZL = src->input0xc4.buttons.LT;
dst->input0x30.buttons.minus = src->input0xc4.buttons.select;
dst->input0x30.buttons.plus = src->input0xc4.buttons.start;
m_buttons.minus = src->input0xc4.buttons.select;
m_buttons.plus = src->input0xc4.buttons.start;
dst->input0x30.buttons.lstick_press = src->input0xc4.buttons.L3;
dst->input0x30.buttons.rstick_press = src->input0xc4.buttons.R3;
m_buttons.lstick_press = src->input0xc4.buttons.L3;
m_buttons.rstick_press = src->input0xc4.buttons.R3;
}
}

View file

@ -94,11 +94,11 @@ namespace ams::controller {
GamesirController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x12(const GamesirReportData *src, SwitchReportData *dst);
void HandleInputReport0xc4(const GamesirReportData *src, SwitchReportData *dst);
void HandleInputReport0x12(const GamesirReportData *src);
void HandleInputReport0xc4(const GamesirReportData *src);
};

View file

@ -26,86 +26,83 @@ namespace ams::controller {
}
void GamestickController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto gamestick_report = reinterpret_cast<const GamestickReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void GamestickController::UpdateControllerState(const bluetooth::HidReport *report) {
auto gamestick_report = reinterpret_cast<const GamestickReportData *>(&report->data);
switch(gamestick_report->id) {
case 0x01:
this->HandleInputReport0x01(gamestick_report, switch_report);
this->HandleInputReport0x01(gamestick_report);
break;
case 0x03:
this->HandleInputReport0x03(gamestick_report, switch_report);
this->HandleInputReport0x03(gamestick_report);
break;
default:
break;
}
}
void GamestickController::HandleInputReport0x01(const GamestickReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.minus = src->input0x01.buttons.back;
dst->input0x30.buttons.home = src->input0x01.buttons.home;
void GamestickController::HandleInputReport0x01(const GamestickReportData *src) {
m_buttons.minus = src->input0x01.buttons.back;
m_buttons.home = src->input0x01.buttons.home;
}
void GamestickController::HandleInputReport0x03(const GamestickReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void GamestickController::HandleInputReport0x03(const GamestickReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x03.dpad == GamestickDPad_S) ||
m_buttons.dpad_down = (src->input0x03.dpad == GamestickDPad_S) ||
(src->input0x03.dpad == GamestickDPad_SE) ||
(src->input0x03.dpad == GamestickDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x03.dpad == GamestickDPad_N) ||
m_buttons.dpad_up = (src->input0x03.dpad == GamestickDPad_N) ||
(src->input0x03.dpad == GamestickDPad_NE) ||
(src->input0x03.dpad == GamestickDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x03.dpad == GamestickDPad_E) ||
m_buttons.dpad_right = (src->input0x03.dpad == GamestickDPad_E) ||
(src->input0x03.dpad == GamestickDPad_NE) ||
(src->input0x03.dpad == GamestickDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x03.dpad == GamestickDPad_W) ||
m_buttons.dpad_left = (src->input0x03.dpad == GamestickDPad_W) ||
(src->input0x03.dpad == GamestickDPad_NW) ||
(src->input0x03.dpad == GamestickDPad_SW);
dst->input0x30.buttons.A = src->input0x03.buttons.B;
dst->input0x30.buttons.B = src->input0x03.buttons.A;
dst->input0x30.buttons.X = src->input0x03.buttons.Y;
dst->input0x30.buttons.Y = src->input0x03.buttons.X;
m_buttons.A = src->input0x03.buttons.B;
m_buttons.B = src->input0x03.buttons.A;
m_buttons.X = src->input0x03.buttons.Y;
m_buttons.Y = src->input0x03.buttons.X;
/*
dst->input0x30.buttons.ZR = src->input0x03.buttons.start && src->input0x03.buttons.R;
dst->input0x30.buttons.ZL = src->input0x03.buttons.start && src->input0x03.buttons.L;
m_buttons.ZR = src->input0x03.buttons.start && src->input0x03.buttons.R;
m_buttons.ZL = src->input0x03.buttons.start && src->input0x03.buttons.L;
if (!dst->input0x30.buttons.ZR)
dst->input0x30.buttons.R = src->input0x03.buttons.R;
if (!m_buttons.ZR)
m_buttons.R = src->input0x03.buttons.R;
if (!dst->input0x30.buttons.ZL)
dst->input0x30.buttons.L = src->input0x03.buttons.L;
if (!m_buttons.ZL)
m_buttons.L = src->input0x03.buttons.L;
if (!(dst->input0x30.buttons.ZR || dst->input0x30.buttons.ZL))
dst->input0x30.buttons.plus = src->input0x03.buttons.start;
if (!(m_buttons.ZR || m_buttons.ZL))
m_buttons.plus = src->input0x03.buttons.start;
*/
dst->input0x30.buttons.L = src->input0x03.buttons.L;
dst->input0x30.buttons.R = src->input0x03.buttons.R;
m_buttons.L = src->input0x03.buttons.L;
m_buttons.R = src->input0x03.buttons.R;
// Combos for ZL/ZR
if (dst->input0x30.buttons.dpad_down) {
dst->input0x30.buttons.ZL = src->input0x03.buttons.L;
dst->input0x30.buttons.ZR = src->input0x03.buttons.R;
dst->input0x30.buttons.dpad_down = !(dst->input0x30.buttons.ZL || dst->input0x30.buttons.ZR);
dst->input0x30.buttons.L = !dst->input0x30.buttons.ZL;
dst->input0x30.buttons.R = !dst->input0x30.buttons.ZR;
if (m_buttons.dpad_down) {
m_buttons.ZL = src->input0x03.buttons.L;
m_buttons.ZR = src->input0x03.buttons.R;
m_buttons.dpad_down = !(m_buttons.ZL || m_buttons.ZR);
m_buttons.L = !m_buttons.ZL;
m_buttons.R = !m_buttons.ZR;
}
dst->input0x30.buttons.plus = src->input0x03.buttons.start;
m_buttons.plus = src->input0x03.buttons.start;
dst->input0x30.buttons.lstick_press = src->input0x03.buttons.lstick_press;
dst->input0x30.buttons.rstick_press = src->input0x03.buttons.rstick_press;
dst->input0x30.buttons.capture = 0;
m_buttons.lstick_press = src->input0x03.buttons.lstick_press;
m_buttons.rstick_press = src->input0x03.buttons.rstick_press;
}
}

View file

@ -93,11 +93,11 @@ namespace ams::controller {
GamestickController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const GamestickReportData *src, SwitchReportData *dst);
void HandleInputReport0x03(const GamestickReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const GamestickReportData *src);
void HandleInputReport0x03(const GamestickReportData *src);
};

View file

@ -25,66 +25,65 @@ namespace ams::controller {
}
void GemboxController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto gembox_report = reinterpret_cast<const GemboxReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void GemboxController::UpdateControllerState(const bluetooth::HidReport *report) {
auto gembox_report = reinterpret_cast<const GemboxReportData *>(&report->data);
switch(gembox_report->id) {
case 0x02:
this->HandleInputReport0x02(gembox_report, switch_report);
this->HandleInputReport0x02(gembox_report);
break;
case 0x07:
this->HandleInputReport0x07(gembox_report, switch_report);
this->HandleInputReport0x07(gembox_report);
break;
default:
break;
}
}
void GemboxController::HandleInputReport0x02(const GemboxReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.minus = src->input0x02.back;
dst->input0x30.buttons.home = src->input0x02.buttons == 0;
void GemboxController::HandleInputReport0x02(const GemboxReportData *src) {
m_buttons.minus = src->input0x02.back;
m_buttons.home = src->input0x02.buttons == 0;
}
void GemboxController::HandleInputReport0x07(const GemboxReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void GemboxController::HandleInputReport0x07(const GemboxReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x07.left_stick.x + 1) + 0x7ff) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x07.left_stick.y + 1)) + 0x7ff) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x07.right_stick.x + 1) + 0x7ff) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x07.right_stick.y + 1)) + 0x7ff) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x07.dpad == GemboxDPad_S) ||
m_buttons.dpad_down = (src->input0x07.dpad == GemboxDPad_S) ||
(src->input0x07.dpad == GemboxDPad_SE) ||
(src->input0x07.dpad == GemboxDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x07.dpad == GemboxDPad_N) ||
m_buttons.dpad_up = (src->input0x07.dpad == GemboxDPad_N) ||
(src->input0x07.dpad == GemboxDPad_NE) ||
(src->input0x07.dpad == GemboxDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x07.dpad == GemboxDPad_E) ||
m_buttons.dpad_right = (src->input0x07.dpad == GemboxDPad_E) ||
(src->input0x07.dpad == GemboxDPad_NE) ||
(src->input0x07.dpad == GemboxDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x07.dpad == GemboxDPad_W) ||
m_buttons.dpad_left = (src->input0x07.dpad == GemboxDPad_W) ||
(src->input0x07.dpad == GemboxDPad_NW) ||
(src->input0x07.dpad == GemboxDPad_SW);
dst->input0x30.buttons.A = src->input0x07.buttons.B;
dst->input0x30.buttons.B = src->input0x07.buttons.A;
dst->input0x30.buttons.X = src->input0x07.buttons.Y;
dst->input0x30.buttons.Y = src->input0x07.buttons.X;
m_buttons.A = src->input0x07.buttons.B;
m_buttons.B = src->input0x07.buttons.A;
m_buttons.X = src->input0x07.buttons.Y;
m_buttons.Y = src->input0x07.buttons.X;
dst->input0x30.buttons.R = src->input0x07.buttons.RB;
dst->input0x30.buttons.ZR = src->input0x07.right_trigger > 0;
dst->input0x30.buttons.L = src->input0x07.buttons.LB;
dst->input0x30.buttons.ZL = src->input0x07.left_trigger > 0;
m_buttons.R = src->input0x07.buttons.RB;
m_buttons.ZR = src->input0x07.right_trigger > 0;
m_buttons.L = src->input0x07.buttons.LB;
m_buttons.ZL = src->input0x07.left_trigger > 0;
dst->input0x30.buttons.plus = src->input0x07.buttons.start;
m_buttons.plus = src->input0x07.buttons.start;
dst->input0x30.buttons.lstick_press = src->input0x07.buttons.L3;
dst->input0x30.buttons.rstick_press = src->input0x07.buttons.R3;
m_buttons.lstick_press = src->input0x07.buttons.L3;
m_buttons.rstick_press = src->input0x07.buttons.R3;
dst->input0x30.buttons.home = 0;
//m_buttons.home = 0;
}
}

View file

@ -93,11 +93,11 @@ namespace ams::controller {
GemboxController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x02(const GemboxReportData *src, SwitchReportData *dst);
void HandleInputReport0x07(const GemboxReportData *src, SwitchReportData *dst);
void HandleInputReport0x02(const GemboxReportData *src);
void HandleInputReport0x07(const GemboxReportData *src);
};

View file

@ -25,67 +25,65 @@ namespace ams::controller {
}
void IpegaController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto ipega_report = reinterpret_cast<const IpegaReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void IpegaController::UpdateControllerState(const bluetooth::HidReport *report) {
auto ipega_report = reinterpret_cast<const IpegaReportData *>(&report->data);
switch(ipega_report->id) {
case 0x02:
this->HandleInputReport0x02(ipega_report, switch_report);
this->HandleInputReport0x02(ipega_report);
break;
case 0x07:
this->HandleInputReport0x07(ipega_report, switch_report);
this->HandleInputReport0x07(ipega_report);
break;
default:
break;
}
}
void IpegaController::HandleInputReport0x02(const IpegaReportData *src, SwitchReportData *dst) {
dst->input0x30.buttons.home = src->input0x02.home;
void IpegaController::HandleInputReport0x02(const IpegaReportData *src) {
m_buttons.home = src->input0x02.home;
}
void IpegaController::HandleInputReport0x07(const IpegaReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void IpegaController::HandleInputReport0x07(const IpegaReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x07.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x07.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x07.buttons.dpad == IpegaDPad_S) ||
m_buttons.dpad_down = (src->input0x07.buttons.dpad == IpegaDPad_S) ||
(src->input0x07.buttons.dpad == IpegaDPad_SE) ||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x07.buttons.dpad == IpegaDPad_N) ||
m_buttons.dpad_up = (src->input0x07.buttons.dpad == IpegaDPad_N) ||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
(src->input0x07.buttons.dpad == IpegaDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x07.buttons.dpad == IpegaDPad_E) ||
m_buttons.dpad_right = (src->input0x07.buttons.dpad == IpegaDPad_E) ||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
(src->input0x07.buttons.dpad == IpegaDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x07.buttons.dpad == IpegaDPad_W) ||
m_buttons.dpad_left = (src->input0x07.buttons.dpad == IpegaDPad_W) ||
(src->input0x07.buttons.dpad == IpegaDPad_NW) ||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
dst->input0x30.buttons.A = src->input0x07.buttons.B;
dst->input0x30.buttons.B = src->input0x07.buttons.A;
dst->input0x30.buttons.X = src->input0x07.buttons.Y;
dst->input0x30.buttons.Y = src->input0x07.buttons.X;
m_buttons.A = src->input0x07.buttons.B;
m_buttons.B = src->input0x07.buttons.A;
m_buttons.X = src->input0x07.buttons.Y;
m_buttons.Y = src->input0x07.buttons.X;
dst->input0x30.buttons.R = src->input0x07.buttons.RB;
dst->input0x30.buttons.ZR = src->input0x07.buttons.RT;
dst->input0x30.buttons.L = src->input0x07.buttons.LB;
dst->input0x30.buttons.ZL = src->input0x07.buttons.LT;
m_buttons.R = src->input0x07.buttons.RB;
m_buttons.ZR = src->input0x07.buttons.RT;
m_buttons.L = src->input0x07.buttons.LB;
m_buttons.ZL = src->input0x07.buttons.LT;
dst->input0x30.buttons.minus = src->input0x07.buttons.view;
dst->input0x30.buttons.plus = src->input0x07.buttons.menu;
m_buttons.minus = src->input0x07.buttons.view;
m_buttons.plus = src->input0x07.buttons.menu;
dst->input0x30.buttons.lstick_press = src->input0x07.buttons.lstick_press;
dst->input0x30.buttons.rstick_press = src->input0x07.buttons.rstick_press;
m_buttons.lstick_press = src->input0x07.buttons.lstick_press;
m_buttons.rstick_press = src->input0x07.buttons.rstick_press;
dst->input0x30.buttons.capture = 0;
dst->input0x30.buttons.home = 0;
//m_buttons.home = 0;
}
}

View file

@ -90,11 +90,11 @@ namespace ams::controller {
IpegaController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x02(const IpegaReportData *src, SwitchReportData *dst);
void HandleInputReport0x07(const IpegaReportData *src, SwitchReportData *dst);
void HandleInputReport0x02(const IpegaReportData *src);
void HandleInputReport0x07(const IpegaReportData *src);
};

View file

@ -25,67 +25,65 @@ namespace ams::controller {
}
void NvidiaShieldController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto nvidia_report = reinterpret_cast<const NvidiaShieldReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void NvidiaShieldController::UpdateControllerState(const bluetooth::HidReport *report) {
auto nvidia_report = reinterpret_cast<const NvidiaShieldReportData *>(&report->data);
switch(nvidia_report->id) {
case 0x01:
this->HandleInputReport0x01(nvidia_report, switch_report);
this->HandleInputReport0x01(nvidia_report);
break;
case 0x03:
this->HandleInputReport0x03(nvidia_report, switch_report);
this->HandleInputReport0x03(nvidia_report);
break;
default:
break;
}
}
void NvidiaShieldController::HandleInputReport0x01(const NvidiaShieldReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void NvidiaShieldController::HandleInputReport0x01(const NvidiaShieldReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x01.dpad == NvidiaShieldDPad_S) ||
m_buttons.dpad_down = (src->input0x01.dpad == NvidiaShieldDPad_S) ||
(src->input0x01.dpad == NvidiaShieldDPad_SE) ||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x01.dpad == NvidiaShieldDPad_N) ||
m_buttons.dpad_up = (src->input0x01.dpad == NvidiaShieldDPad_N) ||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
(src->input0x01.dpad == NvidiaShieldDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x01.dpad == NvidiaShieldDPad_E) ||
m_buttons.dpad_right = (src->input0x01.dpad == NvidiaShieldDPad_E) ||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
(src->input0x01.dpad == NvidiaShieldDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x01.dpad == NvidiaShieldDPad_W) ||
m_buttons.dpad_left = (src->input0x01.dpad == NvidiaShieldDPad_W) ||
(src->input0x01.dpad == NvidiaShieldDPad_NW) ||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
dst->input0x30.buttons.A = src->input0x01.buttons.B;
dst->input0x30.buttons.B = src->input0x01.buttons.A;
dst->input0x30.buttons.X = src->input0x01.buttons.Y;
dst->input0x30.buttons.Y = src->input0x01.buttons.X;
m_buttons.A = src->input0x01.buttons.B;
m_buttons.B = src->input0x01.buttons.A;
m_buttons.X = src->input0x01.buttons.Y;
m_buttons.Y = src->input0x01.buttons.X;
dst->input0x30.buttons.R = src->input0x01.buttons.RB;
dst->input0x30.buttons.ZR = src->input0x01.right_trigger > 0;
dst->input0x30.buttons.L = src->input0x01.buttons.LB;
dst->input0x30.buttons.ZL = src->input0x01.left_trigger > 0;
m_buttons.R = src->input0x01.buttons.RB;
m_buttons.ZR = src->input0x01.right_trigger > 0;
m_buttons.L = src->input0x01.buttons.LB;
m_buttons.ZL = src->input0x01.left_trigger > 0;
dst->input0x30.buttons.minus = src->input0x01.back;
dst->input0x30.buttons.plus = src->input0x01.buttons.start;
m_buttons.minus = src->input0x01.back;
m_buttons.plus = src->input0x01.buttons.start;
dst->input0x30.buttons.lstick_press = src->input0x01.buttons.L3;
dst->input0x30.buttons.rstick_press = src->input0x01.buttons.R3;
m_buttons.lstick_press = src->input0x01.buttons.L3;
m_buttons.rstick_press = src->input0x01.buttons.R3;
dst->input0x30.buttons.home = src->input0x01.home;
m_buttons.home = src->input0x01.home;
}
void NvidiaShieldController::HandleInputReport0x03(const NvidiaShieldReportData *src, SwitchReportData *dst) {
void NvidiaShieldController::HandleInputReport0x03(const NvidiaShieldReportData *src) {
}
}

View file

@ -85,11 +85,11 @@ namespace ams::controller {
NvidiaShieldController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const NvidiaShieldReportData *src, SwitchReportData *dst);
void HandleInputReport0x03(const NvidiaShieldReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const NvidiaShieldReportData *src);
void HandleInputReport0x03(const NvidiaShieldReportData *src);
};

View file

@ -25,58 +25,57 @@ namespace ams::controller {
}
void OuyaController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto ouya_report = reinterpret_cast<const OuyaReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void OuyaController::UpdateControllerState(const bluetooth::HidReport *report) {
auto ouya_report = reinterpret_cast<const OuyaReportData *>(&report->data);
switch(ouya_report->id) {
case 0x03:
this->HandleInputReport0x03(ouya_report, switch_report);
this->HandleInputReport0x03(ouya_report);
break;
case 0x07:
this->HandleInputReport0x07(ouya_report, switch_report);
this->HandleInputReport0x07(ouya_report);
break;
default:
break;
}
}
void OuyaController::HandleInputReport0x03(const OuyaReportData *src, SwitchReportData *dst) {
void OuyaController::HandleInputReport0x03(const OuyaReportData *src) {
m_battery = src->input0x03.battery / 52 << 1;
}
void OuyaController::HandleInputReport0x07(const OuyaReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void OuyaController::HandleInputReport0x07(const OuyaReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x07.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x07.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = src->input0x07.buttons.dpad_down;
dst->input0x30.buttons.dpad_up = src->input0x07.buttons.dpad_up;
dst->input0x30.buttons.dpad_right = src->input0x07.buttons.dpad_right;
dst->input0x30.buttons.dpad_left = src->input0x07.buttons.dpad_left;
m_buttons.dpad_down = src->input0x07.buttons.dpad_down;
m_buttons.dpad_up = src->input0x07.buttons.dpad_up;
m_buttons.dpad_right = src->input0x07.buttons.dpad_right;
m_buttons.dpad_left = src->input0x07.buttons.dpad_left;
dst->input0x30.buttons.A = src->input0x07.buttons.A;
dst->input0x30.buttons.B = src->input0x07.buttons.O;
dst->input0x30.buttons.X = src->input0x07.buttons.Y;
dst->input0x30.buttons.Y = src->input0x07.buttons.U;
m_buttons.A = src->input0x07.buttons.A;
m_buttons.B = src->input0x07.buttons.O;
m_buttons.X = src->input0x07.buttons.Y;
m_buttons.Y = src->input0x07.buttons.U;
dst->input0x30.buttons.R = src->input0x07.buttons.RB;
dst->input0x30.buttons.ZR = src->input0x07.buttons.RT;
dst->input0x30.buttons.L = src->input0x07.buttons.LB;
dst->input0x30.buttons.ZL = src->input0x07.buttons.LT;
m_buttons.R = src->input0x07.buttons.RB;
m_buttons.ZR = src->input0x07.buttons.RT;
m_buttons.L = src->input0x07.buttons.LB;
m_buttons.ZL = src->input0x07.buttons.LT;
dst->input0x30.buttons.minus = 0;
dst->input0x30.buttons.plus = 0;
m_buttons.minus = 0;
m_buttons.plus = 0;
dst->input0x30.buttons.lstick_press = src->input0x07.buttons.LS;
dst->input0x30.buttons.rstick_press = src->input0x07.buttons.RS;
m_buttons.lstick_press = src->input0x07.buttons.LS;
m_buttons.rstick_press = src->input0x07.buttons.RS;
dst->input0x30.buttons.home = src->input0x07.buttons.center_hold;
m_buttons.home = src->input0x07.buttons.center_hold;
}
}

View file

@ -75,11 +75,11 @@ namespace ams::controller {
OuyaController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x03(const OuyaReportData *src, SwitchReportData *dst);
void HandleInputReport0x07(const OuyaReportData *src, SwitchReportData *dst);
void HandleInputReport0x03(const OuyaReportData *src);
void HandleInputReport0x07(const OuyaReportData *src);
};

View file

@ -25,58 +25,57 @@ namespace ams::controller {
}
void SteelseriesController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto steelseries_report = reinterpret_cast<const SteelseriesReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void SteelseriesController::UpdateControllerState(const bluetooth::HidReport *report) {
auto steelseries_report = reinterpret_cast<const SteelseriesReportData *>(&report->data);
switch(steelseries_report->id) {
case 0x01:
this->HandleInputReport0x01(steelseries_report, switch_report);
this->HandleInputReport0x01(steelseries_report);
break;
default:
break;
}
}
void SteelseriesController::HandleInputReport0x01(const SteelseriesReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void SteelseriesController::HandleInputReport0x01(const SteelseriesReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x01.left_stick.x + 1) + 0x7ff) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x01.left_stick.y + 1)) + 0x7ff) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x01.right_stick.x + 1) + 0x7ff) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x01.right_stick.y + 1)) + 0x7ff) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x01.dpad == SteelseriesDPad_S) ||
m_buttons.dpad_down = (src->input0x01.dpad == SteelseriesDPad_S) ||
(src->input0x01.dpad == SteelseriesDPad_SE) ||
(src->input0x01.dpad == SteelseriesDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x01.dpad == SteelseriesDPad_N) ||
m_buttons.dpad_up = (src->input0x01.dpad == SteelseriesDPad_N) ||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
(src->input0x01.dpad == SteelseriesDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x01.dpad == SteelseriesDPad_E) ||
m_buttons.dpad_right = (src->input0x01.dpad == SteelseriesDPad_E) ||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
(src->input0x01.dpad == SteelseriesDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x01.dpad == SteelseriesDPad_W) ||
m_buttons.dpad_left = (src->input0x01.dpad == SteelseriesDPad_W) ||
(src->input0x01.dpad == SteelseriesDPad_NW) ||
(src->input0x01.dpad == SteelseriesDPad_SW);
dst->input0x30.buttons.A = src->input0x01.buttons.B;
dst->input0x30.buttons.B = src->input0x01.buttons.A;
dst->input0x30.buttons.X = src->input0x01.buttons.Y;
dst->input0x30.buttons.Y = src->input0x01.buttons.X;
m_buttons.A = src->input0x01.buttons.B;
m_buttons.B = src->input0x01.buttons.A;
m_buttons.X = src->input0x01.buttons.Y;
m_buttons.Y = src->input0x01.buttons.X;
dst->input0x30.buttons.R = src->input0x01.buttons.R;
dst->input0x30.buttons.L = src->input0x01.buttons.L;
m_buttons.R = src->input0x01.buttons.R;
m_buttons.L = src->input0x01.buttons.L;
dst->input0x30.buttons.minus = src->input0x01.buttons.select;
dst->input0x30.buttons.plus = src->input0x01.buttons.start;
m_buttons.minus = src->input0x01.buttons.select;
m_buttons.plus = src->input0x01.buttons.start;
// Home button combo
dst->input0x30.buttons.home = dst->input0x30.buttons.dpad_down & dst->input0x30.buttons.minus;
if (dst->input0x30.buttons.home){
dst->input0x30.buttons.dpad_down = 0;
dst->input0x30.buttons.minus = 0;
m_buttons.home = m_buttons.dpad_down & m_buttons.minus;
if (m_buttons.home){
m_buttons.dpad_down = 0;
m_buttons.minus = 0;
}
}

View file

@ -76,10 +76,10 @@ namespace ams::controller {
SteelseriesController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const SteelseriesReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const SteelseriesReportData *src);
};

View file

@ -40,38 +40,37 @@ namespace ams::controller {
return this->QueryStatus();
}
void WiiController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto wii_report = reinterpret_cast<const WiiReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void WiiController::UpdateControllerState(const bluetooth::HidReport *report) {
auto wii_report = reinterpret_cast<const WiiReportData *>(&report->data);
switch(wii_report->id) {
case 0x20: // status
this->HandleInputReport0x20(wii_report, switch_report);
this->HandleInputReport0x20(wii_report);
break;
case 0x21: // memory read
this->HandleInputReport0x21(wii_report, switch_report);
this->HandleInputReport0x21(wii_report);
break;
case 0x22: // ack
this->HandleInputReport0x22(wii_report, switch_report);
this->HandleInputReport0x22(wii_report);
break;
case 0x30:
this->HandleInputReport0x30(wii_report, switch_report);
this->HandleInputReport0x30(wii_report);
break;
case 0x31:
this->HandleInputReport0x31(wii_report, switch_report);
this->HandleInputReport0x31(wii_report);
break;
case 0x32:
this->HandleInputReport0x32(wii_report, switch_report);
this->HandleInputReport0x32(wii_report);
break;
case 0x34:
this->HandleInputReport0x34(wii_report, switch_report);
this->HandleInputReport0x34(wii_report);
break;
default:
break;
}
}
void WiiController::HandleInputReport0x20(const WiiReportData *src, SwitchReportData *dst) {
void WiiController::HandleInputReport0x20(const WiiReportData *src) {
if (!src->input0x20.extension_connected) {
m_extension = WiiExtensionController_None;
this->SetReportMode(0x31);
@ -88,7 +87,7 @@ namespace ams::controller {
m_battery = (src->input0x20.battery / 52) << 1;
}
void WiiController::HandleInputReport0x21(const WiiReportData *src, SwitchReportData *dst) {
void WiiController::HandleInputReport0x21(const WiiReportData *src) {
uint16_t read_addr = util::SwapBytes(src->input0x21.address);
//uint8_t size = src->input0x21.size + 1;
@ -126,186 +125,186 @@ namespace ams::controller {
}
}
void WiiController::HandleInputReport0x22(const WiiReportData *src, SwitchReportData *dst) {
void WiiController::HandleInputReport0x22(const WiiReportData *src) {
;
}
void WiiController::HandleInputReport0x30(const WiiReportData *src, SwitchReportData *dst) {
this->MapButtonsHorizontalOrientation(&src->input0x30.buttons, dst);
void WiiController::HandleInputReport0x30(const WiiReportData *src) {
this->MapButtonsHorizontalOrientation(&src->input0x30.buttons);
}
void WiiController::HandleInputReport0x31(const WiiReportData *src, SwitchReportData *dst) {
this->MapButtonsHorizontalOrientation(&src->input0x31.buttons, dst);
void WiiController::HandleInputReport0x31(const WiiReportData *src) {
this->MapButtonsHorizontalOrientation(&src->input0x31.buttons);
// Todo: Accelerometer data
}
void WiiController::HandleInputReport0x32(const WiiReportData *src, SwitchReportData *dst) {
void WiiController::HandleInputReport0x32(const WiiReportData *src) {
if ((m_extension == WiiExtensionController_Nunchuck)
|| (m_extension == WiiExtensionController_Classic)
|| (m_extension == WiiExtensionController_ClassicPro)
|| (m_extension == WiiExtensionController_TaTaCon)) {
this->MapButtonsVerticalOrientation(&src->input0x32.buttons, dst);
this->MapButtonsVerticalOrientation(&src->input0x32.buttons);
}
this->MapExtensionBytes(src->input0x32.extension, dst);
this->MapExtensionBytes(src->input0x32.extension);
}
void WiiController::HandleInputReport0x34(const WiiReportData *src, SwitchReportData *dst) {
void WiiController::HandleInputReport0x34(const WiiReportData *src) {
if ((m_extension == WiiExtensionController_Nunchuck)
|| (m_extension == WiiExtensionController_Classic)
|| (m_extension == WiiExtensionController_ClassicPro)) {
this->MapButtonsVerticalOrientation(&src->input0x34.buttons, dst);
this->MapButtonsVerticalOrientation(&src->input0x34.buttons);
}
this->MapExtensionBytes(src->input0x34.extension, dst);
this->MapExtensionBytes(src->input0x34.extension);
}
void WiiController::MapButtonsHorizontalOrientation(const WiiButtonData *buttons, SwitchReportData *dst) {
dst->input0x30.buttons.dpad_down = buttons->dpad_left;
dst->input0x30.buttons.dpad_up = buttons->dpad_right;
dst->input0x30.buttons.dpad_right = buttons->dpad_down;
dst->input0x30.buttons.dpad_left = buttons->dpad_up;
void WiiController::MapButtonsHorizontalOrientation(const WiiButtonData *buttons) {
m_buttons.dpad_down = buttons->dpad_left;
m_buttons.dpad_up = buttons->dpad_right;
m_buttons.dpad_right = buttons->dpad_down;
m_buttons.dpad_left = buttons->dpad_up;
dst->input0x30.buttons.A = buttons->two;
dst->input0x30.buttons.B = buttons->one;
m_buttons.A = buttons->two;
m_buttons.B = buttons->one;
dst->input0x30.buttons.R = buttons->A;
dst->input0x30.buttons.L = buttons->B;
m_buttons.R = buttons->A;
m_buttons.L = buttons->B;
dst->input0x30.buttons.minus = buttons->minus;
dst->input0x30.buttons.plus = buttons->plus;
m_buttons.minus = buttons->minus;
m_buttons.plus = buttons->plus;
dst->input0x30.buttons.home = buttons->home;
m_buttons.home = buttons->home;
}
void WiiController::MapButtonsVerticalOrientation(const WiiButtonData *buttons, SwitchReportData *dst) {
dst->input0x30.buttons.dpad_down = buttons->dpad_down;
dst->input0x30.buttons.dpad_up = buttons->dpad_up;
dst->input0x30.buttons.dpad_right = buttons->dpad_right;
dst->input0x30.buttons.dpad_left = buttons->dpad_left;
void WiiController::MapButtonsVerticalOrientation(const WiiButtonData *buttons) {
m_buttons.dpad_down = buttons->dpad_down;
m_buttons.dpad_up = buttons->dpad_up;
m_buttons.dpad_right = buttons->dpad_right;
m_buttons.dpad_left = buttons->dpad_left;
dst->input0x30.buttons.A = buttons->A;
dst->input0x30.buttons.B = buttons->B;
m_buttons.A = buttons->A;
m_buttons.B = buttons->B;
// Not the best mapping but at least most buttons are mapped to something when nunchuck is connected.
dst->input0x30.buttons.R = buttons->one;
dst->input0x30.buttons.ZR = buttons->two;
m_buttons.R = buttons->one;
m_buttons.ZR = buttons->two;
dst->input0x30.buttons.minus = buttons->minus;
dst->input0x30.buttons.plus = buttons->plus;
m_buttons.minus = buttons->minus;
m_buttons.plus = buttons->plus;
dst->input0x30.buttons.home = buttons->home;
m_buttons.home = buttons->home;
}
void WiiController::MapExtensionBytes(const uint8_t ext[], SwitchReportData *dst) {
void WiiController::MapExtensionBytes(const uint8_t ext[]) {
switch(m_extension) {
case WiiExtensionController_Nunchuck:
this->MapNunchuckExtension(ext, dst);
this->MapNunchuckExtension(ext);
break;
case WiiExtensionController_Classic:
case WiiExtensionController_ClassicPro:
this->MapClassicControllerExtension(ext, dst);
this->MapClassicControllerExtension(ext);
break;
case WiiExtensionController_WiiUPro:
this->MapWiiUProControllerExtension(ext, dst);
this->MapWiiUProControllerExtension(ext);
break;
case WiiExtensionController_TaTaCon:
this->MapTaTaConExtension(ext, dst);
this->MapTaTaConExtension(ext);
break;
default:
break;
}
}
void WiiController::MapNunchuckExtension(const uint8_t ext[], SwitchReportData *dst) {
void WiiController::MapNunchuckExtension(const uint8_t ext[]) {
auto extension = reinterpret_cast<const WiiNunchuckExtensionData *>(ext);
this->PackStickData(&dst->input0x30.left_stick,
this->PackStickData(&m_left_stick,
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension->stick_x - 0x80) + STICK_ZERO), 0, 0xfff),
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension->stick_y - 0x80) + STICK_ZERO), 0, 0xfff)
);
dst->input0x30.buttons.L = !extension->C;
dst->input0x30.buttons.ZL = !extension->Z;
m_buttons.L = !extension->C;
m_buttons.ZL = !extension->Z;
}
void WiiController::MapClassicControllerExtension(const uint8_t ext[], SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void WiiController::MapClassicControllerExtension(const uint8_t ext[]) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(left_stick_scale_factor * ((ext[0] & 0x3f) - 0x20) + STICK_ZERO) & 0xfff,
static_cast<uint16_t>(left_stick_scale_factor * ((ext[1] & 0x3f) - 0x20) + STICK_ZERO) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(right_stick_scale_factor * ((((ext[0] >> 3) & 0x18) | ((ext[1] >> 5) & 0x06) | ((ext[2] >> 7) & 0x01)) - 0x10) + STICK_ZERO) & 0xfff,
static_cast<uint16_t>(right_stick_scale_factor * ((ext[2] & 0x1f) - 0x10) + STICK_ZERO) & 0xfff
);
auto buttons = reinterpret_cast<const WiiClassicControllerButtonData *>(&ext[4]);
dst->input0x30.buttons.dpad_down = !buttons->dpad_down;
dst->input0x30.buttons.dpad_up = !buttons->dpad_up;
dst->input0x30.buttons.dpad_right = !buttons->dpad_right;
dst->input0x30.buttons.dpad_left = !buttons->dpad_left;
m_buttons.dpad_down = !buttons->dpad_down;
m_buttons.dpad_up = !buttons->dpad_up;
m_buttons.dpad_right = !buttons->dpad_right;
m_buttons.dpad_left = !buttons->dpad_left;
dst->input0x30.buttons.A = !buttons->A;
dst->input0x30.buttons.B = !buttons->B;
dst->input0x30.buttons.X = !buttons->X;
dst->input0x30.buttons.Y = !buttons->Y;
m_buttons.A = !buttons->A;
m_buttons.B = !buttons->B;
m_buttons.X = !buttons->X;
m_buttons.Y = !buttons->Y;
dst->input0x30.buttons.L = !buttons->L;
dst->input0x30.buttons.ZL = !buttons->ZL;
dst->input0x30.buttons.R = !buttons->R;
dst->input0x30.buttons.ZR = !buttons->ZR;
m_buttons.L = !buttons->L;
m_buttons.ZL = !buttons->ZL;
m_buttons.R = !buttons->R;
m_buttons.ZR = !buttons->ZR;
dst->input0x30.buttons.minus = !buttons->minus;
dst->input0x30.buttons.plus = !buttons->plus;
m_buttons.minus = !buttons->minus;
m_buttons.plus = !buttons->plus;
dst->input0x30.buttons.home = !buttons->home;
m_buttons.home = !buttons->home;
}
void WiiController::MapWiiUProControllerExtension(const uint8_t ext[], SwitchReportData *dst) {
void WiiController::MapWiiUProControllerExtension(const uint8_t ext[]) {
auto extension = reinterpret_cast<const WiiUProExtensionData *>(ext);
this->PackStickData(&dst->input0x30.left_stick,
this->PackStickData(&m_left_stick,
std::clamp<uint16_t>(((wiiu_scale_factor * (extension->left_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
std::clamp<uint16_t>(((wiiu_scale_factor * (extension->left_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
std::clamp<uint16_t>(((wiiu_scale_factor * (extension->right_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
std::clamp<uint16_t>(((wiiu_scale_factor * (extension->right_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
);
dst->input0x30.buttons.dpad_down = !extension->buttons.dpad_down;
dst->input0x30.buttons.dpad_up = !extension->buttons.dpad_up;
dst->input0x30.buttons.dpad_right = !extension->buttons.dpad_right;
dst->input0x30.buttons.dpad_left = !extension->buttons.dpad_left;
m_buttons.dpad_down = !extension->buttons.dpad_down;
m_buttons.dpad_up = !extension->buttons.dpad_up;
m_buttons.dpad_right = !extension->buttons.dpad_right;
m_buttons.dpad_left = !extension->buttons.dpad_left;
dst->input0x30.buttons.A = !extension->buttons.A;
dst->input0x30.buttons.B = !extension->buttons.B;
dst->input0x30.buttons.X = !extension->buttons.X;
dst->input0x30.buttons.Y = !extension->buttons.Y;
m_buttons.A = !extension->buttons.A;
m_buttons.B = !extension->buttons.B;
m_buttons.X = !extension->buttons.X;
m_buttons.Y = !extension->buttons.Y;
dst->input0x30.buttons.R = !extension->buttons.R;
dst->input0x30.buttons.ZR = !extension->buttons.ZR;
dst->input0x30.buttons.L = !extension->buttons.L;
dst->input0x30.buttons.ZL = !extension->buttons.ZL;
m_buttons.R = !extension->buttons.R;
m_buttons.ZR = !extension->buttons.ZR;
m_buttons.L = !extension->buttons.L;
m_buttons.ZL = !extension->buttons.ZL;
dst->input0x30.buttons.minus = !extension->buttons.minus;
dst->input0x30.buttons.plus = !extension->buttons.plus;
m_buttons.minus = !extension->buttons.minus;
m_buttons.plus = !extension->buttons.plus;
dst->input0x30.buttons.lstick_press = !extension->buttons.lstick_press;
dst->input0x30.buttons.rstick_press = !extension->buttons.rstick_press;
m_buttons.lstick_press = !extension->buttons.lstick_press;
m_buttons.rstick_press = !extension->buttons.rstick_press;
dst->input0x30.buttons.home = !extension->buttons.home;
m_buttons.home = !extension->buttons.home;
}
void WiiController::MapTaTaConExtension(const uint8_t ext[], SwitchReportData *dst) {
void WiiController::MapTaTaConExtension(const uint8_t ext[]) {
auto extension = reinterpret_cast<const TaTaConExtensionData *>(ext);
dst->input0x30.buttons.X = !extension->R_rim;
dst->input0x30.buttons.Y = !extension->R_center;
dst->input0x30.buttons.dpad_up = !extension->L_rim;
dst->input0x30.buttons.dpad_right = !extension->L_center;
m_buttons.X = !extension->R_rim;
m_buttons.Y = !extension->R_center;
m_buttons.dpad_up = !extension->L_rim;
m_buttons.dpad_right = !extension->L_center;
}
Result WiiController::WriteMemory(uint32_t write_addr, const uint8_t *data, uint8_t size) {

View file

@ -294,25 +294,25 @@ namespace ams::controller {
, m_extension(WiiExtensionController_None) { };
Result Initialize(void);
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
protected:
void HandleInputReport0x20(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x21(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x22(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x30(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x31(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x32(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x34(const WiiReportData *src, SwitchReportData *dst);
void HandleInputReport0x20(const WiiReportData *src);
void HandleInputReport0x21(const WiiReportData *src);
void HandleInputReport0x22(const WiiReportData *src);
void HandleInputReport0x30(const WiiReportData *src);
void HandleInputReport0x31(const WiiReportData *src);
void HandleInputReport0x32(const WiiReportData *src);
void HandleInputReport0x34(const WiiReportData *src);
void MapButtonsHorizontalOrientation(const WiiButtonData *buttons, SwitchReportData *dst);
void MapButtonsVerticalOrientation(const WiiButtonData *buttons, SwitchReportData *dst);
void MapButtonsHorizontalOrientation(const WiiButtonData *buttons);
void MapButtonsVerticalOrientation(const WiiButtonData *buttons);
void MapExtensionBytes(const uint8_t ext[], SwitchReportData *dst);
void MapNunchuckExtension(const uint8_t ext[], SwitchReportData *dst);
void MapClassicControllerExtension(const uint8_t ext[], SwitchReportData *dst);
void MapWiiUProControllerExtension(const uint8_t ext[], SwitchReportData *dst);
void MapTaTaConExtension(const uint8_t ext[], SwitchReportData *dst);
void MapExtensionBytes(const uint8_t ext[]);
void MapNunchuckExtension(const uint8_t ext[]);
void MapClassicControllerExtension(const uint8_t ext[]);
void MapWiiUProControllerExtension(const uint8_t ext[]);
void MapTaTaConExtension(const uint8_t ext[]);
Result WriteMemory(uint32_t write_addr, const uint8_t *data, uint8_t size);
Result ReadMemory(uint32_t read_addr, uint16_t size);

View file

@ -36,66 +36,65 @@ namespace ams::controller {
return ams::ResultSuccess();
}
void XboxOneController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto xbox_report = reinterpret_cast<const XboxOneReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void XboxOneController::UpdateControllerState(const bluetooth::HidReport *report) {
auto xbox_report = reinterpret_cast<const XboxOneReportData *>(&report->data);
switch(xbox_report->id) {
case 0x01:
this->HandleInputReport0x01(xbox_report, switch_report);
this->HandleInputReport0x01(xbox_report);
break;
case 0x04:
this->HandleInputReport0x04(xbox_report, switch_report);
this->HandleInputReport0x04(xbox_report);
break;
default:
break;
}
}
void XboxOneController::HandleInputReport0x01(const XboxOneReportData *src, SwitchReportData *dst) {
this->PackStickData(&dst->input0x30.left_stick,
void XboxOneController::HandleInputReport0x01(const XboxOneReportData *src) {
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x01.buttons.dpad == XboxOneDPad_S) ||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == XboxOneDPad_S) ||
(src->input0x01.buttons.dpad == XboxOneDPad_SE) ||
(src->input0x01.buttons.dpad == XboxOneDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x01.buttons.dpad == XboxOneDPad_N) ||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == XboxOneDPad_N) ||
(src->input0x01.buttons.dpad == XboxOneDPad_NE) ||
(src->input0x01.buttons.dpad == XboxOneDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x01.buttons.dpad == XboxOneDPad_E) ||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == XboxOneDPad_E) ||
(src->input0x01.buttons.dpad == XboxOneDPad_NE) ||
(src->input0x01.buttons.dpad == XboxOneDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x01.buttons.dpad == XboxOneDPad_W) ||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == XboxOneDPad_W) ||
(src->input0x01.buttons.dpad == XboxOneDPad_NW) ||
(src->input0x01.buttons.dpad == XboxOneDPad_SW);
dst->input0x30.buttons.A = src->input0x01.buttons.B;
dst->input0x30.buttons.B = src->input0x01.buttons.A;
dst->input0x30.buttons.X = src->input0x01.buttons.Y;
dst->input0x30.buttons.Y = src->input0x01.buttons.X;
m_buttons.A = src->input0x01.buttons.B;
m_buttons.B = src->input0x01.buttons.A;
m_buttons.X = src->input0x01.buttons.Y;
m_buttons.Y = src->input0x01.buttons.X;
dst->input0x30.buttons.R = src->input0x01.buttons.RB;
dst->input0x30.buttons.ZR = src->input0x01.right_trigger > 0;
dst->input0x30.buttons.L = src->input0x01.buttons.LB;
dst->input0x30.buttons.ZL = src->input0x01.left_trigger > 0;
m_buttons.R = src->input0x01.buttons.RB;
m_buttons.ZR = src->input0x01.right_trigger > 0;
m_buttons.L = src->input0x01.buttons.LB;
m_buttons.ZL = src->input0x01.left_trigger > 0;
dst->input0x30.buttons.minus = src->input0x01.buttons.view;
dst->input0x30.buttons.plus = src->input0x01.buttons.menu;
m_buttons.minus = src->input0x01.buttons.view;
m_buttons.plus = src->input0x01.buttons.menu;
dst->input0x30.buttons.lstick_press = src->input0x01.buttons.lstick_press;
dst->input0x30.buttons.rstick_press = src->input0x01.buttons.rstick_press;
m_buttons.lstick_press = src->input0x01.buttons.lstick_press;
m_buttons.rstick_press = src->input0x01.buttons.rstick_press;
dst->input0x30.buttons.capture = 0;
dst->input0x30.buttons.home = src->input0x01.buttons.guide;
m_buttons.capture = 0;
m_buttons.home = src->input0x01.buttons.guide;
}
void XboxOneController::HandleInputReport0x04(const XboxOneReportData *src, SwitchReportData *dst) {
void XboxOneController::HandleInputReport0x04(const XboxOneReportData *src) {
m_battery = src->input0x04.capacity << 1;
m_charging = src->input0x04.charging;
}

View file

@ -124,11 +124,11 @@ namespace ams::controller {
: EmulatedSwitchController(address) { };
Result Initialize(void);
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x01(const XboxOneReportData *src, SwitchReportData *dst);
void HandleInputReport0x04(const XboxOneReportData *src, SwitchReportData *dst);
void HandleInputReport0x01(const XboxOneReportData *src);
void HandleInputReport0x04(const XboxOneReportData *src);
};

View file

@ -35,61 +35,60 @@ namespace ams::controller {
return ams::ResultSuccess();
}
void XiaomiController::ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report) {
auto xiaomi_report = reinterpret_cast<const XiaomiReportData *>(&in_report->data);
auto switch_report = reinterpret_cast<SwitchReportData *>(&out_report->data);
void XiaomiController::UpdateControllerState(const bluetooth::HidReport *report) {
auto xiaomi_report = reinterpret_cast<const XiaomiReportData *>(&report->data);
switch(xiaomi_report->id) {
case 0x04:
this->HandleInputReport0x04(xiaomi_report, switch_report);
this->HandleInputReport0x04(xiaomi_report);
break;
default:
break;
}
}
void XiaomiController::HandleInputReport0x04(const XiaomiReportData *src, SwitchReportData *dst) {
void XiaomiController::HandleInputReport0x04(const XiaomiReportData *src) {
m_battery = src->input0x04.battery / 52 << 1;
this->PackStickData(&dst->input0x30.left_stick,
this->PackStickData(&m_left_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x04.left_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x04.left_stick.y)) & 0xfff
);
this->PackStickData(&dst->input0x30.right_stick,
this->PackStickData(&m_right_stick,
static_cast<uint16_t>(stick_scale_factor * src->input0x04.right_stick.x) & 0xfff,
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x04.right_stick.y)) & 0xfff
);
dst->input0x30.buttons.dpad_down = (src->input0x04.buttons.dpad == XiaomiDPad_S) ||
m_buttons.dpad_down = (src->input0x04.buttons.dpad == XiaomiDPad_S) ||
(src->input0x04.buttons.dpad == XiaomiDPad_SE) ||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
dst->input0x30.buttons.dpad_up = (src->input0x04.buttons.dpad == XiaomiDPad_N) ||
m_buttons.dpad_up = (src->input0x04.buttons.dpad == XiaomiDPad_N) ||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
(src->input0x04.buttons.dpad == XiaomiDPad_NW);
dst->input0x30.buttons.dpad_right = (src->input0x04.buttons.dpad == XiaomiDPad_E) ||
m_buttons.dpad_right = (src->input0x04.buttons.dpad == XiaomiDPad_E) ||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
(src->input0x04.buttons.dpad == XiaomiDPad_SE);
dst->input0x30.buttons.dpad_left = (src->input0x04.buttons.dpad == XiaomiDPad_W) ||
m_buttons.dpad_left = (src->input0x04.buttons.dpad == XiaomiDPad_W) ||
(src->input0x04.buttons.dpad == XiaomiDPad_NW) ||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
dst->input0x30.buttons.A = src->input0x04.buttons.B;
dst->input0x30.buttons.B = src->input0x04.buttons.A;
dst->input0x30.buttons.X = src->input0x04.buttons.Y;
dst->input0x30.buttons.Y = src->input0x04.buttons.X;
m_buttons.A = src->input0x04.buttons.B;
m_buttons.B = src->input0x04.buttons.A;
m_buttons.X = src->input0x04.buttons.Y;
m_buttons.Y = src->input0x04.buttons.X;
dst->input0x30.buttons.R = src->input0x04.buttons.R1;
dst->input0x30.buttons.ZR = src->input0x04.buttons.R2;
dst->input0x30.buttons.L = src->input0x04.buttons.L1;
dst->input0x30.buttons.ZL = src->input0x04.buttons.L2;
m_buttons.R = src->input0x04.buttons.R1;
m_buttons.ZR = src->input0x04.buttons.R2;
m_buttons.L = src->input0x04.buttons.L1;
m_buttons.ZL = src->input0x04.buttons.L2;
dst->input0x30.buttons.minus = src->input0x04.buttons.back;
dst->input0x30.buttons.plus = src->input0x04.buttons.menu;
m_buttons.minus = src->input0x04.buttons.back;
m_buttons.plus = src->input0x04.buttons.menu;
dst->input0x30.buttons.lstick_press = src->input0x04.buttons.lstick_press;
dst->input0x30.buttons.rstick_press = src->input0x04.buttons.rstick_press;
m_buttons.lstick_press = src->input0x04.buttons.lstick_press;
m_buttons.rstick_press = src->input0x04.buttons.rstick_press;
dst->input0x30.buttons.home = src->input0x04.home;
m_buttons.home = src->input0x04.home;
}
}

View file

@ -94,10 +94,10 @@ namespace ams::controller {
Result Initialize(void);
void ConvertReportFormat(const bluetooth::HidReport *in_report, bluetooth::HidReport *out_report);
void UpdateControllerState(const bluetooth::HidReport *report);
private:
void HandleInputReport0x04(const XiaomiReportData *src, SwitchReportData *dst);
void HandleInputReport0x04(const XiaomiReportData *src);
};