emulators.ppsspp
PPSSPP (Sony PSP) launcher: ROM resolution, ini patching, and hotkey save states.
PPSSPP (Sony PSP) launcher: ROM resolution, ini patching, and hotkey save states.
PPSSPP has no control socket. Everything the broker needs pinned lives in two
inis, both patched before every launch. ppsspp.ini gets FirstRun and
CheckForNewVersion so a freshly seeded /config never opens the setup wizard or
an update toast behind a session nobody can click into, and StateSlot so every
save/load hotkey lands on the broker's one working slot without ever cycling
it. controls.ini gets Save State and Load State bound to the bracket keys:
F1-F12 never reach PPSSPP through this container's streaming/input stack
(confirmed empirically, including with a real keyboard through the user's own
desktop session), so the brackets are what's forced in on every launch rather
than trusted to survive from a one-off manual bind through PPSSPP's own remap
UI. Both files are written with a leading UTF-8 BOM; the patcher has to strip
it on read and put it back on write; a naive line scan would loosen the BOM
onto the first [section] line and never match it.
Save states have no boot-time load flag, unlike Dolphin's -s, so a resume
always goes through the deferred hotkey load below rather than loading before
the window exists to fail into. Unlike Dolphin, PPSSPP writes a screenshot
alongside every state, so the thumbnail here comes from that file rather than
the streamed canvas.
attributelog= logging.getLogger(__name__)attributeROM_ROOT= Path(os.environ.get('ROM_ROOT', '/romm'))Root of the RomM library mount (env ROM_ROOT, default /romm).
A resolved ROM must sit under it; candidates resolving outside are discarded.
attributeCONFIG_DIR= Path(os.environ.get('PPSSPP_CONFIG_DIR', '/config/.config/ppsspp'))PPSSPP's config root (env PPSSPP_CONFIG_DIR, default /config/.config/ppsspp).
attributePSP_DIR= CONFIG_DIR / 'PSP'The emulated memory stick root, holding save data, states and the system inis.
attributeSYSTEM_DIR= PSP_DIR / 'SYSTEM'Directory holding ppsspp.ini and controls.ini.
attributeINI_PATH= SYSTEM_DIR / 'ppsspp.ini'The main ini the broker patches before every launch.
attributeCONTROLS_INI_PATH= SYSTEM_DIR / 'controls.ini'The control mapping ini the broker patches before every launch.
attributeSTATE_DIR= PSP_DIR / 'PPSSPP_STATE'Directory PPSSPP writes its .ppst save states and their .jpg screenshots into.
attributePPSSPP_LOG_PATH= Path(os.environ.get('PPSSPP_LOG_PATH', '/config/ppsspp.log'))Log file the broker tails for this emulator (env PPSSPP_LOG_PATH, default /config/ppsspp.log).
attributeSTATE_SLOT= int(os.environ.get('PPSSPP_STATE_SLOT', '1'))The one slot the broker works in (env PPSSPP_STATE_SLOT, default 1).
RomM holds the library of states, so a requested slot resolves to this one and the routes echo the effective slot.
attributeSAVE_KEY= 'bracketleft'xdotool key for saving the working slot.
F1-F12 never reach PPSSPP through this container's streaming/input stack
(confirmed empirically: bound and unbound alike, nothing was ever
delivered), so the working hotkeys are the bracket keys instead. The
device-1 code is NKCODE (device 1 is the keyboard; device 10 entries
elsewhere in this file are the gamepad's own, unrelated numbering) per
PPSSPP's Qt/NKCodeFromQt.h, which maps Qt::Key_BracketLeft/Right to
NKCODE_LEFT_BRACKET/RIGHT_BRACKET (71/72, Common/Input/KeyCodes.h), not
the 132/134 an earlier remap-UI capture recorded, which traced back to the
same broken injection path this binding works around.
attributeLOAD_KEY= 'bracketright'xdotool key for loading the working slot; see SAVE_KEY for why it is a bracket key.
attributeSTATE_WAIT= float(os.environ.get('PPSSPP_STATE_WAIT', '20.0'))Seconds a save state has to land on disk after the save hotkey (env PPSSPP_STATE_WAIT, default 20).
attributeRESUME_LOAD_WAIT= float(os.environ.get('PPSSPP_RESUME_LOAD_WAIT', '90.0'))Seconds a deferred resume waits for a state file to arrive (env PPSSPP_RESUME_LOAD_WAIT, default 90).
attributeRESUME_LOAD_SETTLE= float(os.environ.get('PPSSPP_RESUME_LOAD_SETTLE', '5.0'))How long the window has to be up before a hotkey is worth sending (env PPSSPP_RESUME_LOAD_SETTLE).
Defaults to 5 seconds.
attributeROM_EXTENSIONS= ('.chd', '.cso', '.pbp', '.iso', '.elf', '.prx')All formats PPSSPP boots directly, best first.
Best means most likely to be the verified, compressed copy; a folder holding several candidates picks by this order. PSP has no multi-disc titles, so there is no disc number to rank on.