diff --git a/mc_mitm/source/controllers/mad_catz_controller.cpp b/mc_mitm/source/controllers/mad_catz_controller.cpp index b0fe86c..8a76d4a 100644 --- a/mc_mitm/source/controllers/mad_catz_controller.cpp +++ b/mc_mitm/source/controllers/mad_catz_controller.cpp @@ -21,6 +21,7 @@ namespace ams::controller { namespace { const constexpr float stick_scale_factor = float(UINT12_MAX) / UINT8_MAX; + const constexpr float media_mode_stick_scale_factor = float(UINT12_MAX) / 39; } @@ -32,6 +33,12 @@ namespace ams::controller { this->MapInputReport0x01(madcatz_report); break; case 0x02: this->MapInputReport0x02(madcatz_report); break; + case 0x81: + this->MapInputReport0x81(madcatz_report); break; + case 0x82: + this->MapInputReport0x82(madcatz_report); break; + case 0x83: + this->MapInputReport0x83(madcatz_report); break; default: break; } @@ -84,4 +91,73 @@ namespace ams::controller { m_buttons.home = src->input0x02.play; } + void MadCatzController::MapInputReport0x81(const MadCatzReportData *src) { + m_left_stick.SetData( + static_cast(stick_scale_factor * src->input0x81.left_stick.x) & 0xfff, + static_cast(stick_scale_factor * (UINT8_MAX - src->input0x81.left_stick.y)) & 0xfff + ); + m_right_stick.SetData( + static_cast(stick_scale_factor * src->input0x81.right_stick.x) & 0xfff, + static_cast(stick_scale_factor * (UINT8_MAX - src->input0x81.right_stick.y)) & 0xfff + ); + + m_buttons.dpad_down = (src->input0x81.buttons.dpad == MadCatzDPad_S) || + (src->input0x81.buttons.dpad == MadCatzDPad_SE) || + (src->input0x81.buttons.dpad == MadCatzDPad_SW); + m_buttons.dpad_up = (src->input0x81.buttons.dpad == MadCatzDPad_N) || + (src->input0x81.buttons.dpad == MadCatzDPad_NE) || + (src->input0x81.buttons.dpad == MadCatzDPad_NW); + m_buttons.dpad_right = (src->input0x81.buttons.dpad == MadCatzDPad_E) || + (src->input0x81.buttons.dpad == MadCatzDPad_NE) || + (src->input0x81.buttons.dpad == MadCatzDPad_SE); + m_buttons.dpad_left = (src->input0x81.buttons.dpad == MadCatzDPad_W) || + (src->input0x81.buttons.dpad == MadCatzDPad_NW) || + (src->input0x81.buttons.dpad == MadCatzDPad_SW); + + m_buttons.A = src->input0x81.buttons.B; + m_buttons.B = src->input0x81.buttons.A; + m_buttons.X = src->input0x81.buttons.Y; + m_buttons.Y = src->input0x81.buttons.X; + + m_buttons.R = src->input0x81.buttons.R1; + m_buttons.ZR = src->input0x81.right_trigger > 0; + m_buttons.L = src->input0x81.buttons.L1; + m_buttons.ZL = src->input0x81.left_trigger > 0; + + m_buttons.minus = src->input0x81.buttons.select; + m_buttons.plus = src->input0x81.buttons.start; + + m_buttons.lstick_press = src->input0x81.buttons.L3; + m_buttons.rstick_press = src->input0x81.buttons.R3; + } + + void MadCatzController::MapInputReport0x82(const MadCatzReportData *src) { + m_buttons.dpad_up = (src->input0x82.buttons.dpad & 0x01) != 0; + m_buttons.dpad_down = (src->input0x82.buttons.dpad & 0x02) != 0; + m_buttons.dpad_left = (src->input0x82.buttons.dpad & 0x04) != 0; + m_buttons.dpad_right = (src->input0x82.buttons.dpad & 0x08) != 0; + + m_buttons.A = src->input0x82.buttons.B; + m_buttons.X = src->input0x82.buttons.Y; + m_buttons.Y = src->input0x82.buttons.X; + + m_buttons.R = src->input0x82.buttons.R1; + m_buttons.L = src->input0x82.buttons.L1; + + m_buttons.minus = src->input0x82.buttons.select; + } + + void MadCatzController::MapInputReport0x83(const MadCatzReportData *src) { + m_left_stick.SetData( + std::clamp(media_mode_stick_scale_factor * -src->input0x83.left_stick.x + 0x7ff, 0, 0xfff), + std::clamp(media_mode_stick_scale_factor * src->input0x83.left_stick.y + 0x7ff, 0, 0xfff) + ); + + m_buttons.ZR = src->input0x83.buttons.R2; + m_buttons.ZL = src->input0x83.buttons.L2; + + m_buttons.lstick_press = src->input0x83.buttons.L3; + m_buttons.rstick_press = src->input0x83.buttons.R3; + } + } diff --git a/mc_mitm/source/controllers/mad_catz_controller.hpp b/mc_mitm/source/controllers/mad_catz_controller.hpp index d67e07b..a65cda6 100644 --- a/mc_mitm/source/controllers/mad_catz_controller.hpp +++ b/mc_mitm/source/controllers/mad_catz_controller.hpp @@ -73,11 +73,87 @@ namespace ams::controller { uint8_t : 0; } __attribute__ ((__packed__)); + struct MadCatzInputReport0x81 { + struct { + union { + struct { + uint8_t A : 1; + uint8_t B : 1; + uint8_t X : 1; + uint8_t Y : 1; + uint8_t L1 : 1; + uint8_t R1 : 1; + uint8_t select : 1; + uint8_t start : 1; + + uint8_t L3 : 1; + uint8_t R3 : 1; + uint8_t : 0; + }; + + struct { + uint8_t A : 1; + uint8_t B : 1; + uint8_t : 1; + uint8_t X : 1; + uint8_t Y : 1; + uint8_t : 1; + uint8_t L1 : 1; + uint8_t R1 : 1; + + uint8_t : 3; + uint8_t start : 1; + uint8_t : 1; + uint8_t L3 : 1; + uint8_t R3 : 1; + uint8_t : 0; + } xinput; + }; + + uint8_t dpad; + } buttons; + MadCatzStickData left_stick; + MadCatzStickData right_stick; + uint8_t left_trigger; + uint8_t right_trigger; + uint8_t reserved; + } __attribute__ ((__packed__)); + + struct MadCatzInputReport0x82 { + struct { + uint8_t : 2; + uint8_t R1 : 1; + uint8_t L1 : 1; + uint8_t Y : 1; + uint8_t B : 1; + uint8_t X : 1; + uint8_t select : 1; + + uint8_t dpad; + } buttons; + uint8_t reserved; + } __attribute__ ((__packed__)); + + struct MadCatzInputReport0x83 { + struct { + uint8_t R2 : 1; + uint8_t L2 : 1; + uint8_t R3 : 1; + uint8_t L3 : 1; + uint8_t : 0; + } buttons; + MadCatzStickData left_stick; + uint8_t reserved[2]; + } __attribute__ ((__packed__)); + struct MadCatzReportData { uint8_t id; union { MadCatzInputReport0x01 input0x01; MadCatzInputReport0x02 input0x02; + MadCatzInputReport0x81 input0x81; + MadCatzInputReport0x82 input0x82; + MadCatzInputReport0x83 input0x83; }; } __attribute__((packed)); @@ -86,7 +162,8 @@ namespace ams::controller { public: static constexpr const HardwareID hardware_ids[] = { {0x0738, 0x5266}, // Mad Catz C.T.R.L.R - {0x0738, 0x5250} // Mad Catz C.T.R.L.R for Samsung + {0x0738, 0x5250}, // Mad Catz C.T.R.L.R for Samsung + {0x0738, 0x5269} // Mad Catz L.Y.N.X. 3 }; MadCatzController(const bluetooth::Address *address, HardwareID id) @@ -97,6 +174,9 @@ namespace ams::controller { private: void MapInputReport0x01(const MadCatzReportData *src); void MapInputReport0x02(const MadCatzReportData *src); + void MapInputReport0x81(const MadCatzReportData *src); + void MapInputReport0x82(const MadCatzReportData *src); + void MapInputReport0x83(const MadCatzReportData *src); };