fix(input): an input still held after the Insert menu no longer blocks the pads' other buttons #340

Open
jarynclouatre wants to merge 1 commit from jarynclouatre/Longshot:fix/pad-after-menu-each into main
Contributor

Why

After the Insert menu was open once, the pads reach the game again only when no input of any controller is down. One input that stays down (a worn or mis-mapped trigger past its rest, a Guide button, something resting on a second controller) keeps every button and both sticks of every pad from the game for the rest of the session, while the Insert menu, which reads the raw word, still answers.

read_input in host/nn_hid.c keeps one flag: if (rx_option(1, 0)) pad_after_menu = 1; else if (pad_after_menu && !pad_raw_now) pad_after_menu = 0;, and gives the game the pads only while it is clear.

What changed

  • input (host/nn_hid.c, read_input): pad_after_menu is now the set of pad inputs (1 << HOS_PAD_*) that were down while the menu was open, or at the first read after it closed, so the press that closed it waits even when no read saw it while the menu was open. After the close each input leaves the set when it is let go, and the game gets bound_pad_buttons of the others (pads_read keeps the last read's inputs without the Back+Start chord in pad_raw_game for that). While the set is empty the game gets pads_read's word as before. The sticks are withheld while the menu is open and count again as soon as it is closed.
  • ocarina (oc_notes, oc_pad_word): the note layer leaves out the waiting pad inputs instead of playing no notes until all are up.
  • tests: tests/test_pads_after_menu.py (new) compiles production's pads_read, bound_pad_buttons and read_input's pad block with fakes for SDL, XInput and the clock. A trigger held through the menu and the close: the press that closed it and the trigger wait, the sticks count at once, South gives B with the trigger still down, the closing button counts when pressed again, the trigger counts once it was let go; a close press no read saw while the menu was open waits too; a button resting on a second pad waits while the first pad's buttons count. tests/test_ocarina_notes.py case (j) now holds the (L) note's pad input after the menu: no note from it, the keys' notes still play, and the note comes back once it was let go. tests/input_background_test.c declares the new state.

Flags and settings

None.

Measurements

main: 5ad0f503 (2026-11-14)
this PR: fix/pad-after-menu-each @ 74998cc5
Hardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14.4; no clang++ there)
Scene: none, the game was not run
Method: python3 -I -B tests/run_all.py, two runs each, interleaved (main, PR, main, PR, with the other two branches' runs between); both runs of a side gave the same counts. The PR's new or changed checks also run against main's source.
How to reproduce: the commands above in a checkout of each commit

main @ 5ad0f503 this PR @ 74998cc5
tests/run_all.py (run 1, run 2) 465 passed, 3 failed, 80 skipped (both) 466 passed, 3 failed, 80 skipped (both)
failing checks test_bake_portability.py, test_pad_layout.py, test_menu_keys.py the same three
tests/test_pads_after_menu.py fails: the stick is withheld while the trigger is down; with that line left out, South gives nothing with the trigger down passes

test_bake_portability.py fails here for a missing Python module (zstandard), on main as well. test_pad_layout.py fails on main since #137 (its fixture lacks host/hold_toggle.h; #331 and #338 fix it). test_menu_keys.py doesn't build with g++ on main since #137 (#338 fixes it).

Testing

Tested: the game-free suite on a Linux PC, as in Measurements. host/nn_hid.c compiles (-fsyntax-only) with llvm-mingw 20261104's x86_64-w64-mingw32-clang and with Linux gcc 15.2, with the same warnings as main's; no file paths are touched.

Not tested: a controller in the game. The new test runs production's pad read and the pad block of read_input with the pads faked at SDL's boundary.

Needs other testers: None.

Screenshots

Nothing on screen.

Risk and rollback

The sticks now count right after the menu closes instead of after every input was let go; host/pad_sdl.c's stick rest guard is unchanged. Reverting the commit puts the single flag back.

Reviewer notes

  • Issue 296 (a 360 pad moves the Insert menu but gives the game nothing) has the same look, but this was not shown to be its cause.
  • #286 moves the same lines of read_input (pads behind another window); one of the two will need a small rebase.

Issues

For #296

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above).
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests).
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported.
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

If applicable

  • Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths.
  • A game-free test added for the fix, failing on main and passing here.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
