Repository navigation
feat: add separate button mappings for the ocarina notes - #1930
Conversation
8d17600 to
fa877cc
Compare
6462f74 to
903f704
Compare
Joey-Magnus
left a comment
There was a problem hiding this comment.
Thanks for this. Being able to bind the five notes on their own is a nice addition, the wait detection is carefully done (the beat timeout, and the dialogue gates that end the wait), and the new checks pass at the PR's head (test_ocarina_*, test_bound_keys, test_input_background, test_menu_keys). But the defaults change how the ocarina plays for most players before they touch the new rows, and I think that needs fixing before it merges.
blocking Keyboard players lose their note keys by default (host/nn_hid.c:876 and :520). During a button wait, oc_pad_word clears L, R, A, X and Y from the merged button word, keyboard included, and puts back only what the note rows hold. The note rows default to Num 0/2/4/6/8. So out of the box, the keys a player already plays the ocarina with (E, Q, R, Space, the left mouse button, or their own bindings) stop playing notes, and the ocarina only answers the numpad. Laptops and tenkeyless keyboards have no numpad, so those players can't play a song until they find the new rows. With NumLock off, the numpad keys also arrive as Insert and the arrows, so Num 0 opens the menu.
blocking Pads on the Xbox / PC or Swap Face layout (host/nn_hid.c:503, :858). The note pads default to the Nintendo positions (A = East, Y = West, X = North) and don't follow the Layout preset. On Xbox / PC, apply_pad_layout puts the Switch's B on East and A on South. During the wait, oc_notes marks East as consumed, so pads_read no longer reports B: the player can't put the ocarina away with their B button, and East plays the A note instead. South, their A, is stripped by oc_pad_word and plays nothing. That's a common layout on PC.
One way to fix both: leave the note rows unbound by default, meaning "the Switch button's own binding", and only take the wait over (strip and consume) for a note the player actually bound. Then nothing changes for anyone who doesn't use the rows, and HOS_OC_NOTES=0 is no longer needed as an escape hatch. If you'd rather keep explicit defaults, derive them from the current L/R/A/Y/X bindings (pad and keys) when the rows are first created, and re-derive the pad ones when the Layout preset changes.
should fix gpu/vk/vk_api.h:58: HOS_KEY_N grows, and the meaning of MkwVkHost::binding/bind changes (the pad set now accepts rows above HOS_SW_N). AGENTS.md asks for an MKWVK_API_VERSION bump when the host/renderer contract changes, and an exe and DLL from either side of this would disagree about the rows (an old host answers -1 and the menu would save pad_note_*=-1). It's a one-line bump. The branch is also several versions behind: its base has version 14, main is at 17.
should fix The branch conflicts with main (mergeable: CONFLICTING), so it needs a rebase. CI hasn't run the test workflows on it yet (only the title check), so they should run after the rebase.
minor The description should open with why the change is needed (CONTRIBUTING, Commits and pull requests), for example "the notes can't be moved off the game's buttons", and include a screenshot of the Controls page with the new rows, since they show on screen. It would also help to say how the wait was checked in game: the field ocarina, a song lesson, the scarecrow, and a dialogue that takes the buttons mid-song.
02b91fc to
0eb1fe7
Compare
|
Thanks both blockers are right. With NumLock off, the default Fixed in 0d55e38, taking your first suggestion: the five rows start unset, meaning "the Switch button's own binding".
I left Should fix: Screenshot added. |
0eb1fe7 to
0d55e38
Compare
Joey-Magnus
left a comment
There was a problem hiding this comment.
Thanks, 0d55e38 fixes both blockers from my last review. The rows start unset, and oc_pad_word (host/nn_hid.c:885) only takes over a Switch bit for a row the player bound, so keyboard defaults and the Xbox / PC layout behave as before. I merged the head into current main: it merges cleanly. tests/run_all.py gives 379 passed, 0 failed. test_ocarina_notes, test_ocarina_note_bindings, test_ocarina_wait, test_menu_keys and test_env_on all pass.
One thing left: oc_notes (host/nn_hid.c:837) reads HOS_OC_NOTES with atoi, so HOS_OC_NOTES=on or =true turns the layer off. Main's rule is env_on / env_value_off (hookshot_env.h, already used in host/display.c). Since the switch defaults to on, !(off && env_value_off(off)) does it. It's also read on every input poll, so a static const would fit better.
Heads-up: #1990, #2261 and #2317 also set MKWVK_API_VERSION to 18. Whichever lands second needs 19. The microphone wait is still untested.
703a705 to
3412588
Compare
|
Removed entirely, since HOS_OC_NOTES is no longer needed. |
|
This now conflicts with main in |
The ocarina's five notes (L, R, A, Y, X while the game waits for one) become five controls of their own: nn_hid bindings (note_l..note_x in the ini, defaults on the numpad, gamepad allowed) and five Controls-page rows. While the wait is on (the next commit's flag), oc_pad_word swaps the note buttons in the merged npad word for the note controls' held state, and the note rows' keys and pad buttons are consumed from their other jobs; away from the wait they do their normal jobs. The Controls page's scroll (the tabs' scroll_rows) keeps the now 29-row list inside any window.
ExecuteWaitOcarinaInputCommon's start (f_828a9190) tells the host its input kind (hos_oc_wait 1 for the live player on buttons, the playtest pinned kind 1; 2 for any other kind), its tick (f_828a9280) re-arms the wait and stamps hos_oc_beat on every running frame (the input resets between note windows end one wait without ending the action), and the running, reset and done branches clear it. A wait whose beat stops advancing for 500 ms (a pause or teardown that cancelled the action without a last tick) is dropped by the host, so shared keys swallowed for a dead wait come back by themselves.
…ver the game's own buttons
… its button over The rows came bound to Numpad 0/2/4/6/8 and the Switch note buttons' pad positions, so every player's own bindings stopped playing notes at the wait, and a pad on the Xbox / PC or Swap Face layout lost its put-away button (the note row consumed the face position the preset had moved). Unset means the game's own button; the wait takes a button over only when the player bound a note to it, which follows the Layout preset on its own. Two fixtures learned main's shape (an inner hos_bind declaration, the note row names) and gained the unset case.
3412588 to
0ed6d49
Compare
Rebased on fce5345
|
…s behind them Upstream's main fails 15 of its own source checks at c356bef (PRs merged without a rebase). These are the eleven outside the upscalers: - vk_memory.cpp: RX_VK_CAPTURE_KEEP_OLD and RX_VK_CAP_BLOCKS are on/off switches and were read as set-means-on, so =0 turned them on (NotRexed#2437). env_on, as the rest. - mouse_native.c: the mouse's kept angles are let go when the camera leaves states 3 and 4 (first-person aim, Z-targeting): they were written back on return, and the view snapped to where it was before (NotRexed#2617; test_mouse_native's yaw). - menu_i18n.h: three English texts changed in vk_menu.cpp (NotRexed#1930, NotRexed#2362, NotRexed#2435), so their 13 translations are keyed and translated again (machine-made, as the file's others). - Fixtures that cut source by its text and missed what the source gained: window_title (NotRexed#2116), dead_import_bytes (NotRexed#1906), env_on in reverb_frame, hos_xinput_pads (NotRexed#2435), wait_recorded's forward declaration (NotRexed#2458); and the Dockerfile check's parser, which took --no-update for a PPA. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
**What this is for:** make the current controls, automatic mesh-shader and automatic button-prompt hints find their translations ([current main CI](https://github.com/NotRexed/Hookshot/actions/runs/43151254256)). **What is measured:** the affected game-free check before and after, with GCC 16.2.1 and Clang 23.1.3 selected, plus one strict full-suite run, as recorded below. This check is Python-only; the two environment runs do not claim compiler coverage. **Not measured:** a game run or Windows execution. ## Cause #1864 imported all thirteen catalogs after #1930, #2362 and #2435 had changed those three complete English hints; runtime lookup is exact, so their old keys no longer match (`gpu/vk/menu_i18n.h`, `vk_menu.cpp`, `vk_menu_i18n.cpp`). The relevant failure in [main's CI log](https://github.com/NotRexed/Hookshot/actions/runs/43151254256) is: ```text 'Gamepad: the D-pad moves, A binds, B goes back.' is no text of vk_menu.cpp (renamed? then translate it again) ``` ## What changed Update all 39 keys and their full translations; leave English help and runtime lookup unchanged. Retain exact membership, order, count, formatting and whitespace checks, and require all three current hints in every language so deleting an entry cannot hide the mismatch. ## How it was tested Recorded on 2026-11-11, Linux kernel `7.2.15-1-omarchy`, base `de866017`, head `f9a7e70f` (version and test records). - Untouched main `a016b7a6`: the affected check fails independently in both compiler environments with the diagnostic above; the branch passes independently in both (`python -I -B tests/run_all.py --strict --jobs 1 tests/test_menu_i18n.py` records). - Each old key was restored independently, and each replacement was separately removed with its table count reduced: all six mutations fail in both environments (12 records), including the new completeness check. - One full `python -I -B tests/run_all.py --strict`: **`456 passed, 14 failed, 20 skipped in 162 s (linux, 32 at once)`**, load 81.38 → 42.70 (complete suite output). - That run's remaining failures are: `test_wayland_libdecor_hint.py`, `test_display_startup_failure.py`, `test_texel_buffer_ownership.py`, `test_audio_aux.py`, `test_audio_biquad.py`, `test_dlss_checks.py`, `test_env_on.py`, `test_framegen_preset.py`, `test_hdr_encode.py`, `test_linux_docker_packages.py`, `test_mods_size_table.py`, `test_mouse_native.py`, `test_readback_part.py`, `test_rumble_menu.py` (complete suite output). The companion fixture, capture-switch, PPA-parser and camera-handover branches address their separate causes; #2614 owns the HDR check and is not duplicated here. ## About the translations The added clauses in the 39 entries were written with a language model, in the wording of each catalogue's existing entry (the part that was already translated is kept word for word). Nobody who speaks these languages natively has read them; corrections are welcome and will not break the check, which compares only the English keys. ## Not tested / risks No game or layout screenshot was taken, and no native-speaker review was performed; the checks establish key coverage and structural consistency, not linguistic or visual polish. ## Overlaps #2417 is an alternative localization implementation, not a repair of these catalogs; it and #2566 merge cleanly with this change in the recorded overlap comparison. Assisted-by: GPT-6 Astra Co-Authored-By: GPT-6 Astra <noreply@openai.com> Co-authored-by: GPT-6 Astra <noreply@openai.com>
- main's 19 is NotRexed#1930's ocarina note bindings (a changed meaning of the pad binding calls, no new field); MkwVkHost.data_dir, still the last field and last in the host's initializer, is 20. - host/prompts.c: NotRexed#2435's keyboard face; choose_face takes the game folder again for prompts/keyboard (a build input), the options stay the data folder's. NotRexed#2435 adds no generated file of its own: all still in cache/prompts. - host/nn_hid.c, docs/development.md: main's text (the ocarina's note controls, the RX_VK_FALLBACK_PHI_LIMIT row) with the data folder's places. - tests/test_ocarina_note_bindings.py, tests/test_ocarina_notes.py (NotRexed#1930): stub hos_data_path as tests/test_bound_keys.py does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This adds 5 rows to the controls menu allowing for remapping of the 5 ocarina notes.
Why? To allow for easier button configurations for different control schemes (keyboard especially) when playing the ocarina. Currently, the notes cannot be moved to separate controls from the main game controls. The default keyboard bindings currently are Space, Q, R, E and Left mouse button, which can make it difficult to remember which note is which.
The default controls are unset, so nothing changes for a player who never touches them.
Ocarina control scheme should be set to normal in the native game settings menu.
Unable to test with Mic inputs. Would appreciate if someone with a working mic could test against this PR.
Checked in game: mappings overlapping with normal controls, interrupting dialogue (Saria, scarecrow, Zelda song of time), environment play spots (zoras domain waterfall). Screenshot of the Controls page with the new rows, all unset, below.
Tested on Linux, Vulkan, RTX 5070 Ti. Full test suite 374 passed, 0 failed.