WIP: feat(input): separate keyboard actions and binding pages #613

Draft
TheDevil wants to merge 3 commits from TheDevil/Longshot:feat/keyboard-actions-bindings into main
First-time contributor

Type: feat · Risk: medium · Tested on: Windows llvm-mingw renderer build and game-free fixtures · Needs: fresh in-game input/controller validation and Linux build

Why

Keyboard players need interaction, sprint and roll on separate bindings without changing controller A. Separate keyboard and controller pages also make those choices understandable. This is the input-only replacement for the corresponding portion of #173. See #180 for keyboard prompts and #185 for the related concern about keeping keyboard/controller input independent.

What changed

An opt-in PC keyboard mode separates sprint hold, sprint toggle and roll from the ordinary A/interact binding. The controller continues to use the game's original A action path and its existing binding/toggle settings.

  • host/pc_controls.c, nx2/oot_pc_controls.py: all three input instructions validated together before hooking; keyboard state, roll edge/buffer, toggle cancellation and both controller A binding slots. Unsupported sites stop the lift instead of applying a partial hook.
  • gpu/vk/vk_menu.cpp: separate Keyboard & Mouse and Controller bindings pages, immediate custom-action binding, independent resets, retained Walk/ocarina controls, and keyboard labels over the native HUD D-pad.
  • gpu/vk/vk_api.h: API 23, preserving main's API-22 text-input callback and adding the shared action record, physical-pad sampling and a game-thread menu observer. Option 61 is separate from existing option IDs.
  • No item-wheel selection, icon extraction, guest-call bridge, NR or 30 FPS change is included. The wheel will be a dependent PR with its own host callbacks/API increment.
  • Existing source-extraction fixtures updated for the new keyboard globals/pages and the HUD-only rendering path; original assertions retained or adapted to the separate-page model.

Measurements

Verdict: the input producer, binding navigation, focus, ocarina, native menu and overlay-order fixtures pass; the NGX-enabled Windows Vulkan renderer links. No current-revision in-game latency/performance result is claimed.

Before: main @ 2b1d38c682
After: this PR @ 92e8eba875
Hardware: Windows x64, i7-14700F, 16 GB RAM; GPU/driver not exercised by the game-free fixtures.
Scene: authored option/clock/input fixtures; no gameplay rendered for this revision.
How to reproduce: run python -I -B tests/run_all.py with the official llvm-mingw compiler on PATH; focused commands are listed under Testing.
Method: game-free production-code fixtures with fake keys/pads/guest memory; native renderer compilation without a game.

Check Before: main @ 2b1d38c6 After: this PR @ 92e8eba8
Independent keyboard sprint hold/toggle and roll absent producer/edge/reset fixtures pass
Controller A slots native actions both slots retain native action bits in fixture
Separate binding pages / invalid toggle cells combined page navigation and disabled Plus/Minus cells pass
Full game-free suite 530 pass, 14 fail, 34 skip 532 pass, same 14 fail, 34 skip

Follow-up extracted audio/stick fixtures pass with the new PC field, and checks for the explicit pc_controls save key and persistence passed after the full run. Renderer rebuilt after the final key mapping, zero compile failures.

Flags and settings

PC mode is off by default. This PR adds no environment switches.

Flag What it is Before this PR After this PR Effect Helps / doesn't help / untested Recommendation
pc_controls opt-in Controls row/ini key absent 0 (off) keyboard action separation and HUD labels KBM players; controller A is native; physical devices pending off by default
key_sprint virtual key absent 0 (unbound) hold to sprint keyboard only bind as preferred
key_sprint_toggle virtual key absent 84 (T) press to toggle sprint keyboard only; focus/menu/controller use cancels it user choice; avoids stock Shift/B conflict
key_roll virtual key absent 5 (Mouse4) separate roll edge keyboard/mouse only user choice

Testing

