mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: decide slots on the region pass grouping
This commit is contained in:
1 parent
c4a080b0f4
commit
1879c984f4
2 files changed
+86
-55
No files matched your search
@@ -131,54 +131,6 @@ def _write_generated_member(zf: zipfile.ZipFile, arcname: str, text: str) -> Non
|
|||||||
zf.writestr(info, text)
|
zf.writestr(info, text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _pack_member_groups(
|
|
||||||
config: dict,
|
|
||||||
pack_systems: dict,
|
|
||||||
emulators_dir: str,
|
|
||||||
db: dict,
|
|
||||||
base_dest: str,
|
|
||||||
emu_profiles: dict | None,
|
|
||||||
target_cores: set[str] | None,
|
|
||||||
source: str,
|
|
||||||
) -> dict[str, list[tuple[str, str]]]:
|
|
||||||
"""Group every candidate of a pack by system, as (destination, name).
|
|
||||||
|
|
||||||
Covers the platform baseline and the core extras, because a narrowing pass
|
|
||||||
that saw only one of the two would compare an incomplete set.
|
|
||||||
"""
|
|
||||||
groups: dict[str, list[tuple[str, str]]] = {}
|
|
||||||
for sys_id, system in pack_systems.items():
|
|
||||||
members = groups.setdefault(sys_id, [])
|
|
||||||
for fe in system.get("files", []):
|
|
||||||
dest = sanitize_pack_path(fe.get("destination", fe.get("name", "")))
|
|
||||||
if dest:
|
|
||||||
members.append((dest, fe.get("name", "")))
|
|
||||||
if source == "platform":
|
|
||||||
return groups
|
|
||||||
# find_undeclared_files reports the profile's display name, not its key,
|
|
||||||
# so index both: on a key-only lookup nearly every core extra fell into a
|
|
||||||
# single bucket and lost its per-system grouping.
|
|
||||||
emu_systems = _emulator_systems_index(emu_profiles)
|
|
||||||
for fe in _collect_emulator_extras(
|
|
||||||
config, emulators_dir, db, set(), base_dest, emu_profiles,
|
|
||||||
target_cores=target_cores, include_all=(source == "truth"),
|
|
||||||
):
|
|
||||||
dest = sanitize_pack_path(fe.get("destination", fe.get("name", "")))
|
|
||||||
if not dest:
|
|
||||||
continue
|
|
||||||
for sys_id in emu_systems.get(fe.get("source_emulator", ""), ["_extras"]):
|
|
||||||
groups.setdefault(sys_id, []).append((dest, fe.get("name", "")))
|
|
||||||
return groups
|
|
||||||
|
|
||||||
|
|
||||||
def _narrowings(
|
def _narrowings(
|
||||||
source: str,
|
source: str,
|
||||||
regions: list[str] | None,
|
regions: list[str] | None,
|
||||||
@@ -576,8 +528,10 @@ def _select_variants(
|
|||||||
"""
|
"""
|
||||||
region_drops: set[str] = set()
|
region_drops: set[str] = set()
|
||||||
region_fallbacks: list[str] = []
|
region_fallbacks: list[str] = []
|
||||||
if regions:
|
# One grouping for both passes: a file judged in its own system by one
|
||||||
region_index = region_mod.build_region_index(emu_profiles or {})
|
# pass must not land in every system of its profile for the other.
|
||||||
|
region_groups: dict[str, list[tuple[str, str]]] = {}
|
||||||
|
if regions or one_per_slot:
|
||||||
region_groups, _extra_dests = platform_region_groups(
|
region_groups, _extra_dests = platform_region_groups(
|
||||||
config,
|
config,
|
||||||
pack_systems,
|
pack_systems,
|
||||||
@@ -589,6 +543,8 @@ def _select_variants(
|
|||||||
include_extras=(source != "platform"),
|
include_extras=(source != "platform"),
|
||||||
include_all=(source == "truth"),
|
include_all=(source == "truth"),
|
||||||
)
|
)
|
||||||
|
if regions:
|
||||||
|
region_index = region_mod.build_region_index(emu_profiles or {})
|
||||||
region_drops = region_mod.resolve_region_drops(
|
region_drops = region_mod.resolve_region_drops(
|
||||||
region_groups, region_index, regions
|
region_groups, region_index, regions
|
||||||
)
|
)
|
||||||
@@ -598,13 +554,9 @@ def _select_variants(
|
|||||||
|
|
||||||
slot_undecidable: list[str] = []
|
slot_undecidable: list[str] = []
|
||||||
if one_per_slot:
|
if one_per_slot:
|
||||||
members_by_system = _pack_member_groups(
|
|
||||||
config, pack_systems, emulators_dir, db, base_dest,
|
|
||||||
emu_profiles, target_cores, source,
|
|
||||||
)
|
|
||||||
slot_groups = {
|
slot_groups = {
|
||||||
sys_id: [(d, n) for d, n in members if d not in region_drops]
|
sys_id: [(d, n) for d, n in members if d not in region_drops]
|
||||||
for sys_id, members in members_by_system.items()
|
for sys_id, members in region_groups.items()
|
||||||
}
|
}
|
||||||
slot_drops, slot_undecidable = slot_mod.resolve_slot_drops(
|
slot_drops, slot_undecidable = slot_mod.resolve_slot_drops(
|
||||||
slot_groups, slot_mod.build_slot_index(emu_profiles or {})
|
slot_groups, slot_mod.build_slot_index(emu_profiles or {})
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
"""--one-per-slot and --region read one grouping of a pack.
|
||||||
|
|
||||||
|
The slot pass put each core extra under every system of its profile. PicoDrive
|
||||||
|
ranks its Mega CD BIOSes within sega-megacd; spread across sega-megadrive,
|
||||||
|
sega-32x and the rest, they shared a tier with unranked files, the tier was
|
||||||
|
ruled undecidable, and the keep overrode the drop.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||||
|
|
||||||
|
|
||||||
|
class SlotPassReadsTheRegionGrouping(unittest.TestCase):
|
||||||
|
def test_ranked_mega_cd_alternatives_are_decided(self):
|
||||||
|
if not (REPO_ROOT / "database.json").is_file():
|
||||||
|
self.skipTest("database.json not built")
|
||||||
|
import generate_pack as gp
|
||||||
|
from common import load_database, load_emulator_profiles, load_platform_config
|
||||||
|
|
||||||
|
previous = os.getcwd()
|
||||||
|
os.chdir(REPO_ROOT)
|
||||||
|
self.addCleanup(os.chdir, previous)
|
||||||
|
db = load_database("database.json")
|
||||||
|
profiles = load_emulator_profiles("emulators")
|
||||||
|
config = load_platform_config("retroarch", "platforms")
|
||||||
|
drops, _fallbacks, _undecided = gp._select_variants(
|
||||||
|
config, config["systems"], "emulators", db,
|
||||||
|
config.get("base_destination", ""), profiles, None, "full", None, True,
|
||||||
|
)
|
||||||
|
names = {os.path.basename(d) for d in drops}
|
||||||
|
for name in ("jp_mcd1_9111.bin", "eu_mcd1_9210.bin"):
|
||||||
|
self.assertIn(name, names)
|
||||||
|
|
||||||
|
def test_one_grouping_function(self):
|
||||||
|
source = (REPO_ROOT / "scripts" / "generate_pack.py").read_text(encoding="utf-8")
|
||||||
|
self.assertNotIn("def _pack_member_groups", source)
|
||||||
|
|
||||||
|
|
||||||
|
class VariantGroupSpansSystems(unittest.TestCase):
|
||||||
|
def test_us_request_withdraws_the_other_mega_cd_lists(self):
|
||||||
|
"""PicoDrive files US under sega-segacd and EU/JP under sega-megacd.
|
||||||
|
|
||||||
|
find_bios (platform/libretro/libretro.c:1296) fills one slot from one
|
||||||
|
of three lists. Grouped by system, sega-megacd had no US member and was
|
||||||
|
kept whole as a fallback.
|
||||||
|
"""
|
||||||
|
if not (REPO_ROOT / "database.json").is_file():
|
||||||
|
self.skipTest("database.json not built")
|
||||||
|
import generate_pack as gp
|
||||||
|
import region as region_mod
|
||||||
|
from common import load_database, load_emulator_profiles, load_platform_config
|
||||||
|
|
||||||
|
previous = os.getcwd()
|
||||||
|
os.chdir(REPO_ROOT)
|
||||||
|
self.addCleanup(os.chdir, previous)
|
||||||
|
db = load_database("database.json")
|
||||||
|
profiles = load_emulator_profiles("emulators")
|
||||||
|
config = load_platform_config("retroarch", "platforms")
|
||||||
|
drops, _fallbacks, _undecided = gp._select_variants(
|
||||||
|
config, config["systems"], "emulators", db,
|
||||||
|
config.get("base_destination", ""), profiles, None, "full",
|
||||||
|
region_mod.parse_requested("us"), False,
|
||||||
|
)
|
||||||
|
names = {os.path.basename(d) for d in drops}
|
||||||
|
for name in ("jp_mcd1_9111.bin", "eu_mcd2_9306.bin"):
|
||||||
|
self.assertIn(name, names)
|
||||||
|
for name in ("us_scd2_9306.bin", "us_scd1_9210.bin"):
|
||||||
|
self.assertNotIn(name, names)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in new issue
Block a user