emulators.dolphin.Dolphin
GameCube and Wii sessions on dolphin-emu.
GameCube and Wii sessions on dolphin-emu.
The broker launches dolphin-emu -b with every setting on the command
line: -u for the user directory, -v for the video backend, and a run
of -C overrides for fullscreen, no stop confirmation, no panic dialogs,
analytics consent already answered, and slot A pinned to a GCI folder
card. Qt is forced onto xcb so the window lives on Xwayland, where
xdotool can reach it. A resume whose state is already on disk loads at
boot with -s, which is both more reliable than the hotkey and invisible
to the player; a resume whose state RomM pushes after activate returns is
delivered by a deferred thread over the load hotkey instead. Saving is
hotkey only: the render window is activated, SAVE_KEY is sent through
XTEST, and the state directory is polled until the file settles, since
the hotkey gives no acknowledgement.
Save data rides the save archive: GC holds the memory cards as loose
.gci files, Wii the NAND, so nothing here needs the whole-card
routes. A state is named for the game id, so pushed names are restamped
into the broker's slot, the working slot is cleared before a boot, and
Dolphin's undo-load buffer is dropped on exit so the archive does not
carry a second full-size copy of a state RomM already stores.
Attributes
attributename= 'dolphin'RomM platform key, dolphin.
attributedisplay_name= 'Dolphin'Human-readable name shown in the UI.
attributesave_root= USER_DIRDolphin's user directory, which the save subtrees hang off.
attributesave_subtrees= ('StateSaves', 'GC', 'Wii')StateSaves, GC and Wii, the directories the save archive carries.
attributerom_extensions= ROM_EXTENSIONSBootable disc formats, best first.
attributesupports_states= TrueTrue, states are saved over the hotkey and loaded at boot or by hotkey.
attributestate_slot= STATE_SLOTThe one slot the broker works in, echoed back as the effective slot.
attributestate_dir= STATE_DIRWhere Dolphin writes .sNN files.
attributelog_path= DOLPHIN_LOG_PATHThe Dolphin log the broker exposes.
attributememory_card_subtree= 'GC'attribute_launch_seq= 0Functions
func__init__(self) -> NoneSet up the process state and the launch sequence counter that fences deferred loads.
paramselfReturns
Nonefuncmemory_card_path(self, platform=None) -> Optional[Path]The whole GC/ tree, or None for Wii (NAND, no physical card).
Returns the tree rather than one region's Card A folder: Dolphin buckets a GCI folder card by the disc's region (GC/<region>/Card A), and a library can mix regions, so syncing has to carry all of them rather than guessing one.
paramselfparamplatformOptional[str]= NoneReturns
typing.Optional[pathlib.Path]funcresolve_rom_file(self, path) -> Optional[Path]Resolve a RomM path to the disc image to boot.
A file is taken as is. A directory is searched one level deep for the
best candidate by _pick_rom_file.
paramselfparampathPathThe ROM file or folder RomM handed over.
Returns
typing.OptionalThe image to pass to dolphin-emu, or None when there is nothing bootable.
func_xdotool(self, *args) -> Optional[str]Run one xdotool command against the session display.
paramselfparamargsstr= ()Returns
typing.OptionalIts stdout, or None if it could not be run, timed out, or exited non-zero.
func_render_window(self) -> Optional[str]Find the window Dolphin renders the game into.
Picked by title rather than by taking the first match, because the main window and any dialog carry the same class, and a hotkey sent at either of those does nothing.
paramselfReturns
typing.OptionalThe X window id as xdotool prints it, or None when no render window is up.
func_send_key(self, key) -> boolFocus the render window and send key through XTEST.
Activating first is what makes this survive the player clicking back into the page: XTEST delivers to whatever holds focus, so a key sent at an unfocused Dolphin goes to the desktop instead.
paramselfparamkeystrThe key name in xdotool's syntax, for example shift+F1.
Returns
boolTrue when the window was found, activated and the key sent, False otherwise.
funclaunch(self, rom_path, resume_slot) -> NoneStop any running instance, seed the pad bindings, and start dolphin-emu.
The binary comes from env DOLPHIN_BIN (default dolphin-emu). With
resume_slot set and a state already in the working slot, the state
is loaded at boot with -s; with the slot still empty, a deferred
thread waits for RomM's push and loads it over the hotkey.
paramselfparamrom_pathPathThe disc image to boot.
paramresume_slotOptional[int]Slot to resume from, or None to boot clean.
Returns
Nonefunc_deferred_load_state(self, seq) -> NoneWait for a pushed state to arrive, then load it over the hotkey.
Gives the file RESUME_LOAD_WAIT to appear, then RESUME_LOAD_SETTLE
for the window to be ready. Abandons itself whenever seq no longer
matches the current launch, so a superseded launch never gets a stray
load.
paramselfparamseqintThe launch sequence number this load belongs to.
Returns
Nonefuncsave_state(self, slot) -> boolSave a state into the broker's slot over the hotkey and wait for it to land.
slot is what RomM asked for and is ignored: this saves into
STATE_SLOT and the caller reads the effective slot back off
state_slot.
paramselfparamslotintThe slot RomM requested; not used.
Returns
boolTrue once the state file has been written and settled within STATE_WAIT, False if
funcload_state(self, slot) -> boolLoad the broker's slot over the hotkey.
The hotkey is silent on an empty slot, so an absent file has to be caught here or the caller reads a no-op as success.
paramselfparamslotintThe slot RomM requested; the broker's STATE_SLOT is what gets loaded.
Returns
boolTrue when a state file exists and the hotkey was sent, False otherwise.
funcstate_path(self) -> Optional[Path]Return the newest state file in the broker's slot, or None when it holds nothing.
paramselfReturns
typing.Optional[pathlib.Path]funcclear_working_slot(self) -> NoneDelete every state in the broker's slot before a new session boots.
A state is named for the game it was taken from, and the game id only comes off the running disc, so a leftover cannot be told apart from the state of the game about to boot. Anything still here belongs to a session that has already exited and whose states RomM holds.
paramselfReturns
Nonefuncstate_target(self, filename) -> Optional[Path]Map a pushed state's filename to where it may be written.
With the slot already holding a state, a pushed name has to match it;
otherwise the game id is taken on trust, bounded to a <game>.s<slot>
basename in the state dir.
paramselfparamfilenamestrThe basename RomM is pushing.
Returns
typing.OptionalThe path to write to, or None when the name is not a state name, carries a path
func_drop_undo_buffer(self) -> NoneDelete the undo-load-state buffer before the save archive is built.
Dolphin rewrites this on every state load, so it lands in the dump as a second full-size copy of a state RomM is already storing, for the sake of an undo hotkey a streaming session has no way to press. A failure to remove it is logged, not raised.
paramselfReturns
Nonefuncsave_and_exit(self, slot) -> dict[str, Any]Save a state if asked, stop the emulator, and drop the undo buffer.
paramselfparamslotOptional[int]Slot RomM asked to save into (resolved to STATE_SLOT), or None to exit
without saving a state.
Returns
dictA dict with state_saved (bool), state_slot (the effective slot, or None when no
funcstop(self) -> NoneInvalidate any in-flight deferred state load before the kill.
paramselfReturns
None