From 409578e20eccd34cb0dc82eff86e734b361871b8 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 14:05:10 +0100 Subject: [PATCH] feat: read Batocera's MAME search paths Batocera starts MAME with -rompath ;/userdata/bios/mame; /userdata/bios, /userdata/roms/mame and the softlist folder added for MESS systems, and -samplepath, -artpath and -crosshairpath below /userdata/bios/mame (generators/mame/mameGenerator.py:129-143, 189 at batocera-43.1, MAME_BIOS in mamePaths.py). No extractor read that generator. It now goes through the generic reader KNULLI uses for its fork of the same file, keeping the command line search settings: the Macintosh boot disk the command names is a file. Rescraped at batocera-43.1: the six records are the only change. Manifests: Batocera drops samples/bbc.zip at the BIOS root, read by neither build. mame/samples/bbc.zip, which its list declares, serves both. The sets stay at the BIOS root, which the rompath lists. --- platforms/batocera.yml | 53 +++++++++++++++++++++++++++ scripts/scraper/batocera_launchers.py | 24 +++++++++++- tests/test_launcher_placement.py | 8 ++++ tests/test_launchers.py | 40 ++++++++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/platforms/batocera.yml b/platforms/batocera.yml index fccda9985..3accfa622 100644 --- a/platforms/batocera.yml +++ b/platforms/batocera.yml @@ -6814,6 +6814,59 @@ launchers: fails_when_missing: false source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/shadps4/shadps4Generator.py:46,\ \ 228" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: ;/userdata/bios/mame;/userdata/bios + passes_to: command line -rompath + fails_when_missing: false + depends_on_option: messMode == -1 + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:129-130" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: ;/userdata/bios/mame;/userdata/bios;/userdata/roms/mame; + passes_to: command line -rompath + fails_when_missing: false + depends_on_option: "not (messMode == -1) and softList in subdirSoftList" + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:129,\ + \ 132-133" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: ;/userdata/bios/mame;/userdata/bios;/userdata/roms/mame + passes_to: command line -rompath + fails_when_missing: false + depends_on_option: "not (messMode == -1) and not (softList in subdirSoftList)" + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:129,\ + \ 132, 135" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: /userdata/bios/mame/samples + passes_to: command line -samplepath + fails_when_missing: false + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:142" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: /var/run/mame_artwork/;/usr/bin/mame/artwork/;/userdata/bios/mame/artwork;/userdata/decorations + passes_to: command line -artpath + fails_when_missing: false + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:143" +- emulator: mame + build: standalone + kind: passes_path + names: [] + search_dir: /userdata/bios/mame/artwork/crosshairs + passes_to: command line -crosshairpath + fails_when_missing: false + source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/mame/mameGenerator.py:189" configs_root: path: /userdata/system/configs from_bios: ../system/configs diff --git a/scripts/scraper/batocera_launchers.py b/scripts/scraper/batocera_launchers.py index 723e7d5ad..f7e44d1ea 100644 --- a/scripts/scraper/batocera_launchers.py +++ b/scripts/scraper/batocera_launchers.py @@ -1119,10 +1119,32 @@ def patched_paths(read: Callable[[str], str], patches: tuple[str, ...] = PATH_PA return launchers +# Generators whose command line hands the emulator /userdata/bios folders as +# search paths: MAME's -rompath and -samplepath (mame/mameGenerator.py). +SEARCH_PATH_GENERATORS = ("mame/mameGenerator.py",) + + +def search_paths(cg: Configgen) -> list[Launcher]: + """Every /userdata/bios path a generator's command line names, read as + KNULLI's generic reader reads its fork of the same generator.""" + try: + from .knulli_launchers import GenericSites, bios_sites # noqa: PLC0415 + except ImportError: + from knulli_launchers import GenericSites, bios_sites # type: ignore[no-redef] # noqa: PLC0415 + # A boot disk image the command line names (the Macintosh's + # /userdata/bios/.img) is a file, no search path. + return [ + launcher + for path in SEARCH_PATH_GENERATORS + for launcher in bios_sites(cg, GenericSites(path, "passes_path")) + if re.match(r"command line -\w", launcher.passes_to or "") + ] + + EXTRACTORS: tuple[Callable[[Configgen], list[Launcher]], ...] = ( duckstation, duckstation_legacy, hatari, xemu, melonds, mupen64plus, x16emu, gsplus, lexaloffle, environment_directories, config_directories, - core_file_options, working_directories, + core_file_options, working_directories, search_paths, ) diff --git a/tests/test_launcher_placement.py b/tests/test_launcher_placement.py index b5793b2e1..b8a24598c 100644 --- a/tests/test_launcher_placement.py +++ b/tests/test_launcher_placement.py @@ -885,6 +885,14 @@ class MameSearchPaths(unittest.TestCase): ("mame/samples/floppy/", "roms")) self.assertNotIn("bundled", tree) + def test_batocera_keeps_the_sets_at_the_root_and_samples_in_bios_mame(self) -> None: + # -rompath ;/userdata/bios/mame;/userdata/bios and + # -samplepath /userdata/bios/mame/samples (mameGenerator.py:129-142). + view = standalone_view("mame", "batocera") + self.assertTrue(all(e["standalone_path"] == e["name"] for e in self.sets(view))) + (bbc,) = [e for e in view["files"] if e["name"] == "bbc.zip"] + self.assertEqual(bbc["standalone_path"], "mame/samples/bbc.zip") + def test_a_moved_tree_is_found_by_its_layout_path(self) -> None: from common import expand_directory_entries, load_database diff --git a/tests/test_launchers.py b/tests/test_launchers.py index c211f63ca..2921a3d2f 100644 --- a/tests/test_launchers.py +++ b/tests/test_launchers.py @@ -529,6 +529,46 @@ OPENMSX_FILEPOOL = ''' def generate(self, system, rom): file.write("filepool add -path /userdata/bios/openmsx -types system_rom -position 2\\n")''' +MAME = f"{GENERATORS}/mame/mameGenerator.py" +MAME_PATHS = f"{GENERATORS}/mame/mamePaths.py" +MAME_HEAD = """from __future__ import annotations +from ...batoceraPaths import BIOS +from .mamePaths import MAME_BIOS +class MameGenerator: + def generate(self, system, rom, playersControllers, metadata, guns, wheels, gameResolution):""" +MAME_COMMAND = """ if messMode == -1: + commandArray += [ "-rompath", f"{romDirname};{MAME_BIOS};{BIOS}" ]""" +MAME_SAMPLES = """ commandArray += [ "-samplepath", MAME_BIOS / "samples" ]""" +MAME_BOOT = """ if boot_disk: + bootDisk = f"/userdata/bios/{boot_disk}.img" + commandArray += [ bootType, bootDisk ]""" + + +class MameSearchPaths(unittest.TestCase): + """mameGenerator.py:129-142 at batocera-43.1: -rompath and -samplepath.""" + + def test_the_command_line_search_paths_are_recorded(self): + from scraper.batocera_launchers import search_paths + + cg = configgen({ + MAME: placed({1: MAME_HEAD, 129: MAME_COMMAND, 142: MAME_SAMPLES, 378: MAME_BOOT}), + MAME_PATHS: "from ...batoceraPaths import BIOS\nMAME_BIOS = BIOS / 'mame'\n", + }) + records = [r.entry() for r in search_paths(cg)] + self.assertEqual( + [(r["emulator"], r["search_dir"], r["passes_to"], r.get("depends_on_option")) + for r in records], + [ + ("mame", ";/userdata/bios/mame;/userdata/bios", + "command line -rompath", "messMode == -1"), + ("mame", "/userdata/bios/mame/samples", "command line -samplepath", None), + ], + ) + self.assertEqual(records[0]["source_ref"], f"{MAME}:129-130") + # The boot disk the command names is a file, no search path. + self.assertFalse([r for r in records if "boot_disk" in r["search_dir"]]) + + class ConfigDirectories(unittest.TestCase): """A BIOS directory written into the emulator's config, at batocera-43.1."""