mirror of
https://github.com/ndeadly/MissionControl
synced 2025-02-16 13:18:27 +00:00
mc.mitm: add support for 8bitdo ultimate 2.4g wireless controller
This commit is contained in:
parent
d83763d38b
commit
6c1c8306ef
2 changed files with 109 additions and 62 deletions
|
@ -15,12 +15,14 @@
|
|||
*/
|
||||
#include "8bitdo_controller.hpp"
|
||||
#include <stratosphere.hpp>
|
||||
#include "controller_utils.hpp"
|
||||
|
||||
namespace ams::controller {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float stick_scale_factor = float(UINT12_MAX) / UINT16_MAX;
|
||||
constexpr float stick_scale_factor_16bit = float(UINT12_MAX) / UINT16_MAX;
|
||||
constexpr float stick_scale_factor_8bit = float(UINT12_MAX) / UINT8_MAX;
|
||||
|
||||
}
|
||||
|
||||
|
@ -53,26 +55,26 @@ namespace ams::controller {
|
|||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SW);
|
||||
} else {
|
||||
m_left_stick.SetData(
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01_v2.left_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.left_stick.y)) & UINT12_MAX
|
||||
static_cast<u16>(stick_scale_factor_16bit * src->input0x01_v2.left_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor_16bit * (UINT16_MAX - src->input0x01_v2.left_stick.y)) & UINT12_MAX
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01_v2.right_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.right_stick.y)) & UINT12_MAX
|
||||
static_cast<u16>(stick_scale_factor_16bit * src->input0x01_v2.right_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor_16bit * (UINT16_MAX - src->input0x01_v2.right_stick.y)) & UINT12_MAX
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_S) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_N) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_E) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_W) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_down = (src->input0x01_v2.dpad == EightBitDoDPadV2_S) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_SE) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v2.dpad == EightBitDoDPadV2_N) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v2.dpad == EightBitDoDPadV2_E) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v2.dpad == EightBitDoDPadV2_W) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_NW) ||
|
||||
(src->input0x01_v2.dpad == EightBitDoDPadV2_SW);
|
||||
|
||||
m_buttons.A = src->input0x01_v2.buttons.B;
|
||||
m_buttons.B = src->input0x01_v2.buttons.A;
|
||||
|
@ -106,34 +108,80 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
void EightBitDoController::MapInputReport0x03(const EightBitDoReportData *src, EightBitDoReportFormat fmt) {
|
||||
if (fmt == EightBitDoReportFormat_ZeroV1) {
|
||||
m_buttons.A = src->input0x03_v1.buttons.B;
|
||||
m_buttons.B = src->input0x03_v1.buttons.A;
|
||||
m_buttons.X = src->input0x03_v1.buttons.Y;
|
||||
m_buttons.Y = src->input0x03_v1.buttons.X;
|
||||
if (m_controller_type == EightBitDoControllerType_Zero) {
|
||||
if (fmt == EightBitDoReportFormat_ZeroV1) {
|
||||
m_buttons.A = src->input0x03_v1.buttons.B;
|
||||
m_buttons.B = src->input0x03_v1.buttons.A;
|
||||
m_buttons.X = src->input0x03_v1.buttons.Y;
|
||||
m_buttons.Y = src->input0x03_v1.buttons.X;
|
||||
|
||||
m_buttons.R = src->input0x03_v1.buttons.R1;
|
||||
m_buttons.L = src->input0x03_v1.buttons.L1;
|
||||
m_buttons.R = src->input0x03_v1.buttons.R1;
|
||||
m_buttons.L = src->input0x03_v1.buttons.L1;
|
||||
|
||||
m_buttons.minus = src->input0x03_v1.buttons.select;
|
||||
m_buttons.plus = src->input0x03_v1.buttons.start;
|
||||
} else if (fmt == EightBitDoReportFormat_ZeroV2) {
|
||||
m_buttons.dpad_down = src->input0x03_v2.left_stick.y == 0xff;
|
||||
m_buttons.dpad_up = src->input0x03_v2.left_stick.y == 0x00;
|
||||
m_buttons.dpad_right = src->input0x03_v2.left_stick.x == 0xff;
|
||||
m_buttons.dpad_left = src->input0x03_v2.left_stick.x == 0x00;
|
||||
m_buttons.minus = src->input0x03_v1.buttons.v2.select;
|
||||
m_buttons.plus = src->input0x03_v1.buttons.v2.start;
|
||||
} else if (fmt == EightBitDoReportFormat_ZeroV2) {
|
||||
m_buttons.dpad_down = src->input0x03_v2.left_stick.y == 0xff;
|
||||
m_buttons.dpad_up = src->input0x03_v2.left_stick.y == 0x00;
|
||||
m_buttons.dpad_right = src->input0x03_v2.left_stick.x == 0xff;
|
||||
m_buttons.dpad_left = src->input0x03_v2.left_stick.x == 0x00;
|
||||
|
||||
m_buttons.A = src->input0x03_v2.buttons.B;
|
||||
m_buttons.B = src->input0x03_v2.buttons.A;
|
||||
m_buttons.X = src->input0x03_v2.buttons.Y;
|
||||
m_buttons.Y = src->input0x03_v2.buttons.X;
|
||||
m_buttons.A = src->input0x03_v2.buttons.B;
|
||||
m_buttons.B = src->input0x03_v2.buttons.A;
|
||||
m_buttons.X = src->input0x03_v2.buttons.Y;
|
||||
m_buttons.Y = src->input0x03_v2.buttons.X;
|
||||
|
||||
m_buttons.R = src->input0x03_v2.buttons.R1;
|
||||
m_buttons.L = src->input0x03_v2.buttons.L1;
|
||||
m_buttons.R = src->input0x03_v2.buttons.R1;
|
||||
m_buttons.L = src->input0x03_v2.buttons.L1;
|
||||
|
||||
m_buttons.minus = src->input0x03_v2.buttons.select;
|
||||
m_buttons.plus = src->input0x03_v2.buttons.start;
|
||||
m_buttons.minus = src->input0x03_v2.buttons.v2.select;
|
||||
m_buttons.plus = src->input0x03_v2.buttons.v2.start;
|
||||
}
|
||||
} else {
|
||||
m_left_stick.SetData(
|
||||
static_cast<u16>(stick_scale_factor_8bit * src->input0x03_v3.left_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor_8bit * (UINT8_MAX - src->input0x03_v3.left_stick.y)) & UINT12_MAX
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<u16>(stick_scale_factor_8bit * src->input0x03_v3.right_stick.x) & UINT12_MAX,
|
||||
static_cast<u16>(stick_scale_factor_8bit * (UINT8_MAX - src->input0x03_v3.right_stick.y)) & UINT12_MAX
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x03_v3.dpad == EightBitDoDPadV2_S) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_SE) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_up = (src->input0x03_v3.dpad == EightBitDoDPadV2_N) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_NW);
|
||||
m_buttons.dpad_right = (src->input0x03_v3.dpad == EightBitDoDPadV2_E) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_SE);
|
||||
m_buttons.dpad_left = (src->input0x03_v3.dpad == EightBitDoDPadV2_W) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_NW) ||
|
||||
(src->input0x03_v3.dpad == EightBitDoDPadV2_SW);
|
||||
|
||||
m_buttons.A = src->input0x03_v3.buttons.B;
|
||||
m_buttons.B = src->input0x03_v3.buttons.A;
|
||||
m_buttons.X = src->input0x03_v3.buttons.Y;
|
||||
m_buttons.Y = src->input0x03_v3.buttons.X;
|
||||
|
||||
m_buttons.L = src->input0x03_v3.buttons.L1;
|
||||
m_buttons.R = src->input0x03_v3.buttons.R1;
|
||||
|
||||
m_buttons.ZL = src->input0x03_v3.left_trigger > (m_trigger_threshold * UINT8_MAX);
|
||||
m_buttons.ZR = src->input0x03_v3.right_trigger > (m_trigger_threshold * UINT8_MAX);
|
||||
|
||||
m_buttons.minus = src->input0x03_v3.buttons.v2.select;
|
||||
m_buttons.plus = src->input0x03_v3.buttons.v2.start;
|
||||
|
||||
m_buttons.lstick_press = src->input0x03_v3.buttons.v2.L3;
|
||||
m_buttons.rstick_press = src->input0x03_v3.buttons.v2.R3;
|
||||
|
||||
m_buttons.home = src->input0x03_v3.buttons.v2.home;
|
||||
|
||||
m_battery = convert_battery_100(src->input0x03_v3.battery);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace ams::controller {
|
|||
EightBitDoControllerType_Zero,
|
||||
EightBitDoControllerType_Sn30ProXboxCloud,
|
||||
EightBitDoControllerType_Sn30ProXboxCloudFwV2,
|
||||
EightBitDoControllerType_Ultimate24gWireless,
|
||||
EightBitDoControllerType_Other
|
||||
};
|
||||
|
||||
|
@ -65,23 +66,7 @@ namespace ams::controller {
|
|||
u16 y;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoButtonDataV1 {
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
u8 : 2;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoButtonDataV2 {
|
||||
struct EightBitDoButtonData {
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
|
@ -113,8 +98,6 @@ namespace ams::controller {
|
|||
u8 : 1;
|
||||
} v2;
|
||||
};
|
||||
|
||||
u8 dpad;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x01V1 {
|
||||
|
@ -124,7 +107,8 @@ namespace ams::controller {
|
|||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x01V2 {
|
||||
EightBitDoButtonDataV2 buttons;
|
||||
EightBitDoButtonData buttons;
|
||||
u8 dpad;
|
||||
EightBitDoStickData16 left_stick;
|
||||
EightBitDoStickData16 right_stick;
|
||||
u8 left_trigger;
|
||||
|
@ -137,7 +121,7 @@ namespace ams::controller {
|
|||
EightBitDoStickData8 left_stick;
|
||||
EightBitDoStickData8 right_stick;
|
||||
u8 _unk[3];
|
||||
EightBitDoButtonDataV1 buttons;
|
||||
EightBitDoButtonData buttons;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x03V2 {
|
||||
|
@ -145,7 +129,18 @@ namespace ams::controller {
|
|||
EightBitDoStickData8 left_stick;
|
||||
EightBitDoStickData8 right_stick;
|
||||
u8 _unk[2];
|
||||
EightBitDoButtonDataV1 buttons;
|
||||
EightBitDoButtonData buttons;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x03V3 {
|
||||
u8 dpad;
|
||||
EightBitDoStickData8 left_stick;
|
||||
EightBitDoStickData8 right_stick;
|
||||
u8 right_trigger;
|
||||
u8 left_trigger;
|
||||
EightBitDoButtonData buttons;
|
||||
u8 battery;
|
||||
u8 _unk0;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoReportData {
|
||||
|
@ -155,6 +150,7 @@ namespace ams::controller {
|
|||
EightBitDoInputReport0x01V2 input0x01_v2;
|
||||
EightBitDoInputReport0x03V1 input0x03_v1;
|
||||
EightBitDoInputReport0x03V2 input0x03_v2;
|
||||
EightBitDoInputReport0x03V3 input0x03_v3;
|
||||
};
|
||||
} PACKED;
|
||||
|
||||
|
@ -164,7 +160,8 @@ namespace ams::controller {
|
|||
static constexpr const HardwareID hardware_ids[] = {
|
||||
{0x05a0, 0x3232}, // 8BitDo Zero
|
||||
{0x2dc8, 0x2100}, // 8BitDo SN30 Pro for Xbox Cloud Gaming
|
||||
{0x2dc8, 0x2101} // 8BitDo SN30 Pro for Xbox Cloud Gaming (fw 2.00)
|
||||
{0x2dc8, 0x2101}, // 8BitDo SN30 Pro for Xbox Cloud Gaming (fw 2.00)
|
||||
{0x2dc8, 0x3012} // 8BitDo Ultimate 2.4g Wireless
|
||||
};
|
||||
|
||||
EightBitDoController(const bluetooth::Address *address, HardwareID id)
|
||||
|
@ -175,6 +172,8 @@ namespace ams::controller {
|
|||
m_controller_type = EightBitDoControllerType_Sn30ProXboxCloud;
|
||||
else if ((id.vid == hardware_ids[2].vid) && (id.pid == hardware_ids[2].pid))
|
||||
m_controller_type = EightBitDoControllerType_Sn30ProXboxCloudFwV2;
|
||||
else if ((id.vid == hardware_ids[3].vid) && (id.pid == hardware_ids[3].pid))
|
||||
m_controller_type = EightBitDoControllerType_Ultimate24gWireless;
|
||||
else
|
||||
m_controller_type = EightBitDoControllerType_Other;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue