feat: read retrobat's cores from its es_systems

RetroBat's platform file carried no core list, and a registry list
copied from Batocera stood in with ports RetroBat never runs and none
of its standalone emulators marked as such. The scraper now reads
es_systems.cfg at the release tag: libretro cores, and every other
emulator as standalone.
This commit is contained in:
Abdessamad Derraz committed 2026-10-17 03:40:09 +02:00
1 parent b25fef6297
commit d9ef6ad0ad
4 files changed
+496 -170

No files matched your search

-169
View File
@@ -232,175 +232,6 @@ platforms:
# Windows: names differing only by case land on one file.
case_insensitive_fs: true
schedule: weekly
cores:
- '81'
- a5200
- abuse
- arduous
- ares
- atari800
- azahar
- bennugd
- bk
- bluemsx
- bsnes
- bstone
- cannonball
- cap32
- catacombgl
- cdogs
- cemu
- cgenius
- citron
- clk
- corsixth
- demul
- devilutionx
- dhewm3
- dice
- dolphin
- dosbox_pure
- dxx-rebirth
- easyrpg
- ecwolf
- eduke32
- eka2l1
- emuscv
- etlegacy
- fake08
- fallout1-ce
- fallout2-ce
- fbalpha2012
- fbalpha2012_neogeo
- fbneo
- fceumm
- flatpak
- flycast
- freechaf
- freeintv
- freej2me
- fury
- fuse
- gambatte
- geargrafx
- gearsystem
- genesisplusgx
- glide64mk2
- gong
- gsplus
- gw
- gzdoom
- hatari
- hcl
- hurrican
- hypseus-singe
- ikemen
- ioquake3
- iortcw
- jazz2-native
- lindbergh-loader
- lowresnx
- lutro
- mame
- mame078plus
- mamemess
- mednafen_lynx
- mednafen_ngp
- mednafen_supergrafx
- mednafen_wswan
- melonds
- mgba
- minivmac
- model2emu
- moonlight
- mrboom
- mupen64plus_next
- neocd
- np2kai
- nxengine
- o2em
- odcommander
- openbor6412
- openjazz
- openjk
- openjkdf2
- openmohaa
- opera
- parallel_n64
- pce_fast
- pcfx
- pcsx2
- pcsx_rearmed
- pd777
- picodrive
- play
- pokemini
- potator
- ppsspp
- prboom
- prosystem
- puae
- px68k
- pygame
- pyxel
- quasi88
- raze
- reminiscence
- rpcs3
- ruffle
- samcoupe
- sameduck
- scummvm
- sdlpop
- sh
- shadps4
- snes9x
- solarus
- sonic-mania
- sonic2013
- sonic3-air
- squirreljme
- steam
- stella
- superbroswar
- supermodel
- taradino
- tgbdual
- theforceengine
- theodore
- thextech
- tic80
- tr1x
- tr2x
- tsugaru
- tyrian
- tyrquake
- uqm
- uzem
- vb
- vecx
- vice_x64
- vircon32
- virtualjaguar
- vita3k
- vox_official
- vpinball
- wasm4
- wine-tkg
- x1
- x128
- x16emu
- xash3d_fwgs
- xemu
- xenia-canary
- xpet
- xplus4
- xrick
- xroar
- xvic
- yabasanshiro
- yquake2
- zc210
target_scraper: null
target_source: null
install:
+417 -1
View File
@@ -1,10 +1,426 @@
platform: RetroBat
version: 8.3.0
version: 8.3.1
homepage: "https://www.retrobat.org"
source: "https://raw.githubusercontent.com/RetroBat-Official/emulatorlauncher/master/batocera-systems/Resources/batocera-systems.json"
base_destination: bios
hash_type: md5
verification_mode: md5
cores:
- 2ship
- "81"
- DoubleCherryGB
- a5200
- altirra
- amiarcadia
- amiberry
- amigaforever
- applewin
- arcadeduck
- arcadeflashweb
- ardens
- arduous
- ares
- atari800
- azahar
- b2
- bennugd
- bigpemu
- bizhawk
- bk
- blastem
- bluemsx
- boom3
- boom3_xp
- bsnes
- bsnes-jg
- bsnes_hd_beta
- bstone
- bsyndrome
- cannonball
- cap32
- capriceforever
- cdogs
- cemu
- cgenius
- chihiro
- chihiro-gun
- citra
- citron
- corsixth
- crocods
- cxbx
- daphne
- demul
- desmume
- desmume2015
- devilutionx
- dhewm3
- dice
- dinothawr
- dolphin
- dolphin-triforce
- dosbox
- dosbox-pure
- dosbox-staging
- dosbox_pure
- doukutsu_rs
- duckstation
- dusklight
- easyrpg
- ecwolf
- eden
- eduke32
- eka2l1
- emuscv
- ep128emu_core
- exodos
- fake08
- fbalpha
- fbalpha2012
- fbalpha2012_cps1
- fbalpha2012_cps2
- fbalpha2012_cps3
- fbalpha2012_neogeo
- fbneo
- fceumm
- flycast
- fpinball
- freechaf
- freeintv
- freej2me
- frodo
- fuse
- gambatte
- gearcoleco
- geargrafx
- gearsystem
- gemrb
- genesis_plus_gx
- genesis_plus_gx_expanded
- genesis_plus_gx_wide
- geolith
- ghostship
- gopher64
- gpsp
- groovymame
- gsplus
- gw
- gzdoom
- handy
- hatari
- hatarib
- hbmame
- holani
- hypseus
- ikemen
- imageviewer
- jgenesis
- jollycv
- jynx
- jzintv
- kega-fusion
- kronos
- linuxloader
- love
- lowresnx
- lutro
- m2000
- m2emulator
- magicengine
- mame
- mame2000
- mame2003
- mame2003_midway
- mame2003_plus
- mame2010
- mame2014
- mame2016
- mame64
- mandarine
- mednafen
- mednafen_gba
- mednafen_lynx
- mednafen_ngp
- mednafen_pce
- mednafen_pce_fast
- mednafen_pcfx
- mednafen_psx_hw
- mednafen_saturn
- mednafen_snes
- mednafen_supergrafx
- mednafen_vb
- mednafen_wswan
- melonds
- melondsds
- mesen
- mesen-s
- mgba
- mugen
- mupen64
- mupen64plus_next
- nekop2
- neocd
- nestopia
- noods
- nosgba
- np2kai
- nxengine
- o2em
- openbor
- opengoal
- openjazz
- openlara
- openmsx
- opera
- oricutron
- parallel_n64
- pcsx2
- pcsx2-16
- pcsx2x6
- pcsx_rearmed
- pd777
- pdark
- phoenix
- pico8
- picodrive
- pinballfx
- play
- pocketcdg
- pokemini
- potator
- powerbomberman
- ppsspp
- prboom
- project64
- prosystem
- psxmame
- puae
- px68k
- quasi88
- quiverlauncher
- race
- raine
- raze
- redream
- reminiscence
- retro8
- rpcs3
- rtcw
- ruffle
- ryujinx
- same_cdi
- sameboy
- sameduck
- scummvm
- shadps4
- simcoupe
- simple64
- singe2
- snes9x
- snes9x2005
- soh
- solarus
- solarus2
- sonic3air
- sonicmania
- sonicretro
- sonicretrocd
- ssf
- starship
- stella
- stella2014
- sudachi
- superbroswar
- supermodel
- swanstation
- teknoparrot
- tgbdual
- theforceengine
- theodore
- tic80
- tsugaru
- tyrquake
- uzdoom
- uzem
- vecx
- vice_x128
- vice_x64
- vice_x64sc
- vice_xpet
- vice_xplus4
- vice_xvic
- vircon32
- virtualjaguar
- vita3k
- vitaquake2
- vitaquake2-rogue
- vitaquake2-xatrix
- vitaquake2-zaero
- vkquake
- vkquake2
- vpinball
- wasm4
- windows
- winuae
- x1
- xash3d
- xemu
- xemu-chihiro
- xenia
- xenia-canary
- xenia-edge
- xenia-manager
- xm6pro
- xroar
- yabasanshiro
- ymir
- yuzu
- zaccariapinball
- zc255
- zesarux
- zinc
- zquestclassic
standalone_cores:
- 2ship
- altirra
- amiberry
- amigaforever
- applewin
- arcadeduck
- arcadeflashweb
- ares
- azahar
- bigpemu
- bizhawk
- blastem
- bstone
- bsyndrome
- capriceforever
- cdogs
- cemu
- cgenius
- chihiro
- chihiro-gun
- citra
- citron
- corsixth
- cxbx
- daphne
- demul
- desmume
- devilutionx
- dhewm3
- dolphin
- dolphin-triforce
- dosbox
- dosbox-pure
- dosbox-staging
- duckstation
- dusklight
- eden
- eduke32
- eka2l1
- exodos
- fbneo
- flycast
- fpinball
- gemrb
- ghostship
- gopher64
- groovymame
- gsplus
- gzdoom
- hatari
- hbmame
- hypseus
- ikemen
- jgenesis
- jynx
- jzintv
- kega-fusion
- kronos
- linuxloader
- love
- m2emulator
- magicengine
- mame64
- mandarine
- mednafen
- melonds
- mesen
- mgba
- mugen
- mupen64
- nosgba
- openbor
- opengoal
- openjazz
- openmsx
- oricutron
- pcsx2
- pcsx2-16
- pcsx2x6
- pdark
- phoenix
- pico8
- pinballfx
- play
- powerbomberman
- ppsspp
- project64
- psxmame
- quiverlauncher
- raine
- raze
- redream
- rpcs3
- rtcw
- ruffle
- ryujinx
- scummvm
- shadps4
- simcoupe
- simple64
- singe2
- snes9x
- soh
- solarus
- solarus2
- sonic3air
- sonicmania
- sonicretro
- sonicretrocd
- ssf
- starship
- stella
- sudachi
- supermodel
- teknoparrot
- theforceengine
- tsugaru
- uzdoom
- vita3k
- vkquake
- vkquake2
- vpinball
- windows
- winuae
- xash3d
- xemu
- xemu-chihiro
- xenia
- xenia-canary
- xenia-edge
- xenia-manager
- xm6pro
- xroar
- yabasanshiro
- ymir
- yuzu
- zaccariapinball
- zesarux
- zinc
- zquestclassic
systems:
3do:
files:
+44
View File
@@ -9,6 +9,8 @@ Hash: MD5 primary
from __future__ import annotations
import json
import urllib.error
import urllib.request
try:
from .base_scraper import (
@@ -34,6 +36,37 @@ SOURCE_URL = (
GITHUB_REPO = "RetroBat-Official/retrobat"
ES_SYSTEMS_URL = (
"https://raw.githubusercontent.com/RetroBat-Official/retrobat/{tag}"
"/system/templates/emulationstation/es_systems.cfg"
)
def es_systems_cores(text: str) -> tuple[set[str], set[str]]:
"""Every core RetroBat's ES offers, and the emulators it runs standalone.
emulatorlauncher starts what es_systems.cfg lists: a libretro core by its
name under ``<emulator name="libretro">``, any other emulator by its own
name. batocera-systems.json names BIOS files only, so the platform read
from it alone had no core list and relied on one kept by hand.
"""
from common import parse_untrusted_xml
root = parse_untrusted_xml(text, "es_systems.cfg")
cores: set[str] = set()
standalone: set[str] = set()
for emulator in root.iter("emulator"):
name = (emulator.get("name") or "").strip()
if not name:
continue
listed = {(core.text or "").strip() for core in emulator.iter("core")} - {""}
if name == "libretro":
cores |= listed
else:
cores.add(name)
standalone.add(name)
return cores, standalone
# Map RetroBat system keys to our normalized system IDs
SYSTEM_SLUG_MAP = {
"ps2": "sony-playstation-2",
@@ -161,6 +194,15 @@ class Scraper(BaseScraper):
systems[req.system]["files"].append(requirement_entry(req))
version = fetch_github_latest_version(GITHUB_REPO)
es_url = ES_SYSTEMS_URL.format(tag=version)
req = urllib.request.Request(es_url, headers={"User-Agent": "retrobios-scraper/1.0"})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
cores, standalone = es_systems_cores(resp.read().decode("utf-8"))
except urllib.error.URLError as e:
raise ConnectionError(f"Failed to fetch {es_url}: {e}") from e
if not cores:
raise RuntimeError(f"es_systems.cfg at {version} names no core")
return {
"platform": "RetroBat",
@@ -170,6 +212,8 @@ class Scraper(BaseScraper):
"base_destination": "bios",
"hash_type": "md5",
"verification_mode": "md5",
"cores": sorted(cores),
"standalone_cores": sorted(standalone),
"systems": systems,
}
+35
View File
@@ -260,6 +260,41 @@ core = "mame2003_plus"
self.assertNotIn("cores", registry["platforms"]["recalbox"])
class RetroBatCoresFromItsES(unittest.TestCase):
"""RetroBat's YAML carried no core list: batocera-systems.json names
BIOS files only, and a registry list copied from Batocera stood in,
with abuse, clk or etlegacy that RetroBat never runs."""
ES_SYSTEMS = """\
<?xml version="1.0"?>
<systemList>
<system><name>snes</name><emulators>
<emulator name="libretro"><cores><core>snes9x</core><core>bsnes</core></cores></emulator>
<emulator name="bsnes" />
</emulators></system>
<system><name>samcoupe</name><emulators>
<emulator name="simcoupe"><cores><core>simcoupe</core></cores></emulator>
</emulators></system>
</systemList>
"""
def test_libretro_cores_and_standalone_emulators(self):
from scraper.retrobat_scraper import es_systems_cores
cores, standalone = es_systems_cores(self.ES_SYSTEMS)
self.assertEqual(cores, {"snes9x", "bsnes", "simcoupe"})
self.assertEqual(standalone, {"bsnes", "simcoupe"})
def test_the_registry_leaves_the_list_to_the_scraper(self):
import yaml
root = Path(__file__).resolve().parents[1]
registry = yaml.safe_load((root / "platforms" / "_registry.yml").read_text())
self.assertNotIn("cores", registry["platforms"]["retrobat"])
platform = yaml.safe_load((root / "platforms" / "retrobat.yml").read_text())
self.assertIn("snes9x", platform["cores"])
class UnreadableReleaseStopsTheScrape(unittest.TestCase):
"""A failed tag lookup fell back to master, or to an empty or invented
version. BizHawk, RomM, Batocera and Recalbox then wrote a YAML read from