Add the HD vibration row to the Controls tab and describe HD rumble in the controls guide.

The row switches rumble_hd and is greyed out, with a note of what it needs, while the gamepad in use is not a Switch
Pro Controller or Joy-Con. Its texts are in all four menu languages.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
chrg6
2026-11-12 22:27:34 -05:00
parent df8431da7b
commit aeb6c0d5c1
4 changed files with 34 additions and 0 deletions

View File

@@ -136,6 +136,19 @@ The stick direction bits (`StickLLeft` to `StickRDown`) are derived from the sti
Keys tilt a stick all the way, so on the keyboard alone Link always runs. `NX2NAVI_WALK_KEY` (`walk_key`, the *Walk key* row under *Analog sticks* on the Controls tab) names a key that, while held, scales the stick values the keys give (movement and camera keys) to `NX2NAVI_WALK_SCALE` of full (`walk_scale`, the *Walk scale* row; 0.2 to 0.9, default 0.51), so Link walks. The value is a key name of the `bind_` lines, or `none` (the default: off). The row offers Shift, Alt, Ctrl, Tab and Caps Lock and names the button a chosen key also presses: with the default bindings Shift is A, Ctrl is B and Tab is Plus, while Alt and Caps Lock are free. The gamepad's sticks and the mouse camera are not scaled. The default is just above half because half of a key's full value falls one short of the 50% the direction bits need. Both settings apply at once while the game runs.
## HD rumble on Switch controllers
The game makes its vibration for linear actuators: per side a low and a high band, each with a frequency and an amplitude. On most gamepads that is reduced to two motor strengths. With `rumble_hd = 1` in `nx2navi.ini` (`NX2NAVI_RUMBLE_HD`, the *HD vibration (Switch)* row on the Controls tab, live, off by default) a Switch controller gets the values as the game makes them, in the controller's own rumble report (`runtime/rumble_hd.c`, `runtime/input.c` "HD rumble"):
| Gamepad the game reads | Reports go | Connection |
|---|---|---|
| Switch Pro Controller (`057e:2009`) | through SDL (`SDL_SendGamepadEffect`) | USB and Bluetooth |
| One Joy-Con | through SDL; the stronger side's value, as it has one actuator | Bluetooth, or the USB charging grip |
| A left and a right Joy-Con as one gamepad | to the two Joy-Con's HID devices directly (`runtime/input_hd_pair.c`), as SDL takes no rumble data for the combined gamepad | Bluetooth |
| Anything else, the Switch 2 controllers included | the motors, as with `rumble_hd = 0` | |
The log says which it is when a gamepad is taken: `input: HD rumble available for this gamepad: a Pro Controller, through SDL (rumble_hd = 1)`, or `not available` with the reason; the row on the Controls tab is greyed out for a gamepad that cannot take it. With `rumble_hd = 0` nothing is written to the controller and the line says that its driver is asked once the setting is on. The first report a gamepad gets is logged with its bytes (`input: HD rumble: first report written (left ..., right ...)`); a report the controller or its driver refuses is logged too, and the gamepad then rumbles through its motors again. Frequencies are clamped to what the actuators take (41 to 626 Hz in the low band, 82 to 1253 Hz in the high band) and amplitudes to 0..1, the actuators' safe maximum. `rumble_strength` scales the amplitude (100 is the game's own; the default 130 is louder), `rumble_curve` does not apply, and `rumble = 0` silences this path too. A report is written at most every 15 ms (`rumble_hd_ms`, 5 to 50: raise it if a Bluetooth controller stutters or disconnects with HD rumble on), with the newest value only; a value that holds is written again every 30 ms, and the neutral value goes out when the game stops sending for 250 ms, when another gamepad takes over, when the setting is turned off and when the game exits. While HD rumble is on the game makes no dual-motor rumble call for that gamepad. A DualShock 3 on the direct reader keeps its motors either way.
## Nintendo Switch 2 controllers
Windows does not present the Switch 2 Pro Controller as a gamepad SDL can open (the log says `input: no gamepad`), so it needs a bridge program that wakes it and creates a virtual gamepad, for example one that emulates a DualSense: that gives buttons, rumble, gyro and accelerometer. The log then shows `input: gamepad "DualSense Wireless Controller" ... (rumble, gyro and accelerometer, ...)` and `input: motion sensors on`. Bridges that output a DualShock 4 whose gyro and accelerometer never change give buttons and rumble but no motion. Run one bridge at a time; Steam Input can also claim the controller, so close Steam if the bridge does not find it. With several virtual and real gamepads connected the game follows whichever one is pressed.