A DualShock 4 or DualSense touchpad click opens the menu as F1 #1846

Merged
nicholasgower merged 1 commit from feat/touchpad-menu into main 2026-11-10 21:05:25 +00:00
nicholasgower commented 2026-11-10 18:16:17 +00:00 (Migrated from github.com)

Clicking the touchpad on a DualShock 4 or DualSense did nothing, so a PlayStation pad could only open the menu with Home or Select and Start together. The touchpad is a button no Switch controller has, and its click is the natural menu key on those pads: it now does what F1 does.

What changed

  • host/pad_sdl.c reads SDL's touchpad button (button 20 in both SDL2's SDL_CONTROLLER_BUTTON_TOUCHPAD and SDL3's SDL_GAMEPAD_BUTTON_TOUCHPAD) and sets a new HOS_PAD_TOUCHPAD bit (gpu/vk/vk_api.h). The bit is past HOS_PAD_N, so it is not one of the inputs the Controls page can bind to a Switch button.
  • gpu/vk/vk_menu.cpp presses F1's slot (press[6]) on that bit: a click opens the menu while playing, and closes it again, exactly as F1 does. A click while the Controls page is listening for a new binding is ignored.
  • readme.md documents it under In-game menu.

Testing

  • New tests/test_touchpad_menu.py compiles the poll's button block from host/pad_sdl.c over a stand-in SDL and checks that only the touchpad click sets HOS_PAD_TOUCHPAD, that an ordinary button still sets its own bit, and that the bit is outside the bindable positions. It then checks vk_menu.cpp maps it to F1 (press[6]), not Insert/confirm/back, and masks it from the binding listener.
  • python -I -B tests/run_all.py locally: the new check and the menu and pad checks pass (test_touchpad_menu, test_menu_keys, test_stick_rest, test_bound_keys, test_rumble_*, test_hd_rumble, test_input_background). The full run's 11 failures on this PC are environment-only: no clang on PATH, no privilege to create symlinks (WinError 1314), and Python 3.14's \\?\ paths. CI on Linux with the tools installed is the real check.

Build

Rebased onto main (51de681) and built a complete game folder from the user's .nup with nx2/make_game.py: the compile, the hookshot.exe and hookshot_vk.dll links, and shader preparation all succeeded.

main itself does not link right now: #1720's merge left out the vk_replay.cpp half of present ahead, so mkwvk::present_commit and mkwvk::present_defer_into are undefined. Open PR #1858 is the pending fix. I applied that one commit to the working tree for this build only; it is not part of this PR, and the red Vulkan job here is that same main breakage.

Not tested

  • In the game with a real DualShock 4 or DualSense: there is no controller and no dump here. It needs a Windows or Linux run where SDL's HIDAPI driver sees the pad (the bundled SDL2.dll/sdl2-compat and SDL3 both support the button) to confirm the menu opens and closes on a click.
  • No screenshots: the change shows as the existing menu opening from a new input.

No issue links: there is no open issue for it in the repository.

