Skip to content

Give the Win32 render window a File/View menu and hotkeys - #8

Open
dougchansan wants to merge 2 commits into
ExpansionPak:moderngekko-vendorfrom
dougchansan:platform-win32-state-menu
Open

Give the Win32 render window a File/View menu and hotkeys#8
dougchansan wants to merge 2 commits into
ExpansionPak:moderngekko-vendorfrom
dougchansan:platform-win32-state-menu

Conversation

@dougchansan

@dougchansan dougchansan commented Aug 5, 2026

Copy link
Copy Markdown

The DolphinNoGUI window has no way to save or load a state, and Esc as its only key. Getting back to a scene means booting and playing in, every time.

File menu open over a running game

File carries Save State (F1), a Load State submenu, and Pause. View carries Fullscreen (F11 or Alt+Enter) and Mute Audio. Space held is fast-forward.

Load State submenu

No new frontend obligations

All of it goes through Core, State and Config directly rather than new Host_* hooks. Adding hooks would oblige every frontend to implement them before it could build; this way nothing outside this file has to change.

Details worth flagging

States are written to and listed from Dolphin's own StateSaves directory, named by wall clock (state-YYYYmmdd-HHMMSS.sav) rather than by slot, so repeated saves accumulate instead of overwriting one another and sort meaningfully by name.

The Load State list is rebuilt whenever the menu opens, because states appear while it is closed. It is newest-first with a filename tiebreak, so the order does not shuffle between opens on a filesystem whose timestamps are coarse enough for two states to share a write time. The range of command ids is bounded and the list truncated to it, rather than running past the end.

F1 ignores auto-repeat — bit 30 of lParam is the previous key state — or holding it down would write a state every few milliseconds.

Fast-forward is cancelled on WM_KILLFOCUS. Without that, alt-tabbing mid-hold delivers the key-up to another window and leaves emulation stuck at 2x.

Pause and Mute read their checked state from the core when the menu opens, so the tick cannot drift out of step with an emulation that was paused or muted some other way.

Fullscreen hides the menu bar and restores the previous window style and rect on the way back, rather than assuming a default.

Testing

Built with MSVC/Ninja Release and exercised against a running game (Pokémon Colosseum, booted into a savestate), driving each command by posting it to the window and then checking it had an effect:

Result
F1 writes a state new state-20260804-231457.sav appeared
Save State menu item second state written
Pause halts emulation, and resumes CPU load 1.031 → 0.018 → 1.042 cpu-seconds per wall second
Fullscreen expands and restores window width 1556 → 5120 → 1556 px
Mute check mark tracks the config absent before the toggle, present after
Load State lists newest-first screenshot above

One measurement note, since it nearly produced a wrong answer: the window title is not a usable pause signal. When the core pauses, the title stops being updated and keeps whatever FPS it last showed, so a paused run reads identical to a running one — my first attempt "failed" Pause on that basis. Process CPU time cannot be faked that way.

unknown_instruction reads g_static_recomp_core and ppc_state, but the
translation unit includes neither the header that declares the former nor
a binding for the latter, so core does not compile:

  Interpreter.cpp(294): error C2065: 'g_static_recomp_core': undeclared identifier
  Interpreter.cpp(299): error C2065: 'ppc_state': undeclared identifier

It is not reached through the PCH either -- pch.h does not pull in
StaticRecompCore.h.

The ppc_state binding already existed further down the same function, past
the first use. Moving it to the top serves both uses rather than adding a
second one, which would be a redefinition.
DolphinNoGUI's window had no way to save or load a state, and Esc as the
only key. Getting back to a scene meant booting and playing in.

File carries Save State (F1), a Load State submenu, and Pause. View
carries Fullscreen (F11 or Alt+Enter) and Mute Audio. Space held is
fast-forward.

All of it goes through Core, State and Config directly rather than new
Host_* hooks, so no frontend has to implement anything to pick this up.

States are written to and listed from Dolphin's own StateSaves directory,
named by wall clock rather than by slot, so repeated saves accumulate
instead of overwriting each other and sort meaningfully by name. The Load
State list is rebuilt whenever the menu opens, because states appear
while it is closed; it is newest-first with a filename tiebreak so the
order does not shuffle between opens on a filesystem with coarse
timestamps.

F1 ignores auto-repeat -- bit 30 of lParam -- or holding it down would
write a state every few milliseconds. Fast-forward is also cancelled on
WM_KILLFOCUS, so alt-tabbing mid-hold cannot leave emulation stuck at 2x
with the key-up delivered elsewhere.
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