Skip to content

Add cross-platform gamepad rumble via SDL2#860

Open
chiefautism wants to merge 2 commits intobuttplugio:masterfrom
chiefautism:sdl-gamepad-support
Open

Add cross-platform gamepad rumble via SDL2#860
chiefautism wants to merge 2 commits intobuttplugio:masterfrom
chiefautism:sdl-gamepad-support

Conversation

@chiefautism
Copy link
Copy Markdown

Summary

  • New crate: buttplug_server_hwmgr_sdl_gamepad — cross-platform gamepad haptics via SDL2
  • Xbox, PlayStation, and Switch controllers appear as XInput-compatible buttplug devices with dual vibration motors (left/right, 65535 steps each)
  • Works on macOS (GCController backend), Windows (XInput/DirectInput), Linux (evdev)
  • New CLI flag: intiface-engine --use-sdl-gamepad
  • SDL2 statically linked via bundled feature — no system dependency required

Motivation

buttplug currently supports gamepads only via XInput on Windows. SDL2 provides a single cross-platform API for gamepad rumble that works everywhere, including macOS where XInput is unavailable.

This unlocks game controllers as haptic devices for creative applications — interactive fiction with haptic feedback, biofeedback loops, accessibility tools, and more.

Implementation

  • SdlGamepadCommunicationManager: scans for controllers via SDL2's GameController API on a dedicated thread (SDL types are !Send)
  • SdlGamepadHardware: wraps a GameController with a worker thread that processes rumble commands, with 5ms drain batching to coalesce per-motor write_value calls
  • Reuses the existing XInput protocol/device config — gamepads appear as "XBox (XInput) Compatible Gamepad"
  • Stop fix: SDL on macOS requires duration > 0 for zero-rumble to override active rumble

Test plan

  • Build on macOS ARM64 (Apple Silicon)
  • Xbox Series X controller detected via Bluetooth
  • Vibrate at various intensities (ScalarCmd)
  • Stop working correctly (StopDeviceCmd)
  • Build on Windows
  • Build on Linux
  • Test with DualSense
  • Test with Switch Pro Controller

🤖 Generated with Claude Code

chiefautism and others added 2 commits April 5, 2026 01:12
New crate: buttplug_server_hwmgr_sdl_gamepad

Adds SDL2-based gamepad haptics as a buttplug device communication manager.
Xbox, PlayStation, and Switch controllers appear as XInput-compatible
buttplug devices with dual vibration motors (left/right, 65535 steps each).

Works on macOS (GCController backend), Windows (XInput/DirectInput),
and Linux (evdev) — all from a single SDL2 codebase.

Usage: intiface-engine --use-sdl-gamepad --websocket-port 12345

Tested with Xbox Series X controller on macOS via Bluetooth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Buttplug sends separate write_value calls for each motor (left then right).
Without draining, a stop sequence would send rumble(65535, 0, 10000) then
rumble(0, 0, 10000) — the first call re-activates vibration before the
second can cancel it.

Now the SDL worker thread waits 5ms and drains all pending commands before
applying, so both motor values arrive as a single set_rumble() call.

Also: SDL on macOS requires duration > 0 to override active rumble,
so stop now sends rumble(0, 0, 10000) instead of rumble(0, 0, 1).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@qdot
Copy link
Copy Markdown
Member

qdot commented Apr 4, 2026

Oh hell yeah. Lemme know what platforms you need tests run on if you don't have them yourself. I've also got xbox/dualsense/pro controllers to test with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants