chore: merge round 2 fixes (profile names)

This commit is contained in:
Abdessamad Derraz committed 2026-10-21 10:14:59 +02:00
commit d7afac0993
24 files changed
+185 -48

No files matched your search

+2 -16
View File
@@ -112,12 +112,12 @@ files:
source_ref: "desktop-ui/emulator/colecovision.cpp:12"
# --- Famicom Disk System ---
- name: disksys.rom
- name: rp2c33-01.bin
system: famicom-disk-system
required: true
sha256: "fdc1a76e654feea993fcb38366e05ee5f4eb641f86fe6bebaeefd412e112dd72"
validation: [sha256]
description: "Famicom Disk System BIOS"
description: "Famicom Disk System BIOS, RP2C33-01 revision"
source_ref: "desktop-ui/emulator/famicom-disk-system.cpp:19"
# --- Game Boy Advance ---
@@ -202,7 +202,6 @@ files:
# --- Mega LD (LaserActive SEGA PAC) ---
- name: mega_ld_bios_U.bin
aliases: ["[BIOS] LaserActive PAC-S10 (US) (v1.04).bin"]
system: mega-ld
region: [north-america]
required: true
@@ -220,14 +219,6 @@ files:
description: "LaserActive SEGA PAC BIOS (Japan), v1.02"
source_ref: "desktop-ui/emulator/mega-ld.cpp:17"
- name: "[BIOS] LaserActive PAC-S1 (Japan) (v1.05).bin"
system: mega-ld
region: [japan]
required: false
description: "LaserActive SEGA PAC BIOS (Japan), v1.05"
note: "Absent from the firmware table, so the scan by hash never assigns it. A path written into the Japanese BIOS slot of settings.bml is read as is, with no hash check. RetroBat writes this name there first and falls back to v1.02."
source_ref: "desktop-ui/emulator/mega-ld.cpp:17, desktop-ui/emulator/mega-ld.cpp:54, desktop-ui/settings/firmware.cpp:109, desktop-ui/emulator/emulator.cpp:188-197"
# --- MSX ---
- name: msx-japanese.rom
system: msx
@@ -270,7 +261,6 @@ files:
# --- Neo Geo Pocket ---
- name: ngp_bios.rom
aliases: ["[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"]
system: neo-geo-pocket
required: true
sha256: "0293555b21c4fac516d25199df7809b26beeae150e1d4504a050db32264a6ad7"
@@ -280,7 +270,6 @@ files:
# --- Neo Geo Pocket Color ---
- name: ngpc_bios.rom
aliases: ["[BIOS] SNK Neo Geo Pocket (Japan, Europe) (En,Ja).ngp"]
system: neo-geo-pocket-color
required: true
sha256: "8fb845a2f71514cec20728e2f0fecfade69444f8d50898b92c2259f1ba63e10d"
@@ -350,7 +339,6 @@ files:
# --- PC Engine LD (LaserActive NEC PAC) ---
- name: pac-n10.pce
aliases: ["[BIOS] LaserActive PAC-N10 (US) (v1.02).bin"]
system: pc-engine-ld
required: true
sha256: "0e87a3385a27b3a4cac51934819b7eefa5b3d690768d2495633838488cd0e2e4"
@@ -359,7 +347,6 @@ files:
source_ref: "desktop-ui/emulator/pc-engine-ld.cpp:18"
- name: pac-n1.pce
aliases: ["[BIOS] LaserActive PAC-N1 (Japan) (v1.02).bin"]
system: pc-engine-ld
required: true
sha256: "459325690a458baebd77495c91e37c4dddfdd542ba13a821ce954e5bb245627f"
@@ -368,7 +355,6 @@ files:
source_ref: "desktop-ui/emulator/pc-engine-ld.cpp:19"
- name: pce-lp1.pce
aliases: ["[BIOS] LaserActive PCE-LP1 (Japan) (v1.02).bin"]
system: pc-engine-ld
required: true
sha256: "3f43b3b577117d84002e99cb0baeb97b0d65b1d70b4adadc68817185c6a687f0"
-1
View File
@@ -65,7 +65,6 @@ notes: |
files:
- name: ROM
aliases: [mac.rom]
required: true
min_size: 524288
max_size: 1048576
+1 -1
View File
@@ -29,7 +29,7 @@ notes: |
Core continues without DSP firmware but coprocessor games won't function.
exclusion_note: >
firmware_count=0 in .info is correct. DSP firmware (NEC uPD7725/uPD96050,
The .info declares firmware_count=0. DSP firmware (NEC uPD7725/uPD96050,
Hitachi CX4) is loaded from the ROM directory via game XML markup, not from
system_dir. RetroArch cannot pre-populate firmware in the ROM directory.
Upstream byuu.org is defunct, and this libretro port is the preserved v085 code.
+2 -2
View File
@@ -52,8 +52,8 @@ notes: |
neogeo.zip is a parent ROM set, loaded from g_rom_dir alongside game ZIPs.
g_system_dir is set (src/burner/libretro/libretro.cpp:3016) but never used for file loading.
The .info note "BIOS files must be inside the ROM directory" is accurate here:
neogeo.zip must be in the same directory as game ROM ZIPs.
neogeo.zip is read from the same directory as the game ROM ZIPs, as the .info
note "BIOS files must be inside the ROM directory" states.
files: []
-3
View File
@@ -51,7 +51,6 @@ notes: |
files:
- name: us_scd1_9210.bin
aliases: [bios_CD_U.bin]
system: sega-megacd
region: [north-america, latin-america]
required: true
@@ -60,7 +59,6 @@ files:
source_ref: "Fusion.exe 0x44b662-0x44b670 (default path), 0x478877-0x4788d6 (open, message, fread 0x20000)"
- name: jp_mcd1_9111.bin
aliases: [bios_CD_J.bin]
system: sega-megacd
region: [japan]
required: true
@@ -69,7 +67,6 @@ files:
source_ref: "Fusion.exe 0x44b676 (default path), 0x4788f9-0x478959 (open, message, fread 0x20000)"
- name: eu_mcd1_9210.bin
aliases: [bios_CD_E.bin]
system: sega-megacd
region: [europe, oceania]
required: true
+9 -6
View File
@@ -34,15 +34,16 @@ notes: |
files:
- name: hiscore.dat
load_from: content_dir
required: false
category: game_data
system: arcade
sha1: "21ddda0c61bd4f1cc04fb9d09e16d403d620f9e8"
md5: "9b262149ec70cbda741a8ba55784f8e1"
size: 36182
source_ref: "src/hiscore.c:18,132-146,252-254, src/cpuintrf.c:664-666"
source_ref: "src/hiscore.c:18,132-146,252-254, src/cpuintrf.c:664-666, src/libretro/fileio.c:1002-1014, src/libretro/libretro.c:1044-1052"
note: >-
high score definitions, loaded from ROM directory. metadata/hiscore.dat
high score definitions, opened from IMAMEBASEPATH, the directory of the loaded content. metadata/hiscore.dat
of the core repository. is_mem_range reads only "cpu:addr:len:start:end"
lines under a "gamename:" header.
@@ -55,18 +56,20 @@ files:
note: "cheat definitions, loaded from system_dir/mame2000/cheat/"
- name: history.dat
load_from: content_dir
required: false
category: game_data
system: arcade
source_ref: "src/datafile.c:52,281,541"
note: "game history database, loaded from ROM directory"
source_ref: "src/datafile.c:52,281,541, src/libretro/fileio.c:1002-1014"
note: "game history database, opened from IMAMEBASEPATH, the directory of the loaded content"
- name: mameinfo.dat
load_from: content_dir
required: false
category: game_data
system: arcade
source_ref: "src/datafile.c:53,281,568"
note: "game technical info database, loaded from ROM directory"
source_ref: "src/datafile.c:53,281,568, src/libretro/fileio.c:1002-1014"
note: "game technical info database, opened from IMAMEBASEPATH, the directory of the loaded content"
- name: neogeo.zip
required: true
+1
View File
@@ -102,6 +102,7 @@ notes: |
files:
# Data files
- name: hiscore.dat
load_from: working_directory
required: false
category: game_data
system: arcade
+1
View File
@@ -91,6 +91,7 @@ notes: |
files:
# Data files
- name: hiscore.dat
load_from: working_directory
installed_on: [recalbox]
required: false
category: game_data
-2
View File
@@ -13,8 +13,6 @@ cores: [mupen64plus_next, mupen64plus_next_develop, mupen64plus_next_gles3, mupe
files:
- name: "IPL.n64"
path: "Mupen64plus/IPL.n64"
standalone_path: "64DD_IPL.bin"
aliases: ["64DD_IPL.bin"]
size: 4194304
required: false
description: "64DD IPL ROM"
+1 -5
View File
@@ -30,18 +30,14 @@ notes: |
ref: src/platform/core/src/loader/bios.cpp:17-48, src/platform/sdl/main.cpp:177-192,
src/nba/src/core.cpp:42-44
ROCKNIX patches config.toml and keymap.toml to /storage/.config/nanoboyadvance/
and its config.toml sets bios_path = /storage/roms/bios/gba_bios.bin.
files:
- name: "bios.bin"
path: "bios.bin"
aliases: ["gba_bios.bin"]
system: nintendo-gba
required: true
size: 16384
validation: [size]
config_key: "general.bios_path"
description: "Game Boy Advance BIOS"
note: "Any file name through general.bios_path or --bios, or bios.bin beside the executable when neither is set. ROCKNIX points the key at gba_bios.bin in its BIOS directory."
note: "Any file name through general.bios_path or --bios, or bios.bin beside the executable when neither is set."
source_ref: "src/platform/core/src/loader/bios.cpp:17-48, src/platform/core/src/config.cpp:36, src/platform/sdl/main.cpp:177-192"
+1 -1
View File
@@ -26,6 +26,6 @@ notes: >
subdirectories as .ogg/.mp3/.wav files or cdaudio.wad (src/gameflow.h:1272-1356).
System directory used only for shader cache at {system_dir}/openlara/cache/
(src/platform/libretro/main.cpp:177-197). No BIOS, firmware, or engine data files required in
system directory. .info omits sat from supported_extensions (code declares it).
system directory. The code declares the sat extension, which the .info supported_extensions does not list.
files: []
+2 -1
View File
@@ -29,7 +29,8 @@ notes: |
directory, it is loaded automatically. No hash or size validation is
performed on the BIOS file.
The .info declares firmware_count=1 (U only), missing the PAL BIOS.
The .info declares one firmware, the U BIOS. The code also opens the E BIOS
for PAL cartridges (core/libretro.c:581-582).
files:
- name: "7800 BIOS (U).rom"
+2 -2
View File
@@ -20,8 +20,8 @@ notes: |
The fork sets appdir to the RetroArch system directory root
(retro_host.c:216-217), unlike the upstream which appends /dc
(upstream retro_host.c:196-198). The .info still declares dc/ prefix paths
matching the upstream, not this fork.
(upstream retro_host.c:196-198). The .info declares dc/ prefix paths, the
layout the upstream reads.
boot.bin is validated against four known MD5 hashes (boot.c:25-30).
Validation failure logs a warning but the core continues via HLE.
+1 -1
View File
@@ -76,5 +76,5 @@ notes:
OpenSBI: https://github.com/riscv-software-src/opensbi/releases.
Pre-built images for RVVM: https://github.com/LekKit/RVVM/wiki/Running
info_firmware_count: >
.info declares 0 firmware. Correct: the core loads firmware via
.info declares 0 firmware. The core loads firmware via
user-specified paths in the .rvvm config, not from system_dir.
+1 -1
View File
@@ -23,7 +23,7 @@ notes: |
stub firmware (NDS), and HLE boot skip (GB/GBC). BIOS loading controlled by core options
(default: on). Files loaded from system_dir/SkyEmu/ subdirectory.
Standalone validates exact BIOS file size, while libretro only rejects files exceeding buffer.
.info missing gb_bios.bin (gb.h:1603).
The .info does not list gb_bios.bin, which the code reads (gb.h:1603).
files:
- name: cgb_boot.bin
-1
View File
@@ -144,7 +144,6 @@ files:
source_ref: "libmain.so LoadBIOS 0x5b2e4-0x5b2f4, Speccy59-Ubuntu-x86-bin speccy 0x3dcbe-0x3dcd1"
- name: ZXS16.ROM
aliases: ["ZXS48.ROM", "48.rom"]
system: sinclair-zx-spectrum
required: true
max_size: 16384
+1 -1
View File
@@ -17,7 +17,7 @@ notes: |
All entries are optional: without a class library, the core runs a built-in
modeless stars demo but cannot execute J2ME software.
The .info declares firmware_count=8 but the code defines 10 search names
(squirreljme-{version}-test.jar and squirreljme-test.jar are missing from .info).
(the two not in the .info are squirreljme-{version}-test.jar and squirreljme-test.jar).
files:
- name: "squirreljme-0.3.0-fast.jar"
+1 -1
View File
@@ -14,4 +14,4 @@ notes: >
WebAssembly-based fantasy console. 320x240 screen, 32-color palette,
256KB memory. The WASM runtime (platform + loader modules) is compiled
to C via wasm2c and embedded in the binary. No external files required.
firmware_count=0 in .info is correct.
The .info declares firmware_count=0.
+1 -1
View File
@@ -17,7 +17,7 @@ notes: >
DTV has its own color system (viciidtv-color.c), and external palette loading
is disabled. JiffyDOS is not supported (excluded from build conditionals).
The .info declares 4 JiffyDOS firmware (firmware_count=4) but the code
never loads them for this core. The .info also omits dtvrom.bin.
never loads them for this core. The .info does not list dtvrom.bin.
files:
- name: "dtvrom.bin"
+11
View File
@@ -666,6 +666,17 @@ def find_undeclared_files(
path_base, by_name, by_path_suffix, data_names,
by_name_lower,
)
if in_repo and not any(
f.get(h) for h in ("sha1", "md5", "crc32", "sha256")
):
# A name alone answers nothing when every copy of that
# name fails the size the code checks: the resolver
# rejects them all. NanoBoyAdvance's 16 KB bios.bin met
# only PCem's and QEMU's PC BIOS images of that name.
# The fallback below then decides as for any mismatch.
_lp, _st = resolve_local_file(f, db, dest_hint=dest)
if _st == "hash_mismatch":
in_repo = False
if not in_repo:
# Hash fallback: the repo may hold the content under a
# different filename (exos21.rom vs exos21.bin).
+103
View File
@@ -5453,6 +5453,109 @@ class AHashScanningCoreContradictsNoPlatform(unittest.TestCase):
self.assertEqual(claimed, [])
class AHashScanLabelNamesNoOtherDump(unittest.TestCase):
"""A core that finds its firmware by content names no file, so each
entry name is a label. ares labelled its Famicom Disk System revision
(RP2C33-01, crc32 1c7ae5d5) disksys.rom, the name six NES cores read for
the RP2C33A-01A dump: on ROCKNIX the manifest put ares's revision at
disksys.rom for all of them. A label that another profile gives a
different dump is refused, the two dumps compared through the
collection's hash indexes."""
# Names the core's own code gives the image, not labels.
CODE_NAMED = {
("bizhawk", "MSX.rom"):
"FirmwareDatabase.cs:362 names the image MSX.rom",
("swanstation", "ps1_rom.bin"):
"the whole PS3 image is the file the PS3 itself names ps1_rom.bin, "
"beetle_psx reads its first 512 KB under the same name",
}
@staticmethod
def _identity(entry: dict, db: dict) -> tuple[set, set]:
raw: set = set()
sha1s: set = set()
indexes = db["indexes"]
for field, index in (("sha1", None), ("md5", "by_md5"),
("crc32", "by_crc32"), ("sha256", "by_sha256")):
value = entry.get(field)
values = value if isinstance(value, list) else [value] if value else []
for item in values:
for digest in str(item).lower().split(","):
digest = digest.strip()
if not digest:
continue
raw.add((field, digest))
sha1 = digest if index is None else indexes[index].get(digest)
if sha1 in db["files"]:
sha1s.add(sha1)
return raw, sha1s
def test_labels_are_not_other_dumps_names(self):
import json
from scripts.common import load_emulator_profiles
if not (ROOT / "database.json").exists():
self.skipTest("database.json is not built")
db = json.loads((ROOT / "database.json").read_text(encoding="utf-8"))
profiles = load_emulator_profiles(str(ROOT / "emulators"))
by_name: dict[str, list[tuple[str, dict]]] = {}
for emulator, profile in profiles.items():
for entry in profile.get("files") or []:
for name in [entry.get("name"), *(entry.get("aliases") or [])]:
if name:
by_name.setdefault(str(name).casefold(), []).append((emulator, entry))
clashes = []
for emulator, profile in profiles.items():
if profile.get("found_by") != "content":
continue
for entry in profile.get("files") or []:
raw, sha1s = self._identity(entry, db)
if not sha1s:
continue
for name in [entry.get("name"), *(entry.get("aliases") or [])]:
if (emulator, name) in self.CODE_NAMED:
continue
for other, other_entry in by_name.get(str(name).casefold(), []):
if other == emulator:
continue
other_raw, other_sha1s = self._identity(other_entry, db)
if other_sha1s and not raw & other_raw and not sha1s & other_sha1s:
clashes.append(f"{emulator} {name} is {other}'s name for another dump")
self.assertEqual(sorted(set(clashes)), [])
class ANoteOutsideTheSystemDirCarriesLoadFrom(unittest.TestCase):
"""mame2000 opens hiscore.dat, history.dat and mameinfo.dat from the
directory of the loaded content (src/libretro/fileio.c:1002-1014), and
mame2014 and mame2015 open hiscore.dat from the working directory
(src/emu/hiscore.c:330-337). Their notes said so, but no load_from did:
the entries claimed system/hiscore.dat and the RetroArch pack shipped a
file neither core opens there. A libretro entry whose note places the
read outside the system directory declares where."""
ELSEWHERE = re.compile(
r"\b(?:opened|read|loaded)\b[^.]*?\bfrom (?:the )?(?:working directory|"
r"ROM directory|content directory|directory of the loaded content)"
r"|IMAMEBASEPATH",
re.IGNORECASE,
)
def test_prose_and_load_from_agree(self):
offenders = []
for path in sorted((ROOT / "emulators").glob("*.yml")):
profile = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
if profile.get("type") != "libretro":
continue
for entry in profile.get("files") or []:
if entry.get("path") or entry.get("load_from") or entry.get("mode") == "standalone":
continue
if self.ELSEWHERE.search(str(entry.get("note") or "")):
offenders.append(f"{path.name}: {entry.get('name')}")
self.assertEqual(offenders, [])
class ReportsHoldTheDataTrees(unittest.TestCase):
"""Run on their own, the README, site and slot reports resolved against
data/ without the shared hold, so a concurrent refresh could swap a tree
+19
View File
@@ -231,6 +231,25 @@ class LauncherLayerTest(unittest.TestCase):
self.assertIn("v103.bin", report)
self.assertIn("boot.bin", report)
def test_a_name_whose_copies_fail_the_size_is_not_held(self) -> None:
"""NanoBoyAdvance reads a 16 KB bios.bin, and the collection's
bios.bin files are PCem's and QEMU's PC BIOS images. Counted held by
name, the entry escaped the launcher layer, which settles only what
the collection lacks, and the ROCKNIX pack carried PCem's 64 KB image
beside the gba_bios.bin its launcher passes."""
profile = {
"emulator": "FixEmu", "type": "standalone", "systems": ["test-sys"],
"files": [{"name": "core.bin", "required": True,
"size": len(CONTENT["plain.bin"]), "validation": ["size"]}],
}
with open(os.path.join(self.emulators_dir, "fixemu.yml"), "w") as fh:
yaml.dump(profile, fh)
self.config["launchers"][2]["names"] = ["plain.bin"]
_emulator_profiles_cache.clear()
self.profiles = load_emulator_profiles(self.emulators_dir)
self.assertNotIn("core.bin", {u["name"] for u in self._report()})
self.assertNotIn("core.bin", self._pack_names())
def test_no_place_is_filled_twice(self) -> None:
added = [u["path"] for u in self._report() if u.get("launcher")]
self.assertEqual(sorted(added), ["e.bin", "sub/fix.bin"])
+21
View File
@@ -225,6 +225,18 @@ class ProfilesStateFactsAboutOtherProjects(unittest.TestCase):
re.IGNORECASE,
)
# A line that names another project's file grades it when it calls the
# file correct or accurate, says it still declares something, or that an
# entry is missing from it or omitted. prosystem, retrodream,
# fbalpha2012_neogeo and seven more profiles wrote it that way.
OTHER_FILE = re.compile(r"(\.info\b|core-info|System\.dat)", re.IGNORECASE)
GRADES = re.compile(
r"\b(?:is (?:correct|accurate|inaccurate|outdated|stale)|accurate here|"
r"correct:|still (?:declares|lists)|omits|missing (?:the|from))|"
r"\.info missing",
re.IGNORECASE,
)
def test_profile_prose_and_comments(self):
offenders = [
f"{path.relative_to(ROOT)}: {line.strip()[:100]}"
@@ -234,6 +246,15 @@ class ProfilesStateFactsAboutOtherProjects(unittest.TestCase):
]
self.assertEqual(offenders, [], "\n".join(offenders[:40]))
def test_no_grade_on_another_projects_file(self):
offenders = [
f"{path.relative_to(ROOT)}: {line.strip()[:100]}"
for path in sorted((ROOT / "emulators").glob("*.yml"))
for line in path.read_text(encoding="utf-8").splitlines()
if self.OTHER_FILE.search(line) and self.GRADES.search(line)
]
self.assertEqual(offenders, [], "\n".join(offenders[:40]))
class NoClauseSemicolons(unittest.TestCase):
def _check(self, files: list[Path], extract) -> None:
+4 -2
View File
@@ -266,8 +266,10 @@ to the way the project writes:
number with its criterion says more.
- Headings in sentence case, never repeating the site name.
- In emulator profiles, no verdict on another project's file: "phantom",
"misleading", "bogus", "typo", "has errors", "incorrectly says". The note
states what that file declares and what the code reads.
"misleading", "bogus", "typo", "has errors", "incorrectly says", and on a
line naming a .info, core-info or System.dat no "is correct", "is
accurate", "still declares", "omits" or "missing". The note states what
that file declares and what the code reads.
Formatting stays: bold labels, lists, tables and admonitions make a page
easier to use. When markup shows raw on the site, the rendering is fixed and