fix(prompts): a control bound only on Input 2 shows that button's picture #485

Open
jarynclouatre wants to merge 1 commit from jarynclouatre/Longshot:fix/prompt-input2-picture into main
Contributor

Type: fix · Risk: low · Tested on: Linux x86-64 (game-free checks only) · Needs: none

Why

With Input 1 of a control cleared (Delete on the Controls page) and Input 2 set to another pad button, that button presses the control, but the game's prompt for it still shows the default button's picture.

current_binds and cmap4_bind in host/prompts.c read only hos_binding(HOS_BIND_PAD, b, 0). The input side uses both slots (bound_pad_buttons in host/nn_hid.c), and the keyboard face already falls back to the second slot (first_key).

None filed. Found reading host/prompts.c against the Controls page's two inputs.

How to reproduce

Seen on: found reading the code; not seen in the game
Settings and switches: Xbox button prompts; A's Input 1 cleared and Input 2 bound to LB.
Steps: On the Controls page, clear A's Input 1 with Delete, bind A's Input 2 to LB, and look at the prompts for A.
Expected: The prompts for A show LB, which presses A.
Actual: The prompts for A show B, which no longer presses A. The same happens on every face.

What changed

Button pictures now use Input 2 when Input 1 is clear. Changes to that second input also reach the textures and the live check.

  • prompts (host/prompts.c): a new first_pad(b) next to first_key returns Input 1's pad input, or Input 2's when Input 1 is clear. current_binds and cmap4_bind use it. A control with both inputs still shows Input 1's picture, a paddle still shows the default's icon, and a control with no pad input keeps today's picture. Since the snapshot from current_binds now follows Input 2, a change to a sole Input 2 while the game runs also reaches the textures and the live check.
  • tests (tests/test_prompt_font_bind.py): the stand-in hos_binding now has both slots; the left stick's click is bound on Input 2 only and the right stick's on both. The text-code check now builds its controls with the real current_binds over the same stand-in, and a new check compares that snapshot with what the inputs show.

Measurements

Verdict: the changed test fails with main's Input 1-only behaviour and passes here; the suite has no new failures.

Hardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14)
Scene: none, the game was not run
Method: 2026-11-14. python3 -I -B tests/run_all.py --jobs 4, two runs each (main twice, then the branches of this batch in turn, twice). The changed test also ran with first_pad reading Input 1 only (main's behaviour). Branch: fix/prompt-input2-picture.
How to reproduce: the commands above in a checkout of each commit

Before: main @ 9c9d69ed After: this PR @ 6894f0ec
tests/run_all.py (run 1, run 2) 485 passed, 2 failed, 83 skipped (both) 485 passed, 2 failed, 83 skipped (both)
failing checks test_bake_portability.py, test_walk_key.py the same two
tests/test_prompt_font_bind.py FAIL: face 0: 3 buttons bound, not 4 with Input 1 read only pass

test_bake_portability.py fails here for a missing Python module (zstandard). test_walk_key.py's fixture doesn't link on main (undefined reference to hos_oot_autoload_input).

Flags and settings

None.

Testing

Tested: the game-free suite on a Linux PC, as in Measurements; the test compiles first_key, first_pad, current_binds, cmap4_bind and text_code from host/prompts.c with gcc. host/prompts.c compiles (-fsyntax-only -Wall -Wextra) with llvm-mingw 20261104's x86_64-w64-mingw32-clang with no warnings, and whole with gcc in tests/test_mods_size_table.py's fixture.

Not tested: the game. A look at the prompts after binding a control on Input 2 only would show it.

Must be tested: None.

Risks

What could break: Only a control whose Input 1 is clear and Input 2 is set shows something new.

Turning it off: Reverting the commit puts the Input 1-only reading back.

Compatibility: Nothing changes for saves or longshot_options.ini; only such a control's prompt picture differs.

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named).
  • 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.

When it applies

  • Numbers from the same PC, scene and settings, at least 2 interleaved runs each, the median reported.
  • 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.
