Bug 1802842 - Support Xbox Series X controller on macOS. r=mac-reviewers,mstange

I verified on my Xbox Series X controller.

`kAcceleratorUsage` and `kBrakeUsage` aren't button on Xbox Series X.
So I added more check whether it is button.

Differential Revision: https://phabricator.services.mozilla.com/D163199
This commit is contained in:
Makoto Kato 2023-03-28 10:07:38 +00:00
Родитель 5807a30612
Коммит 0d94677e85
3 изменённых файлов: 115 добавлений и 3 удалений

Просмотреть файл

@ -1030,6 +1030,99 @@ class XboxOneRemapper final : public GamepadRemapper {
}
};
class XboxSeriesXRemapper final : public GamepadRemapper {
public:
virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
virtual uint32_t GetButtonCount() const override {
return BUTTON_INDEX_COUNT;
}
virtual void RemapAxisMoveEvent(GamepadHandle aHandle, uint32_t aAxis,
double aValue) const override {
RefPtr<GamepadPlatformService> service =
GamepadPlatformService::GetParentService();
if (!service) {
return;
}
switch (aAxis) {
case 0:
service->NewAxisMoveEvent(aHandle, AXIS_INDEX_LEFT_STICK_X, aValue);
break;
case 1:
service->NewAxisMoveEvent(aHandle, AXIS_INDEX_LEFT_STICK_Y, aValue);
break;
case 2:
service->NewAxisMoveEvent(aHandle, AXIS_INDEX_RIGHT_STICK_X, aValue);
break;
case 5:
service->NewAxisMoveEvent(aHandle, AXIS_INDEX_RIGHT_STICK_Y, aValue);
break;
case 9:
FetchDpadFromAxis(aHandle, aValue);
break;
case 148: {
const double value = AxisToButtonValue(aValue);
service->NewButtonEvent(aHandle, BUTTON_INDEX_RIGHT_TRIGGER,
value > BUTTON_THRESHOLD_VALUE, value);
break;
}
case 149: {
const double value = AxisToButtonValue(aValue);
service->NewButtonEvent(aHandle, BUTTON_INDEX_LEFT_TRIGGER,
value > BUTTON_THRESHOLD_VALUE, value);
break;
}
default:
NS_WARNING(
nsPrintfCString(
"Axis idx '%d' doesn't support in XboxSeriesXRemapper().",
aAxis)
.get());
break;
}
}
virtual void RemapButtonEvent(GamepadHandle aHandle, uint32_t aButton,
bool aPressed) const override {
RefPtr<GamepadPlatformService> service =
GamepadPlatformService::GetParentService();
if (!service) {
return;
}
if (GetButtonCount() <= aButton) {
NS_WARNING(
nsPrintfCString(
"Button idx '%d' doesn't support in XboxSeriesXRemapper().",
aButton)
.get());
return;
}
const std::unordered_map<uint32_t, uint32_t> buttonMapping = {
{0, BUTTON_INDEX_PRIMARY},
{1, BUTTON_INDEX_SECONDARY},
{3, BUTTON_INDEX_TERTIARY},
{4, BUTTON_INDEX_QUATERNARY},
{6, BUTTON_INDEX_LEFT_SHOULDER},
{7, BUTTON_INDEX_RIGHT_SHOULDER},
{10, BUTTON_INDEX_BACK_SELECT},
{11, BUTTON_INDEX_START},
{12, BUTTON_INDEX_META},
{13, BUTTON_INDEX_LEFT_THUMBSTICK},
{14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
auto find = buttonMapping.find(aButton);
if (find != buttonMapping.end()) {
service->NewButtonEvent(aHandle, find->second, aPressed);
} else {
service->NewButtonEvent(aHandle, aButton, aPressed);
}
}
};
class LogitechDInputRemapper final : public GamepadRemapper {
public:
virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
@ -2086,6 +2179,8 @@ already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
{GamepadId::kMicrosoftProductXboxOneSWireless2016,
new XboxOneS2016FirmwareRemapper()},
{GamepadId::kMicrosoftProductXboxAdaptiveWireless, new XboxOneRemapper()},
{GamepadId::kMicrosoftProductXboxSeriesXWireless,
new XboxSeriesXRemapper()},
{GamepadId::kNintendoProduct2006, new SwitchJoyConRemapper()},
{GamepadId::kNintendoProduct2007, new SwitchJoyConRemapper()},
{GamepadId::kNintendoProduct2009, new SwitchProRemapper()},

Просмотреть файл

@ -56,6 +56,8 @@ enum class GamepadId : uint32_t {
kMicrosoftProductXboxAdaptive = 0x045e0b0a,
// Microsoft Xbox Adaptive Wireless
kMicrosoftProductXboxAdaptiveWireless = 0x045e0b0c,
// Microsoft Xbox Series X Wireless
kMicrosoftProductXboxSeriesXWireless = 0x045e0b13,
// Switch Joy-Con L
kNintendoProduct2006 = 0x057e2006,
// Switch Joy-Con R

Просмотреть файл

@ -165,9 +165,24 @@ void Gamepad::init(IOHIDDeviceRef aDevice, bool aDefaultRemapper) {
IOHIDElementGetLogicalMin(element),
IOHIDElementGetLogicalMax(element)};
axes.AppendElement(axis);
} else if ((usagePage == kSimUsagePage &&
(usage == kAcceleratorUsage || usage == kBrakeUsage)) ||
(usagePage == kButtonUsagePage) ||
} else if (usagePage == kSimUsagePage &&
(usage == kAcceleratorUsage || usage == kBrakeUsage)) {
if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button) {
Button button(int(buttons.Length()), element,
IOHIDElementGetLogicalMin(element),
IOHIDElementGetLogicalMax(element));
buttons.AppendElement(button);
} else {
Axis axis = {aDefaultRemapper ? int(axes.Length())
: static_cast<int>(usage - kAxisUsageMin),
element,
usagePage,
usage,
IOHIDElementGetLogicalMin(element),
IOHIDElementGetLogicalMax(element)};
axes.AppendElement(axis);
}
} else if ((usagePage == kButtonUsagePage) ||
(usagePage == kConsumerPage &&
(usage == kHomeUsage || usage == kBackUsage))) {
Button button(int(buttons.Length()), element,