fix: join platform system names to profiles

The rom folder survey joined 463 folders to their default core's whole
profile, no system of it matching. SYSTEM_ALIASES, the one table
_norm_system_id reads, now folds ten more spellings of one machine:
apple2gs, astrocade, astrocde, creativision, gamepocketcomputer,
nintendo-super-game-boy, cps1, cps2, cps3 and pgm. The profiles that
used them take the canonical id (mame, groovymame, mamemess, mame0258,
mame0278, bsnes, mesen-s, mesence, jollycv, fbalpha2012 and its three
CPS cores, fbneo_cps12), as test_system_ids requires.

With bsnes and bsnes-hd now filing SGB1.sfc under one system, their
claims fold onto one report entry. _names_content read only the first
claim, hashless, and nSide's SGB1.sfc/ tree took the path before the
file. A hash on any folded claim now counts: every pack keeps the
destinations it had.

The site drops the eight display names the canonical ids replace and
names tvgames. README counts 533 systems instead of 541.
This commit is contained in:
Abdessamad Derraz committed 2026-11-03 15:23:30 +01:00
1 parent ae8aae8469
commit a0c560479b
20 files changed
+238 -169

No files matched your search

+2 -2
View File
@@ -84,14 +84,14 @@ Each file is checked the way your platform checks it. Most compare a checksum, t
- **1,086 files** the platforms' emulators load are still to be found, and 138 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made). Both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/)
- **18 platforms** supported with platform-specific verification
- **623 emulators** profiled from source (RetroArch cores + standalone)
- **541 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **533 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **19,916 files in the collection**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,713 system files, 2,975 arcade ROM sets, 11,228 game and engine data files. That is every platform and emulator together, so no pack holds them all: each carries what its own emulators load, counted in the download table
- **565 of 5,713 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC). Arcade sets and engine data fall outside what those catalogs index
- **15.7 GB** for the whole collection
## Supported systems
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 507+ more.
NES, SNES, Nintendo 64, GameCube, Wii, Game Boy, Game Boy Advance, Nintendo DS, Nintendo 3DS, Switch, PlayStation, PlayStation 2, PlayStation 3, PSP, PS Vita, Mega Drive, Saturn, Dreamcast, Game Gear, Master System, Neo Geo, Atari 2600, Atari 7800, Atari Lynx, Atari ST, MSX, PC Engine, TurboGrafx-16, ColecoVision, Intellivision, Commodore 64, Amiga, ZX Spectrum, Arcade (MAME), and 499+ more.
Full list with per-file details: **[https://abdess.github.io/retrobios/](https://abdess.github.io/retrobios/)**
+3 -3
View File
@@ -14,7 +14,7 @@ version_basis:
pattern: 'static const string Version\s*=\s*"([^"]+)"'
display_name: "Nintendo - SNES / SFC (bsnes)"
cores: [bsnes]
systems: [nintendo-snes, nintendo-super-game-boy, nintendo-satellaview]
systems: [nintendo-snes, nintendo-sgb, nintendo-satellaview]
# bsnes supports HLE for DSP1/DSP1B/DSP2/DSP4, ST010, and Cx4.
# When HLE is enabled (core option bsnes_coprocessor_prefer_hle) or
@@ -203,13 +203,13 @@ files:
# Core option bsnes_sgb_bios selects between SGB1.sfc and SGB2.sfc.
- name: "SGB1.sfc"
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
note: "Super Game Boy 1 cartridge ROM, loaded when playing .gb/.gbc via SGB mode"
source_ref: "source bsnes/target-libretro/libretro.cpp:937-946 (system_dir + sgb_bios), source bsnes/target-libretro/libretro.cpp:393 (core option bsnes_sgb_bios)"
- name: "SGB2.sfc"
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
note: "Super Game Boy 2 cartridge ROM, uses dedicated oscillator for accurate GB speed"
source_ref: "source bsnes/target-libretro/libretro.cpp:937-946 (system_dir + sgb_bios), source bsnes/target-libretro/libretro.cpp:393 (core option bsnes_sgb_bios)"
+4 -4
View File
@@ -19,10 +19,10 @@ cores:
systems:
- arcade
- neogeo
- cps1
- cps2
- cps3
- pgm
- capcom-cps1
- capcom-cps2
- capcom-cps3
- igs-pgm
notes: |
Frozen snapshot of Final Burn Alpha v0.2.97.29 (circa 2012), full version.
+1 -1
View File
@@ -14,7 +14,7 @@ display_name: "Arcade (FB Alpha 2012 CPS-1)"
cores:
- fbalpha2012_cps1
systems:
- cps1
- capcom-cps1
notes: |
Frozen snapshot of Final Burn Alpha v0.2.97.28 (circa 2012), CPS-1 only.
+1 -1
View File
@@ -14,7 +14,7 @@ display_name: "Arcade (FB Alpha 2012 CPS-2)"
cores:
- fbalpha2012_cps2
systems:
- cps2
- capcom-cps2
notes: |
Frozen snapshot of Final Burn Alpha v0.2.97.28 (circa 2012), CPS-2 only.
+1 -1
View File
@@ -16,7 +16,7 @@ library_name: "FB Alpha 2012 CPS-3"
cores:
- fbalpha2012_cps3
systems:
- cps3
- capcom-cps3
notes: |
Frozen snapshot of Final Burn Alpha v0.2.97.29 (circa 2012), CPS-3 only.
+2 -2
View File
@@ -16,8 +16,8 @@ display_name: "Arcade (FinalBurn Neo) (CPS-1 / CPS-2)"
cores:
- fbneo_cps12
systems:
- cps1
- cps2
- capcom-cps1
- capcom-cps2
- arcade
notes: |
+2 -2
View File
@@ -50,7 +50,7 @@ systems:
- konami-twinkle
- panasonic-3do
- hyper-neogeo64
- apple2gs
- apple-iigs
- apf-m1000
- bally-astrocade
- coleco-adam
@@ -3328,7 +3328,7 @@ files:
- name: apple2gs.zip
required: true
category: bios_zip
system: apple2gs
system: apple-iigs
source_ref: "source src/mame/apple/apple2gs.cpp:4012"
contents:
- name: 341s0632-2.bin
+2 -2
View File
@@ -16,7 +16,7 @@ cores:
- jollycv
systems:
- colecovision
- creativision
- crvision
- myvision
notes: |
@@ -67,7 +67,7 @@ files:
note: "Mapped at 0x0000-0x1FFF, replaced by the lower 8K of SGM RAM when the Super Game Module enables it. The MD5 is the value the JG bioslist declares, and the core compares the size only."
- name: "bioscv.rom"
system: creativision
system: crvision
description: "VTech CreatiVision BIOS ROM"
required: true
size: 2048
+123 -123
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -49,7 +49,7 @@ systems:
- konami-twinkle
- panasonic-3do
- hyper-neogeo64
- apple2gs
- apple-iigs
- apf-m1000
- bally-astrocade
- coleco-adam
+1 -1
View File
@@ -49,7 +49,7 @@ systems:
- konami-twinkle
- panasonic-3do
- hyper-neogeo64
- apple2gs
- apple-iigs
- apf-m1000
- bally-astrocade
- coleco-adam
+6 -7
View File
@@ -17,9 +17,8 @@ cores:
- mamemess
systems:
- apple2
- apple2gs
- astrocde
- astrocade
- apple-iigs
- bally-astrocade
- coleco-adam
- crvision
- entex-advision
@@ -667,7 +666,7 @@ files:
- name: astrocde.zip
required: true
category: bios_zip
system: astrocde
system: bally-astrocade
source_ref: "upstream src/mame/bally/astrohome.cpp:244-247"
contents:
- name: astro.bin
@@ -678,7 +677,7 @@ files:
- name: astrocdl.zip
required: false
category: bios_zip
system: astrocde
system: bally-astrocade
source_ref: "upstream src/mame/bally/astrohome.cpp:249-251"
contents:
- name: ballyhlc.bin
@@ -689,7 +688,7 @@ files:
- name: astrocdw.zip
required: false
category: bios_zip
system: astrocde
system: bally-astrocade
source_ref: "upstream src/mame/bally/astrohome.cpp:254-257"
contents:
- name: bioswhit.bin
@@ -875,7 +874,7 @@ files:
- name: apple2gs.zip
required: true
category: bios_zip
system: apple2gs
system: apple-iigs
source_ref: "source src/mame/apple/apple2gs.cpp:3893-3907"
contents:
- name: 341s0632-2.bin
+1 -1
View File
@@ -17,7 +17,7 @@ version_basis:
pattern: 'uint16_t major = (\d+);\s*\n\s*uint8_t minor = (\d+);\s*\n\s*uint8_t revision = (\d+);'
format: "{1}.{2}.{3}"
cores: [mesen-s, mesen_s]
systems: [nintendo-snes, nintendo-gb, nintendo-gbc, nintendo-super-game-boy, nintendo-satellaview]
systems: [nintendo-snes, nintendo-gb, nintendo-gbc, nintendo-sgb, nintendo-satellaview]
notes: >
High-accuracy SNES/SFC emulator with Game Boy/Color and Super Game Boy
+5 -5
View File
@@ -32,7 +32,7 @@ systems:
- nintendo-snes
- nintendo-satellaview
- nintendo-sufami-turbo
- nintendo-super-game-boy
- nintendo-sgb
- nintendo-gb
- nintendo-gbc
- nintendo-gba
@@ -411,7 +411,7 @@ files:
- name: "SGB1.sfc"
standalone_path: "Firmware/SGB1.sfc"
mode: standalone
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
size: 262144
validation: [size]
@@ -422,7 +422,7 @@ files:
- name: "SGB2.sfc"
path: "SGB2.sfc"
standalone_path: "Firmware/SGB2.sfc"
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
size: 524288
validation: [size]
@@ -461,7 +461,7 @@ files:
standalone_path: "Firmware/sgb_boot.bin"
mode: standalone
aliases: ["sgb_bios.bin"]
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
size: 256
validation: [size]
@@ -473,7 +473,7 @@ files:
path: "sgb2_boot.bin"
standalone_path: "Firmware/sgb2_boot.bin"
aliases: ["sgb_bios.bin"]
system: nintendo-super-game-boy
system: nintendo-sgb
required: false
size: 256
validation: [size]
+14
View File
@@ -2663,6 +2663,20 @@ SYSTEM_ALIASES: dict[str, str] = {
# profiles use only through these.
"sega-segacd": "sega-megacd",
"nes-fds": "nintendo-fds",
# One machine, two spellings across platform folders and profiles:
# Recalbox's apple2gs, Batocera's astrocade, KNULLI and RetroBat's
# astrocde, MiSTer's creativision, Batocera's gamepocketcomputer
# folder, BizHawk's Super Game Boy, the FBA 2012 board names.
"apple2gs": "apple-iigs",
"astrocade": "bally-astrocade",
"astrocde": "bally-astrocade",
"creativision": "crvision",
"gamepocketcomputer": "gamepock",
"nintendo-super-game-boy": "nintendo-sgb",
"cps1": "capcom-cps1",
"cps2": "capcom-cps2",
"cps3": "capcom-cps3",
"pgm": "igs-pgm",
}
+11 -2
View File
@@ -1377,8 +1377,17 @@ class _ClaimRanks:
def _names_content(entry: dict) -> bool:
"""Whether a report entry declares the bytes it wants, not only a name."""
return any(entry.get(field) for field in ("sha1", "md5", "sha256", "crc32"))
"""Whether a report entry declares the bytes it wants, not only a name.
The claims folded onto the entry count: bsnes asks for SGB1.sfc by name
and bsnes-hd pins its md5 under the same system, and the entry carrying
both went after nSide's SGB1.sfc/ tree, which took the path from the file.
"""
return any(
claim.get(field)
for claim in (entry, *entry.get("other_claims", []))
for field in ("sha1", "md5", "sha256", "crc32")
)
def _save_fields(extra: dict, pack_path: str, placement: ExtraPlacement) -> None:
+1 -8
View File
@@ -860,7 +860,6 @@ SYSTEM_NAMES: dict[str, str] = {
"apple-iie": "Apple IIe",
"apple-ios": "Apple iOS",
"apple2": "Apple II",
"apple2gs": "Apple IIGS",
"arcade": "Arcade games",
"arcade-laserdisc": "Laserdisc arcade games",
"arcadia-systems": "Arcadia Systems Multi Select",
@@ -869,7 +868,6 @@ SYSTEM_NAMES: dict[str, str] = {
"aristocrat-mk6": "Aristocrat MK6",
"aristocrat-mk7": "Aristocrat MK7",
"arm": "ARM",
"astrocde": "Bally Astrocade",
"atari-falcon": "Atari Falcon",
"atari-jaguarcd": "Atari Jaguar CD",
"atari-ste": "Atari STE",
@@ -920,10 +918,6 @@ SYSTEM_NAMES: dict[str, str] = {
"commodore-cdtv": "Commodore CDTV",
"commodore-cubo": "CD Express Cubo CD32",
"coolbar": "Coolbar feature phones",
"cps1": "Capcom CPS-1",
"cps2": "Capcom CPS-2",
"cps3": "Capcom CPS-3",
"crvision": "VTech CreatiVision",
"cstrike": "Counter-Strike",
"ctf": "Quake II: Capture the Flag",
"czero": "Counter-Strike: Condition Zero",
@@ -1073,7 +1067,6 @@ SYSTEM_NAMES: dict[str, str] = {
"nintendo-nss": "Nintendo Super System",
"nintendo-playch10": "Nintendo PlayChoice-10",
"nintendo-sfcbox": "Nintendo Super Famicom Box",
"nintendo-sgb": "Nintendo Super Game Boy",
"nintendo-virtualboy": "Nintendo Virtual Boy",
"nintendo-wii-arcade": "Nintendo Wii arcade boards",
"nmk16": "NMK16",
@@ -1092,7 +1085,6 @@ SYSTEM_NAMES: dict[str, str] = {
"pce-tourvision": "TourVision",
"pdark": "Perfect Dark",
"pegasus": "Aamber Pegasus",
"pgm": "IGS PolyGame Master",
"philips-p2000t": "Philips P2000T",
"philips-vg5k": "Philips VG 5000",
"picocomputer-6502": "Picocomputer 6502 programs",
@@ -1216,6 +1208,7 @@ SYSTEM_NAMES: dict[str, str] = {
"tomb-raider-1": "Tomb Raider",
"tomb-raider-2": "Tomb Raider II",
"transport-tycoon-deluxe": "Transport Tycoon Deluxe",
"tvgames": "Plug-and-play TV games",
"tyrian": "Tyrian",
"ur-quan-masters": "Star Control II",
"urban-terror": "Urban Terror",
-1
View File
@@ -32,7 +32,6 @@ UNLINKED: dict[str, str] = {
# several systems' files or not reviewed as the system's own. The
# heading names the program, not the system.
"capcom-cps3": "Arcade > FBNeo",
"cps3": "Arcade > Arcade holds one CPS-3 set among every board's",
"commanderx16": "Arcade > Arcade",
"dark-forces-ii": "Game Engines > OpenJKDF2",
"fpinball": "Other > future-pinball-fploader",
+57 -2
View File
@@ -16,8 +16,8 @@ from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO_ROOT / "scripts"))
from common import SYSTEM_ALIASES, load_emulator_profiles # noqa: E402
from packextras import _slug_for # noqa: E402
from common import SYSTEM_ALIASES, _norm_system_id, load_emulator_profiles # noqa: E402
from packextras import _names_content, _slug_for # noqa: E402
class ProfilesSpellEachMachineOnce(unittest.TestCase):
@@ -35,6 +35,61 @@ class ProfilesSpellEachMachineOnce(unittest.TestCase):
self.assertEqual(sorted(set(found)), [])
class PlatformNamesReachTheProfileSystem(unittest.TestCase):
"""Folder and system names a platform gives a machine, joined to the
profile that runs it there. Each pair fell back to the whole profile in
a survey of the rom folders of 38 setups, the two spellings not meeting
once normalized."""
# (name a platform uses, profile running it there)
PAIRS = [
("apple-iigs", "mame"),
("apple2gs", "gsplus-legacy"),
("astrocde", "mame"),
("astrocade", "mame"),
("creativision", "mame"),
("gamepocketcomputer", "mame"),
("nintendo-sgb", "bsnes"),
("nintendo-sgb", "mesen-s"),
("capcom-cps1", "fbalpha2012_cps1"),
("capcom-cps2", "fbalpha2012_cps2"),
("capcom-cps3", "fbalpha2012_cps3"),
("capcom-cps1", "fbalpha2012"),
("igs-pgm", "fbalpha2012"),
]
def test_each_name_meets_a_system_of_its_profile(self):
profiles = load_emulator_profiles(str(REPO_ROOT / "emulators"))
unmet = [
f"{name} -> {emulator}"
for name, emulator in self.PAIRS
if _norm_system_id(name)
not in {_norm_system_id(str(s)) for s in profiles[emulator].get("systems", [])}
]
self.assertEqual(unmet, [])
def test_both_spellings_normalize_alike(self):
for alias, canonical in SYSTEM_ALIASES.items():
with self.subTest(alias=alias):
self.assertEqual(_norm_system_id(alias), _norm_system_id(canonical))
class AFoldedClaimKeepsItsProof(unittest.TestCase):
"""One spelling per machine folds bsnes-hd's SGB1.sfc onto bsnes's: the
entry still pins the bytes, so it is placed before nSide's SGB1.sfc/
tree and the file keeps its path."""
def test_a_hash_on_a_folded_claim_counts(self):
entry = {
"name": "SGB1.sfc", "md5": None, "sha1": None,
"other_claims": [{"name": "SGB1.sfc", "md5": "b15ddb15721c657d82c5bab6db982ee9"}],
}
self.assertTrue(_names_content(entry))
def test_names_alone_name_no_content(self):
self.assertFalse(_names_content({"name": "SGB1.sfc", "other_claims": [{"name": "SGB1.sfc"}]}))
class AFileGoesToItsOwnSystemFolder(unittest.TestCase):
PROFILES = {"picodrive": {"systems": ["sega-game-gear", "sega-megacd"]}}
SYSTEMS = {"sega-game-gear", "sega-mega-cd"}