webstation-broker
DeveloperPython referenceemulators

emulators.shadps4

shadPS4 (PlayStation 4) launcher: binary selection, ROM resolution, and IPC-driven shutdown.

shadPS4 (PlayStation 4) launcher: binary selection, ROM resolution, and IPC-driven shutdown.

shadPS4 has no save states. Persistence is the game's own save data, which the game commits to plain host files under <data>/home/<user_id>/savedata/<game_serial>/<slot>/. Save paths are keyed by the game serial, so shipping the whole home/1000/savedata subtree makes a save archive restored into a fresh container line up with the titles it belongs to.

Control plane: shadPS4's IPC protocol (SHADPS4_ENABLE_IPC=true) reads commands from stdin. We feed RUN then START so the game boots headlessly, and STOP for a graceful quit (it pushes SDL_EVENT_QUIT, the same path as a window close). shadPS4 registers no SIGTERM/SIGINT handler, so SIGTERM would kill the process hard and leave read-write save mounts with their sce_sys/corrupted marker in place; STOP must come first and SIGTERM is only the escalation fallback.

attributelog
= logging.getLogger(__name__)
attributeROM_ROOT
= Path(os.environ.get('ROM_ROOT', '/romm'))

Library root ROM paths resolve under (env ROM_ROOT, default /romm).

attributeXDG_DATA_HOME
= os.environ.get('XDG_DATA_HOME') or str(Path.home() / '.local/share')

The XDG data root, ~/.local/share when XDG_DATA_HOME is unset.

attributeVERSIONS_DIR
= Path(os.environ.get('SHADPS4_VERSIONS_DIR', str(Path.home() / '.local/share/shadPS4QtLauncher/versions')))

Where the launcher downloads builds, one folder per release (env SHADPS4_VERSIONS_DIR).

Defaults to ~/.local/share/shadPS4QtLauncher/versions.

attributeDATA_DIR
= Path(os.environ.get('SHADPS4_DATA_DIR', str(Path(XDG_DATA_HOME) / 'shadPS4')))

shadPS4's data root holding save data (env SHADPS4_DATA_DIR, default $XDG_DATA_HOME/shadPS4).

attributeSHADPS4_LOG_PATH
= Path(os.environ.get('SHADPS4_LOG_PATH', '/config/shadps4.log'))

The emulator log file (env SHADPS4_LOG_PATH, default /config/shadps4.log).

attributeROM_EXTENSIONS
= ('.zar', '.bin')

Bootable formats: shadPS4 boots a game folder (eboot.bin inside it) or a .zar archive file.

attributeBIN_NAME
= os.environ.get('SHADPS4_BIN_NAME', 'Shadps4-sdl.AppImage')

The binary looked for inside a release folder (env SHADPS4_BIN_NAME, default Shadps4-sdl.AppImage).

Release folders look like v0.17.0 - Garbage Collector's Edition - 2026-07-30. The Pre-release folder always carries the newest build and trumps all.