Repository navigation
Vibration handles before a controller's haptics are routed (a game that asks once at startup lost every value) - #246
parsifal295 wants to merge 2 commits into
Conversation
…verlord asks for its handles once at startup, before GameController reports the pad, and kept an empty answer for the whole session hid::GetVibrationDeviceHandles answered 0 handles until a controller's haptics were routed (vib_targets: dm_haptics_available). Unicorn Overlord calls it once at startup; on the Mac the DualSense is reported a moment later, so the game kept no handles and sent every value (two hid::SendVibrationValue a frame per player) to handle 0, which reached no output: no rumble for the whole session. On Horizon the handles are computed from the npad id and style alone (libnx _hidGetVibrationDeviceHandles), and vib_send already checks for an output at each send. The handles now need only rumble on with an output sink installed (new dm_haptics_enabled) and the npad's connected style; no sink, rumble off or a disconnected npad still get none, and IsVibrationPermitted still follows the routed outputs (t_hid's checks for both are unchanged). DM_RUMBLE_LOG=1 logs the handle requests and, once a second, the values sent, those that reached no output and the peak amplitude. Docs: services.md "Vibration handles before a controller is reported" (symptom index regenerated), the rumble switches in development.md, and Unicorn Overlord's note (Input: what its two vibration paths do; Found on this game). Checked: t_hid (61 checks, one new: handles before routing), t_haptics and t_haptics_apple pass; the tool tests and the docs check pass; dmhost builds for Unicorn Overlord. On the Mac with a DualSense (Unicorn Overlord, Asian release): before, the request was answered with none and every value reached no output; after, the handles are 0x3 / 0x10003 and none is dropped
…een in the log only The reference entry and the game note said the game lost its rumble. It has none (on the Switch it does not vibrate either): it sends amplitude 0 throughout, so nothing could be felt before or after the fix. The symptom is now the log's (handles answered with none, every value reaching no output), what a rumbling game would lose is said as such, and the Found on line says the fix is not yet checked on a game that rumbles. Symptom index regenerated; the docs check passes
GetVibrationDeviceHandles used routed haptics availability to decide whether handles existed. Games that cache this answer at startup could retain an empty answer after a controller connected. Return handles for a connected npad style when rumble is enabled and an output sink is installed; check routed outputs when values are sent, keeping the existing permission and lifecycle behavior. Include the PR's rumble diagnostics, count unroutable values individually in mixed batches, and protect aggregate counters across game threads. Correct the code comment to describe Unicorn Overlord's observed empty handles and zero values without claiming restored physical rumble. Add regressions for cached startup handles delivering a nonzero value after routing, diagnostic totals and concurrent sends. Include HID in the existing ThreadSanitizer target and record the mechanism in the service reference. Checked with GAME=010069401ADB8000: full host suite, 73 HID checks, audio and HID ThreadSanitizer checks, docs checks, Mac host build, and iOS compilation (133 files). Physical rumble and iOS runtime remain untested. Broader tool validation is incomplete because Capstone is missing and iconutil failed. Co-authored-by: parsifal295 <130349765+parsifal295@users.noreply.github.com>
|
Thanks @parsifal295. I confirmed the startup handle bug with a regression that fails on the original code: handles requested before haptics routing must remain usable when an output is routed later. The fixed test delivers a nonzero value through those cached handles. Landed on Validation passed: full host suite, 73 HID checks, audio/HID ThreadSanitizer checks, docs checks, Mac host build and iOS source compilation (133 files). Physical controller rumble and iOS runtime remain untested; broader tool validation was incomplete due to missing Capstone and an iconutil failure. Closing this PR because the corrected implementation is now on |
GetVibrationDeviceHandles used routed haptics availability to decide whether handles existed. Games that cache this answer at startup could retain an empty answer after a controller connected. Return handles for a connected npad style when rumble is enabled and an output sink is installed; check routed outputs when values are sent, keeping the existing permission and lifecycle behavior. Include the PR's rumble diagnostics, count unroutable values individually in mixed batches, and protect aggregate counters across game threads. Correct the code comment to describe Unicorn Overlord's observed empty handles and zero values without claiming restored physical rumble. Add regressions for cached startup handles delivering a nonzero value after routing, diagnostic totals and concurrent sends. Include HID in the existing ThreadSanitizer target and record the mechanism in the service reference. Checked with GAME=010069401ADB8000: full host suite, 73 HID checks, audio and HID ThreadSanitizer checks, docs checks, Mac host build, and iOS compilation (133 files). Physical rumble and iOS runtime remain untested. Broader tool validation is incomplete because Capstone is missing and iconutil failed. Co-authored-by: parsifal295 <130349765+parsifal295@users.noreply.github.com>
hid::GetVibrationDeviceHandlesanswered 0 handles until a controller's haptics were routed (vib_targets→dm_haptics_available). A game that asks once at startup, before GameController reports the pad, keeps that empty answer and sends every vibration value to handle 0, which reaches no output for the whole session: a game that rumbles would stay silent.Found in the log of Unicorn Overlord on the Mac with a DualSense (
DM_RUMBLE_LOG=1, below). Unicorn Overlord itself has no rumble (on the Switch it does not vibrate either: it sends amplitude 0 throughout), so the bug changed nothing in its play; the fix is not yet checked on a game that rumbles.On Horizon the handles are computed from the npad id and style alone (libnx
_hidGetVibrationDeviceHandles), andvib_sendalready checks for an output at each send. The handles now need only rumble on with an output sink installed (newdm_haptics_enabled) and the npad's connected style. No sink, rumble off or a disconnected npad still get none, andIsVibrationPermittedstill follows the routed outputs: t_hid's existing checks for both are unchanged, plus one new check (handles before routing).DM_RUMBLE_LOG=1logs the handle requests and, once a second, the values sent, those that reached no output and the peak amplitude.Docs:
docs/reference/services.md"Vibration handles before a controller is reported" (symptom index regenerated), the rumble switches indocs/development.md, and Unicorn Overlord's note (Input: its two vibration paths and that it has no rumble; Found on this game).Related PRs
dm/host/hle_hid.c. The hunks do not overlap: this change applies cleanly on top of Add Steam Controller (2026) support on macOS #221'shle_hid.c, in either order. Its Steam Controller rumble goes through the same handles, so a Steam Controller that connects after the game has asked needs this too. (Add Steam Controller (2026) support on macOS #221 itself currently conflicts with main indm/host/tests/Makefile, unrelated to this change.)Checked
dm/host/tests: t_hid (61 checks), t_haptics and t_haptics_apple pass.DM_RUMBLE_LOG=1: before, the startup request was answered with none and every value reached no output; after, the handles are 0x3 / 0x10003 and no value is dropped.