mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
fix: place launcher links and platform BIOS paths
A links record naming a file is where the emulator reads it: ROCKNIX links /storage/roms/bios/nds_bios_arm9.bin into DraStic's system folder (start_drastic.sh:37-41). $biosdir, ${biosPath} and $bios_path are the BIOS directory as RetroPie, EmuDeck and RetroDECK write it, and every place of those platforms was dropped as an unknown folder. A core name the launcher replaces is no longer packed when held: EmuDeck passes Complex_4627v1.03.bin to xemu (emuDeckXemu.sh:60-61), which never opens Complex_4627.bin.
This commit is contained in:
1 parent
9102fb3c01
commit
20829d09ce
2 files changed
+75
-6
No files matched your search
+31
-6
@@ -22,10 +22,23 @@ from dataclasses import dataclass
|
||||
|
||||
from common import declared_root, name_match_size_ok, sanitize_pack_path
|
||||
|
||||
# The kinds whose names say which file the launcher opens. The others hand
|
||||
# over a directory, copy a file the platform already names, or let the
|
||||
# The kinds whose names say which file the launcher opens. A link of a named
|
||||
# file is one too: ROCKNIX links /storage/roms/bios/nds_bios_arm9.bin into
|
||||
# DraStic's system folder, so that is the path the emulator reads. The others
|
||||
# hand over a directory, copy a file the platform already names, or let the
|
||||
# emulator choose.
|
||||
PLACE_KINDS = ("names_searched", "fixed_name", "core_option")
|
||||
PLACE_KINDS = ("names_searched", "fixed_name", "core_option", "links")
|
||||
|
||||
# How each launcher extractor spells the BIOS directory in search_dir, as the
|
||||
# platform's own scripts name it: RetroPie's scriptmodules ($biosdir,
|
||||
# retropie_launchers.BIOSDIR), EmuDeck's EmuScripts (${biosPath},
|
||||
# emudeck_launchers.BIOS) and RetroDECK's framework ($bios_path,
|
||||
# retrodeck_launchers.BIOS).
|
||||
BIOS_ROOT_TOKENS = ("$biosdir", "${biosdir}", "${biosPath}", "$bios_path", "${bios_path}")
|
||||
|
||||
# A path spelled from a home or filesystem root names the BIOS directory by
|
||||
# its base name: /userdata/bios, ~/roms/bios, $HOME/RetroPie/BIOS.
|
||||
_ROOTED = ("/", "~/", "$HOME/", "$home/", "${HOME}/")
|
||||
|
||||
_LABELLED = re.compile(r"^([^\s()]+\.[A-Za-z0-9]+) \([^()]*\)$")
|
||||
_PLACEHOLDER = re.compile(r"\{(\w+)\}")
|
||||
@@ -68,19 +81,22 @@ class LauncherPlace:
|
||||
option or a system leaves that default in use elsewhere, and a core
|
||||
option offers a file the user may choose without ever choosing it.
|
||||
"""
|
||||
return self.kind in ("names_searched", "fixed_name") and not self.conditional
|
||||
return (
|
||||
self.kind in ("names_searched", "fixed_name", "links")
|
||||
and not self.conditional
|
||||
)
|
||||
|
||||
|
||||
def _bios_relative(directory: str, base: str) -> str | None:
|
||||
"""A launcher directory relative to the BIOS root, None when it is not one."""
|
||||
directory = directory.strip().rstrip("/")
|
||||
roots = {base, "<system_directory>"}
|
||||
roots = {base, "<system_directory>", *BIOS_ROOT_TOKENS}
|
||||
head, _, rest = directory.partition("/")
|
||||
if directory in roots:
|
||||
return ""
|
||||
if head in roots:
|
||||
relative = rest
|
||||
elif directory.startswith("/") and base and f"/{base}/" in f"{directory}/":
|
||||
elif directory.startswith(_ROOTED) and base and f"/{base}/" in f"{directory}/":
|
||||
relative = f"{directory}/".split(f"/{base}/", 1)[1].rstrip("/")
|
||||
else:
|
||||
return None
|
||||
@@ -390,9 +406,18 @@ class LauncherLayer:
|
||||
if isinstance(filled, dict):
|
||||
added.append(filled)
|
||||
if place.stands_for_default:
|
||||
# The emulator opens the launcher's file instead of its
|
||||
# own name, so a copy under that name is read by nobody:
|
||||
# EmuDeck passes Complex_4627v1.03.bin to xemu, which then
|
||||
# never opens Complex_4627.bin. A held file sitting on one
|
||||
# of the place's own paths is what fills it.
|
||||
own = {place.fold(p) for p in place.paths}
|
||||
settled.update(
|
||||
id(report) for _candidate, report in matched
|
||||
if not report.get("in_repo")
|
||||
or place.fold(sanitize_pack_path(
|
||||
report.get("path") or report.get("name", "")
|
||||
)) not in own
|
||||
)
|
||||
return added, settled
|
||||
|
||||
|
||||
@@ -250,6 +250,50 @@ class LauncherLayerTest(unittest.TestCase):
|
||||
self.assertNotIn("core.bin", {u["name"] for u in self._report()})
|
||||
self.assertNotIn("core.bin", self._pack_names())
|
||||
|
||||
def test_the_default_name_a_launcher_replaces_is_not_packed(self) -> None:
|
||||
"""EmuDeck passes Complex_4627v1.03.bin to xemu, which then never
|
||||
opens Complex_4627.bin: the pack carried both, one read by nobody."""
|
||||
report = {u["path"]: u for u in self._report()}
|
||||
self.assertIn("sub/fix.bin", report)
|
||||
self.assertNotIn("core.bin", report)
|
||||
self.assertNotIn("core.bin", self._pack_names())
|
||||
|
||||
def test_a_link_of_a_named_file_is_a_place(self) -> None:
|
||||
"""ROCKNIX links /storage/roms/bios/nds_bios_arm9.bin into DraStic's
|
||||
system folder (start_drastic.sh:37-41): the file goes where the
|
||||
link reads it, not under the emulator's own folder."""
|
||||
self.config["launchers"][2].update(
|
||||
kind="links", names=["fix.bin"], search_dir="/storage/roms/bios",
|
||||
)
|
||||
places = [p for p in launcher_places(self.config) if p.kind == "links"]
|
||||
self.assertEqual([p.paths for p in places], [("fix.bin",)])
|
||||
self.assertTrue(places[0].stands_for_default)
|
||||
report = {u["path"]: u for u in self._report()}
|
||||
self.assertIn("fix.bin", report)
|
||||
self.assertNotIn("core.bin", report)
|
||||
|
||||
def test_a_link_of_a_directory_is_no_place(self) -> None:
|
||||
self.config["launchers"][2].update(
|
||||
kind="links", names=[], search_dir="/userdata/bios/sub",
|
||||
)
|
||||
self.assertFalse([p for p in launcher_places(self.config) if p.kind == "links"])
|
||||
|
||||
def test_the_platform_spelling_of_the_bios_folder_is_a_root(self) -> None:
|
||||
"""RetroPie names $biosdir, EmuDeck ${biosPath}, RetroDECK $bios_path:
|
||||
read as no folder at all, every place of those platforms was dropped."""
|
||||
for spelling in ("$biosdir", "${biosPath}", "$bios_path", "$HOME/RetroPie/bios"):
|
||||
self.config["launchers"][2]["search_dir"] = f"{spelling}/sub"
|
||||
with self.subTest(spelling=spelling):
|
||||
self.assertEqual(launcher_places(self.config)[2].paths, ("sub/sub/fix.bin",))
|
||||
|
||||
def test_every_extractor_spelling_of_the_bios_folder_is_known(self) -> None:
|
||||
import launchers
|
||||
from scraper import emudeck_launchers, retrodeck_launchers, retropie_launchers
|
||||
|
||||
for token in (emudeck_launchers.BIOS, retrodeck_launchers.BIOS,
|
||||
retropie_launchers.BIOSDIR):
|
||||
self.assertIn(token, launchers.BIOS_ROOT_TOKENS)
|
||||
|
||||
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"])
|
||||
|
||||
Reference in new issue
Block a user