A RetroArch store engine for WarpEngine catalogs
The Batocera store reaches one kind of machine. RetroArch reads the same cartridges on desktop Linux, Windows and macOS, on Android, on the Steam Deck and on the console ports — the same seven titles, a far larger audience — so this writes RetroArch's own library format instead: one .lpl playlist per platform, with box art in the thumbnail folders that playlist's name points at. Three things it does differently, each because RetroArch is not one machine: - It reads retroarch.cfg for its directories. On the macOS install this was developed against, playlist_directory is ~/Documents/RetroArch/ playlists while cores and thumbnails are under ~/Library/Application Support/RetroArch — an engine assuming <base>/playlists writes into the void. The leading ':' of a portable install is expanded too. - It can write for a machine it is not running on (`export`). Android runs RetroArch but cannot run Python, so the only way to serve it is to render the tree here and copy it over; the same mechanism handles an SD card that will be mounted elsewhere. - It refuses to write while RetroArch is running, because RetroArch holds its playlists in memory and writes them back on exit. The Batocera engine defers the write instead; here there is no Ports menu launching us, so refusing is both simpler and safer. Decisions worth recording. One playlist per platform, because default_core_path is a header field — that is what makes every entry start without a core prompt; the entries themselves stay on DETECT so the file survives being moved to a machine whose cores live elsewhere. A missing core is a note, not an error, or the store would never run for anyone the first time. The playlist name carries the store's name, so we never write into RetroArch's own Commodore - 64.lpl and never collide with the official thumbnail packs — and an entry the user added to our playlist survives a rewrite. Thumbnails must be PNG and one of our covers is a GIF, so the engine shells out to sips/magick/convert/ffmpeg, and simply goes without the image if the machine has none of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"store": {
|
||||
"id": "warp",
|
||||
"name": "WarpEngine Store",
|
||||
"base_url": "https://example.org",
|
||||
"api": {
|
||||
"catalog": "/api/software",
|
||||
"download": "/api/download"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"retroarch_dir": null,
|
||||
"playlists_dir": null,
|
||||
"thumbnails_dir": null,
|
||||
"libretro_dir": null,
|
||||
"content_root": null,
|
||||
"subfolder": "warp",
|
||||
"target_prefix": null
|
||||
},
|
||||
"playlist": {
|
||||
"name_template": "{store} - {label}",
|
||||
"write_crc32": true,
|
||||
"thumbnail_kinds": [
|
||||
"Named_Boxarts",
|
||||
"Named_Titles",
|
||||
"Named_Snaps"
|
||||
]
|
||||
},
|
||||
"catalog": {
|
||||
"statuses": [
|
||||
"released",
|
||||
"archived"
|
||||
],
|
||||
"owner_id": null,
|
||||
"only": [],
|
||||
"exclude": []
|
||||
},
|
||||
"platforms": {
|
||||
"c64": {
|
||||
"label": "Commodore 64",
|
||||
"kind": "cartridge",
|
||||
"ext": ".prg",
|
||||
"core": {
|
||||
"file": "vice_x64_libretro",
|
||||
"name": "VICE x64"
|
||||
},
|
||||
"enabled": true
|
||||
},
|
||||
"tic80": {
|
||||
"label": "TIC-80",
|
||||
"kind": "cartridge",
|
||||
"ext": ".tic",
|
||||
"core": {
|
||||
"file": "tic80_libretro",
|
||||
"name": "TIC-80"
|
||||
},
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"behavior": {
|
||||
"prune": true,
|
||||
"timeout": 30,
|
||||
"insecure": false,
|
||||
"refuse_while_running": true,
|
||||
"convert_images": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user