Tests pin player 1 (0x04), the default blue (0, 0, 128) and the instant
bit (0x20) to hid-playstation.c and SDL; the docs say what Horizon resets
on quit (more than SDL or the kernel do) and that the mute LED is never
touched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lightbar shows the player's health (green to amber to red) or the
dimension, at half brightness, chosen in the controller options (Lightbar:
Health / Dimension / Off; health by default). The player LEDs show player 1.
When Horizon lets go of the pad, the lights it changed go back to a host's
defaults.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The pad's audio device is also found by Windows' "Wireless Controller"
endpoint name (the four channels rule out a DualShock 4); a name test.
- docs/controllers.md: the haptics need reports without the rumble flags
(SDL, nondebug/dualsense, dse-haptics), which Horizon now always sends while
they are open; Windows needs the Quadraphonic speaker setup; on Linux ALSA
can't open the card while PipeWire holds it; Bluetooth haptics (report
0x32, SAxense) are documented and not done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each rumble event plays a short shape instead of one flat block: a hit
starts at full strength and dies away, an explosion rolls on, a totem
swells, a broken block is a tick. They drive the motors' emulation in the
HID report.
On USB the pad is also a four-channel audio device whose channels 3 and 4
drive its actuators: with HORIZON_DUALSENSE_HAPTICS=1 the shapes play there
as waveforms (80 Hz and 200 Hz tones for the heavy and light parts),
channels 1 and 2 silent, until that path is confirmed on a real pad.
docs/controllers.md says what each OS and transport allows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A loaded crossbow and the boosts (rocket, pig, strider) get a weapon
catch that breaks in the zone where the trigger threshold presses, so the
click is the shot (the boost was a feedback wall that never gave way).
- Draws start at zone 2 and stop at 6 of 8 (held for as long as you like).
- A shield in the use hand weighs (feedback 2, 3); disabled by an axe, the
trigger locks (feedback 1, 8), as Deathloop does for a jammed gun.
- Mining buzzes slower on harder blocks (40/30/20/10 Hz).
- A 0 Hz vibration frees the trigger (Nielk1's factory); tests pin the
bytes to DSX++'s and dualsensectl's examples.
- docs/controllers.md: the table with the effect of each action and why.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each trigger feels the action bound to it: resistance growing while a bow
draws, a trident charges or a crossbow loads, a gun trigger's click on a
loaded crossbow, a wall where pulling boosts (a rocket while gliding, the
stick of a ridden pig or strider), and a light buzz while mining, scaled by
the block's hardness. Free in menus, paused, unfocused, on another pad,
with controllers off, and on quit. On by default, "Adaptive Triggers" in
the controller options turns them off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Every report carries the motors; still motors send no rumble flags, as SDL
stops rumble (a report without them ends the emulation and re-arms the
audio haptics), so a trigger change no longer cuts a vibration.
- Legacy vibration at half strength (SDL); the Edge always takes V2; an
unreadable firmware version falls back to legacy.
- The first report after opening clears the motor/trigger attenuation
(flags 1 bit 6, byte 36; dualsensectl, pydualsense).
- The LED reset goes in a report of its own before any colour
(hid-playstation's dualsense_reset_leds); over Bluetooth the colour waits
for the connection animation (SDL's sensor clock check).
- Bluetooth output only where gilrs keeps reading the pad (Linux), else with
HORIZON_DUALSENSE_BT=1: any output switches the pad to its full report.
- USB is preferred when the pad is on both.
- Tests pin the reset report and its CRC (zlib), the flags and the clock offset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The horizon-dualsense crate builds the DualSense's output report (USB 0x02,
Bluetooth 0x31 with its CRC-32 seeded with 0xA2) and writes it with hidapi
from a thread. The game sends its rumble pulses through it when the active
pad is a DualSense, so vibration now works on macOS too, and falls back to
gilrs force feedback when the pad can't be opened. Quitting frees the
triggers and stops the motors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vanilla 26.3 has no gamepad code; Horizon's own design follows Bedrock's
default controller layout. Mapping, menus, glyphs, options file, rumble,
Steam Deck and the PR plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>