A
warp-engine-retroarch-storeegy WarpEngine-katalógusból húzza be a játékokat a RetroArch könyvtárába: platformonként egy.lpllejátszási lista, borítóképekkel azokban a bélyegkép-mappákban, amelyekre a lista neve mutat. Ez csak a motor — a site, az áruház neve és az, hogy hova kerülnek a játékok, egy külön áruházrepóconfig.jsonfájljából jön. A közös fele a warpstore.
warpstore a közös mag
▲
warp-engine-retroarch-store ez a motor — retroarch_store.py, install.sh
▲
│ config.json
ttg-retroarch-store áruházrepók
▼
teletypegames.org
A referenciaáruház a TTG RetroArch Store.
Repó: https://git.teletypegames.org/stores/warp-engine-retroarch-store Közös mag: warpstore Testvérmotor: Batocera áruházmotor RetroArch: https://www.retroarch.com
retroarch.cfg fájljából jön.export), és ez az egyetlen módja Android kiszolgálásának, ahol fut a RetroArch, de Python nincs.retroarch.cfg fájlt, és nem nyúl a megjelenítési beállításokhoz.<store>-retroarch-store sync
│
├─ GET /api/software a teljes katalógus
├─ a libretro core által indítható platformok c64 → VICE, tic80 → TIC-80
├─ a legfrissebb nem dev kiadás amely a kazettát hordozza
├─ GET /api/download?path=<asset> .prg / .tic a tartalommappába
├─ GET <software.imageUrl> borítókép, PNG-be konvertálva
└─ <store> - <label>.lpl kiírása lejátszási lista + bélyegképek
A RetroArch nem egyetlen gép. Ebből három tervezési pont következik.
Olvassa a retroarch.cfg fájlt. A lejátszási listák mappája nem mindig a RetroArch könyvtárán belül van. Azon a macOS-telepítésen, amelyen ez készült, a playlist_directory a ~/Documents/RetroArch/playlists, miközben a core-ok és a bélyegképek a ~/Library/Application Support/RetroArch alatt élnek. A ~ feloldódik, és a hordozható telepítés által a saját könyvtárához használt vezető : is.
Tud másik gépre írni. Az Androidon nincs Python, így az egyetlen módja a kiszolgálásának, ha máshol rendereljük le a fát, és átmásoljuk. Ugyanez a mechanizmus fedi le azt az SD-kártyát is, amely a kézikonzolon más útvonalra lesz felcsatolva.
Futó RetroArch mellett nem hajlandó írni. A RetroArch memóriában tartja a lejátszási listákat, és kilépéskor visszaírja őket — kedvencek, utoljára játszott, rendezési sorrend —, így egy alatta végzett írás elveszhet. A Batocera-motor helyette későbbre halasztja, mert ott a Ports-menü indította el; itt semmi nem indít minket, így a visszautasítás egyszerűbb és biztonságosabb.
Amit a Batoceráhozhoz képest elveszítünk: egy .lpl bejegyzésnek nincs leírás- vagy fejlesztőmezője, így a desc és az author nem marad meg — a RetroArch ezeket a saját adatbázisaiból veszi. A RetroArch ráadásul nem tud szkriptet indítani, tehát nincs alkalmazáson belüli indítás: a szinkron shellből vagy ütemezőből fut.
A telepítő paraméterként kapja az áruházat, így bármilyen konfigurációval működik:
curl -fsSL https://git.teletypegames.org/stores/warp-engine-retroarch-store/raw/branch/master/install.sh |
STORE_CONFIG=https://git.example.org/tools/my-store/raw/branch/master/config.json sh
Kiolvassa a store.id értéket a konfigurációból, majd a motort, a közös magot és a konfigurációt a ~/.local/share/warp-engine-store/example-retroarch/ könyvtárba telepíti, az example-retroarch-store indítót a ~/.local/bin alá írja, kiírja a feloldott útvonalakat, és lefuttatja az első szinkront.
Az áruház könyvtárának neve az áruházazonosító -retroarch utótaggal, nem a csupasz azonosító: az asztali áruházmotor ugyanezt a gyökeret használja, és a közös könyvtár közös config.json és state.json fájlt jelentene. Egy korábbi telepítést a telepítő következő futása áthelyez.
| Környezeti változó | Jelentés |
|---|---|
STORE_CONFIG |
kötelező — az áruház config.json fájljának útvonala vagy URL-je |
STORE_ROOT |
hol élnek az áruházak (alapérték ${XDG_DATA_HOME:-~/.local/share}/warp-engine-store) |
BIN_DIR |
hova kerül az indító (alapérték ~/.local/bin) |
RETROARCH_DIR |
a RetroArch könyvtára, ha szokatlan helyen van |
STORE_SKIP_SYNC |
1 esetén szinkron nélküli telepítés |
ENGINE_RAW_BASE |
honnan töltse le a retroarch_store.py fájlt |
WARPSTORE_RAW_BASE |
honnan töltse le a warpstore.py fájlt |
WARPSTORE_SRC |
egy helyi warpstore.py, amit letöltés helyett telepítsen |
S=~/.local/bin/example-retroarch-store
$S paths # a feloldott könyvtárak, és hogy megvannak-e a core-ok
$S list # kompatibilis bejegyzések; * telepítve, ^ van frissítés
$S sync # minden újdonság letöltése, a listák frissítése
$S sync blessingofra # csak egy cím (soha nem takarít)
$S -n sync # szárazon futtatás
$S remove c64:c64demo # eltávolítás (a csupasz név is jó)
$S purge # minden eltávolítása, amit ez az áruház telepített
$S config # az érvényes konfiguráció
A globális kapcsolók az alparancs elé jönnek: $S --retroarch-dir /mnt/ra sync.
Szinkron után indítsd újra a RetroArchot — a menüjét induláskor építi fel, így egy új lejátszási lista nem jelenik meg egy futó példányban.
curl -fsSL https://git.teletypegames.org/stores/warp-engine-retroarch-store/raw/branch/master/uninstall.sh | sh
Az eltávolítást a motor végzi, nem a shellszkript: előbb purge, majd az indító és az áruház könyvtára. Csak a state.json tudja, mely lejátszási listák, bélyegképek és tartalomfájlok voltak a mieink — és ha a motor nem tud végezni (fut a RetroArch, eltűnt egy könyvtár), semmi máshoz nem nyúl, így soha nem maradsz úgy, hogy a fájlok megvannak, de a motor nincs, amely ismerné őket.
| Környezeti változó | Jelentés |
|---|---|
STORE_ID |
melyik áruházat távolítsa el; csak több telepített áruház esetén kell |
STORE_CONFIG |
a STORE_ID alternatívája — az azonosítót a konfigurációból olvassa ki |
DRY_RUN |
1 esetén kiírja, mi tűnne el, és semmit nem távolít el |
KEEP_HOME |
1 esetén megtartja az áruház könyvtárát (állapot, katalógus-gyorsítótár, napló) az újratelepítéshez |
FORCE |
1 esetén futó RetroArch mellett is takarít |
STORE_ROOT, BIN_DIR |
ugyanaz, mint a telepítőnél |
Amit szándékosan meghagy:
.lpl mentések — mindegyik a lejátszási listáról, az áruházazonosítóról és a -backup utótagról kapja a nevét, és a futás végén kilistázódik. Ezek a listák abban az állapotban, ahogy először találtuk őket, tehát tartalmazhatnak olyan bejegyzéseket is, amelyek soha nem voltak a mieink.A szárazon futtatás fájlokat listáz, könyvtártörléseket nem: nem tudhatja, mely könyvtárak maradnak üresen.
Ha minden áruházat le akarsz szedni egy gépről — mindkét motort, a közös magot, az indítókat —, használd a warpstore szkriptjét:
curl -fsSL https://git.teletypegames.org/engines/warpstore/raw/branch/master/uninstall.sh | sh
~/.local/share/warp-engine-store/example-retroarch/
├── retroarch_store.py, warpstore.py, config.json
└── state.json, catalog.json
<content_root>/example/c64/ blessingofra-2.0.0.prg, rabbit-1.0.0.prg, …
<playlists_dir>/Example Store - Commodore 64.lpl
<thumbnails_dir>/Example Store - Commodore 64/Named_Boxarts/Blessing of Ra.png
/Named_Titles/… /Named_Snaps/…
A content_root alapértelmezés szerint a RetroArch könyvtárán belüli content mappa; a másik kettő a retroarch.cfg fájlból jön. A paths kiírja, mi lett feloldva, és melyik válasz honnan jött — ezt futtasd először, ha egy szinkron váratlan helyre került.
Minden az áruház saját paths.subfolder mappájába kerül, és a takarítás csak ehhez nyúlhat: soha nem a felhasználó tartalmához, és soha nem egy másik áruházéhoz. A lejátszásilista-fájl az áruház nevét viseli, tehát a miénk — de egy a felhasználó által felvett bejegyzés túléli az újraírást, mert csak az áruház tartalommappájába mutató elemek cserélődnek le. Amikor egy lejátszási listához először nyúlunk, -backup másolat készül róla.
{
"version": "1.5",
"default_core_path": "/…/cores/vice_x64_libretro.dylib",
"default_core_name": "VICE x64",
"label_display_mode": 0,
"right_thumbnail_mode": 0,
"left_thumbnail_mode": 0,
"thumbnail_match_mode": 0,
"sort_mode": 0,
"items": [
{
"path": "/…/content/example/c64/blessingofra-2.0.0.prg",
"entry_slot": -1,
"label": "Blessing of Ra",
"core_path": "DETECT",
"core_name": "DETECT",
"crc32": "4253CFC6|crc",
"db_name": "Example Store - Commodore 64.lpl"
}
]
}
default_core_path fejlécmező. Csak így indul minden bejegyzés egyetlen kattintással, core-kérdés nélkül. A bejegyzések DETECT értéken maradnak, így a fájl ott is működik, ahol a core-ok máshol vannak — legrosszabb esetben egy kérdés, nem egy halott bejegyzés.{store} - {label} soha nem ír bele a RetroArch saját Commodore - 64.lpl fájljába, és soha nem ütközik a hivatalos bélyegképcsomagokkal. Ez egyben a db_name is, amelyből a RetroArch megtalálja a bélyegképeket: a thumbnails_dir alatti mappát, amelynek a neve pontosan a lejátszási lista neve .lpl nélkül, benne a Named_* mappákkal.0 értékűek — amit a felhasználó globálisan beállított. Egy áruháznak semmi köze felülbírálni.crc32 valódi, a letöltött fájlból számolva, így a RetroArch a mentéseket és a bélyegképeket a tartalomhoz tudja kötni.A hiányzó core megjegyzés, nem hiba. Ha a platform core-ja nincs meg a libretro_directory mappában, a lejátszási lista akkor is kiíródik: a default_core_path üresen marad, a bejegyzések DETECT értéken maradnak, a RetroArch pedig egyszer rákérdez. A list és a paths ezt jelzi, a megoldással együtt:
c64: core not found: vice_x64_libretro.dylib — entries stay on DETECT
(Online Updater ▸ Core Downloader ▸ VICE x64)
A borítóképnek PNG-nek kell lennie. A RetroArch a címkét .png kiterjesztéssel keresi, mással nem. A katalógus azt szolgálja ki, amit feltöltöttek — az egyik borítónk GIF —, a szabványkönyvtár pedig nem tud képet újrakódolni, ezért a motor kifelé hív: sips (macOS-be építve), magick, convert vagy ffmpeg, amelyiket elsőként megtalálja. Ha egyik sincs, a bejegyzés borítókép nélkül marad, ami jobb, mint egy elbukott szinkron. Az őszinte megoldás felfelé van: a WarpEngine kiszolgálhatna PNG-változatot.
A borító egyszer töltődik le, és mindhárom Named_* mappába bekerül, hardlinkelve, ahol a fájlrendszer engedi.
exportA sync ennek a gépnek a RetroArchjába telepít. Az export az egész áruházat egy kanonikus fába rendereli le máshova.
# Android adb-n keresztül
$S export /tmp/ra-example \
--target-prefix /storage/emulated/0/RetroArch \
--target-libretro-dir /data/data/com.retroarch.aarch64/cores \
--core-suffix _android.so
adb push /tmp/ra-example/. /storage/emulated/0/RetroArch/
# Itt felcsatolt SD-kártya, ami a kézikonzolon a /mnt/sdcard alatt lesz
$S export /Volumes/SDCARD/RetroArch --target-prefix /mnt/sdcard/RetroArch
A fa mindig playlists, thumbnails és content a megadott könyvtáron belül. A --target-prefix az, aminek a lejátszási listák szerint a tartalmat hívják azon a gépen, amely futtatni fogja; enélkül az exportkönyvtár saját útvonala kerül bele. A célútvonalak úgy íródnak, ahogy a cél írja őket — POSIX, hacsak az előtag nem néz ki windowsosnak.
Az export szándékosan állapotmentes: a katalógus teljes pillanatképe, nem inkrementális frissítés, és nem zavarhatja meg az ugyanabban az áruházkönyvtárban lévő helyi telepítést.
Egy katalógusplatform akkor telepíthető, ha valamelyik libretro core közvetlenül el tudja indítani az assetjét:
| Katalógusplatform | Asset típusa | Core | Kiterjesztés |
|---|---|---|---|
c64 |
cartridge |
vice_x64_libretro (VICE x64) |
.prg |
tic80 |
cartridge |
tic80_libretro (TIC-80) |
.tic |
Mindkét core minden releváns célra elkészül — macOS x86_64/arm64, Linux x86_64/aarch64/armhf, Windows x86_64, Android arm64-v8a/armeabi-v7a —, tehát a kazetták mindenhol futnak, ahol a RetroArch.
A többi WarpEngine-platform (ebitengine, love, godot, bevy, phaser) webes buildet és operációs rendszerenkénti natív archívumokat szállít. Ezeket egyetlen libretro core sem futtatja, tehát ez a motor nem tudja kiszolgálni őket; Batocera-dobozon Portként telepíthetők.
A motort végponttól végpontig kipróbáltuk az éles katalóguson: letöltés, lejátszási listák, bélyegképek, GIF-konverzió, idegen bejegyzések megőrzése, takarítás, eltávolítás, androidos export és teljes telepítés a forge-ból. Két dolog kíván valódi futtatást:
.prg fájlt, vagy betölti és megvárja a RUN parancsot? Ha vár, a megoldás egy core-beállítás vagy .d64 szállítása.adb push írt.A tervezési jegyzetek és a mérések, amelyekből ez a motor készült, a devarea/RETROARCH_STORE.md fájlban vannak.