Tested: Windows full suite, focused production-code fixtures and NGX-enabled Vulkan renderer link. Checks cover both controller A binding slots, held/edge input, roll buffers, focus/menu cancellation, key conflicts, independent binding-page resets, controller toggle navigation, ocarina note rows, existing menu mouse behavior and HUD-only overlay recording. git diff --check passes.

Baseline failures reproduced on main: tests/test_appimage_player_build.py, tests/test_cpm_discovery.py, tests/test_crash_dialog.py, tests/test_env_on.py, tests/test_finish_output.py, tests/test_lift_cleanup_error.py, tests/test_linux_preflight.py, tests/test_make_game_cache.py, tests/test_oot_state_tap.py, tests/test_readback_late.py, tests/test_tested_configurations.py, tests/test_vk_pgo.py, tests/test_vram_budget_row.py, tests/test_walk_key.py.

Not tested: this split revision in a running game, physical gamepads, Linux host/renderer build, unusual mouse buttons/layouts and long play sessions. Earlier combined-install results are not substituted for a fresh run of this API-23 slice. The user's installed game was not changed.

Must be tested:

  • Windows, by hand: fresh build with API-23 host and renderer; enable PC mode, bind sprint hold/toggle/roll and interaction separately, check walking/interacting/rolling and focus/pause changes; then verify original A interaction/sprint/roll on both physical controller binding slots, expecting correct timing/input behavior without regressions (by hand).
  • Linux, by hand: build host and renderer, check PC mode off and on, key rebinding, focus loss and native controller/ocarina behavior, expecting a successful native build and the same behavior (by hand).

Risks

What could break: guest instruction assumptions, input-device transitions, buffered roll and persistence of custom bindings; a mismatched host/renderer is not compatible. Mouse/menu/HUD focus needs a fresh live check after this rebase.

Turning it off: PC keyboard controls Off restores native action behavior. Reverting this commit removes the optional controls and pages.

Compatibility: saves and shader/pipeline cache formats do not change. New ini keys are optional. API advances 22 to 23: rebuild host and renderer together; main's text input remains present. Builder/lift includes the new instruction-checked module; no game assets or executable patches are distributed.

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

  • AI assistance recorded with Assisted-by: trailer.
  • New settings documented, opt-in and default bindings stated.
  • API bumped to 23, keeping main's text-input callback.
  • Regression fixtures added and affected source-reading checks updated.
  • Fresh split-revision in-game measurements/screenshots and docs/tested/ fragment: pending; WIP.
  • Host build/runtime on Windows and Linux: renderer and production-code Windows fixtures pass; full host/Linux/live validation pending.
  • Docs updated.

Upstream refresh

Current head: 04fa541dc8ccbaf29b089b5058a541de4436827a. Main snapshot 6c9edffe is incorporated by merge, preserving published history. 10 focused checks passed after the merge; zero failures/skips. Earlier full-suite measurements remain tied to their named feature commits above. The literal rebase checklist remains unticked because history was merged, not rewritten. Fresh game/Linux checks remain WIP.

