Skip to content

dsperate-sa: rebind "mod" button so that the menu is usable on RK3266/RK3566 handhelds - #3579

Draft
LaurensBosscher wants to merge 2 commits into
ROCKNIX:nextfrom
LaurensBosscher:dsperate-sa-hotkeys
Draft

LaurensBosscher wants to merge 2 commits into
ROCKNIX:nextfrom
LaurensBosscher:dsperate-sa-hotkeys

Conversation

@LaurensBosscher

@LaurensBosscher LaurensBosscher commented Oct 29, 2026 •

Copy link
Copy Markdown

Status: Draft. This was AI generated. I will review and test before changing the status.

Summary

What does this PR do?

Issue

There was no way to open the menu, or see the FPS while using: dsperate-sa on the Powkiddy X55 and, I expect, other handhelds

Fix

Guide = Select hold

Input Result
one Select press DS Select pressed and released — nothing swallowed
GUIDE + X show/hide
GUIDE + Y pause
GUIDE + A Fast Forward
GUIDE + START quit
GUIDE + L2 / R2 screen_swap / fast_forward_toggle
L2 or R2 alone nothing (the layout no longer moves)

Testing & Verification

  • Device(s) Tested: Powkiddy X55 (RK3566), ROCKNIX 20261001. *

Test Steps

  1. Booted Mario Kart DS
  2. Tested the buttons as described above.

Test Results & Evidence

Additional Context & Reviewer Notes

  • Released images read /usr/config/dsperate/dsperate.ini and seed /storage/.config/dsperate/dsperate.ini only when it is missing, so none of this reaches 20261001. On that image the local fix for an unreachable guide is adding modifier = back to the /storage copy.
  • RK3326's .oga/.r33s already had mod+dpup/mod+dpdown; RK3588 is untouched; H700, S922X, RK3326 .s1_f2/.xut keep modifier = guide and get only the layout change.
  • Quit is also in the pause menu (modifier + X), so the new chord is a shortcut, not the only way out.

AI Assistance Disclosure

While ROCKNIX has no restrictions on using AI tools, transparency helps reviewers set the proper context during code review.

Did you use AI tools (e.g., ChatGPT, Copilot, Claude) to assist with this pull request?

  • No Written entirely without AI tools.
  • Partially AI was used for minor assistance (e.g., refactoring, writing tests, debugging, documentation).
  • Yes AI generated a major portion of the code or implementation.

@sydarn

sydarn commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

I think Select would be more fitting and in line with other emulators. I think we should try to keep convention on either select or guide. Depending on what the device has on the left hand side. If an emulator support multiple hotkeys you can assign both as hotkeys, I think ppsspp does this for example.

@LaurensBosscher

Copy link
Copy Markdown
Author

I think Select would be more fitting and in line with other emulators. I think we should try to keep convention on either select or guide. Depending on what the device has on the left hand side. If an emulator support multiple hotkeys you can assign both as hotkeys, I think ppsspp does this for example.

Hi @sydarn,

Thanks, for the suggestion, let me update this one and see if we can use select instead of the trigger!

@sydarn

sydarn commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

I don't think we should remove guide from Inputplumber, maybe the best would actually be change DSperate itself to add a second hotkey.

@sydarn

sydarn commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Additionally, this shouldn't really be a problem for X55. X55 now emit guide additionally to select on the select button:
https://github.com/ROCKNIX/distribution/blob/next/projects/ROCKNIX/devices/RK3566/filesystem/usr/share/inputplumber/capability_maps/powkiddy_x55.yaml#L71

If it doesn't work, that might be another bug in that case.

Addendum:
I can see it being in an issue on rk3399, and maybe some rk3326 devices.

@LaurensBosscher LaurensBosscher changed the title dsperate-sa: put the pad hotkey modifier on L2 (Powkiddy X55 and other pads with no FUNC key) dsperate-sa: stop binding the screen layout to bare L2/R2 Nov 1, 2026
@LaurensBosscher

LaurensBosscher commented Nov 1, 2026 •

Copy link
Copy Markdown
Author

Text below is all AI:

I dropped the L2/Select switch — you were right, guide stays in config/InputPlumber/dsperate.ini.

I traced the X55's InputPlumber stream against DSperate's own input code and it is not just a naming choice:

  • powkiddy_x55.yaml (and powkiddy, powkiddy_x35, anbernic_gen1, anbernic_arc) map BTN_SELECT twice, Select then Guide. InputPlumber's default MultiSource translation emits both, in map order, so one press is BACK + GUIDE.
  • SDL emits BACK before GUIDE even inside a single DualSense report (SDL_hidapi_ps5.c:1214 vs :1223).
  • DSperate 3.0.5 sets pad_mod_used_ on any other press under the modifier (src/frontend/sdl/input.cpp:514), so the "tap on release" for the modifier's DS button never fires.

