mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-13 13:33:52 -06:00
fix: drop the atari800 config key aliases
ROM_5200_A, ROM_BASIC_A and six more are atari800.cfg keys, not names
atari800 opens: MatchByName knows only atariosa.rom and its kin
(sysrom.c:278-294), and the keys are config_key since 969907e29. The
twelve labels the scan identifies by CRC32 are found_by: content, and a
platform declaration of a file such an entry accepts by hash, in the
folder the core scans, now meets it: RetroDECK's ROM_BASIC_A answers
atari-basic-rev-a.rom without the alias.
This commit is contained in:
1 parent
a9fdf6eefc
commit
5794ed4178
6 files changed
+152
-10
No files matched your search
@@ -3495,6 +3495,50 @@ def declared_root(config: dict) -> str:
|
||||
return root if count / len(roots) > 0.9 else ""
|
||||
|
||||
|
||||
def platform_declared_contents(config: dict, db: dict) -> dict[str, set[str]]:
|
||||
"""The folders each declared file's content sits in, keyed by its hashes.
|
||||
|
||||
A core that scans a folder and identifies a ROM by its checksum reads a
|
||||
declared file whatever its name: RetroDECK lists atari800's Atari BASIC
|
||||
Rev A as ROM_BASIC_A, and the core takes it by CRC32. Keys are
|
||||
"md5:", "sha1:" and "crc32:" values of the database file the
|
||||
declaration resolves to, each with the declared slot's folder.
|
||||
"""
|
||||
prefix = declared_root(config).lower()
|
||||
by_md5 = db.get("indexes", {}).get("by_md5", {})
|
||||
files_db = db.get("files", {})
|
||||
contents: dict[str, set[str]] = {}
|
||||
for system in config.get("systems", {}).values():
|
||||
for fe in system.get("files", []):
|
||||
if fe.get("zipped_file"):
|
||||
continue
|
||||
record = files_db.get((fe.get("sha1") or "").lower())
|
||||
md5 = (fe.get("md5") or "").lower()
|
||||
if record is None and md5 and "," not in md5:
|
||||
sha1 = by_md5.get(md5, "")
|
||||
record = files_db.get(sha1[0] if isinstance(sha1, list) else sha1)
|
||||
if not record:
|
||||
continue
|
||||
slot = sanitize_pack_path(fe.get("destination") or fe.get("name", "")).lower()
|
||||
if prefix and slot.startswith(prefix + "/"):
|
||||
slot = slot[len(prefix) + 1:]
|
||||
folder = slot.rpartition("/")[0]
|
||||
for field in ("md5", "sha1", "crc32"):
|
||||
value = str(record.get(field) or "").lower()
|
||||
if value:
|
||||
contents.setdefault(f"{field}:{value}", set()).add(folder)
|
||||
return contents
|
||||
|
||||
|
||||
def merged_platform_declared_contents(configs: list[dict], db: dict) -> dict[str, set[str]]:
|
||||
"""`platform_declared_contents` of several platforms, one index."""
|
||||
merged: dict[str, set[str]] = {}
|
||||
for config in configs:
|
||||
for key, folders in platform_declared_contents(config, db).items():
|
||||
merged.setdefault(key, set()).update(folders)
|
||||
return merged
|
||||
|
||||
|
||||
def merged_platform_declarations(
|
||||
configs: list[dict], db: dict
|
||||
) -> dict[str, list[tuple[int | None, str]]]:
|
||||
|
||||
@@ -35,6 +35,7 @@ from common import (
|
||||
get_mame_clone_map,
|
||||
list_emulator_profiles,
|
||||
list_registered_platforms,
|
||||
merged_platform_declared_contents,
|
||||
load_data_dir_registry,
|
||||
load_database,
|
||||
load_emulator_profiles,
|
||||
@@ -867,7 +868,8 @@ def _cross_reference_profile(
|
||||
# A platform declares files of its BIOS tree: none answers for one
|
||||
# the core reads below the save directory.
|
||||
in_platform = not save_root and declaration_settles(
|
||||
f, fname, platform_names, effective_path, index.get("folded_slots", frozenset())
|
||||
f, fname, platform_names, effective_path, index.get("folded_slots", frozenset()),
|
||||
index.get("declared_contents"),
|
||||
)
|
||||
|
||||
if in_platform:
|
||||
@@ -1318,6 +1320,7 @@ def cross_reference(
|
||||
folded_slots: frozenset[str] = frozenset(),
|
||||
platform: str = "",
|
||||
launcher_layer: LauncherLayer | None = None,
|
||||
declared_contents: dict[str, set[str]] | None = None,
|
||||
) -> dict:
|
||||
"""Compare emulator profiles against platform declarations.
|
||||
|
||||
@@ -1355,6 +1358,7 @@ def cross_reference(
|
||||
"data_names": data_names,
|
||||
"all_declared": all_declared,
|
||||
"folded_slots": folded_slots,
|
||||
"declared_contents": declared_contents,
|
||||
"bios_dir": db.get("bios_dir"),
|
||||
"launcher_candidates": [] if launcher_layer else None,
|
||||
}
|
||||
@@ -1561,6 +1565,13 @@ def main() -> None:
|
||||
all_declared=declared_names(args.platforms_dir, selected, db),
|
||||
standalone_cores=standalone_cores,
|
||||
folded_slots=folded_declared_slots(args.platforms_dir, selected, db),
|
||||
declared_contents=merged_platform_declared_contents(
|
||||
[
|
||||
load_platform_config(name, args.platforms_dir)
|
||||
for name in selected or list_registered_platforms(args.platforms_dir)
|
||||
],
|
||||
db,
|
||||
),
|
||||
platform=config.get("_key", args.platform) if args.platform else "",
|
||||
# What the platform's launchers open, as verify and the builder read it.
|
||||
launcher_layer=LauncherLayer(
|
||||
|
||||
@@ -606,9 +606,15 @@ def declaration_settles(
|
||||
declared_names: Mapping[str, list[tuple[int | None, str]]] | set[str],
|
||||
dest: str = "",
|
||||
folded_slots: frozenset[str] = frozenset(),
|
||||
declared_contents: Mapping[str, set[str]] | None = None,
|
||||
) -> bool:
|
||||
"""Whether a platform declaration meets a core's requirement.
|
||||
|
||||
An entry the core finds by content (``found_by: content`` on the entry)
|
||||
is met by any declaration of a file it accepts by hash, in the folder it
|
||||
scans: atari800 takes RetroDECK's ROM_BASIC_A by its CRC32, so its own
|
||||
label for that ROM is not one more file to ship.
|
||||
|
||||
A platform declaring the name the core reads has met the requirement
|
||||
where the declaration fills the entry's own slot, whose content the slot
|
||||
arbitration decides, or elsewhere at a size the core accepts: the builder
|
||||
@@ -630,6 +636,13 @@ def declaration_settles(
|
||||
return True
|
||||
slot = sanitize_pack_path(dest or fname).lower()
|
||||
directory = slot if dest.endswith("/") else slot.rpartition("/")[0]
|
||||
if declared_contents and file_entry.get("found_by") == "content":
|
||||
for field in ("md5", "sha1", "crc32"):
|
||||
values = file_entry.get(field) or []
|
||||
for value in values if isinstance(values, list) else str(values).split(","):
|
||||
folders = declared_contents.get(f"{field}:{str(value).strip().lower()}")
|
||||
if folders and directory in folders:
|
||||
return True
|
||||
if not dest.endswith("/") and slot in folded_slots:
|
||||
return True
|
||||
for name in (fname, *file_entry.get("aliases", [])):
|
||||
|
||||
+5
-1
@@ -60,6 +60,7 @@ from common import (
|
||||
compute_hashes,
|
||||
expand_directory_entries,
|
||||
platform_declarations,
|
||||
platform_declared_contents,
|
||||
group_identical_platforms,
|
||||
list_emulator_profiles,
|
||||
list_system_ids,
|
||||
@@ -454,6 +455,7 @@ def _candidate_verdict(
|
||||
declared_names: Mapping[str, list[tuple[int | None, str]]] | set[str],
|
||||
dest: str = "",
|
||||
folded_slots: frozenset[str] = frozenset(),
|
||||
declared_contents: Mapping[str, set[str]] | None = None,
|
||||
) -> str:
|
||||
"""Whether a profile entry can be a gap, and whether it is settled.
|
||||
|
||||
@@ -469,7 +471,7 @@ def _candidate_verdict(
|
||||
if outside_gap_scope(file_entry, is_standalone):
|
||||
return "skip"
|
||||
if not include_all and declaration_settles(
|
||||
file_entry, fname, declared_names, dest, folded_slots
|
||||
file_entry, fname, declared_names, dest, folded_slots, declared_contents
|
||||
):
|
||||
return "settled"
|
||||
return "keep"
|
||||
@@ -503,6 +505,7 @@ def find_undeclared_files(
|
||||
if declared_names is None:
|
||||
declared_names = platform_declarations(config, db)
|
||||
folded_slots = case_folded_slots(config, declared_names)
|
||||
declared_contents = platform_declared_contents(config, db)
|
||||
|
||||
# Whether the builder drops a file whose local copy contradicts its
|
||||
# declared hash, which decides if such a copy counts as held here.
|
||||
@@ -603,6 +606,7 @@ def find_undeclared_files(
|
||||
verdict = _candidate_verdict(
|
||||
f, fname, is_standalone, include_all,
|
||||
{} if save_root else declared_names, dest, folded_slots,
|
||||
None if save_root else declared_contents,
|
||||
)
|
||||
if verdict == "settled":
|
||||
seen_files.add(seen_key)
|
||||
|
||||
Reference in new issue
Block a user