EN /HU | Belépés

WarpEngine RetroArch Store

A warp-engine-retroarch-store egy WarpEngine-katalógusból húzza be a játékokat a RetroArch könyvtárába: platformonként egy .lpl lejá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.json fájljából jön. A közös fele a warpstore.

TXT
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

Amit kapsz

  • Minden gép, amin fut a RetroArch — asztali Linux, Windows, macOS, Android, Steam Deck, a konzolportok. Ugyanazok a kazetták, amiket a Batocera-áruház telepít, jóval nagyobb közönséggel.
  • Semmilyen feltételezett útvonal — a négy szükséges könyvtár a felhasználó saját retroarch.cfg fájljából jön.
  • Olyan gépre is tud írni, amelyen nem fut (export), és ez az egyetlen módja Android kiszolgálásának, ahol fut a RetroArch, de Python nincs.
  • Soha nem szerkeszti a retroarch.cfg fájlt, és nem nyúl a megjelenítési beállításokhoz.
  • Nulla függőség — csak a Python 3 szabványkönyvtára.
TXT
<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

Miért nem a Batocera-áruház ez

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.


Egy áruház telepítése

A telepítő paraméterként kapja az áruházat, így bármilyen konfigurációval működik:

SH
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

Használat

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


Eltávolítás

SH
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:

  • a felhasználó által az áruház mappájába tett tartalom — egy könyvtár csak akkor tűnik el, ha üres, tehát egyetlen kósza fájl megtartja.
  • egy lejátszási lista, amelyben még vannak saját bejegyzései — csak az áruház tartalommappájába mutató elemek kerülnek ki. Az üresen maradt listát törli; amelyik nem üres, azt nélkülünk újraírja.
  • az .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:

SH
curl -fsSL https://git.teletypegames.org/engines/warpstore/raw/branch/master/uninstall.sh | sh

Hova kerülnek a dolgok

TXT
~/.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.


A lejátszási lista

JSON
{
  "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"
    }
  ]
}
  • Platformonként egy lejátszási lista, mert a 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.
  • A név a névtér. A {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.
  • A megjelenítési mezők mind 0 értékűek — amit a felhasználó globálisan beállított. Egy áruháznak semmi köze felülbírálni.
  • A 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:

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


Másik gépre: export

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

SH
# 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.


Platform-leképezés

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.


Amit valódi hardveren még nem ellenőriztünk

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:

  • Automatikusan elindítja-e a VICE core a nyers .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.
  • Az androidos átmásolás — a fenti útvonalak dokumentált alapértékek, nem mérések, és az sem tesztelt, hogy a scoped storage engedi-e a RetroArchnak olvasni azt, amit az 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.