Files
psxrecomp/runtime
Matthew Stanley fc5b07f677 input: derive every pad source from one predicate (pad_sources_for)
The runtime decided which sources may drive a pad slot in three independent
places - the button merge in capture_pad_slot, the HYBRID analog/digital
auto-switch (hybrid_stick_active / hybrid_dpad_active), and the analog stick
fold. Nothing kept them in step.

That is a live hazard rather than a tidiness issue. If the button merge is
widened without widening the hybrid detectors, a source can assert the D-pad
while the hybrid state machine never sees it, so the pad reports D-pad presses
while still presenting ANALOG and never falls back to digital - the exact
failure the hybrid logic exists to prevent, and silent when it happens.
Commit 3ba40b02 previously removed a keyboard-always-P1 behaviour for related
reasons; the hybrid gates were written assuming it stayed removed.

pad_sources_for(p, dev_here) now returns the source set once (device,
keybinds, all_pads) and all three consumers read it. Input-routing POLICY
becomes a change to that one function instead of three conditions that must
be edited together.

Pure refactor - behaviour is unchanged:
  device   == (p.kind != 0), as before
  keybinds == (p.kind == 1 || dev_here), the same expression the hybrid
              D-pad detector already used
  all_pads == dev_here, as before
dev_here implies slot 0, so the previously hardcoded player 1 in
pad_from_keyboard(1) and psx_keybinds_sticks(keys, 1, ...) is the same value
as `player`. Where a consumer is now reached that was not before (kind==1 in
analog mode re-entering psx_keybinds_sticks), the call is idempotent: it only
sets fixed extremes on held binds, and pad_sticks_for already applied it with
the same player.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 19:04:12 -07:00
..
2026-07-29 03:18:10 -04:00
2026-07-29 03:18:10 -04:00