mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 17:33:30 -05:00
fix: group a system once whatever its spelling
The platform's files and the core extras for the Master System sat in two region groups, sega-master-system and sega-mastersystem, reduced apart. A US pack kept the declared Japanese BIOS. A core extra's system group now takes the platform's spelling, in the pack, the report and the installer's manifest fields alike.
This commit is contained in:
1 parent
97c973c7e2
commit
a40a68c1f7
4 files changed
+100
-9
No files matched your search
@@ -19,7 +19,7 @@ from dataclasses import dataclass
|
||||
|
||||
import region as region_mod
|
||||
from common import _norm_system_id, sanitize_pack_path
|
||||
from packextras import _extra_system_ids, _kept, extra_region_groups
|
||||
from packextras import _extra_system_ids, _kept, extra_region_groups, system_spellings
|
||||
|
||||
|
||||
def _dest(entry: dict) -> str:
|
||||
@@ -58,11 +58,14 @@ class SelectionIndex:
|
||||
|
||||
owned_by: dict[str, set[str]] = {}
|
||||
extra_groups: dict[str, set[str]] = {}
|
||||
spellings = system_spellings(pack_systems)
|
||||
for extra in extras:
|
||||
dest = _dest(extra)
|
||||
if not dest:
|
||||
continue
|
||||
extra_groups.setdefault(dest, set()).update(extra_region_groups(extra))
|
||||
extra_groups.setdefault(dest, set()).update(
|
||||
extra_region_groups(extra, spellings)
|
||||
)
|
||||
# A profile system the platform does not have is no system the
|
||||
# pack's --system accepts: it would offer what the pack refuses.
|
||||
for sys_id in _extra_system_ids(extra):
|
||||
|
||||
+32
-6
@@ -6,7 +6,9 @@ this module builds so the report and the pack withdraw the same files."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from common import PROFILE_IDENTITY_FIELDS
|
||||
from collections.abc import Iterable
|
||||
|
||||
from common import PROFILE_IDENTITY_FIELDS, _norm_system_id
|
||||
from common import archive_members
|
||||
from common import declared_root, expand_platform_declared_names, platform_declarations
|
||||
from common import load_emulator_profiles
|
||||
@@ -948,6 +950,7 @@ def platform_region_groups(
|
||||
absent=absent,
|
||||
)
|
||||
held = {id(extra) for extra in extras}
|
||||
spellings = system_spellings(systems)
|
||||
for extra in _kept(extras + absent, required_only):
|
||||
dest = sanitize_pack_path(extra.get("destination", extra.get("name", "")))
|
||||
if not dest:
|
||||
@@ -965,7 +968,7 @@ def platform_region_groups(
|
||||
# looked up by name its scph50006 took DuckStation's [japan], which
|
||||
# describes DuckStation's own PS1-on-PS2 choice.
|
||||
competes = not extra.get("agnostic_scan") or extra.get("region")
|
||||
for group_id in extra_region_groups(extra) if competes else ():
|
||||
for group_id in extra_region_groups(extra, spellings) if competes else ():
|
||||
groups.setdefault(group_id, []).append((dest, name))
|
||||
if extras_out is not None and id(extra) in held:
|
||||
extras_out.append(extra)
|
||||
@@ -974,8 +977,31 @@ def platform_region_groups(
|
||||
return groups, extra_dests
|
||||
|
||||
|
||||
def extra_region_groups(extra: dict) -> list[str]:
|
||||
"""The region groups a core extra competes in."""
|
||||
def system_spellings(systems: Iterable[str]) -> dict[str, str]:
|
||||
"""A platform's own spelling of each system, keyed the way ids compare.
|
||||
|
||||
RetroDECK files the Master System as sega-master-system, the profiles as
|
||||
sega-mastersystem. Grouped under both, the declared bios/bios_J.sms and
|
||||
the core's bios_J.sms were reduced apart and a --region us pack kept the
|
||||
Japanese BIOS.
|
||||
"""
|
||||
spellings: dict[str, str] = {}
|
||||
for sys_id in sorted(systems):
|
||||
spellings.setdefault(_norm_system_id(sys_id), sys_id)
|
||||
return spellings
|
||||
|
||||
|
||||
def extra_region_groups(
|
||||
extra: dict, spellings: dict[str, str] | None = None
|
||||
) -> list[str]:
|
||||
"""The region groups a core extra competes in.
|
||||
|
||||
A group named after a system takes the platform's spelling of it, so the
|
||||
extra competes beside the files the platform declares for that system.
|
||||
"""
|
||||
def system_group(sys_id: str) -> str:
|
||||
return (spellings or {}).get(_norm_system_id(sys_id), sys_id)
|
||||
|
||||
emulator = extra.get("source_emulator", "")
|
||||
variant = extra.get("variant_group")
|
||||
if variant:
|
||||
@@ -986,10 +1012,10 @@ def extra_region_groups(extra: dict) -> list[str]:
|
||||
return [f"{emulator}:variant:{variant}"]
|
||||
explicit = extra.get("source_system")
|
||||
if explicit:
|
||||
return [str(explicit)]
|
||||
return [system_group(str(explicit))]
|
||||
systems = [str(s) for s in extra.get("source_systems", []) if s]
|
||||
if len(systems) == 1:
|
||||
return systems
|
||||
return [system_group(systems[0])]
|
||||
# No system names the machine this file is chosen for. Filed under every
|
||||
# system of a 30-system profile, CLK's American MSX ROM made the
|
||||
# Enterprise group drop its German ROM. Alone, it drops nothing and is
|
||||
|
||||
@@ -6251,6 +6251,44 @@ struct BurnDriver BurnDrvneogeo = {
|
||||
("declared.bin", "declared.bin")],
|
||||
)
|
||||
|
||||
def test_a_system_spelled_two_ways_is_one_group(self):
|
||||
"""RetroDECK files the Master System as sega-master-system, the
|
||||
profiles as sega-mastersystem. Two groups reduced apart, and a
|
||||
--region us pack kept the declared Japanese BIOS."""
|
||||
import hashlib # noqa: PLC0415
|
||||
|
||||
from packextras import platform_region_groups # noqa: PLC0415
|
||||
|
||||
files, by_name = {}, {}
|
||||
for name in ("bios_U.sms", "bios_J.sms"):
|
||||
payload = name.encode()
|
||||
path = os.path.join(self.bios_dir, name)
|
||||
with open(path, "wb") as handle:
|
||||
handle.write(payload)
|
||||
sha1 = hashlib.sha1(payload).hexdigest()
|
||||
files[sha1] = {"path": path, "name": name, "size": len(payload),
|
||||
"md5": hashlib.md5(payload).hexdigest()}
|
||||
by_name[name] = [sha1]
|
||||
db = {"files": files, "indexes": {"by_name": by_name, "by_md5": {},
|
||||
"by_crc32": {}, "by_path_suffix": {}}}
|
||||
profiles = {"smscore": {
|
||||
"emulator": "SMS Core", "type": "libretro",
|
||||
"systems": ["sega-mastersystem"],
|
||||
"files": [{"name": "bios_U.sms", "region": ["north-america"]},
|
||||
{"name": "bios_J.sms", "region": ["japan"]}],
|
||||
}}
|
||||
config = {"platform": "P", "cores": ["smscore"], "base_destination": "system",
|
||||
"systems": {"sega-master-system": {"files": [
|
||||
{"name": "bios_J.sms", "destination": "bios/bios_J.sms"}]}}}
|
||||
groups, _ = platform_region_groups(
|
||||
config, config["systems"], self.emulators_dir, db, "system", profiles,
|
||||
)
|
||||
self.assertNotIn("sega-mastersystem", groups)
|
||||
self.assertEqual(
|
||||
sorted(dest for dest, _ in groups["sega-master-system"]),
|
||||
["bios/bios_J.sms", "bios_J.sms", "bios_U.sms"],
|
||||
)
|
||||
|
||||
def test_slot_narrowed_pack_gets_its_own_name(self):
|
||||
names = {
|
||||
os.path.basename(self._region_pack()),
|
||||
|
||||
@@ -14,7 +14,7 @@ from pathlib import Path
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
from packextras import extra_region_groups # noqa: E402
|
||||
from packextras import extra_region_groups, system_spellings # noqa: E402
|
||||
|
||||
|
||||
class TheGroupFollowsWhatTheProfileSays(unittest.TestCase):
|
||||
@@ -63,5 +63,29 @@ class TheEnterpriseKeepsItsRom(unittest.TestCase):
|
||||
self.assertNotIn("bios/brd.rom", drops)
|
||||
|
||||
|
||||
class TheGroupTakesThePlatformSpelling(unittest.TestCase):
|
||||
def test_a_profile_spelling_maps_to_the_platform_one(self):
|
||||
spellings = system_spellings(["sega-master-system", "sony-playstation"])
|
||||
self.assertEqual(
|
||||
extra_region_groups({"source_system": "sega-mastersystem"}, spellings),
|
||||
["sega-master-system"],
|
||||
)
|
||||
|
||||
def test_a_system_the_platform_lacks_keeps_its_name(self):
|
||||
spellings = system_spellings(["sony-playstation"])
|
||||
self.assertEqual(
|
||||
extra_region_groups({"source_systems": ["sega-saturn"]}, spellings),
|
||||
["sega-saturn"],
|
||||
)
|
||||
|
||||
def test_file_and_variant_groups_are_untouched(self):
|
||||
spellings = system_spellings(["sega-megacd"])
|
||||
self.assertEqual(
|
||||
extra_region_groups({"source_emulator": "picodrive", "variant_group": "mcd",
|
||||
"source_system": "sega-megacd"}, spellings),
|
||||
["picodrive:variant:mcd"],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user