Skip to content

Commit 0ad7fd4

Browse files
committed
bluetooth-mitm: add support for steelseries stratus duo controller
1 parent 737f0ed commit 0ad7fd4

File tree

2 files changed

+127
-19
lines changed

2 files changed

+127
-19
lines changed

mc_mitm/source/controllers/steelseries_controller.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ namespace ams::controller {
3131
case 0x01:
3232
this->HandleInputReport0x01(steelseries_report);
3333
break;
34+
case 0x12:
35+
this->HandleInputReport0x12(steelseries_report);
36+
break;
37+
case 0xc4:
38+
this->HandleInputReport0xc4(steelseries_report);
39+
break;
3440
default:
3541
// Todo: handle this properly
3642
this->HandleMfiInputReport(steelseries_report);
@@ -70,7 +76,51 @@ namespace ams::controller {
7076
m_buttons.L = src->input0x01.buttons.L;
7177

7278
m_buttons.minus = src->input0x01.buttons.select;
73-
m_buttons.plus = src->input0x01.buttons.start;
79+
m_buttons.plus = src->input0x01.buttons.start;
80+
}
81+
82+
void SteelseriesController::HandleInputReport0x12(const SteelseriesReportData *src) {
83+
m_buttons.home = src->input0x12.home;
84+
}
85+
86+
void SteelseriesController::HandleInputReport0xc4(const SteelseriesReportData *src) {
87+
m_left_stick = this->PackStickData(
88+
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
89+
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
90+
);
91+
m_right_stick = this->PackStickData(
92+
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
93+
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
94+
);
95+
96+
m_buttons.dpad_down = (src->input0xc4.dpad == SteelseriesDPad2_S) ||
97+
(src->input0xc4.dpad == SteelseriesDPad2_SE) ||
98+
(src->input0xc4.dpad == SteelseriesDPad2_SW);
99+
m_buttons.dpad_up = (src->input0xc4.dpad == SteelseriesDPad2_N) ||
100+
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
101+
(src->input0xc4.dpad == SteelseriesDPad2_NW);
102+
m_buttons.dpad_right = (src->input0xc4.dpad == SteelseriesDPad2_E) ||
103+
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
104+
(src->input0xc4.dpad == SteelseriesDPad2_SE);
105+
m_buttons.dpad_left = (src->input0xc4.dpad == SteelseriesDPad2_W) ||
106+
(src->input0xc4.dpad == SteelseriesDPad2_NW) ||
107+
(src->input0xc4.dpad == SteelseriesDPad2_SW);
108+
109+
m_buttons.A = src->input0xc4.buttons.B;
110+
m_buttons.B = src->input0xc4.buttons.A;
111+
m_buttons.X = src->input0xc4.buttons.Y;
112+
m_buttons.Y = src->input0xc4.buttons.X;
113+
114+
m_buttons.R = src->input0xc4.buttons.R1;
115+
m_buttons.ZR = src->input0xc4.buttons.R2;
116+
m_buttons.L = src->input0xc4.buttons.L1;
117+
m_buttons.ZL = src->input0xc4.buttons.L2;
118+
119+
m_buttons.lstick_press = src->input0xc4.buttons.L3;
120+
m_buttons.rstick_press = src->input0xc4.buttons.R3;
121+
122+
m_buttons.minus = src->input0xc4.buttons.select;
123+
m_buttons.plus = src->input0xc4.buttons.start;
74124
}
75125

76126
void SteelseriesController::HandleMfiInputReport(const SteelseriesReportData *src) {

mc_mitm/source/controllers/steelseries_controller.hpp

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,22 @@ namespace ams::controller {
2727
SteelseriesDPad_SW,
2828
SteelseriesDPad_W,
2929
SteelseriesDPad_NW,
30-
SteelseriesDPad_Released = 0x0f
30+
SteelseriesDPad_Released = 0x0f,
3131
};
32-
33-
struct SteelseriesStickData {
32+
33+
enum SteelseriesDPadDirection2 {
34+
SteelseriesDPad2_Released = 0x0,
35+
SteelseriesDPad2_N,
36+
SteelseriesDPad2_NE,
37+
SteelseriesDPad2_E,
38+
SteelseriesDPad2_SE,
39+
SteelseriesDPad2_S,
40+
SteelseriesDPad2_SW,
41+
SteelseriesDPad2_W,
42+
SteelseriesDPad2_NW,
43+
};
44+
45+
struct SteelseriesStickData {
3446
uint8_t x;
3547
uint8_t y;
3648
} __attribute__ ((__packed__));
@@ -51,6 +63,26 @@ namespace ams::controller {
5163
uint8_t : 0;
5264
} __attribute__ ((__packed__));
5365

66+
struct SteelseriesButtonData2 {
67+
uint8_t A : 1;
68+
uint8_t B : 1;
69+
uint8_t : 1;
70+
uint8_t X : 1;
71+
uint8_t Y : 1;
72+
uint8_t : 1;
73+
uint8_t L1 : 1;
74+
uint8_t R1 : 1;
75+
76+
uint8_t L2 : 1;
77+
uint8_t R2 : 1;
78+
uint8_t start : 1;
79+
uint8_t select : 1;
80+
uint8_t : 1;
81+
uint8_t L3 : 1;
82+
uint8_t R3 : 1;
83+
uint8_t : 0;
84+
} __attribute__ ((__packed__));
85+
5486
struct SteelseriesMfiButtonData {
5587
uint8_t dpad_up;
5688
uint8_t dpad_right;
@@ -71,23 +103,46 @@ namespace ams::controller {
71103

72104
struct SteelseriesMfiInputReport {
73105
SteelseriesMfiButtonData buttons;
74-
SteelseriesStickData left_stick;
75-
SteelseriesStickData right_stick;
106+
SteelseriesStickData left_stick;
107+
SteelseriesStickData right_stick;
108+
} __attribute__((packed));
109+
110+
struct SteelseriesInputReport0x01 {
111+
uint8_t dpad;
112+
SteelseriesStickData left_stick;
113+
SteelseriesStickData right_stick;
114+
SteelseriesButtonData buttons;
115+
} __attribute__((packed));
116+
117+
struct SteelseriesInputReport0x12 {
118+
uint8_t : 3;
119+
uint8_t home : 1;
120+
uint8_t : 0;
121+
122+
uint8_t _unk0[2];
123+
124+
uint8_t _unk1; // Maybe battery
125+
76126
} __attribute__((packed));
77-
78-
struct SteelseriesInputReport0x01 {
79-
uint8_t dpad;
80-
SteelseriesStickData left_stick;
81-
SteelseriesStickData right_stick;
82-
SteelseriesButtonData buttons;
127+
128+
struct SteelseriesInputReport0xc4 {
129+
SteelseriesStickData left_stick;
130+
SteelseriesStickData right_stick;
131+
uint8_t left_trigger;
132+
uint8_t right_trigger;
133+
SteelseriesButtonData2 buttons;
134+
uint8_t dpad;
135+
uint8_t _unk[2];
83136
} __attribute__((packed));
84-
85-
struct SteelseriesReportData {
137+
138+
struct SteelseriesReportData {
86139
union {
87140
struct {
88141
uint8_t id;
89142
union {
90-
SteelseriesInputReport0x01 input0x01;
143+
SteelseriesInputReport0x01 input0x01;
144+
SteelseriesInputReport0x12 input0x12;
145+
SteelseriesInputReport0xc4 input0xc4;
91146
};
92147
};
93148

@@ -98,18 +153,21 @@ namespace ams::controller {
98153
class SteelseriesController : public EmulatedSwitchController {
99154

100155
public:
101-
static constexpr const HardwareID hardware_ids[] = {
156+
static constexpr const HardwareID hardware_ids[] = {
102157
{0x1038, 0x1412}, // Steelseries Free
103-
{0x0111, 0x1420} // Steelseries Nimbus
104-
};
158+
{0x0111, 0x1420}, // Steelseries Nimbus
159+
{0x0111, 0x1431} // Steelseries Stratus Duo
160+
};
105161

106-
SteelseriesController(const bluetooth::Address *address)
162+
SteelseriesController(const bluetooth::Address *address)
107163
: EmulatedSwitchController(address) { };
108164

109165
void UpdateControllerState(const bluetooth::HidReport *report);
110166

111167
private:
112168
void HandleInputReport0x01(const SteelseriesReportData *src);
169+
void HandleInputReport0x12(const SteelseriesReportData *src);
170+
void HandleInputReport0xc4(const SteelseriesReportData *src);
113171
void HandleMfiInputReport(const SteelseriesReportData *src);
114172
};
115173

0 commit comments

Comments
 (0)