Skip to content

Feature/vibration driver review#361

Merged
maxjivi05 merged 12 commits into
WinNative-Emu:mainfrom
s1mptom:feature/vibration-driver-review
Jun 4, 2026
Merged

Feature/vibration driver review#361
maxjivi05 merged 12 commits into
WinNative-Emu:mainfrom
s1mptom:feature/vibration-driver-review

Conversation

@s1mptom
Copy link
Copy Markdown
Contributor

@s1mptom s1mptom commented May 5, 2026

Summary

GameSir controllers in Android mode receive vibration commands via the Game
Controller Mode (GCM) protocol, not through the standard Android InputDevice
vibrator API. This PR adds a dedicated rumble subsystem that handles these
controllers directly.

What's added:

  • GcmRumbleMode enum (DISABLED / KNOWN / ALL) with SharedPreferences persistence
  • GamepadRumbleDriver interface + GamepadRumbleManager dispatcher
  • GameSirG8UsbRumbleDriver — sends 9-byte vibration commands over USB bulk
    transfer to G8+ MFi controllers (VID 0x3537, PID 274)
  • GameSirX5sBleRumbleDriver — sends vibration commands over BLE GATT to X5s
    (VID 0x3537, PID 0x1119)
  • UI in the Input Controls drawer pane: toggle (on/off) + mode chips
    (Known: G8+ MFi, X5s / All GameSir — experimental)
  • Phone/device fallback vibrator is suppressed for slots managed by GCM to
    avoid double-rumble
  • USB host feature declaration + Bluetooth permissions in AndroidManifest

Modes:

  • DISABLED (default) — feature off, existing vibration behavior unchanged
  • KNOWN — only known supported models: G8+ MFi (USB) and X5s (BLE)
  • ALL (experimental) — any GameSir USB or BLE device; useful for untested
    models but may not work on all hardware

Pavel Turbin and others added 4 commits May 5, 2026 15:08
- Add GcmRumbleMode enum (DISABLED/KNOWN/ALL) with SharedPreferences migration
- Add GameSirG8UsbRumbleDriver (USB bulk transfer, VID=13623/PID=274)
- Add GameSirX5sBleRumbleDriver (BLE GATT, heartbeat pattern)
- Add GamepadRumbleManager with USB-first driver priority
- Add GCM rumble mode dropdown to InputControlsDialog
- Fix vibration socket race condition via executor shutdown/await
- Fix USB permission reset after device re-enumeration
- Fix G8+ MFi in ALL mode via UsbManager VID/PID verification
- Implement smart fallback: KNOWN suppresses only X5s+G8+; ALL suppresses any GameSir
…port

- Resolve conflict: drop showInputControlsDialog() (replaced by drawer menu)
- Add GCM rumble mode chip selector to InputControlsPane in XServerDrawerMenu
- Wire onInputControlsGcmRumbleModeChanged callback in XServerDisplayActivity
- Replace 3-chip selector with toggle + conditional Known/All chips
- Add subtitle inside toggle row: 'For Android mode controllers only'
- Auto-scroll to bottom when toggle is enabled
- Default GCM mode to DISABLED instead of KNOWN
- Remove debug applicationIdSuffix/versionNameSuffix from build.gradle
- Unify DISABLED as the default everywhere: GcmRumbleMode.fromPrefValue,
  WinHandler field init, GamepadRumbleManager field init, X5s/G8 driver
  field inits, and the renderDrawerMenu() pref fallback
- Remove never-existing deprecated API wrappers (PREF_GAMESIR_USB_VIBRATION,
  isGameSirUsbVibrationEnabled, setGameSirUsbVibrationEnabled) and the
  dead migration block from WinHandler constructor
- Revert InputControlsDialog/InputControlsDialogContent changes — the
  dialog is never instantiated so the gcmRumbleMode additions were dead code
- Add setMode(GcmRumbleMode) to GamepadRumbleDriver interface; replace
  instanceof cast in GamepadRumbleManager with the interface method
- Remove deprecated setEnabled() helper from GamepadRumbleManager
- Fix GameSirG8UsbRumbleDriver.findDevice() to return any GameSir USB
  device in ALL mode, not just the G8+ MFi PID 274

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ghost
Copy link
Copy Markdown

ghost commented May 5, 2026

