webstation-broker
DeveloperPython referenceemulatorsemulators.dolphin

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_DIR

Dolphin'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_EXTENSIONS

Bootable disc formats, best first.

attributesupports_states
= True

True, states are saved over the hotkey and loaded at boot or by hotkey.

attributestate_slot
= STATE_SLOT

The one slot the broker works in, echoed back as the effective slot.

attributestate_dir
= STATE_DIR

Where Dolphin writes .sNN files.

attributelog_path
= DOLPHIN_LOG_PATH

The Dolphin log the broker exposes.

attributememory_card_subtree
= 'GC'
attribute_launch_seq
= 0

Functions

func__init__(self) -> None

Set up the process state and the launch sequence counter that fences deferred loads.

paramself

Returns

None
funcmemory_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.

paramself
paramplatformOptional[str]
= None

Returns

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.

paramself
parampathPath

The ROM file or folder RomM handed over.

Returns

typing.Optional

The 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.

paramself
paramargsstr
= ()

Returns

typing.Optional

Its 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.

paramself

Returns

typing.Optional

The X window id as xdotool prints it, or None when no render window is up.

func_send_key(self, key) -> bool

Focus 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.

paramself
paramkeystr

The key name in xdotool's syntax, for example shift+F1.

Returns

bool

True when the window was found, activated and the key sent, False otherwise.

funclaunch(self, rom_path, resume_slot) -> None

Stop 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.

paramself
paramrom_pathPath

The disc image to boot.

paramresume_slotOptional[int]

Slot to resume from, or None to boot clean.

Returns

None
func_deferred_load_state(self, seq) -> None

Wait 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.

paramself
paramseqint

The launch sequence number this load belongs to.

Returns

None
funcsave_state(self, slot) -> bool

Save 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.

paramself
paramslotint

The slot RomM requested; not used.

Returns

bool

True once the state file has been written and settled within STATE_WAIT, False if

funcload_state(self, slot) -> bool

Load 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.

paramself
paramslotint

The slot RomM requested; the broker's STATE_SLOT is what gets loaded.

Returns

bool

True 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.

paramself

Returns

typing.Optional[pathlib.Path]
funcclear_working_slot(self) -> None

Delete 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.

paramself

Returns

None
funcstate_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.

paramself
paramfilenamestr

The basename RomM is pushing.

Returns

typing.Optional

The path to write to, or None when the name is not a state name, carries a path

func_drop_undo_buffer(self) -> None

Delete 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.

paramself

Returns

None
funcsave_and_exit(self, slot) -> dict[str, Any]

Save a state if asked, stop the emulator, and drop the undo buffer.

paramself
paramslotOptional[int]

Slot RomM asked to save into (resolved to STATE_SLOT), or None to exit without saving a state.

Returns

dict

A dict with state_saved (bool), state_slot (the effective slot, or None when no

funcstop(self) -> None

Invalidate any in-flight deferred state load before the kill.

paramself

Returns

None

On this page