**Type:** feat · **Risk:** medium · **Tested on:** Windows llvm-mingw renderer build and game-free fixtures · **Needs:** fresh in-game input/controller validation and Linux build ## Why Keyboard players need interaction, sprint and roll on separate bindings without changing controller A. Separate keyboard and controller pages also make those choices understandable. This is the input-only replacement for the corresponding portion of https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/173. See #180 for keyboard prompts and #185 for the related concern about keeping keyboard/controller input independent. ## What changed An opt-in PC keyboard mode separates sprint hold, sprint toggle and roll from the ordinary A/interact binding. The controller continues to use the game's original A action path and its existing binding/toggle settings. - `host/pc_controls.c`, `nx2/oot_pc_controls.py`: all three input instructions validated together before hooking; keyboard state, roll edge/buffer, toggle cancellation and both controller A binding slots. Unsupported sites stop the lift instead of applying a partial hook. - `gpu/vk/vk_menu.cpp`: separate Keyboard & Mouse and Controller bindings pages, immediate custom-action binding, independent resets, retained Walk/ocarina controls, and keyboard labels over the native HUD D-pad. - `gpu/vk/vk_api.h`: API **23**, preserving main's API-22 text-input callback and adding the shared action record, physical-pad sampling and a game-thread menu observer. Option 61 is separate from existing option IDs. - No item-wheel selection, icon extraction, guest-call bridge, NR or 30 FPS change is included. The wheel will be a dependent PR with its own host callbacks/API increment. - Existing source-extraction fixtures updated for the new keyboard globals/pages and the HUD-only rendering path; original assertions retained or adapted to the separate-page model. ## Measurements **Verdict:** the input producer, binding navigation, focus, ocarina, native menu and overlay-order fixtures pass; the NGX-enabled Windows Vulkan renderer links. No current-revision in-game latency/performance result is claimed. Before: main @ 2b1d38c682baaa4d52f2cacc75fffb9505c1f34f After: this PR @ 92e8eba875c8fb9bab682b5161a3e856c6f988a9 Hardware: Windows x64, i7-14700F, 16 GB RAM; GPU/driver not exercised by the game-free fixtures. Scene: authored option/clock/input fixtures; no gameplay rendered for this revision. How to reproduce: run `python -I -B tests/run_all.py` with the official llvm-mingw compiler on PATH; focused commands are listed under Testing. Method: game-free production-code fixtures with fake keys/pads/guest memory; native renderer compilation without a game. | Check | Before: main @ 2b1d38c6 | After: this PR @ 92e8eba8 | |---|---|---| | Independent keyboard sprint hold/toggle and roll | absent | producer/edge/reset fixtures pass | | Controller A slots | native actions | both slots retain native action bits in fixture | | Separate binding pages / invalid toggle cells | combined page | navigation and disabled Plus/Minus cells pass | | Full game-free suite | 530 pass, 14 fail, 34 skip | 532 pass, same 14 fail, 34 skip | Follow-up extracted audio/stick fixtures pass with the new PC field, and checks for the explicit `pc_controls` save key and persistence passed after the full run. Renderer rebuilt after the final key mapping, zero compile failures. ### Flags and settings PC mode is off by default. This PR adds no environment switches. | Flag | What it is | Before this PR | After this PR | Effect | Helps / doesn't help / untested | Recommendation | |---|---|---|---|---|---|---| | pc_controls | opt-in Controls row/ini key | absent | 0 (off) | keyboard action separation and HUD labels | KBM players; controller A is native; physical devices pending | off by default | | key_sprint | virtual key | absent | 0 (unbound) | hold to sprint | keyboard only | bind as preferred | | key_sprint_toggle | virtual key | absent | 84 (T) | press to toggle sprint | keyboard only; focus/menu/controller use cancels it | user choice; avoids stock Shift/B conflict | | key_roll | virtual key | absent | 5 (Mouse4) | separate roll edge | keyboard/mouse only | user choice | ## Testing **Tested:** Windows full suite, focused production-code fixtures and NGX-enabled Vulkan renderer link. Checks cover both controller A binding slots, held/edge input, roll buffers, focus/menu cancellation, key conflicts, independent binding-page resets, controller toggle navigation, ocarina note rows, existing menu mouse behavior and HUD-only overlay recording. `git diff --check` passes. Baseline failures reproduced on main: `tests/test_appimage_player_build.py`, `tests/test_cpm_discovery.py`, `tests/test_crash_dialog.py`, `tests/test_env_on.py`, `tests/test_finish_output.py`, `tests/test_lift_cleanup_error.py`, `tests/test_linux_preflight.py`, `tests/test_make_game_cache.py`, `tests/test_oot_state_tap.py`, `tests/test_readback_late.py`, `tests/test_tested_configurations.py`, `tests/test_vk_pgo.py`, `tests/test_vram_budget_row.py`, `tests/test_walk_key.py`. **Not tested:** this split revision in a running game, physical gamepads, Linux host/renderer build, unusual mouse buttons/layouts and long play sessions. Earlier combined-install results are not substituted for a fresh run of this API-23 slice. The user's installed game was not changed. **Must be tested:** - Windows, by hand: fresh build with API-23 host and renderer; enable PC mode, bind sprint hold/toggle/roll and interaction separately, check walking/interacting/rolling and focus/pause changes; then verify original A interaction/sprint/roll on both physical controller binding slots, expecting correct timing/input behavior without regressions (by hand). - Linux, by hand: build host and renderer, check PC mode off and on, key rebinding, focus loss and native controller/ocarina behavior, expecting a successful native build and the same behavior (by hand). ## Risks **What could break:** guest instruction assumptions, input-device transitions, buffered roll and persistence of custom bindings; a mismatched host/renderer is not compatible. Mouse/menu/HUD focus needs a fresh live check after this rebase. **Turning it off:** PC keyboard controls Off restores native action behavior. Reverting this commit removes the optional controls and pages. **Compatibility:** saves and shader/pipeline cache formats do not change. New ini keys are optional. API advances 22 to 23: rebuild host and renderer together; main's text input remains present. Builder/lift includes the new instruction-checked module; no game assets or executable patches are distributed. ## 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. - [ ] 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] AI assistance recorded with `Assisted-by:` trailer. - [x] New settings documented, opt-in and default bindings stated. - [x] API bumped to 23, keeping main's text-input callback. - [x] Regression fixtures added and affected source-reading checks updated. - [ ] Fresh split-revision in-game measurements/screenshots and `docs/tested/` fragment: pending; WIP. - [ ] Host build/runtime on Windows and Linux: renderer and production-code Windows fixtures pass; full host/Linux/live validation pending. - [x] Docs updated. ## Upstream refresh Current head: `04fa541dc8ccbaf29b089b5058a541de4436827a`. Main snapshot `6c9edffe` is incorporated by merge, preserving published history. 10 focused checks passed after the merge; zero failures/skips. Earlier full-suite measurements remain tied to their named feature commits above. The literal rebase checklist remains unticked because history was merged, not rewritten. Fresh game/Linux checks remain WIP.
feat(input): separate keyboard actions and binding pages
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 16s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
9a7dd1f059
Assisted-by: OpenAI Codex
test(input): keep extracted menu fixtures complete
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 5s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
92e8eba875
Assisted-by: OpenAI Codex
Author
First-time contributor