**Type:** fix · **Risk:** low · **Tested on:** Linux x86-64 (game-free checks only) · **Needs:** none ## Why With Input 1 of a control cleared (Delete on the Controls page) and Input 2 set to another pad button, that button presses the control, but the game's prompt for it still shows the default button's picture. `current_binds` and `cmap4_bind` in `host/prompts.c` read only `hos_binding(HOS_BIND_PAD, b, 0)`. The input side uses both slots (`bound_pad_buttons` in `host/nn_hid.c`), and the keyboard face already falls back to the second slot (`first_key`). None filed. Found reading `host/prompts.c` against the Controls page's two inputs. ## How to reproduce **Seen on:** found reading the code; not seen in the game **Settings and switches:** Xbox button prompts; A's Input 1 cleared and Input 2 bound to LB. **Steps:** On the Controls page, clear A's Input 1 with Delete, bind A's Input 2 to LB, and look at the prompts for A. **Expected:** The prompts for A show LB, which presses A. **Actual:** The prompts for A show B, which no longer presses A. The same happens on every face. ## What changed Button pictures now use Input 2 when Input 1 is clear. Changes to that second input also reach the textures and the live check. - prompts (`host/prompts.c`): a new `first_pad(b)` next to `first_key` returns Input 1's pad input, or Input 2's when Input 1 is clear. `current_binds` and `cmap4_bind` use it. A control with both inputs still shows Input 1's picture, a paddle still shows the default's icon, and a control with no pad input keeps today's picture. Since the snapshot from `current_binds` now follows Input 2, a change to a sole Input 2 while the game runs also reaches the textures and the live check. - tests (`tests/test_prompt_font_bind.py`): the stand-in `hos_binding` now has both slots; the left stick's click is bound on Input 2 only and the right stick's on both. The text-code check now builds its controls with the real `current_binds` over the same stand-in, and a new check compares that snapshot with what the inputs show. ## Measurements **Verdict:** the changed test fails with main's Input 1-only behaviour and passes here; the suite has no new failures. Hardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14) Scene: none, the game was not run Method: 2026-11-14. `python3 -I -B tests/run_all.py --jobs 4`, two runs each (main twice, then the branches of this batch in turn, twice). The changed test also ran with `first_pad` reading Input 1 only (main's behaviour). Branch: `fix/prompt-input2-picture`. How to reproduce: the commands above in a checkout of each commit | | Before: main @ 9c9d69ed | After: this PR @ 6894f0ec | |---|---|---| | `tests/run_all.py` (run 1, run 2) | 485 passed, 2 failed, 83 skipped (both) | 485 passed, 2 failed, 83 skipped (both) | | failing checks | `test_bake_portability.py`, `test_walk_key.py` | the same two | | `tests/test_prompt_font_bind.py` | `FAIL: face 0: 3 buttons bound, not 4` with Input 1 read only | pass | `test_bake_portability.py` fails here for a missing Python module (zstandard). `test_walk_key.py`'s fixture doesn't link on main (`undefined reference to hos_oot_autoload_input`). ### Flags and settings None. ## Testing **Tested:** the game-free suite on a Linux PC, as in Measurements; the test compiles `first_key`, `first_pad`, `current_binds`, `cmap4_bind` and `text_code` from `host/prompts.c` with gcc. `host/prompts.c` compiles (`-fsyntax-only -Wall -Wextra`) with llvm-mingw 20261104's x86_64-w64-mingw32-clang with no warnings, and whole with gcc in `tests/test_mods_size_table.py`'s fixture. **Not tested:** the game. A look at the prompts after binding a control on Input 2 only would show it. **Must be tested:** None. ## Risks **What could break:** Only a control whose Input 1 is clear and Input 2 is set shows something new. **Turning it off:** Reverting the commit puts the Input 1-only reading back. **Compatibility:** Nothing changes for saves or `longshot_options.ini`; only such a control's prompt picture differs. ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). - [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. ### When it applies - [x] Numbers from the same PC, scene and settings, at least 2 interleaved runs each, the median reported. - [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(prompts): a control bound only on Input 2 shows that button's picture
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
Website / Website on Cloudflare (pull_request_target) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 13s
beanstalk/approval Test farm not requested
6894f0ec16
current_binds and cmap4_bind read only a control's Input 1 pad binding. With
Input 1 cleared and Input 2 set, the input side presses the control from
Input 2, but the prompt kept the default button's picture and the live check
never saw a change to Input 2.

first_pad takes Input 1's pad input, else Input 2's, the way first_key already
does for keys. A control with both inputs still shows Input 1's picture.
jarynclouatre changed title from WIP: fix(prompts): a control bound only on Input 2 shows that button's picture to fix(prompts): a control bound only on Input 2 shows that button's picture 2026-11-14 16:31:20 +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
Website / Website on Cloudflare (pull_request_target) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 13s
beanstalk/approval Test farm not requested
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/prompt-input2-picture:jarynclouatre-fix/prompt-input2-picture'
git switch 'jarynclouatre-fix/prompt-input2-picture'
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!485
No description provided.