Skip to content

In-game menu: its picture on the hardware renderer; unmuting a game started muted opens the audio device (#74) - #105

Merged
gascarcella merged 1 commit into
mainfrom
gascarcella/launcher-in-the-games-window-the-launchers-scree
Oct 24, 2026
Merged

gascarcella merged 1 commit into
mainfrom
gascarcella/launcher-in-the-games-window-the-launchers-scree

Conversation

@gascarcella

@gascarcella gascarcella commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Two leftovers of #74, the in-game menu.

What

  • The menu's picture on the hardware renderer. <PREFIX>_PORT_MENU_SHOT was the software renderer's only: SDL creates the swapchain's images to be drawn and blitted into, not read (Vulkan: COLOR_ATTACHMENT | TRANSFER_DST; D3D12: RENDER_TARGET_OUTPUT). The present that takes the picture now draws the game's picture and the menu into a texture of the swapchain's format, blits it into the swapchain (the window shows what is saved) and downloads it (runtime/render_gpu.c; menu.h port_menu_shot_due, port_menu_shot_save). Every other present is unchanged.
  • Unmuting a game started muted. A game started with audio.mute had no audio device, so switching the mute off in the menu waited for the next start. The device now opens when audio.mute goes from on to off (paused while the menu's pause lasts, playing when the game goes on). --mute alone keeps it shut (only a change of audio.mute opens it), and a device that failed to open is not asked for again (runtime/audio.c).
  • The test: tests/hello_test.py --menu starts muted and its live file unmutes it: the device must open. --menu --gpu also takes the Settings page on the hardware renderer, on Mesa's lavapipe (which presents to SDL's offscreen driver; NVIDIA's driver cannot), and requires the software picture but for anti-aliased edges: at most 0.1 % of the pixels off by more than 8 levels. Measured: lavapipe against OpenGL, 0 such pixels (at most 2 levels); NVIDIA's D3D12 under Wine, 54 (a radio button's rim); another page, 55,259. The PNG is read without Pillow.
  • CI: the launcher job installs mesa-vulkan-drivers and runs --menu --gpu; menu-gpu.png joins the kept pictures.
  • Docs: docs/LAUNCHER.md "In-game menu" and the audio.mute row, docs/RUNTIME.md, CLAUDE.md's command line.

Gates that ran

Gate Result
python3 tests/hello_test.py --menu --gpu pass (the GPU picture on lavapipe, the live unmute, the four Mods pictures)
python3 tests/hello_test.py (headless) pass
hello with PSXSTACK_SDL alone, --input-test on both renderers 82 of 82 each
hello cross-built for Windows, with and without the menu no warnings; --exe --wine --gpu pass
hello with the menu under Wine, --renderer gpu (D3D12, vkd3d, NVIDIA) the picture taken through the blit, the live unmute opens WASAPI, the menu's round trip passes
launcher build + --self-test (offscreen) 556 of 556
py_compile pass
dw2003recomp main (with #112) with the submodule at this branch: scripts/test.sh --layer port pass (census, probe, port test, settings with the menu build's input self-test, render_gpu, filters, textures, hz60, battle, vram, subpixel, debug, savestate, crash)
dw2003recomp build/port-sdl (-DPSXSTACK_SDL=ON -DPSXSTACK_MENU=ON), CI's input self-tests 82 of 82, 90 of 90 (rebound.json), the menu's round trip in both
dw2003recomp: started muted, unmuted live, the XP boost page at 1280x800 on the hardware renderer (lavapipe) the device opens; nothing wider than its window
dw2003recomp tests/port/render_gpu.py --lavapipe (the window's SDL_GPU present headless, which the port layer skips on NVIDIA) pass

Rebased onto main after #102–#104 (Player 2), conflicts in the docs, menu.cpp's header comment and the test's docstring only. Re-run on the rebased commit: hello_test.py --menu --gpu (now with the players' part), hello_test.py headless, both Windows cross-builds (no warnings) and --exe --wine --gpu. The dw2003recomp rows were run before the rebase.

Not run: a real Steam Deck or real Windows with these two changes (the menu itself has been play-tested for hours on Linux and the Deck with the hardware renderer).

🤖 Generated with Claude Code

…tarted muted opens the audio device (#74)

The hardware renderer's swapchain cannot be read back (SDL creates its images to be drawn and blitted into only), so
<PREFIX>_PORT_MENU_SHOT was the software renderer's alone. The present that takes the picture now draws the game's
picture and the menu into a texture of the swapchain's format, blits it into the swapchain and downloads it
(menu.h port_menu_shot_due, port_menu_shot_save). tests/hello_test.py --menu --gpu takes the Settings page on the
hardware renderer (Mesa's lavapipe, which presents to SDL's offscreen driver) and requires the software picture but
for anti-aliased edges; CI's launcher job installs lavapipe and runs it.

A game started with audio.mute had no audio device, so switching the mute off in the menu only took effect at the
next start. The device now opens when audio.mute goes from on to off (paused while the menu's pause lasts); --mute
alone keeps it shut, and a device that failed to open is not asked for again. The menu test starts muted and its
live file unmutes it: the device must open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gascarcella
gascarcella force-pushed the gascarcella/launcher-in-the-games-window-the-launchers-scree branch from ddf951c to ddfb319 Compare October 24, 2026 20:48
@gascarcella
gascarcella merged commit 30d1364 into main Oct 24, 2026
5 checks passed
@gascarcella
gascarcella deleted the gascarcella/launcher-in-the-games-window-the-launchers-scree branch October 24, 2026 21:42
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.

1 participant