Repository navigation
Conversation
…aptics on slot attach GetVibrationDeviceHandles hands out vibration handles at startup before a physical controller's haptics route is registered, while GetVibrationDeviceInfo still gated its answer on vib_targets (which requires dm_haptics_available()). Games that query GetVibrationDeviceInfo right after GetVibrationDeviceHandles during startup received DeviceType_Unknown (0) and Position_None (0), permanently disabling vibration for the session. Split vib_players from vib_targets so GetVibrationDeviceInfo reports LinearResonantActuator (1) and Left/Right (1/2) whenever a haptics sink is initialized and the handle addresses a valid player slot. Also intercept BeginForcedVibrationSession, EndForcedVibrationSession, and the detail/system PermitVibrationSession / PermitVibration functions in hle_hid.c so games like Super Mario Party (main+0x5d503c) do not enter the SDK's IHidServer proxy and dereference a null pointer on startup. On iOS, DmGamepad.m attached motion when a controller took a player slot in pads_slotted, pads_merged, or DM_PAD_PRESS_TO_JOIN, but deferred dm_haptics_apple_controller until the end of read_pad after the quit-prompt and controller-applet (cp_poll) guards. Route Core Haptics as soon as the slot is taken and use dm_gamepad_pads_read when the controller prompt returns to idle.
LNPANDY
added a commit
to LNPANDY/NX2Apple
that referenced
this pull request
Nov 9, 2026
LNPANDY
added a commit
to LNPANDY/NX2Apple
that referenced
this pull request
Nov 9, 2026
…aptics on slot attach (#1072) * hid: report vibration device info for startup handles and route iOS haptics on slot attach * patches: intercept forced/permit vibration sessions in 0106 (seedds/nxnative#2070)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
f45d362),GetVibrationDeviceHandlesreturns non-empty handles at startup before a physical controller's haptics route is registered (dm_haptics_available() == 0). However,GetVibrationDeviceInfostill gated its response onvib_targets(which requiresdm_haptics_available()). Games that queryGetVibrationDeviceInforight afterGetVibrationDeviceHandlesduring startup receivedDeviceType_Unknown (0)andPosition_None (0), permanently disabling controller vibration for the session. Splitvib_playersfromvib_targetssoGetVibrationDeviceInforeportsLinearResonantActuator (1)andLeft/Right(1/2) wheneverdm_hapticsis initialized and the handle addresses a valid player slot, whileSendVibrationValue/SendVibrationValuescontinue gating actuator output onvib_targets(dm_haptics_available()).ForcedVibrationSession/PermitVibrationSessioninhle_hid.c: Games such as Super Mario Party (010036B0034E4000,main+0x5d503c) callnn::hid::EndForcedVibrationSession()unconditionally during startup afterInitializeVibrationDevice. Without HLE interception, execution falls into the SDK'snn::hid::detail::EndPermitVibrationSession(), which attempts to callIHidServervia an uninitialized IPC proxy and crashes with a null pointer dereference (sdk+0x3526bc). InterceptBeginForcedVibrationSession,EndForcedVibrationSession, and thedetail/systemBeginPermitVibrationSession,EndPermitVibrationSession, andPermitVibrationfunctions withHLE_FORCE.DmGamepad.m),pads_slotted,pads_merged, andDM_PAD_PRESS_TO_JOINattached motion immediately when a controller claimed a player slot, but deferreddm_haptics_apple_controlleruntil the end ofread_pad(after the quit-prompt and controller-appletcp_pollearly returns). Bind Core Haptics when the slot is assigned and usedm_gamepad_pads_readwhen the controller applet returns to idle so haptics routing is never skipped during the transition frame.Testing
make -C dm/host/tests GAME=0100000000010000 build/t_hid build/t_haptics build/t_haptics_apple(t_hid: 210 checks, 0 failed;t_haptics&t_haptics_apple: pass)010036B0034E4000) on macOS with a Bluetooth controller: boots cleanly past shader precompilation at 60 FPS with activeVibrationNodehaptics output (~400 samples/sec).