Clicking the touchpad on a DualShock 4 or DualSense did nothing, so a PlayStation pad could only open the menu with Home or Select and Start together. The touchpad is a button no Switch controller has, and its click is the natural menu key on those pads: it now does what <kbd>F1</kbd> does. ## What changed - `host/pad_sdl.c` reads SDL's touchpad button (button 20 in both SDL2's `SDL_CONTROLLER_BUTTON_TOUCHPAD` and SDL3's `SDL_GAMEPAD_BUTTON_TOUCHPAD`) and sets a new `HOS_PAD_TOUCHPAD` bit (`gpu/vk/vk_api.h`). The bit is past `HOS_PAD_N`, so it is not one of the inputs the Controls page can bind to a Switch button. - `gpu/vk/vk_menu.cpp` presses F1's slot (`press[6]`) on that bit: a click opens the menu while playing, and closes it again, exactly as <kbd>F1</kbd> does. A click while the Controls page is listening for a new binding is ignored. - `readme.md` documents it under **In-game menu**. ## Testing - New `tests/test_touchpad_menu.py` compiles the poll's button block from `host/pad_sdl.c` over a stand-in SDL and checks that only the touchpad click sets `HOS_PAD_TOUCHPAD`, that an ordinary button still sets its own bit, and that the bit is outside the bindable positions. It then checks `vk_menu.cpp` maps it to <kbd>F1</kbd> (`press[6]`), not Insert/confirm/back, and masks it from the binding listener. - `python -I -B tests/run_all.py` locally: the new check and the menu and pad checks pass (`test_touchpad_menu`, `test_menu_keys`, `test_stick_rest`, `test_bound_keys`, `test_rumble_*`, `test_hd_rumble`, `test_input_background`). The full run's 11 failures on this PC are environment-only: no `clang` on PATH, no privilege to create symlinks (WinError 1314), and Python 3.14's `\\?\` paths. CI on Linux with the tools installed is the real check. ## Build Rebased onto `main` (51de681) and built a complete game folder from the user's `.nup` with `nx2/make_game.py`: the compile, the `hookshot.exe` and `hookshot_vk.dll` links, and shader preparation all succeeded. `main` itself does not link right now: #1720's merge left out the `vk_replay.cpp` half of `present ahead`, so `mkwvk::present_commit` and `mkwvk::present_defer_into` are undefined. Open PR #1858 is the pending fix. I applied that one commit to the working tree for this build only; it is not part of this PR, and the red Vulkan job here is that same main breakage. ## Not tested - In the game with a real DualShock 4 or DualSense: there is no controller and no dump here. It needs a Windows or Linux run where SDL's HIDAPI driver sees the pad (the bundled SDL2.dll/sdl2-compat and SDL3 both support the button) to confirm the menu opens and closes on a click. - No screenshots: the change shows as the existing menu opening from a new input. No issue links: there is no open issue for it in the repository.
barrenechea commented 2026-11-10 18:18:48 +00:00 (Migrated from github.com)

I wonder if it shouldn't be the "PS" button in that case, rather than the touchpad click? Would be more "natural" as the guide button I think

I wonder if it shouldn't be the "PS" button in that case, rather than the touchpad click? Would be more "natural" as the guide button I think
nicholasgower commented 2026-11-10 18:27:07 +00:00 (Migrated from github.com)

I wonder if it shouldn't be the "PS" button in that case, rather than the touchpad click? Would be more "natural" as the guide button I think

One problem with this idea is that PCs often override the home button with other menus, whether it be Steam Big Picture or Xbox Game Bar. On Playstation controllers, the touchpad is the only button that isn't required for Switch inputs.

> I wonder if it shouldn't be the "PS" button in that case, rather than the touchpad click? Would be more "natural" as the guide button I think One problem with this idea is that PCs often override the home button with other menus, whether it be Steam Big Picture or Xbox Game Bar. On Playstation controllers, the touchpad is the only button that isn't required for Switch inputs.
nicholasgower commented 2026-11-10 19:22:12 +00:00 (Migrated from github.com)

I've tested this myself, and I can confirm that it works.

I've tested this myself, and I can confirm that it works.
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 20:56:01 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. The touchpad click (bit 31) reaches menu_tick through hos_pad_raw and never reaches the Switch button mapping, since pad_bind only covers 0..HOS_PAD_N-1. The binding listener masks it too, and press[6] lines up with F1, so it opens the menu the same way the key does.

CI: test_touchpad_menu passes on both Python jobs. The other failures (the present_commit/present_defer_into link error, test_present_ahead, test_present_semaphores, test_draw_parameters, test_nup_out_of_space, test_wayland_libdecor_hint) aren't from this diff. As the description says, the link error and present tests come from main's breakage after #1720.

Looks good. The touchpad click (bit 31) reaches `menu_tick` through `hos_pad_raw` and never reaches the Switch button mapping, since `pad_bind` only covers 0..HOS_PAD_N-1. The binding listener masks it too, and `press[6]` lines up with F1, so it opens the menu the same way the key does. CI: `test_touchpad_menu` passes on both Python jobs. The other failures (the `present_commit`/`present_defer_into` link error, `test_present_ahead`, `test_present_semaphores`, `test_draw_parameters`, `test_nup_out_of_space`, `test_wayland_libdecor_hint`) aren't from this diff. As the description says, the link error and present tests come from main's breakage after #1720.
Commenting is not possible because the repository is archived.
No description provided.