mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-04-15 21:32:32 -05:00
refactor: replace emulator extras with cross-reference discovery
_collect_emulator_extras() now uses find_undeclared_files() from verify.py instead of manual emulator name lists. This gives: - System-overlap matching (automatic, no manual config needed) - mode: standalone filtering (no standalone files in libretro packs) - type: launcher filtering (no launcher BIOS in system_dir) - data_directories coverage (no false gaps) - hle_fallback propagation - Works for ANY platform (same logic for RetroArch, Batocera, etc.) RetroArch --include-extras now discovers 91 extra files from emulator profiles automatically.
This commit is contained in:
@@ -27,7 +27,8 @@ sys.path.insert(0, os.path.dirname(__file__))
|
|||||||
from common import (
|
from common import (
|
||||||
build_zip_contents_index, check_inside_zip, compute_hashes,
|
build_zip_contents_index, check_inside_zip, compute_hashes,
|
||||||
group_identical_platforms, load_database, load_data_dir_registry,
|
group_identical_platforms, load_database, load_data_dir_registry,
|
||||||
load_platform_config, md5_composite, resolve_local_file,
|
load_emulator_profiles, load_platform_config, md5_composite,
|
||||||
|
resolve_local_file,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -172,73 +173,43 @@ def download_external(file_entry: dict, dest_path: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _load_emulator_extras(
|
def _collect_emulator_extras(
|
||||||
platform_name: str,
|
config: dict,
|
||||||
platforms_dir: str,
|
|
||||||
emulators_dir: str,
|
emulators_dir: str,
|
||||||
seen: dict,
|
db: dict,
|
||||||
|
seen: set,
|
||||||
base_dest: str,
|
base_dest: str,
|
||||||
config: dict | None = None,
|
emu_profiles: dict | None = None,
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
"""Load extra files from emulator profiles not already in the platform pack.
|
"""Collect extra files from emulator profiles not in the platform pack.
|
||||||
|
|
||||||
Collects emulators from two sources:
|
Uses the same system-overlap matching as verify.py cross-reference:
|
||||||
1. Auto-detected from platform config "core:" fields per system
|
- Matches emulators by shared system IDs with the platform
|
||||||
2. Manual "emulators:" list in _registry.yml
|
- Filters mode: standalone, type: launcher, type: alias
|
||||||
|
- Respects data_directories coverage
|
||||||
|
- Only returns files that exist in the repo (packable)
|
||||||
|
|
||||||
|
Works for ANY platform (RetroArch, Batocera, Recalbox, etc.)
|
||||||
"""
|
"""
|
||||||
emu_names = set()
|
from verify import find_undeclared_files
|
||||||
|
|
||||||
# Source 1: auto-detect from platform config core: fields
|
|
||||||
if config:
|
|
||||||
for system in config.get("systems", {}).values():
|
|
||||||
core = system.get("core", "")
|
|
||||||
if core:
|
|
||||||
emu_names.add(core)
|
|
||||||
|
|
||||||
# Source 2: manual list from _registry.yml
|
|
||||||
registry_path = os.path.join(platforms_dir, "_registry.yml")
|
|
||||||
if os.path.exists(registry_path):
|
|
||||||
with open(registry_path) as f:
|
|
||||||
registry = yaml.safe_load(f) or {}
|
|
||||||
platform_cfg = registry.get("platforms", {}).get(platform_name, {})
|
|
||||||
for name in platform_cfg.get("emulators", []):
|
|
||||||
emu_names.add(name)
|
|
||||||
|
|
||||||
if not emu_names:
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
undeclared = find_undeclared_files(config, emulators_dir, db, emu_profiles)
|
||||||
extras = []
|
extras = []
|
||||||
emu_dir = Path(emulators_dir)
|
for u in undeclared:
|
||||||
for emu_name in emu_names:
|
if not u["in_repo"]:
|
||||||
emu_path = emu_dir / f"{emu_name}.yml"
|
|
||||||
if not emu_path.exists():
|
|
||||||
continue
|
continue
|
||||||
with open(emu_path) as f:
|
name = u["name"]
|
||||||
profile = yaml.safe_load(f) or {}
|
dest = name
|
||||||
|
full_dest = f"{base_dest}/{dest}" if base_dest else dest
|
||||||
# Follow alias
|
if full_dest in seen:
|
||||||
if profile.get("alias_of"):
|
continue
|
||||||
parent = emu_dir / f"{profile['alias_of']}.yml"
|
extras.append({
|
||||||
if parent.exists():
|
"name": name,
|
||||||
with open(parent) as f:
|
"destination": dest,
|
||||||
profile = yaml.safe_load(f) or {}
|
"required": u.get("required", False),
|
||||||
|
"hle_fallback": u.get("hle_fallback", False),
|
||||||
for fe in profile.get("files", []):
|
"source_emulator": u.get("emulator", ""),
|
||||||
name = fe.get("name", "")
|
})
|
||||||
if not name or name.startswith("<"):
|
|
||||||
continue
|
|
||||||
dest = fe.get("destination", name)
|
|
||||||
full_dest = f"{base_dest}/{dest}" if base_dest else dest
|
|
||||||
if full_dest in seen:
|
|
||||||
continue
|
|
||||||
extras.append({
|
|
||||||
"name": name,
|
|
||||||
"sha1": fe.get("sha1"),
|
|
||||||
"md5": fe.get("md5"),
|
|
||||||
"destination": dest,
|
|
||||||
"required": fe.get("required", False),
|
|
||||||
"source_emulator": emu_name,
|
|
||||||
})
|
|
||||||
return extras
|
return extras
|
||||||
|
|
||||||
|
|
||||||
@@ -375,12 +346,13 @@ def generate_pack(
|
|||||||
zf.write(local_path, full_dest)
|
zf.write(local_path, full_dest)
|
||||||
total_files += 1
|
total_files += 1
|
||||||
|
|
||||||
# Tier 2: emulator extras
|
# Tier 2: emulator extras (files cores need but platform doesn't declare)
|
||||||
extra_count = 0
|
extra_count = 0
|
||||||
if include_extras:
|
if include_extras:
|
||||||
extras = _load_emulator_extras(
|
emu_profiles = load_emulator_profiles(emulators_dir)
|
||||||
platform_name, platforms_dir, emulators_dir,
|
extras = _collect_emulator_extras(
|
||||||
seen_destinations, base_dest, config=config,
|
config, emulators_dir, db,
|
||||||
|
seen_destinations, base_dest, emu_profiles,
|
||||||
)
|
)
|
||||||
for fe in extras:
|
for fe in extras:
|
||||||
dest = _sanitize_path(fe.get("destination", fe["name"]))
|
dest = _sanitize_path(fe.get("destination", fe["name"]))
|
||||||
|
|||||||
Reference in New Issue
Block a user