From ffb3cbfed3ade15281a886834b0835fc12f4928d Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 02:36:02 +0100 Subject: [PATCH] fix: place Xbox files where RetroBat reads them Each Cxbx build reads its data from the folder its settings.ini sits in, which RetroBat writes beside the binary: the three profiles name Settings::GetDataLocation, so keys.bin, EmuDisk and EmuMediaBoard go to emulators/ on RetroBat instead of the BIOS root. RetroBat writes cxbx-reloaded's EEPROM.bin and xemu's eeprom.bin and xbox_hdd.qcow2 itself (installed_on), and mounts an .iso with its own tool, so Cxbx's dokan2.dll is never loaded there (unread_on). --- emulators/chihiro-ds.yml | 2 ++ emulators/cxbx-reloaded-2023.yml | 2 ++ emulators/cxbx-reloaded.yml | 4 ++++ emulators/xemu.yml | 6 ++++-- tests/test_launcher_placement.py | 30 ++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/emulators/chihiro-ds.yml b/emulators/chihiro-ds.yml index bd2a774e4..138ffa88a 100644 --- a/emulators/chihiro-ds.yml +++ b/emulators/chihiro-ds.yml @@ -17,6 +17,8 @@ systems: - sega-chihiro - microsoft-xbox mode: standalone +standalone_directories: + - "Settings::GetDataLocation" notes: | Cxbx-Reloaded derivative built for the Chihiro light gun games, used by diff --git a/emulators/cxbx-reloaded-2023.yml b/emulators/cxbx-reloaded-2023.yml index b213b70e2..bbd49ea0e 100644 --- a/emulators/cxbx-reloaded-2023.yml +++ b/emulators/cxbx-reloaded-2023.yml @@ -16,6 +16,8 @@ systems: - sega-chihiro - microsoft-xbox mode: standalone +standalone_directories: + - "Settings::GetDataLocation" notes: | The Cxbx-Reloaded build RetroBat installs as its "chihiro" emulator diff --git a/emulators/cxbx-reloaded.yml b/emulators/cxbx-reloaded.yml index 33a7a1179..200bdb70e 100644 --- a/emulators/cxbx-reloaded.yml +++ b/emulators/cxbx-reloaded.yml @@ -18,6 +18,8 @@ systems: - microsoft-xbox - sega-chihiro mode: standalone +standalone_directories: + - "Settings::GetDataLocation" data_root: windows: @@ -193,6 +195,7 @@ files: path: "EEPROM.bin" system: microsoft-xbox required: false + installed_on: [retrobat] has_builtin: true size: 256 validation: [size] @@ -337,6 +340,7 @@ files: - name: dokan2.dll required: false + unread_on: [retrobat] description: "Dokany user mode library" note: >- Loaded by name with every entry point resolved individually, and the diff --git a/emulators/xemu.yml b/emulators/xemu.yml index b61eff341..deb5cc35a 100644 --- a/emulators/xemu.yml +++ b/emulators/xemu.yml @@ -166,6 +166,7 @@ files: standalone_path: eeprom.bin aliases: [eeprom.bin] required: false + installed_on: [retrobat] has_builtin: true size: 256 validation: [size] @@ -188,7 +189,7 @@ files: - name: xbox_hdd.qcow2 mode: standalone required: false - installed_on: [batocera, emudeck, recalbox, retrodeck, rocknix] + installed_on: [batocera, emudeck, recalbox, retrobat, retrodeck, rocknix] config_key: sys.files.hdd_path found_by: content description: "Xbox hard disk image, 8 GB with the retail partition layout" @@ -201,7 +202,8 @@ files: (xemu-hdd-image 1.0, xbox_hdd.qcow2.zip), which carries its own unsigned dashboard and empty TDATA and UDATA folders. Batocera, Recalbox, RetroDECK, EmuDeck and ROCKNIX install that image themselves - and point hdd_path at it. + and point hdd_path at it. RetroBat's launcher writes the image it + carries when the save folder holds none. source_ref: "system/vl.c:3060-3074, ui/xemu-snapshots.c:156, config_spec.yml:362-366" - name: xbox_hdd.qcow2 diff --git a/tests/test_launcher_placement.py b/tests/test_launcher_placement.py index 36af88691..7020d450d 100644 --- a/tests/test_launcher_placement.py +++ b/tests/test_launcher_placement.py @@ -262,6 +262,36 @@ class FsUaeOnRetroPie(unittest.TestCase): self.assertEqual(held, [("kick13.rom", ["fs-uae"])]) +class XboxOnRetroBat(unittest.TestCase): + """RetroBat's launcher writes xemu's eeprom.bin and disk image into + saves/ and cxbx-reloaded's EEPROM.bin into its emulator folder, + and each Cxbx build reads its data from the folder it runs from + (Xemu.Generator.cs:82-113, Cxbx.Generator.cs:99-115, 158, 216-223).""" + + def test_nothing_lands_at_the_bios_root(self) -> None: + import json + + db_path = REPO_ROOT / "database.json" + if not db_path.exists(): + self.skipTest("database.json is not built") + db = json.loads(db_path.read_text(encoding="utf-8")) + with redirect_stdout(io.StringIO()): + manifest = generate_manifest( + "retrobat", str(REPO_ROOT / "platforms"), db, str(REPO_ROOT / "bios"), + str(REPO_ROOT / "platforms" / "_registry.yml"), + emulators_dir=str(REPO_ROOT / "emulators"), offline=True, + ) + at_root = {f["dest"].lower() for f in manifest["files"] if not f.get("root")} + # The launcher writes the two EEPROMs and the disk image, mounts an + # .iso with its own tool, and each Cxbx build reads keys.bin from + # its own folder. + self.assertFalse(at_root & {"eeprom.bin", "xbox_hdd.qcow2", "dokan2.dll", "keys.bin"}) + placed = {(f.get("root"), f["dest"]) for f in manifest["files"]} + self.assertIn(("emulators", "cxbx-reloaded/keys.bin"), placed) + self.assertIn(("emulators", "chihiro/EEPROM.bin"), placed) + self.assertNotIn(("emulators", "cxbx-reloaded/EEPROM.bin"), placed) + + PROGRAM = b"PROGRAM BINARY" PROGRAM_DATA = b"PROGRAM DATA"