diff --git a/install.ps1 b/install.ps1 index 16e613e2..4048f572 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,7 +11,7 @@ $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" - $defaultInstallSha256 = "fe8de4eda0919c268d4d2c0d571c7d0dc1cf675d7604263766f5f99a35aa3724" + $defaultInstallSha256 = "a5437191c86a4ecd9042443c3d58a501bd007b851603f7e778c179f31f6c2463" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 9cd3e52e..9a6c2d0d 100644 --- a/install.py +++ b/install.py @@ -185,7 +185,7 @@ OTHER_SYSTEMS = "other" AVAILABLE_PLATFORMS = ( "retroarch", "batocera", "recalbox", "retrobat", "emudeck", "lakka", "retrodeck", "rocknix", "romm", "bizhawk", "misterfpga", - "retropie", + "retropie", "amberelec", "emuelec", "knulli", ) # The names the frontends give themselves, as each manifest's display_name @@ -197,6 +197,7 @@ PLATFORM_NAMES = { "retrobat": "RetroBat", "emudeck": "EmuDeck", "lakka": "Lakka", "retrodeck": "RetroDECK", "rocknix": "ROCKNIX", "romm": "RomM", "bizhawk": "BizHawk", "misterfpga": "MiSTer FPGA", "retropie": "RetroPie", + "amberelec": "AmberELEC", "emuelec": "EmuELEC", "knulli": "KNULLI", } SITE_URL = "https://abdess.github.io/retrobios/" @@ -213,6 +214,10 @@ DEFAULT_DESTS = { "retrodeck": Path.home() / "retrodeck", "emudeck": Path.home() / "Emulation" / "bios", "rocknix": Path("/storage/roms/bios"), + # Their BIOS lists name files under /storage/roms beside bios/. + "amberelec": Path("/storage/roms"), + "emuelec": Path("/storage/roms"), + "knulli": Path("/userdata/bios"), "misterfpga": Path("/media/fat/games"), "retropie": Path.home() / "RetroPie" / "BIOS", "romm": Path("/romm/library/bios"), @@ -745,13 +750,12 @@ _BOARD_SOURCES: dict[str, tuple[str, str]] = { } -# A derivative installed under a platform's name, with its own board file. +# A platform that names its board without publishing a core list per board. # Knulli moves /usr/share/batocera to /usr/share/knulli (knulli-linux # 57afa662, board/scripts/post-build-script.sh:264-278) and writes its board -# to knulli.arch (package/system/knulli-system/knulli-system.mk:98-99). Its -# packages are its own, so Batocera's per-board core lists do not apply. +# to knulli.arch (package/system/knulli-system/knulli-system.mk:98-99). _DERIVATIVE_BOARDS: dict[str, tuple[str, str]] = { - "batocera": ("Knulli", "/usr/share/knulli/knulli.arch"), + "knulli": ("Knulli", "/usr/share/knulli/knulli.arch"), } @@ -827,8 +831,14 @@ _EMBEDDED_RULES: tuple[tuple[str, str, tuple[str, ...], str], ...] = ( # Knulli (knulli-linux 57afa662): OS_NAME in os-release # (board/scripts/post-build-script.sh:233-236) and knulli.version # (package/system/knulli-system/knulli-system.mk:98-102). - ("batocera", "os_release", ("OS_NAME=knulli",), "/userdata/bios"), - ("batocera", "file_exists", ("/usr/share/knulli/knulli.version",), "/userdata/bios"), + ("knulli", "os_release", ("OS_NAME=knulli",), "/userdata/bios"), + ("knulli", "file_exists", ("/usr/share/knulli/knulli.version",), "/userdata/bios"), + # scripts/image writes NAME from DISTRONAME. AmberELEC a21975bf: + # scripts/image:152 (ID is "coreelec", line 154) and + # distributions/AmberELEC/options:17. EmuELEC v4.8: scripts/image:174-176 + # (ID is DISTRONAME lowercased) and distributions/EmuELEC/options:4. + ("amberelec", "os_release", ("NAME=AmberELEC",), "/storage/roms"), + ("emuelec", "os_release", ("ID=emuelec",), "/storage/roms"), ("lakka", "os_release", ("ID=lakka",), "/storage/system"), # batocera.linux 38845725, batocera-system.mk:21-22 (the same lines in # batocera-30): batocera.arch and batocera.version. diff --git a/install.sh b/install.sh index 6f563d44..59373fd0 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ esac TEMP_INSTALLER="" TEMP_DIRECTORY="" DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -DEFAULT_INSTALL_SHA256="fe8de4eda0919c268d4d2c0d571c7d0dc1cf675d7604263766f5f99a35aa3724" +DEFAULT_INSTALL_SHA256="a5437191c86a4ecd9042443c3d58a501bd007b851603f7e778c179f31f6c2463" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/tests/test_install.py b/tests/test_install.py index c16ca60e..a8ddf2ef 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1078,7 +1078,7 @@ class DetectionFollowsTheRegistry(unittest.TestCase): lambda p: str(p) in ("/usr/share/knulli/knulli.version", "/usr/share/batocera/batocera.version"), ): - self.assertEqual(install._detect_embedded(), [("batocera", Path("/userdata/bios"))]) + self.assertEqual(install._detect_embedded(), [("knulli", Path("/userdata/bios"))]) # What ROCKNIX writes since 2025: OS_NAME and HW_DEVICE, no ID. with unittest.mock.patch.object(install, "_parse_os_release", return_value={"OS_NAME": "ROCKNIX", "HW_DEVICE": "RK3566"}): @@ -4264,16 +4264,25 @@ class BatoceraAndKnulliByWhatTheirBuildsWrite(unittest.TestCase): def test_knulli_by_its_os_release_or_version_file(self): self.assertEqual(self._detect({"OS_NAME": "knulli"}, ()), - [("batocera", Path("/userdata/bios"))]) + [("knulli", Path("/userdata/bios"))]) self.assertEqual(self._detect({}, ("/usr/share/knulli/knulli.version",)), - [("batocera", Path("/userdata/bios"))]) + [("knulli", Path("/userdata/bios"))]) + + def test_amberelec_and_emuelec_by_their_os_release(self): + """Both write os-release from DISTRONAME in scripts/image. AmberELEC + keeps CoreELEC's ID, so its NAME tells it apart.""" + self.assertEqual(self._detect({"NAME": "AmberELEC", "ID": "coreelec"}, ()), + [("amberelec", Path("/storage/roms"))]) + self.assertEqual(self._detect({"NAME": "EmuELEC", "ID": "emuelec"}, ()), + [("emuelec", Path("/storage/roms"))]) + self.assertEqual(self._detect({"NAME": "CoreELEC", "ID": "coreelec"}, ()), []) def test_a_knulli_board_is_named_and_not_narrowed(self): board = Path(_tempdir(self)) / "knulli.arch" board.write_text("a133") with unittest.mock.patch.dict(install._DERIVATIVE_BOARDS, - {"batocera": ("Knulli", str(board))}): - self.assertEqual(install.derivative_board("batocera"), ("Knulli", "a133")) + {"knulli": ("Knulli", str(board))}): + self.assertEqual(install.derivative_board("knulli"), ("Knulli", "a133")) self.assertIsNone(install.derivative_board("recalbox")) def test_the_run_says_why_every_board_is_installed(self):