feat: name the pad inside muxterm

gptokeyb2 owns the pad in muxterm on muOS with PortMaster, and muxterm keeps PgUp and PgDn for its scrollback. The launcher now says so with RETROBIOS_PAD=gptokeyb_muxterm, and the hints name the gptokeyb buttons with no paging key.
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 21:47:55 +02:00
1 parent 34fb1a4cbb
commit d1414263fa
8 files changed
+1215 -9

No files matched your search

+1 -1
View File
@@ -11,7 +11,7 @@
$ErrorActionPreference = "Stop"
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
$defaultInstallSha256 = "563ed14fea5ea54f5d6cb98311932293e714e9581014ea60c195325c20a587eb"
$defaultInstallSha256 = "0047a2f49b22271b69e9a4731165c3230fffa85fa0045a2f725a8bb8668ea9f5"
$maximumInstallerBytes = 2MB
$installerExit = 0
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
+10 -2
View File
@@ -10039,7 +10039,7 @@ def plain_requested(args: argparse.Namespace, env: Mapping[str, str] | None = No
# (ports/shared/tui.txt exports RB_PAD as this), so the bar names those
# buttons and no others.
TUI_PAD_ENV = "RETROBIOS_PAD"
TUI_PAD_ROUTES = ("gptokeyb", "muxterm", "evmapy", "miyoo")
TUI_PAD_ROUTES = ("gptokeyb", "gptokeyb_muxterm", "muxterm", "evmapy", "miyoo")
# Set by Steam for what it starts, and by gamescope: a controller may be
# all there is, mapped by Steam Input to keys nobody here can name.
_STEAM_MARKERS = ("SteamGamepadUI", "SteamDeck", "SteamGameId", "GAMESCOPE_WAYLAND_DISPLAY")
@@ -10251,6 +10251,7 @@ def _filter_row(state: TuiState) -> TuiRow:
return TuiRow("filter", f"Filter: {text}")
# A pad has no / and no letters: muxterm's own keyboard types.
how = {"muxterm": "Select shows a keyboard", "gptokeyb": "with a keyboard",
"gptokeyb_muxterm": "with a keyboard",
"evmapy": "with a keyboard", "miyoo": "with a keyboard"}.get(state.pad, "/ to type")
return TuiRow("filter", f"Filter ({how})", style="dim")
@@ -11280,6 +11281,9 @@ _ROUTE_KEYS: dict[str, dict[str, str | None]] = {
"miyoo": {"A/Enter": "A", "B/Esc": "R2", "X/Space": "A", "Y/o": "L2", "?": None,
"/": None, "Ctrl-C": None, "Enter": "Start", "Esc": None, "Ctrl-U": None},
}
# gptokeyb2 with retrobios.gptk inside muxterm, which no longer reads the pad:
# the gptokeyb buttons.
_ROUTE_KEYS["gptokeyb_muxterm"] = _ROUTE_KEYS["gptokeyb"]
def _route_hint(state: TuiState, parts: tuple) -> tuple:
@@ -11858,6 +11862,7 @@ _STOP_KEYS = {
"both": ("B or Ctrl-C", "B, Ctrl-C or Start+Select"),
"keys": ("Esc or Ctrl-C", "Esc or Ctrl-C"),
"gptokeyb": ("B", "B or Start+Select"),
"gptokeyb_muxterm": ("B", "B or Start+Select"),
"evmapy": ("B", "B"),
"muxterm": ("B", "B"),
"miyoo": ("R2", "R2"),
@@ -12124,6 +12129,9 @@ _HELP_KEYS: dict[str, dict[str, str | None]] = {
"back": "R2, Esc, Backspace", "stop": "R2, Esc, Ctrl-C", "kill": None,
"enter": "Start, Enter", "esc": "Esc"},
}
# muxterm keeps PgUp and PgDn for its scrollback even when gptokeyb2 owns the
# pad, and the launcher sends nothing on L1 and R1 there.
_HELP_KEYS["gptokeyb_muxterm"] = {**_HELP_KEYS["gptokeyb"], "page": None}
def _route_extras(state: TuiState) -> list[tuple[str, str]]:
@@ -12140,7 +12148,7 @@ def _help_lines(state: TuiState) -> list[tuple[str, str]]:
names = _HELP_KEYS.get(state.pad, _HELP_KEYS["both"])
# gptokeyb's kill: Start pressed first also chooses the row in focus.
kill = ([(names["kill"], "Quit at once")]
if state.pad == "gptokeyb" else [])
if state.pad in ("gptokeyb", "gptokeyb_muxterm") else [])
if screen == "installing":
return [(names["stop"], "Stop: what is done stays done"),
*([(names["kill"], "Stop")] if names["kill"] else []),
+1 -1
View File
@@ -18,7 +18,7 @@ esac
TEMP_INSTALLER=""
TEMP_DIRECTORY=""
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
DEFAULT_INSTALL_SHA256="563ed14fea5ea54f5d6cb98311932293e714e9581014ea60c195325c20a587eb"
DEFAULT_INSTALL_SHA256="0047a2f49b22271b69e9a4731165c3230fffa85fa0045a2f725a8bb8668ea9f5"
MAX_INSTALLER_BYTES=2097152
cleanup() {
+1
View File
@@ -437,6 +437,7 @@ rb_muxterm() {
return 0
fi
RB_TERMAPP=(env "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT=$RB_SDL_NO_PAD" "$1" --gl --)
RB_PAD="gptokeyb_muxterm"
if awk '$1 == "l1" || $1 == "r1" { print $1 " = \\\""; next } { print }' \
"$RB_GPTK" > "$RB_STATE/muxterm.gptk" 2>> "$RB_LOG"; then
RB_GPTK="$RB_STATE/muxterm.gptk"
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1151,7 +1151,7 @@ class ThePortMasterPort(unittest.TestCase):
[hint] = device.lines("termapp.sdl")
assert_muxterm_hides_every_pad(self, hint)
assert_muxterm_mapping(self, device.mapper_args(), self.gamedir / "retrobios.gptk")
self.assertEqual(call["pad"], "gptokeyb")
self.assertEqual(call["pad"], "gptokeyb_muxterm")
self.assertEqual(call["idle_exit"], "300")
self.assertEqual(self.dialog(device), ["FINISH"])
@@ -1483,7 +1483,7 @@ class TheMuosApp(unittest.TestCase):
self.assertRegex(args[1], r"^retrobios-stop-\d+x$")
assert_muxterm_mapping(self, args, app / "retrobios.gptk")
self.assertEqual(read_gptk(Path(args[-1]))["y"], ["tab"])
self.assertEqual(call["pad"], "gptokeyb")
self.assertEqual(call["pad"], "gptokeyb_muxterm")
self.assertEqual(call["idle_exit"], "300")
device.assert_mapper_stopped()
+9 -1
View File
@@ -60,7 +60,7 @@ except ImportError:
GOLDEN = REPO_ROOT / "tests" / "fixtures" / "tui"
SIZES = ((40, 12), (40, 15), (80, 24), (120, 40))
# RETROBIOS_PAD's values, and "keys" for a desktop that sets none.
ROUTES = ("keys", "gptokeyb", "evmapy", "muxterm", "miyoo")
ROUTES = ("keys", "gptokeyb", "gptokeyb_muxterm", "evmapy", "muxterm", "miyoo")
UP, DOWN, RIGHT, LEFT = "\x1b[A", "\x1b[B", "\x1b[C", "\x1b[D"
Key = install.TuiKey
@@ -994,6 +994,7 @@ def _bar_keys(line: str) -> set:
ROUTE_KEYS = {
"keys": {"Enter", "Esc", "Space", "o", "?", "/", "Ctrl-C", "Ctrl-U"},
"gptokeyb": {"A", "B", "X", "Y", "Start+Select"},
"gptokeyb_muxterm": {"A", "B", "X", "Y", "Start+Select"},
"evmapy": {"A", "B", "X", "Y"},
"muxterm": {"Start", "B", "Y", "Menu", "Select"},
"miyoo": {"A", "Start", "R2", "L2"},
@@ -1098,6 +1099,13 @@ class PadRoutes(unittest.TestCase):
"Close the terminal"):
self.assertIn(words, muxterm)
self.assertNotIn("Start+Select", muxterm)
# gptokeyb2 owns the pad inside muxterm, which keeps PgUp and PgDn
# for its scrollback: the gptokeyb buttons, and no page key.
in_muxterm = help_text("gptokeyb_muxterm", "preview")
for words in ("A, Start, Enter", "Select, then Start"):
self.assertIn(words, in_muxterm)
self.assertNotIn("L1/R1", in_muxterm)
self.assertIn("L1/R1", help_text("gptokeyb", "preview"))
# muxterm keeps PgUp and PgDn for its scrollback, and L1 and R1
# send nothing: no paging is offered there, on a list or a pager.
for screen in ("systems", "result", "plan"):
+3 -2
View File
@@ -1081,7 +1081,8 @@ Each launcher tells the interface which buttons reach it, in
| Value | Input | Set by |
|-------|-------|--------|
| `gptokeyb` | gptokeyb or gptokeyb2 with `retrobios.gptk`, the table above | the PortMaster port, the Tools entry, the muOS app with PortMaster |
| `gptokeyb` | gptokeyb or gptokeyb2 with `retrobios.gptk`, the table above | the PortMaster port and the Tools entry |
| `gptokeyb_muxterm` | the same, inside muxterm, which keeps L1 and R1 for its scrollback: no button pages | the muOS app with PortMaster |
| `muxterm` | muxterm's own keys: D-pad, Start as Enter, B as Backspace, Y as Space | the muOS app without PortMaster |
| `evmapy` | `RetroBIOS.sh.keys`, the same buttons as the table | the Batocera and Knulli port |
| `miyoo` | buttons that are already keys: A as Space, Start as Enter, L1 and R1 as E and T, L2 as Tab, R2 as Backspace | no launcher yet |
@@ -1340,7 +1341,7 @@ RetroArch folder that holds only `scph5501.bin`, in the order written:
| `FORCE_COLOR`, `CLICOLOR_FORCE` | Colour even when the output is a pipe or a file, set to any value but `0` or an empty one. `NO_COLOR` wins over both, and the progress line stays one line per file |
| `SSL_CERT_FILE`, `SSL_CERT_DIR` | The trusted certificates to check servers with, for a Python that finds none of its own |
| `RETROBIOS_PLAIN`, `ACCESSIBLE` | Set to anything but `0`: the questions come line by line, as with `--plain`, instead of the full-screen interface |
| `RETROBIOS_PAD` | The buttons a handheld launcher's mapper sends to the full screen (`gptokeyb`, `muxterm`, `evmapy`, `miyoo`), so its hints name them. See [On a handheld](#on-a-handheld-the-retrobios-port) |
| `RETROBIOS_PAD` | The buttons a handheld launcher's mapper sends to the full screen (`gptokeyb`, `gptokeyb_muxterm`, `muxterm`, `evmapy`, `miyoo`), so its hints name them. See [On a handheld](#on-a-handheld-the-retrobios-port) |
| `RETROBIOS_IDLE_EXIT` | Seconds the full screen's first screen waits for a first button. With none pressed, it closes with exit status 0 |
| `HTTPS_PROXY`, `NO_PROXY` | Honoured for every download through the standard library's default proxy handling: one names the proxy, the other the hosts to reach directly |