Aligned the description with the current template and named fixture results. Pending in-game/Linux validation remains explicit and the PR stays WIP.

Aligned the description with the current template and named fixture results. Pending in-game/Linux validation remains explicit and the PR stays WIP.
Merge current main into keyboard controls
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 5s
Website / Website on Cloudflare (pull_request_target) Has been skipped
04fa541dc8
Assisted-by: Codex
Author
First-time contributor

Updated the branch to include main @ 6c9edffe by non-rewriting merge. Current head 04fa541dc8; 10 focused post-merge checks passed, 0 failed/skipped. Description preserves commit-specific full-suite results and remaining live/Linux validation. Still WIP.

Updated the branch to include main @ 6c9edffe by non-rewriting merge. Current head 04fa541dc8ccbaf29b089b5058a541de4436827a; 10 focused post-merge checks passed, 0 failed/skipped. Description preserves commit-specific full-suite results and remaining live/Linux validation. Still WIP.
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 5s
Website / Website on Cloudflare (pull_request_target) Has been skipped
This pull request has changes conflicting with the target branch.
  • gpu/vk/menu_i18n.h
  • gpu/vk/vk_api.h
  • host/rx_backend.c
Some workflows are waiting to be reviewed.
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'feat/keyboard-actions-bindings:TheDevil-feat/keyboard-actions-bindings'
git switch 'TheDevil-feat/keyboard-actions-bindings'
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!613
No description provided.