diff --git a/platforms/retropie.yml b/platforms/retropie.yml index 34276c303..f63b8e80e 100644 --- a/platforms/retropie.yml +++ b/platforms/retropie.yml @@ -693,6 +693,24 @@ launchers: passes_to: rompath in $md_conf_root/mame/mame.ini fails_when_missing: false source_ref: "scriptmodules/emulators/mame.sh:133" +- emulator: mame + package: mame + build: standalone + kind: passes_path + names: [] + search_dir: $romdir/mame/samples;$romdir/arcade/samples + passes_to: samplepath in $md_conf_root/mame/mame.ini + fails_when_missing: false + source_ref: "scriptmodules/emulators/mame.sh:135" +- emulator: mame + package: mame + build: standalone + kind: passes_path + names: [] + search_dir: $romdir/mame/artwork;$romdir/arcade/artwork + passes_to: artpath in $md_conf_root/mame/mame.ini + fails_when_missing: false + source_ref: "scriptmodules/emulators/mame.sh:136" - emulator: mame4all package: mame4all repo: "git https://github.com/RetroPie/mame4all-pi.git master" @@ -703,6 +721,24 @@ launchers: kind: package names: [] source_ref: "scriptmodules/emulators/mame4all.sh:12, 16, 91-92" +- emulator: mame4all + package: mame4all + build: standalone + kind: passes_path + names: [] + search_dir: $romdir/mame-mame4all/samples;$romdir/arcade/samples + passes_to: samplepath in $md_conf_root/mame-mame4all/mame.cfg + fails_when_missing: false + source_ref: "scriptmodules/emulators/mame4all.sh:78" +- emulator: mame4all + package: mame4all + build: standalone + kind: passes_path + names: [] + search_dir: $romdir/mame-mame4all;$romdir/arcade + passes_to: rompath in $md_conf_root/mame-mame4all/mame.cfg + fails_when_missing: false + source_ref: "scriptmodules/emulators/mame4all.sh:79" - emulator: minivmac package: minivmac repo: "git https://github.com/minivmac/minivmac.git master" diff --git a/scripts/launchers.py b/scripts/launchers.py index 6d959339a..2884035b9 100644 --- a/scripts/launchers.py +++ b/scripts/launchers.py @@ -314,8 +314,9 @@ BIOS_ROOT_VARIABLES = ("$biosdir", "$home/RetroPie/BIOS", "${biosPath}", "$bios_ # The name a platform's launch code gives its roms root: RetroDECK's # component scripts write $roms_path (retrodeck_launchers), the setting whose -# default is the roms root (config/retrodeck/retrodeck.json:5). -ROMS_ROOT_VARIABLES = ("$roms_path", "${roms_path}") +# default is the roms root (config/retrodeck/retrodeck.json:5), RetroPie's +# scriptmodules $romdir (retropie_packages.sh:47-49). +ROMS_ROOT_VARIABLES = ("$roms_path", "${roms_path}", "$romdir", "${romdir}") # The kinds that hand an emulator a whole directory. A scans_dir record sets # the directory the emulator picks its file from: ROCKNIX writes ARMSX2's diff --git a/scripts/scraper/retropie_launchers.py b/scripts/scraper/retropie_launchers.py index a56cd9a2c..1f48b28c0 100644 --- a/scripts/scraper/retropie_launchers.py +++ b/scripts/scraper/retropie_launchers.py @@ -32,6 +32,9 @@ SECTIONS = ("emulators", "libretrocores", "ports") PACKAGES_SCRIPT = "retropie_packages.sh" BIOSDIR = "$biosdir" +# The roms root (retropie_packages.sh:47-49): MAME's mame.ini lists rom, +# sample and artwork folders below it (scriptmodules/emulators/mame.sh:133-136). +ROMDIR = "$romdir" # The package whose config every lr- core runs under. LIBRETRO_FRONTEND = "retroarch" # The launch scripts copied next to an emulator spell the directory out. @@ -464,6 +467,20 @@ class Scripts: return results +def _search_list_in_roms(event: "Event") -> bool: + """An iniSet whose value is a list of folders below the roms root. + + One folder alone is where a program writes (cfg_directory, nvram_directory + and the others MAME's mame.ini sets): a list is where it searches. + """ + if len(event.words) < 3 or len(event.words[2]) != 1: + return False + parts = [p for p in event.words[2][0].split(";") if p] + return len(parts) > 1 and all( + p.startswith(ROMDIR + "/") or p.startswith("${romdir}/") for p in parts + ) + + def _mentions_bios(text: str) -> bool: return BIOSDIR in text or "${biosdir}" in text or BIOS_SPELLED in text @@ -541,6 +558,12 @@ class PackageReader: if command == "addEmulator": self._add_emulator(event) return + if command == "iniSet" and not _mentions_bios(event.raw): + # A search path below the roms root: MAME reads its samples from + # samplepath $romdir/mame/samples;$romdir/arcade/samples. + if _search_list_in_roms(event): + self._ini_set(event) + return if not _mentions_bios(event.raw): return if command in HOUSEKEEPING: diff --git a/tests/test_launcher_placement.py b/tests/test_launcher_placement.py index 605776250..b5793b2e1 100644 --- a/tests/test_launcher_placement.py +++ b/tests/test_launcher_placement.py @@ -873,6 +873,18 @@ class MameSearchPaths(unittest.TestCase): if e["name"] == "hash/" and e.get("mode") == "standalone"] self.assertTrue(entry.get("bundled")) + def test_retropie_reads_samples_below_its_roms(self) -> None: + # samplepath $romdir/mame/samples;$romdir/arcade/samples (mame.sh:135). + view = standalone_view("mame", "retropie") + (bbc,) = [e for e in view["files"] if e["name"] == "bbc.zip"] + self.assertEqual((bbc["standalone_path"], bbc.get("root")), + ("mame/samples/bbc.zip", "roms")) + (tree,) = [e for e in view["files"] + if e["name"] == "floppy/" and e.get("mode") == "standalone"] + self.assertEqual((tree["standalone_path"], tree.get("root")), + ("mame/samples/floppy/", "roms")) + self.assertNotIn("bundled", tree) + 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_retropie.py b/tests/test_launchers_retropie.py index b57cc60b8..1e194179a 100644 --- a/tests/test_launchers_retropie.py +++ b/tests/test_launchers_retropie.py @@ -239,6 +239,45 @@ class LinksAndCopies(unittest.TestCase): self.assertEqual(base[0]["names"], ["hiscore.dat", "cheat.dat"]) +MAME = module("mame", """ + function configure_mame() { + local system="mame" + local temp_ini_mame="$(mktemp)" + iniConfig " " "" "$temp_ini_mame" + iniSet "rompath" "$romdir/$system;$romdir/arcade;$biosdir/$system" + iniSet "hashpath" "$md_inst/hash" + iniSet "samplepath" "$romdir/$system/samples;$romdir/arcade/samples" + iniSet "cfg_directory" "$romdir/$system/cfg" + copyDefaultConfig "$temp_ini_mame" "$md_conf_root/$system/mame.ini" + addEmulator 0 "$md_id" "arcade" "$md_inst/mame %BASENAME%" + addSystem "arcade" + } +""", 109) + + +class IniSearchLists(unittest.TestCase): + """MAME's mame.ini lists folders below $romdir (mame.sh:133-136).""" + + def test_a_list_below_the_roms_root_is_a_search_path(self): + found = [r for r in records({f"{EMULATORS}/mame.sh": MAME}, "mame") + if r["kind"] == "passes_path"] + self.assertEqual( + [(r["search_dir"], r["passes_to"].split(" in ")[0]) for r in found], + [ + ("$romdir/mame;$romdir/arcade;$biosdir/mame", "rompath"), + ("$romdir/mame/samples;$romdir/arcade/samples", "samplepath"), + ], + ) + self.assertEqual(found[1]["source_ref"], f"{EMULATORS}/mame.sh:115") + + def test_one_folder_written_to_is_no_search_path(self): + # cfg_directory is where MAME writes, $md_inst/hash a folder of the + # package itself. + found = records({f"{EMULATORS}/mame.sh": MAME}, "mame") + self.assertFalse([r for r in found if "cfg" in str(r.get("search_dir"))]) + self.assertFalse([r for r in found if "hash" in str(r.get("search_dir"))]) + + class CommandLines(unittest.TestCase): def test_sdltrs_passes_one_rom_per_machine(self): found = records({f"{EMULATORS}/sdltrs.sh": SDLTRS}, "sdltrs")