feat: lay out standalone files by build mode

This commit is contained in:
Abdessamad Derraz committed 2026-10-04 16:35:59 +02:00
1 parent 6148ab2e55
commit 887fc34bf6
8 files changed
+107 -37

No files matched your search

+2 -3
View File
@@ -10,6 +10,7 @@ from common import expand_platform_declared_names
from common import load_emulator_profiles
from common import resolution_is_hash_exact
from common import resolve_local_file
from common import runs_standalone
from common import sanitize_pack_path
def _emulator_systems_index(emu_profiles: dict | None) -> dict[str, list[str]]:
"""Map both the profile key and its display name to the profile's systems.
@@ -469,9 +470,7 @@ def _collect_emulator_extras(
continue
if emu_name not in relevant:
continue
is_standalone = emu_name in standalone_set or bool(
standalone_set & {str(c) for c in profile.get("cores", [])}
)
is_standalone = runs_standalone(emu_name, profile, standalone_set)
for f in profile.get("files", []):
fname = f.get("name", "")
if not fname:
+23 -13
View File
@@ -99,26 +99,34 @@ SYSTEM_SLUG_MAP = {
}
def split_cores(names) -> tuple[list[str], list[str]]:
"""(every core name, the standalone ones) from es_bios.xml ``core`` values."""
cores = {name for name in names if name}
standalone = {name for name in cores if not name.startswith("libretro")}
return sorted(cores), sorted(standalone)
class Scraper(BaseScraper):
"""Scraper for Recalbox es_bios.xml."""
def __init__(self, url: str = SOURCE_URL):
super().__init__(url=url)
def _fetch_cores(self) -> list[str]:
"""Extract unique core names from es_bios.xml bios elements."""
def _fetch_cores(self) -> tuple[list[str], list[str]]:
"""Core names from es_bios.xml, and those Recalbox runs standalone.
The ``core`` attribute writes a libretro core as ``libretro/<name>``
and a standalone emulator by its bare name (``dolphin``, ``pcsx2``,
``xemu``), so the prefix is the build mode. One entry spells
``libretro-hatari``; a name that starts with ``libretro`` is a core.
"""
raw = self._fetch_raw()
root = parse_untrusted_xml(raw, "es_bios.xml")
cores: set[str] = set()
for bios_elem in root.findall(".//system/bios"):
raw_core = bios_elem.get("core", "").strip()
if not raw_core:
continue
for part in raw_core.split(","):
name = part.strip()
if name:
cores.add(name)
return sorted(cores)
return split_cores(
part.strip()
for bios_elem in root.findall(".//system/bios")
for part in bios_elem.get("core", "").split(",")
)
def fetch_requirements(self) -> list[BiosRequirement]:
"""Parse es_bios.xml and return BIOS requirements."""
@@ -213,6 +221,7 @@ class Scraper(BaseScraper):
if not version:
version = "10.0"
cores, standalone = self._fetch_cores()
return {
"platform": "Recalbox",
"version": version,
@@ -221,7 +230,8 @@ class Scraper(BaseScraper):
"base_destination": "bios",
"hash_type": "md5",
"verification_mode": "md5",
"cores": self._fetch_cores(),
"cores": cores,
"standalone_cores": standalone,
"systems": systems,
}
+2 -3
View File
@@ -24,6 +24,7 @@ from common import (
load_data_dir_registry,
resolution_is_hash_exact,
resolve_local_file,
runs_standalone,
)
# A profile entry can prove a slot without declaring a hash: Dolphin names no
@@ -148,9 +149,7 @@ def profile_claims(
for emu_name, profile in sorted(profiles.items()):
if profile.get("type") in ("launcher", "alias"):
continue
is_standalone = emu_name in standalone_cores or bool(
standalone_cores & {str(c) for c in profile.get("cores", [])}
)
is_standalone = runs_standalone(emu_name, profile, standalone_cores)
for entry in profile.get("files") or []:
if not isinstance(entry, dict):
continue
+3 -7
View File
@@ -52,6 +52,7 @@ from common import (
resolve_local_file,
ProfileSelectionError,
resolve_platform_cores,
runs_standalone,
sanitize_pack_path,
select_emulator_profiles,
)
@@ -455,10 +456,7 @@ def find_undeclared_files(
if profile.get("bios_mode") == "agnostic":
continue
# Check if this profile is standalone: match profile name or any cores: alias
is_standalone = emu_name in standalone_set or bool(
standalone_set & {str(c) for c in profile.get("cores", [])}
)
is_standalone = runs_standalone(emu_name, profile, standalone_set)
for f in profile.get("files", []):
fname = f.get("name", "")
@@ -673,9 +671,7 @@ def find_exclusion_notes(
# Count standalone-only files -but only report as excluded if the
# platform does NOT use this emulator in standalone mode
standalone_set = set(str(c) for c in config.get("standalone_cores", []))
is_standalone = emu_name in standalone_set or bool(
standalone_set & {str(c) for c in profile.get("cores", [])}
)
is_standalone = runs_standalone(emu_name, profile, standalone_set)
if not is_standalone:
standalone_files = [
f for f in profile.get("files", []) if f.get("mode") == "standalone"