## Why After the Insert menu was open once, the pads reach the game again only when no input of any controller is down. One input that stays down (a worn or mis-mapped trigger past its rest, a Guide button, something resting on a second controller) keeps every button and both sticks of every pad from the game for the rest of the session, while the Insert menu, which reads the raw word, still answers. `read_input` in `host/nn_hid.c` keeps one flag: `if (rx_option(1, 0)) pad_after_menu = 1; else if (pad_after_menu && !pad_raw_now) pad_after_menu = 0;`, and gives the game the pads only while it is clear. ## What changed - input (`host/nn_hid.c`, `read_input`): `pad_after_menu` is now the set of pad inputs (`1 << HOS_PAD_*`) that were down while the menu was open, or at the first read after it closed, so the press that closed it waits even when no read saw it while the menu was open. After the close each input leaves the set when it is let go, and the game gets `bound_pad_buttons` of the others (`pads_read` keeps the last read's inputs without the Back+Start chord in `pad_raw_game` for that). While the set is empty the game gets `pads_read`'s word as before. The sticks are withheld while the menu is open and count again as soon as it is closed. - ocarina (`oc_notes`, `oc_pad_word`): the note layer leaves out the waiting pad inputs instead of playing no notes until all are up. - tests: `tests/test_pads_after_menu.py` (new) compiles production's `pads_read`, `bound_pad_buttons` and `read_input`'s pad block with fakes for SDL, XInput and the clock. A trigger held through the menu and the close: the press that closed it and the trigger wait, the sticks count at once, South gives B with the trigger still down, the closing button counts when pressed again, the trigger counts once it was let go; a close press no read saw while the menu was open waits too; a button resting on a second pad waits while the first pad's buttons count. `tests/test_ocarina_notes.py` case (j) now holds the (L) note's pad input after the menu: no note from it, the keys' notes still play, and the note comes back once it was let go. `tests/input_background_test.c` declares the new state. ## Flags and settings None. ## Measurements main: 5ad0f503 (2026-11-14) this PR: fix/pad-after-menu-each @ 74998cc5 Hardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14.4; no clang++ there) Scene: none, the game was not run Method: `python3 -I -B tests/run_all.py`, two runs each, interleaved (main, PR, main, PR, with the other two branches' runs between); both runs of a side gave the same counts. The PR's new or changed checks also run against main's source. How to reproduce: the commands above in a checkout of each commit | | main @ 5ad0f503 | this PR @ 74998cc5 | |---|---|---| | `tests/run_all.py` (run 1, run 2) | 465 passed, 3 failed, 80 skipped (both) | 466 passed, 3 failed, 80 skipped (both) | | failing checks | `test_bake_portability.py`, `test_pad_layout.py`, `test_menu_keys.py` | the same three | | `tests/test_pads_after_menu.py` | fails: the stick is withheld while the trigger is down; with that line left out, South gives nothing with the trigger down | passes | `test_bake_portability.py` fails here for a missing Python module (zstandard), on main as well. `test_pad_layout.py` fails on main since #137 (its fixture lacks `host/hold_toggle.h`; #331 and #338 fix it). `test_menu_keys.py` doesn't build with g++ on main since #137 (#338 fixes it). ## Testing **Tested:** the game-free suite on a Linux PC, as in Measurements. `host/nn_hid.c` compiles (`-fsyntax-only`) with llvm-mingw 20261104's x86_64-w64-mingw32-clang and with Linux gcc 15.2, with the same warnings as main's; no file paths are touched. **Not tested:** a controller in the game. The new test runs production's pad read and the pad block of `read_input` with the pads faked at SDL's boundary. **Needs other testers:** None. ## Screenshots Nothing on screen. ## Risk and rollback The sticks now count right after the menu closes instead of after every input was let go; `host/pad_sdl.c`'s stick rest guard is unchanged. Reverting the commit puts the single flag back. ## Reviewer notes - Issue 296 (a 360 pad moves the Insert menu but gives the game nothing) has the same look, but this was not shown to be its cause. - #286 moves the same lines of `read_input` (pads behind another window); one of the two will need a small rebase. ## Issues For #296 ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). - [x] Tested in the game, or what wasn't is named under Testing. - [x] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). - [x] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### If applicable - [x] Host code builds on both Windows (llvm-mingw) and Linux, with UTF-8 paths. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened.
fix(input): an input still held after the Insert menu no longer blocks the pads' other buttons
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 11s
Website / Website on Cloudflare (pull_request_target) Has been skipped
74998cc555
After the Insert menu closed, read_input gave the game no pad input until
every input of every pad was up (one pad_after_menu flag). One input that
stayed down, a worn trigger past its rest, a Guide button, something resting
on a second controller, kept all buttons and both sticks of all pads from the
game for the rest of the session, while the menu, which reads the raw word,
still answered.

pad_after_menu is now the set of inputs that were down while the menu was
open or at the first read after it closed; each leaves the set when it is let
go, and the game gets the bound buttons of the rest (pads_read keeps the
chordless raw word for that). The press that closed the menu still waits
until released. The sticks count again as soon as the menu is closed. The
ocarina's note layer leaves out the waiting inputs instead of waiting for all.
jarynclouatre changed title from WIP: fix(input): an input still held after the Insert menu no longer blocks the pads' other buttons to fix(input): an input still held after the Insert menu no longer blocks the pads' other buttons 2026-11-14 02:15:21 +00:00
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 11s
Website / Website on Cloudflare (pull_request_target) Has been skipped
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
Some workflows are waiting to be reviewed.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'fix/pad-after-menu-each:jarynclouatre-fix/pad-after-menu-each'
git switch 'jarynclouatre-fix/pad-after-menu-each'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!340
No description provided.