Преглед изворни кода

Add Emscripten joystick rumble support

Adds support for Emscripten (Web) joystick rumble support via EM_ASM_INT macros and HTML5's Gamepad API.

(cherry picked from commit 1fbed16cb0512e08651b99f7b0a6c1db4b0b61c6)
Nintorch пре 1 месец
родитељ
комит
16c0329a2a
1 измењених фајлова са 40 додато и 1 уклоњено
  1. 40 1
      src/joystick/emscripten/SDL_sysjoystick.c

+ 40 - 1
src/joystick/emscripten/SDL_sysjoystick.c

@@ -305,6 +305,7 @@ static SDL_JoystickID EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index)
 static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
 {
     SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
+    bool rumble_available = false;
 
     if (!item) {
         return SDL_SetError("No such device");
@@ -323,6 +324,22 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
     joystick->nbuttons = item->nbuttons;
     joystick->naxes = item->naxes;
 
+    rumble_available = EM_ASM_INT({
+        let gamepads = navigator['getGamepads']();
+        if (!gamepads) {
+            return 0;
+        }
+        let gamepad = gamepads[$0];
+        if (!gamepad || !gamepad['vibrationActuator']) {
+            return 0;
+        }
+        return 1;
+        }, item->index);
+
+    if (rumble_available) {
+        SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
+    }
+
     return true;
 }
 
@@ -390,7 +407,29 @@ static SDL_GUID EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
 
 static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
 {
-    return SDL_Unsupported();
+    SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
+
+    // clang-format off
+    bool result = EM_ASM_INT({
+        let gamepads = navigator['getGamepads']();
+        if (!gamepads) {
+            return 0;
+        }
+        let gamepad = gamepads[$0];
+        if (!gamepad || !gamepad['vibrationActuator']) {
+            return 0;
+        }
+
+        gamepad['vibrationActuator']['playEffect']('dual-rumble', {
+            'startDelay': 0,
+            'duration': 3000,
+            'weakMagnitude': $1 / 0xFFFF,
+            'strongMagnitude': $2 / 0xFFFF,
+        });
+        return 1;
+        }, item->index, low_frequency_rumble, high_frequency_rumble);
+
+    return result;
 }
 
 static bool EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)