Good work here! I'll test it out cause I'm curious if this can work on enabling rumble on Odin 3 also.

@s1mptom
Copy link
Copy Markdown
Contributor Author

s1mptom commented May 5, 2026

Good work here! I'll test it out cause I'm curious if this can work on enabling rumble on Odin 3 also.

Hm, these hacks are bound to Gamesir ids. There are some checks, but you could try to add your "driver" :) Now there's a "manager" layer to deal with it.

Claude helped me to find commands and ways to send them)

Pavel Turbin added 6 commits May 8, 2026 10:02
…ver-review

# Conflicts:
#	app/src/main/AndroidManifest.xml
Two issues caused vibration to be silent for an extended time after
entering a game:

1. A paired X5s actively connected as BLE-HID does not advertise, so
   the BLE scan never finds it. Vibration only works after the
   controller happens to advertise (mode switch, reconnect, etc.).
   Fix: Try bonded devices first via direct GATT connect — multiple
   GATT clients can coexist on the same physical link, so this works
   even while the controller is in use as HID. Scan stays as fallback.

2. After a successful command, pendingCommand is null. If the GATT
   link then drops, the disconnect handler skipped reconnection
   because it was gated on pendingCommand != null. Subsequent rumble
   events had to wait for a fresh scan (~3s).
   Fix: Reconnect whenever the rumble mode is enabled.

Also:
- Reset connecting=false if connectGatt returns null, otherwise
  ensureConnected() bails forever on transient adapter issues.
- ensureConnected() bails immediately when mode is DISABLED to
  avoid pointless scans.
Resolved conflicts: kept GcmRumbleMode additions from feature branch,
adopted vibration-disabled-by-default from main (6b04e18).
…defaults

GameSirX5sBleRumbleDriver: reconnect after GATT disconnect whenever
GcmRumbleMode is enabled, not only when a command is pending. Phone
notifications caused GATT to drop while vibration was idle — without a
pending command the scan was never restarted, leaving vibration broken
until container restart.

Also reverts the bonded-device connect path from ccfc684 which caused
GATT status=147 loops when X5s was already connected as HID.

WinHandler: default vibrationEnabledSlots to true so vibration works
out of the box when the global toggle is on.
Replace scan-only approach with dual-track connection: register a
background autoConnect=true for the bonded X5s (letting the OS connect
whenever the device becomes available) while also running a BLE scan in
parallel. This fixes the case where X5s is already connected as Classic
BT HID and does not advertise BLE, making the scan-only path fail
silently every time.
@juniorjoselito763-cell
Copy link
Copy Markdown

$ dpkg --add-architecture armhf
$ apt install build-essential make cmake g++-arm-linux-gnueabihf
$ apt install libasound2-dev:arm64 libasound2-dev:armhf

@Xnick417x
Copy link
Copy Markdown
Collaborator

$ dpkg --add-architecture armhf $ apt install build-essential make cmake g++-arm-linux-gnueabihf $ apt install libasound2-dev:arm64 libasound2-dev:armhf

Care to explain?

maxjivi05 added 2 commits June 4, 2026 09:00
The X3 Pro is wired (USB-C) for input but, like the X5s, drives rumble over the
GameSir BLE GATT protocol (write char 0x865f, command 0x04 + duration 1 with a
~200ms heartbeat) — confirmed by capturing the official GameSir app.

- BLE driver: match the X3 Pro (PID 0x0106 / name "GameSir-X3 Pro") in KNOWN
  mode; discover by advertised name (no MAC) and also match the scan-record name
  so the pad is recognised on first sight when getName() is still null.
- USB driver: never claim the X3 Pro (it rumbles over BLE only).
- WinHandler: treat the X3 Pro as GCM-managed; keep the phone fallback for OSC.
- Condense the rumble subsystem comments to one line each.
Bring the GCM rumble branch up to date with the current WinNative base (through
WinNative-Emu#512) and drop the unavailable in.dragonbra:javasteam:1.8.1-SNAPSHOT dependency
that the base no longer uses. Re-apply the rumble integration (WinHandler hooks,
Input Controls drawer toggle, activity listener, manifest permissions) on top of
the updated vibration code; the rumble driver files merged cleanly.
@maxjivi05 maxjivi05 merged commit 9786796 into WinNative-Emu:main Jun 4, 2026
4 checks passed
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.

4 participants