Commit Graph
4 Commits
Author SHA1 Message Date
Joe MattielloandClaude Opus 5.5 337e595810 fix(app): Pro Controller (6-button) device with its own X Y Z L R controls (#1019)
* fix(app): add the Pro Controller (6-button) device with its own X Y Z L R controls

Settings > Input now offers "Pro Controller (6-button)" on both Jaguar ports.
The core has no RETRO_DEVICE id for it, only virtualjaguar_pN_device =
pad_pro, and the app locks that option to auto, so the core's
pro_controller[] flag could never turn on from the app. The option lock now
takes the Pro ports into account (lockedCoreOptionFor), and
CoreHost::refreshLocks() hands a changed value to the core through
GET_VARIABLE_UPDATE. retro_run() runs check_variables() before
update_input(), so a switch takes effect on the next frame. The app stores
a private id for the device in the joypad class and gives the core a
standard pad for it.

New controls X / Y / Z / L / R (Pro) are appended after C_TVMENU, so saved
ids keep their meaning. On a Pro port the Router presses them as RetroPad
X / L2 / R2 / L / R, and the core's Pro path turns those into keypad
9 / 8 / 7 / 4 / 6. They are never synthesised as keypad digits.

Gamepad defaults on a Pro port, Genesis 6-button style: A / B / C = East /
South / West, X / Y / Z = Left Shoulder / North / Right Shoulder, L / R =
the triggers. Keypad 0-4 have no pad button there and are reached through
the keypad overlay (Share). 5 / 6 stay on the stick clicks, 7 / 8 / 9 / *
on the right stick and # on Guide. The standard-pad defaults are unchanged:
a new remap_unit digest, frozen from the tree before this change, covers
every control that already existed. The keyboard has no Pro bindings,
because A S D / Q E already press keypad 9 8 7 / 4 6, the same wires.

The cheat sheet, the controls overlay and the remap table show the Pro
buttons for a Pro port.

Closes #1017

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(app): keep the Pro Controller lock on the emulation thread's owner

After #1000 the option state CoreHost keeps for the core (locked_, the
session values) belongs to the emulation thread, and the UI reads a
published snapshot of it. Three changes follow:

- refreshLocks() queues itself through `post` when it is called off the
  owner. On the owner it bumps the option serial and publishes, so the
  UI's copy of the locked values follows.
- App::proPorts is atomic, because the option lock reads it on the
  emulation thread.
- applyPortDevices() works out each port's kind from the lock's own
  value, not the UI snapshot, which lags until the queued refresh has
  run and been pinned.

With --emu-thread on, limitFeaturesForEmuThread() replaces the option
lock. Its lock called the 2-argument lockedCoreOption(), so pad_pro
never reached the core in that mode. It now uses lockedCoreOptionFor()
with the Pro ports, as wireHost()'s lock does.

Tests:
- core_host_thread: a lock value moved from the UI thread reaches the
  core before the next frame's input (RetroPad X reads as keypad 9 under
  pad_pro, keypad 0 without), the UI snapshot shows it after a pin, and
  no owner violations occur.
- pro_controller_option_on / _off: the app itself hands the core pad_pro
  for a config naming the Pro Controller, with the emulation thread on
  and off. The _on test fails when limitFeaturesForEmuThread() keeps the
  old lock.

Refs #1017

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-17 19:25:04 -04:00
Joseph MattielloandClaude Sonnet 5.5 56334e5780 fix(app): controls overlay off by default, hides on click/tap/Esc/F3
The cheat sheet popped up at every game start for keyboard players and could
not be dismissed with the mouse. Now:
- Settings > Input "Show the controls overlay when a game starts" defaults OFF;
  a keyboard player gets a one-per-session "Press F3 for the controls" toast.
- A click or tap anywhere (not on ImGui), Esc or F3 hides it; the dismissing
  press is masked from the game's pointer input until released.
- An auto-shown overlay also hides itself after 8 s; one opened with F3 stays.
- Pure show/hide policy in cheatsheet.{h,cpp} with unit tests; smoke tests
  cover default, on, off and rebound.

Refs #837

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-14 00:32:39 -04:00
Joseph MattielloandClaude Sonnet 5.5 a9a73f3db9 fix(app): report --option on a locked core option; no stick-as-D-pad on analog ports; Esc/F10 wording
--option naming an option the app forces (alt_inputs, pN_device, ...) is now rejected like an
unknown key instead of silently running the forced value; a stale saved value warns.  A gamepad's
left stick no longer also presses the D-pad where it is the analog axis (gear shift, hat).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-13 01:24:49 -04:00
Joseph MattielloandClaude Sonnet 5.5 edef0ac9f6 feat(app): input devices -- mouse, rotary, analog, driving, paddle, 6D, light gun, Team Tap
Per-port device picker (global and per game), host-input routing for every
non-pad device through the remap layer, Team Tap player slots, mouse capture,
a controls cheat-sheet overlay, a Pro Controller keyboard layout, and the
core's own remap/device options locked so they cannot fight the app.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-13 00:55:32 -04:00