Net: modifier = back on the X55 drives DS mask 0x0000 for a Select press — DS Select silently stops existing. modifier = guide drives the normal press+release, because there guide is the Select button, so holding it is already Select-as-modifier and tapping it still reaches the game. On the pads with a real FUNC key, guide stays that key and the DS Select stays a plain button. I put a comment in the file so this doesn't get "fixed" back to back later.

What the PR does now:

  1. layout_next/layout_prev move off the bare +righttrigger/+lefttrigger to mod+dpup/mod+dpdown (RK3588 already had it) — pressing L2 or R2 alone no longer re-lays the screens out mid-game.
  2. On the two configs whose modifier already is Select (RK3326, RK3399), quit moves off Select+Start to Select+L2, with screen_swap on mod+y and fps on mod+a. Select+Start is the pair ROCKNIX builds its global exit chord from (L1+Select+Start, input_sense:54-60) and what every other emulator here uses for Quit Game.

Verified against DSperate v3.0.5's Input (the real Config::load() + Input::configure(), driving the actual event streams): every chord in the twelve changed files fires as documented, a bare L2/R2 does nothing, and Input::collisions() is empty for all of them. Hardware: my X55 is on 20261001 (legacy joypad, no BTN_MODE at all, which is why the guide modifier is unreachable there), so the InputPlumber path itself still needs a pass on next.

layout_next/layout_prev were bound to +righttrigger/+lefttrigger in
every device config but RK3588, RK3326's .oga and .r33s: pressing L2 or
R2 on its own cycled the screen layout during play. A DS has no trigger
so nothing was using them, but the secondary screen re-laying itself out
under the player's fingers is not something to bind to an unmodified
trigger.

Bind them as mod+dpup/mod+dpdown as RK3588 already does - the d-pad
directions the slot hotkeys leave free - so the triggers stay inert
unless the modifier is held. Same two lines in each file; the modifier
differs per device and is untouched.
RK3326 and RK3399 already use Select as the pad hotkey modifier, and on
those pads quit = mod+start is Select+Start - the combo ROCKNIX builds
its global exit hotkey from (L1+Select+Start) and the one every other
emulator here uses for Quit Game. Move quit to L2, which the DS has no
button for, and re-home the two bindings that lived on L2 and Y:
screen_swap to mod+y, fps to mod+a.

InputPlumber keeps guide. On the five RK3566 pads whose capability maps
emit Guide from BTN_SELECT, guide *is* Select: holding it is the
modifier and tapping it still reaches the DS, while pads with a real
FUNC key keep their DS Select as a plain button. A comment records why
"back" cannot be used there: DSperate sees the alias Guide event while
the modifier is held, counts the press as "not alone", and never taps
the DS Select out on release.

Checked against DSperate 3.0.5's Input for every file: select+X pause,
select+L2 quit, select+R1/L1 save/load state, select+dpup/dpdown layout,
select+Y screen_swap, select+A fps, triggers inert when bare, guide+X
pause and Select+Start inert on InputPlumber, Input::collisions() empty
everywhere.
@LaurensBosscher

Copy link
Copy Markdown
Author

@sydarn ,

Tested on my Powkiddy X55 and it's all working with select!

I would also suggest that we switch L2 <> L1 and R2 <> R1. The triggers are in a more ergonomically position on all handhelds, having the gameplay functionality on L2 and R2 is less comfortable and a worse experience than the original Nintendo DS. Let me know if you agree and I'll do a PR with that change.

@LaurensBosscher
LaurensBosscher marked this pull request as ready for review November 1, 2026 11:35
@beebono

beebono commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

I'm not sure I understand the problem with Quit being Start+Select? The kill hotkey of L1+Start+Select is an unclean force quit, and shouldn't be used in most cases as far as I know. And changing the layout keys/swapping L1-2/R1-2 can be done at user level if desired?
EDIT: To clarify, the layout swap keys were set that way to match DraStic for consistency.

@LaurensBosscher

Copy link
Copy Markdown
Author

Start

It's not a problem.

I initially thought it was better to have another key as the modifier button because users might accidentally press select + start and kill the emulator but given that we use select for other emulators as well I doubt that this will be an issue.

With regards to L1/L2, L1 (triggers) is more comfortable when playing Mario Kart (when you have to press and hold them for quite a while when drifting) but if the key is bound to a less used function it should also not be an issue.

@LaurensBosscher LaurensBosscher changed the title dsperate-sa: stop binding the screen layout to bare L2/R2 dsperate-sa: rebind modify button so that the menu is usable on RK3266/RK3566 handhelds Nov 1, 2026
@LaurensBosscher LaurensBosscher changed the title dsperate-sa: rebind modify button so that the menu is usable on RK3266/RK3566 handhelds dsperate-sa: rebind "mod" button so that the menu is usable on RK3266/RK3566 handhelds Nov 1, 2026
@LaurensBosscher

Copy link
Copy Markdown
Author

Changed to draft, I'll redo this with the latest version in mind. I want to make sure that we still need this now that we have Input plumber.

@LaurensBosscher
LaurensBosscher marked this pull request as draft November 1, 2026 23:27

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants