mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 18:59:07 -05:00
fix: find BizHawk beside its executable
BizHawk reads the Firmware folder next to EmuHawk wherever the archive was extracted. The installer looked in ~/.config/BizHawk/Firmware, which no build reads, and wrote there when nothing was found.
This commit is contained in:
1 parent
fc47ac9f1f
commit
16f8b87ef4
7 files changed
+118
-18
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "7fb25b2ee8d7cdab5c852431732cf8ef92e6e9a81d24aeae7cb24b34dd413660"
|
||||
$defaultInstallSha256 = "d86244b95c49d37d3950e0547fe13fa6df589dc21ba9868d46da4ab305522b3f"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+50
-4
@@ -178,20 +178,17 @@ def _os_default_dests(os_type: str) -> dict[str, Path]:
|
||||
"""
|
||||
home = Path.home()
|
||||
if os_type == "windows":
|
||||
profile = Path(os.environ.get("USERPROFILE", str(home)))
|
||||
return {
|
||||
# RetroArch's system directory defaults to <exe folder>\system
|
||||
# (platform_win32.c), and its installer to C:\RetroArch-Win64.
|
||||
"retroarch": Path("C:/RetroArch-Win64/system"),
|
||||
# RetroBat's installer defaults to C:\RetroBat (installer.iss).
|
||||
"retrobat": Path("C:/RetroBat/bios"),
|
||||
"bizhawk": profile / "BizHawk" / "Firmware",
|
||||
}
|
||||
if os_type == "darwin":
|
||||
return {"retroarch": _macos_retroarch_base() / "system"}
|
||||
return {
|
||||
"retroarch": home / ".config" / "retroarch" / "system",
|
||||
"bizhawk": home / ".config" / "BizHawk" / "Firmware",
|
||||
}
|
||||
|
||||
# Set when the run is interrupted, so queued downloads end instead of draining
|
||||
@@ -949,7 +946,6 @@ _PATH_RULES: tuple[tuple[str, str, str, str | None], ...] = (
|
||||
("linux", "romm", "/romm/library/bios", None),
|
||||
("linux", "retropie", "$HOME/RetroPie/BIOS", None),
|
||||
("windows", "bizhawk", "%USERPROFILE%\\BizHawk\\Firmware", None),
|
||||
("linux", "bizhawk", "$HOME/.config/BizHawk/Firmware", None),
|
||||
("linux", "misterfpga", "/media/fat/MiSTer", "/media/fat/games"),
|
||||
)
|
||||
|
||||
@@ -967,6 +963,38 @@ def _rule_path(template: str) -> Path:
|
||||
return Path(template)
|
||||
|
||||
|
||||
# The registry's executable rules: (os, platform, glob under $HOME or
|
||||
# %USERPROFILE%, folder beside the executable that holds the BIOS). BizHawk is
|
||||
# a portable archive reading <EmuHawk folder>/Firmware (PathExtensions.cs
|
||||
# DataDirectoryPath), wherever it was extracted; ~/.config/BizHawk/Firmware,
|
||||
# the old guess, is a folder no build reads.
|
||||
_EXE_RULES: tuple[tuple[str, str, tuple[str, ...], str], ...] = (
|
||||
("linux", "bizhawk", ("$HOME/BizHawk*/EmuHawkMono.sh", "$HOME/*/BizHawk*/EmuHawkMono.sh"),
|
||||
"Firmware"),
|
||||
("windows", "bizhawk", ("%USERPROFILE%\\BizHawk*\\EmuHawk.exe",
|
||||
"%USERPROFILE%\\*\\BizHawk*\\EmuHawk.exe"), "Firmware"),
|
||||
)
|
||||
|
||||
|
||||
def _detect_by_executable(os_type: str, found: list[tuple[str, Path]]) -> None:
|
||||
"""Add a portable install found by its executable, the newest first."""
|
||||
systems = ("linux", "windows") if os_type == "wsl" else (os_type,)
|
||||
for rule_os, platform_name, patterns, subdir in _EXE_RULES:
|
||||
if rule_os not in systems or any(name == platform_name for name, _ in found):
|
||||
continue
|
||||
hits: list[Path] = []
|
||||
for pattern in patterns:
|
||||
base, _, rest = pattern.partition("/" if "/" in pattern else "\\")
|
||||
glob = "/".join(part for part in re.split(r"[\\/]", rest) if part)
|
||||
try:
|
||||
hits.extend(path for path in _rule_path(base).glob(glob) if path.is_file())
|
||||
except OSError:
|
||||
continue
|
||||
if hits:
|
||||
newest = max(hits, key=lambda path: path.stat().st_mtime)
|
||||
found.append((platform_name, newest.parent / subdir))
|
||||
|
||||
|
||||
def _detect_by_path(os_type: str, found: list[tuple[str, Path]]) -> None:
|
||||
"""Add what a registry path rule finds, for a platform not found yet."""
|
||||
systems = ("linux", "windows") if os_type == "wsl" else (os_type,)
|
||||
@@ -1113,6 +1141,7 @@ def detect_platforms(os_type: str) -> list[tuple[str, Path]]:
|
||||
if bizhawk is not None and not any(name == "bizhawk" for name, _ in found):
|
||||
found.append(("bizhawk", bizhawk))
|
||||
|
||||
_detect_by_executable(os_type, found)
|
||||
_detect_by_path(os_type, found)
|
||||
return found
|
||||
|
||||
@@ -3060,6 +3089,13 @@ def _prompt_manual_platform(os_type: str) -> list[tuple[str, Path]]:
|
||||
return [(plat, dest)]
|
||||
|
||||
|
||||
# Platforms with no install location of their own: the BIOS folder sits
|
||||
# beside the executable, wherever the archive was extracted.
|
||||
PORTABLE_ONLY = {
|
||||
"bizhawk": "BizHawk reads the Firmware folder beside EmuHawk, and none was found.",
|
||||
}
|
||||
|
||||
|
||||
def _default_dest(os_type: str, platform_name: str) -> Path:
|
||||
"""Fall back path for a platform named on the command line but not found.
|
||||
|
||||
@@ -3491,6 +3527,16 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None:
|
||||
matched = [(n, p) for n, p in detected if n == args.platform]
|
||||
if matched:
|
||||
platforms = matched
|
||||
elif args.platform in PORTABLE_ONLY:
|
||||
# A portable emulator reads the folder beside its executable:
|
||||
# any default would be a folder it never opens.
|
||||
print(
|
||||
f" Platform '{args.platform}' not found. {PORTABLE_ONLY[args.platform]} "
|
||||
f"Name it with --dest, for example: --platform {args.platform} "
|
||||
f"--dest '<BizHawk folder>{os.sep}Firmware'",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
default_dest = _default_dest(os_type, args.platform)
|
||||
print(
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="7fb25b2ee8d7cdab5c852431732cf8ef92e6e9a81d24aeae7cb24b34dd413660"
|
||||
DEFAULT_INSTALL_SHA256="d86244b95c49d37d3950e0547fe13fa6df589dc21ba9868d46da4ab305522b3f"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
+10
-2
@@ -575,12 +575,20 @@ platforms:
|
||||
target_source: null
|
||||
install:
|
||||
detect:
|
||||
# A portable archive reading <EmuHawk folder>/Firmware wherever it was
|
||||
# extracted (PathExtensions.cs DataDirectoryPath): found by its
|
||||
# executable in the home folder or one level down, the newest first.
|
||||
- os: windows
|
||||
method: path_exists
|
||||
path: '%USERPROFILE%\BizHawk\Firmware'
|
||||
- os: linux
|
||||
method: path_exists
|
||||
path: $HOME/.config/BizHawk/Firmware
|
||||
method: executable
|
||||
file: [$HOME/BizHawk*/EmuHawkMono.sh, $HOME/*/BizHawk*/EmuHawkMono.sh]
|
||||
bios_subdir: Firmware
|
||||
- os: windows
|
||||
method: executable
|
||||
file: ['%USERPROFILE%\BizHawk*\EmuHawk.exe', '%USERPROFILE%\*\BizHawk*\EmuHawk.exe']
|
||||
bios_subdir: Firmware
|
||||
misterfpga:
|
||||
config: misterfpga.yml
|
||||
status: active
|
||||
|
||||
@@ -155,10 +155,9 @@ def _build_readme(
|
||||
),
|
||||
"bizhawk": (
|
||||
"INSTALLATION GUIDE\n\n"
|
||||
" 1. Open your BizHawk installation folder\n"
|
||||
" 2. Navigate to the Firmware subfolder:\n"
|
||||
" - Windows: BizHawk\\Firmware\\\n"
|
||||
" - Linux: ~/.config/BizHawk/Firmware/\n"
|
||||
" 1. Open the folder you extracted BizHawk to, the one holding\n"
|
||||
" EmuHawk.exe (Windows) or EmuHawkMono.sh (Linux)\n"
|
||||
" 2. Navigate to its Firmware subfolder\n"
|
||||
" 3. Extract all files from this archive directly into your Firmware folder\n"
|
||||
" 4. In BizHawk: Config > Paths > Firmware should\n"
|
||||
" point to this folder\n\n"
|
||||
|
||||
+47
-2
@@ -229,6 +229,10 @@ class TestDefaultsFollowTheRegistry(unittest.TestCase):
|
||||
elif rule.get("parse_key") == "system_directory":
|
||||
config = self._expand(rule["config"])
|
||||
by_os.setdefault(rule["os"], set()).add(config.parent / "system")
|
||||
if name in install.PORTABLE_ONLY:
|
||||
# No folder of its own to fall back on: the run stops
|
||||
# and asks for --dest (test_a_portable_platform_is_not_guessed).
|
||||
continue
|
||||
for os_type, candidates in by_os.items():
|
||||
with self.subTest(platform=name, os=os_type):
|
||||
self.assertIn(install._default_dest(os_type, name), candidates)
|
||||
@@ -1043,11 +1047,52 @@ class DetectionFollowsTheRegistry(unittest.TestCase):
|
||||
def test_a_home_layout_is_detected(self):
|
||||
home = self._home()
|
||||
(home / "RetroPie" / "BIOS").mkdir(parents=True)
|
||||
(home / ".config" / "BizHawk" / "Firmware").mkdir(parents=True)
|
||||
found: list = []
|
||||
install._detect_by_path("linux", found)
|
||||
self.assertIn(("retropie", home / "RetroPie" / "BIOS"), found)
|
||||
self.assertIn(("bizhawk", home / ".config" / "BizHawk" / "Firmware"), found)
|
||||
|
||||
def test_bizhawk_is_found_by_its_executable(self):
|
||||
"""~/.config/BizHawk/Firmware is a folder no build reads: the
|
||||
archive extracted to ~/Games/BizHawk-2.11.1 reads the Firmware folder
|
||||
beside EmuHawkMono.sh."""
|
||||
home = self._home()
|
||||
extracted = home / "Games" / "BizHawk-2.11.1"
|
||||
extracted.mkdir(parents=True)
|
||||
(extracted / "EmuHawkMono.sh").write_text("#!/bin/sh\n")
|
||||
found: list = []
|
||||
install._detect_by_executable("linux", found)
|
||||
self.assertEqual(found, [("bizhawk", extracted / "Firmware")])
|
||||
self.assertNotIn("bizhawk", install._os_default_dests("linux"))
|
||||
self.assertNotIn("bizhawk", install._os_default_dests("windows"))
|
||||
|
||||
def test_a_portable_platform_is_not_guessed(self):
|
||||
"""--platform bizhawk with no install found wrote 924 files into
|
||||
~/.config/BizHawk/Firmware, then detected that folder next time."""
|
||||
home = self._home()
|
||||
with unittest.mock.patch.object(sys, "argv", ["install.py", "--platform", "bizhawk"]), \
|
||||
unittest.mock.patch.object(install, "detect_os", return_value="linux"), \
|
||||
unittest.mock.patch.object(install, "detect_platforms", return_value=[]), \
|
||||
contextlib.redirect_stdout(io.StringIO()), \
|
||||
contextlib.redirect_stderr(io.StringIO()) as err, \
|
||||
self.assertRaises(SystemExit) as stop:
|
||||
install.main()
|
||||
self.assertEqual(stop.exception.code, 1)
|
||||
self.assertIn("--dest", err.getvalue())
|
||||
self.assertFalse((home / ".config" / "BizHawk").exists())
|
||||
|
||||
def test_the_executable_table_is_the_registry(self):
|
||||
import yaml # noqa: PLC0415
|
||||
|
||||
registry = yaml.safe_load(
|
||||
(Path(__file__).resolve().parents[1] / "platforms" / "_registry.yml").read_text()
|
||||
)
|
||||
rules = {
|
||||
(rule["os"], name, tuple(rule["file"]), rule["bios_subdir"])
|
||||
for name, entry in registry["platforms"].items()
|
||||
for rule in (entry.get("install") or {}).get("detect", [])
|
||||
if rule["method"] == "executable"
|
||||
}
|
||||
self.assertEqual(set(install._EXE_RULES), rules)
|
||||
|
||||
def test_a_windows_profile_path_is_detected(self):
|
||||
home = self._home()
|
||||
|
||||
+6
-4
@@ -285,7 +285,8 @@ not already found that way.
|
||||
| `~/.var/app/net.retrodeck.retrodeck` | RetroDECK | `~/retrodeck` |
|
||||
| `/romm/library/bios` | RomM | the same |
|
||||
| `~/RetroPie/BIOS` | RetroPie | the same |
|
||||
| `%USERPROFILE%\BizHawk\Firmware` or `~/.config/BizHawk/Firmware` | BizHawk | the same |
|
||||
| `%USERPROFILE%\BizHawk\Firmware` | BizHawk | the same |
|
||||
| `EmuHawk.exe` or `EmuHawkMono.sh` in a `BizHawk*` folder of the home folder or one level down (`~/Games/BizHawk-2.11.1`), the newest | BizHawk | `Firmware` beside it |
|
||||
|
||||
Desktop installs are read from their own configuration, and several can be
|
||||
found on one machine.
|
||||
@@ -338,9 +339,10 @@ destination falls back to the directory its detection looks for:
|
||||
`/storage/system` for Lakka, `~/retrodeck` for RetroDECK, `~/Emulation/bios`
|
||||
for EmuDeck, `/storage/roms/bios` for ROCKNIX, `/media/fat/games` for MiSTer,
|
||||
`~/RetroPie/BIOS` for RetroPie, `/romm/library/bios` for RomM,
|
||||
`C:\RetroBat\bios` for RetroBat, `%USERPROFILE%\BizHawk\Firmware` (Windows)
|
||||
or `~/.config/BizHawk/Firmware` for BizHawk, and RetroArch's own default
|
||||
system directory for RetroArch. On Android a forced `--platform retroarch` falls back to
|
||||
`C:\RetroBat\bios` for RetroBat, and RetroArch's own default system
|
||||
directory for RetroArch. BizHawk has no such folder: it reads `Firmware`
|
||||
beside its executable wherever the archive was extracted, so a forced
|
||||
`--platform bizhawk` that finds no install stops and asks for `--dest`. On Android a forced `--platform retroarch` falls back to
|
||||
`<shared storage>/RetroArch/system` instead, a home directory there belonging
|
||||
to Termux rather than to the frontend. Pass `--dest` to say where instead of
|
||||
relying on that.
|
||||
|
||||
Reference in new issue
Block a user