Fix Xbox One controller detection on the web

(cherry picked from commit 4f031ea5da)
This commit is contained in:
Nintorch
2026-06-12 12:06:32 +05:00
committed by Sam Lantinga
parent 1731bb0d8e
commit 6cdec7ac09

View File

@@ -147,15 +147,18 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep
vendor = SDL_GetEmscriptenJoystickVendor(gamepadEvent->index);
product = SDL_GetEmscriptenJoystickProduct(gamepadEvent->index);
is_xinput = SDL_IsEmscriptenJoystickXInput(gamepadEvent->index);
// Use a generic VID/PID representing an XInput controller
if (!vendor && !product && is_xinput) {
vendor = USB_VENDOR_MICROSOFT;
product = USB_PRODUCT_XBOX360_XUSB_CONTROLLER;
}
os_id = SDL_GetEmscriptenOSID();
item->trigger_rumble_available = MAIN_THREAD_EM_ASM_INT({
let gamepad = navigator['getGamepads']()[$0];
// This effect is not supported in Safari, so it's okay for us to check the vibrationActuator.effects array here for the browsers that do support it
if (!gamepad || !gamepad['vibrationActuator'] || !gamepad['vibrationActuator']['effects'] || !gamepad['vibrationActuator']['effects']['includes']('trigger-rumble')) {
return false;
}
return true;
}, item->index);
if (os_id != 0) {
if (os_id == 1 || os_id == 3) { // Android or iOS (mobile)
bus = SDL_HARDWARE_BUS_BLUETOOTH;
@@ -164,6 +167,21 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep
}
}
if (!vendor && !product && is_xinput) {
// Use a generic VID/PID representing an XInput controller
vendor = USB_VENDOR_MICROSOFT;
product = USB_PRODUCT_XBOX360_XUSB_CONTROLLER;
if (item->trigger_rumble_available) {
// Assume Xbox One S Controller
if (bus == SDL_HARDWARE_BUS_BLUETOOTH) {
product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH;
} else {
product = USB_PRODUCT_XBOX_ONE_S;
}
}
}
if (SDL_strcmp(gamepadEvent->mapping, "standard") == 0) {
// We should differentiate between devices that are mapped or unmapped by the browser.
os_id += 0x80;
@@ -513,15 +531,7 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
}
item->trigger_rumble_available = MAIN_THREAD_EM_ASM_INT({
let gamepad = navigator['getGamepads']()[$0];
// This effect is not supported in Safari, so it's okay for us to check the vibrationActuator.effects array here for the browsers that do support it
if (!gamepad || !gamepad['vibrationActuator'] || !gamepad['vibrationActuator']['effects'] || !gamepad['vibrationActuator']['effects']['includes']('trigger-rumble')) {
return false;
}
return true;
}, item->index);
// item->trigger_rumble_available is set in Emscripten_JoyStickConnected
if (item->trigger_rumble_available) {
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, true);
}