Native DualSense rumble and queued-disconnect investigation¶
Historical record. This preserves the source, tests and limitations recorded at the time; it is not current setup guidance. See the documentation index.
Observed environment¶
The user was deliberately rolling back installed releases to find a haptics
regression. The live capture below was RC4.5.3 + VIIPER 0.1.3-rc4.5, not
RC4.5.7. No diagnostic tool changed those versions. Physical Bluetooth
DualSense, virtual DualSense, and the existing dsm profile were selected.
Hades II evidence¶
- Hades used SDL 2.32.6 and recognized the virtual USB DualSense VID/PID.
- Repeated non-suspending managed-memory samples found native control traffic advancing while atomic media remained at 138 delivered frames. The last media burst preceded Hades startup. CoreAudio independently showed no Hades session on the unmuted, active, four-channel virtual DualSense endpoint.
- This absence of PCM is not proof of failed game support. A separate bounded
native-report watch captured nonzero SDL improved-rumble commands: native
report flag 0
0x02, flag 20x04, light motor strengths including 43 and 76. Ordinary controller rumble does not need an audio stream. - The Bluetooth helper continued completing writes. The captured samples did not show an active helper deadlock, media backlog, or transport write failure.
- Source review found that quiescent-state consumption erased continuous rumble mode bits, and the helper erased them again when merging subsequent media templates. This can end a correctly delivered native rumble effect at the next audio carrier. SDL explicitly uses a zero-mode command to return to audio haptics; mode bits cannot all be treated as one-shot validity strobes.
Reference: SDL 2.32.6 PS5 implementation.
The user identified 5.0.3.0 / RC4.3 as the last working DualSense-haptics build.
Exact tag VIIPERRC4.3 resolves to 3579450dc8f50a74d9532e711249589c732c460b.
Although the validity-consuming helper already existed there, raw game reports
used TryPublishCachedBluetoothCombinedState and retained the mode in the
streaming template. Commit 4d41a613 (first released in RC4.4) routed raw game
commands through TryPublishAtomicNativeGameStateTransition, exposing this
path to the mode-clearing helper. This matches the reported version boundary.
The repair stays on current source and retains subsequent immutable-command
ordering, retry, media scheduling, and per-trigger ownership improvements; it
does not restore the old coalescing transport.
Local diagnostic evidence is under isolated_results/native-haptics-evening-*
and isolated_results/native-watch. These are best-effort live reads, not an
atomic trace of every report. The watch ended normally with zero read errors;
it never suspended, injected into, or wrote to either controller process.
Separate disconnect stall¶
After the user reported a stall, the log stopped at closing VIIPER connections. Heap dumps of the mapper and Bluetooth helper established a circular wait:
- The device-command worker executes queued UI
DisconnectBT. StopOutputUpdatewaits for lifecycle completion.- The lifecycle worker joins the device-command worker before final output.
- A concurrent service Stop also waits for that lifecycle completion.
The GUI was still pumping messages. Both RC4.5.3 and the then-current RC4.5.7 source contain this cycle. The fix must transfer a joined worker's disconnect intent to the lifecycle owner, retain final neutral-output ordering, and keep definitive completion waits for external callers—not substitute a timeout that allows overlapping writers.
Evidence: isolated_results/haptics-stop-stall-20260911, including both heap
dumps, all managed stacks, and synchronization diagnostics. After capture, only
the exact stuck controller processes were closed and the same installed test
version was relaunched. The controller reconnected; profiles and installed files
were unchanged. Recovery alone is not the source fix.
Old installation cleanup¶
The specific 5.0.3.0 entry was an orphaned RC4.3 Burn registration, not an installed MSI. Its MSI product state was unknown; only the newer installed product was registered. Three exact stale registry keys were exported and removed. The old cached installer was moved to a recoverable Desktop backup; the old uninstaller was not invoked against shared current-version resources. Current MSI registration was independently checked unchanged. The user later deliberately reinstalled 5.0.3.0 as the known-working comparison build. That fresh installed reference was not removed or uninstalled by the orphan cleanup or the private-candidate handoff.
Validation status¶
- Four real-helper tests reproduced loss of the legacy/improved rumble mode
on subsequent media, covering both idle-command and piggyback presentation.
Red result:
isolated_results/rc457-native-rumble-mode/sdl-rumble-mode-red.trx. - Combined focused run: 116 passed, zero failed, including 15 new
real-helper rumble cases and four queued-disconnect lifecycle cases.
rumble-lifecycle-green.trxSHA-256:FC89393D6D7712FEB531E5090ECE0EDF5FAB466237D88B95ECA074DC73E612BD. - First full run: 5,410 passed, three failed, 11 gated skips. The failures were old cached-mode expectations. They were updated to assert continuous mode separately from one-shot triggers/LEDs; the idle case additionally checks the actual physical zero-motor guard. No case was removed or skipped.
- Final rebuilt, unfiltered Release x64 run: 5,413 passed, zero failed,
11 gated skips, 5,424 total. This includes 2,646 passing tests in
Switch 2/Joy-Con/Nintendo test classes. Allocation checks remained enabled
and passed.
Result:
isolated_results/rc457-native-rumble-final-green/full-native-rumble-disconnect-green.trx. - Functional source is committed as
14b8920b060ea9e81b64747116da543a54c93c08. - The complete private portable candidate was verified and launched, as recorded below. It is not a new published release.
- Physical acceptance in Hades II and Expedition 33 remains required. No claim of zero end-to-end latency or complete game coverage follows from unit tests.
Verified private portable handoff¶
Candidate root:
C:\Users\hbash\Desktop\DS4Windows-Haptics-Disconnect-Fix-20260911.
The archive and extracted payload both passed strict verification with all
553 files, including the pinned broker and required runtime/dependencies.
PRIVATE-CANDIDATE-MANIFEST.jsonSHA-256:D47D96AC468E7341BA0F3873CACFEC44E630F177CAF3E099EE2A721C2491FFFA.- Verified archive:
resume\x64\Release\DS4Windows_HAPTICS-DISCONNECT-FIX-20260911_x64.zip. SHA-256:BE258AD8C3372DAC7B217C2606FB11FB7F2EFDD464FB4451E00EA8AEAD72D9BD. - The first package failed the unchanged strict runtime-config check because
local SDK 8 emitted different runtime metadata. The exact released runtime
config was restored only in fresh staging, and the unchanged verifier then
passed. The original failed archive and runtime config remain preserved in
isolated_results/rc457-rumble-private/original-runtimeconfig-evidence. No verification rule was weakened and no installed runtime was changed.
At 18:07:18 local time on 2026-09-11, the private mapper started as PID 16132
with portable broker PID 3164. Bluetooth helper PID 28488 belonged to mapper
16132. The log found physical DualSense 10:18:49:BB:74:C7 at 18:07:25 and
recorded virtual DualSense association, active feedback, and speaker PCM
startup at 18:07:27. These are connection/startup observations, not proof that
a game supplied PCM or that the physical haptics feel correct.
The installed comparison build and original user profile were left intact.
The dsm profile's verified SHA-256 remained
FA2F06C5C7345DA583D5710327FCDA42B78A9F3951D4392D6656A4FF856BE8AA.
Normal RC4.3 shutdown removed the physical controller's HidHide entry; the
strict handoff guard detected that change and halted. Handoff resumed only
after explicit restoration of that exact entry. The private lab mode cannot
change HidHide device entries. Only the private application's allowlist entry
was added; global cloaking settings were not changed. The guarded halt,
restoration, profile copy, and final launch evidence are retained under the
candidate's handoff-evidence directory.
A subsequent non-suspending startup sample is retained under
isolated_results/native-haptics-evening-private-startup. Mapper 16132 and
helper 28488 both reported problems=[] and suspended=false. The mapper had
zero transport fault reports and zero rejected reports, with 17 control
deliveries and zero speaker deliveries. Helper rumble mode, improved mode,
and both motors were zero in this idle sample. No transport fault was observed
there; this is not physical haptics acceptance. Hades II and Expedition 33
feel/trigger confirmation remains pending.