mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 12:33:53 -06:00
fix: record what RetroBat writes for xemu and Cxbx
The xemu generator writes eeprom.bin and xbox_hdd.qcow2 into saves/<system> from its own resources and passes both in xemu.toml, copies chihiro_eeprom.bin between saves/chihiro and the emulator folder, and points the Chihiro snapshot store at saves/chihiro. The Cxbx generator runs each build from its emulator folder (chihiro, chihiro-ds, cxbx-reloaded, else cxbx-r), where it writes settings.ini, writes EEPROM.bin into cxbx-reloaded for an Xbox, and mounts an .iso with its own xbox-iso-vfs.exe after checking the Dokan 2 runtime. Nine records, read at emulatorLauncher ca486005. A program the launcher runs from its own folder is no launcher read left to collect. xemu-chihiro lists the two files it generates, chihiro_eeprom.bin and chihiro_snapshots.qcow2, as unsourceable.
This commit is contained in:
1 parent
9c46f7471d
commit
7f38954041
6 files changed
+563
-1
No files matched your search
@@ -117,6 +117,25 @@ files:
|
||||
description: "Base board configuration EEPROM"
|
||||
source_ref: "source hw/xbox/chihiro/chihiro.c:2336-2401, source system/vl.c:3221-3223"
|
||||
|
||||
- name: chihiro_eeprom.bin
|
||||
system: sega-chihiro
|
||||
required: false
|
||||
size: 256
|
||||
validation: [size]
|
||||
unsourceable: "generated with the debug key in the data directory when absent and written back by the machine"
|
||||
description: "Chihiro EEPROM"
|
||||
note: "A file carrying the retail key is renamed aside and a debug one generated in its place. Any other size than 256 bytes stops the machine with a message."
|
||||
source_ref: "source system/vl.c:2978-3067"
|
||||
|
||||
- name: chihiro_snapshots.qcow2
|
||||
system: sega-chihiro
|
||||
required: false
|
||||
config_key: chihiro.roms.snapshot_store_path
|
||||
unsourceable: "created empty when missing, then holds the VM snapshots"
|
||||
description: "Chihiro VM snapshot store"
|
||||
note: "Defaults to the data directory. A store that exists and cannot be opened leaves snapshots unavailable."
|
||||
source_ref: "source system/vl.c:2051-2110, source config_spec.yml:916-921"
|
||||
|
||||
- name: ver1305.bin
|
||||
system: sega-chihiro
|
||||
required: false
|
||||
|
||||
@@ -4069,6 +4069,69 @@ launchers:
|
||||
depends_on_option: core in capsimgCore, rom extension ".ipf", the target does not
|
||||
exist
|
||||
source_ref: "emulatorLauncher/Generators/LibRetro.Generator.cs:1018-1027, 2750"
|
||||
- emulator: chihiro
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"chihiro\")>"
|
||||
passes_to: "Settings::GetDataLocation, the folder holding settings.ini, which the\
|
||||
\ launcher writes beside the binary"
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:99-101, 158"
|
||||
- emulator: chihiro-gun
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"chihiro-ds\")>"
|
||||
passes_to: "Settings::GetDataLocation, the folder holding settings.ini, which the\
|
||||
\ launcher writes beside the binary"
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:104-106, 158"
|
||||
- emulator: cxbx-reloaded
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: "<AppConfig.GetFullPath(\"cxbx-reloaded\")>"
|
||||
passes_to: "Settings::GetDataLocation, the folder holding settings.ini, which the\
|
||||
\ launcher writes beside the binary"
|
||||
fails_when_missing: false
|
||||
depends_on_option: "neither core nor emulator is \"chihiro\" or \"chihiro-gun\"\
|
||||
, <AppConfig.GetFullPath(\"cxbx-r\")> when \"cxbx-reloaded\" is not set"
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:111-115, 158"
|
||||
- emulator: chihiro, chihiro-gun, cxbx-reloaded
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
names:
|
||||
- xbox-iso-vfs.exe
|
||||
case_insensitive: true
|
||||
search_dir: <emulatorLauncher folder>
|
||||
passes_to: exec
|
||||
fails_when_missing: xbox-iso-vfs is required and is not installed
|
||||
depends_on_option: rom extension ".iso"
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:25-30"
|
||||
- emulator: chihiro, chihiro-gun, cxbx-reloaded
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
names:
|
||||
- dokan2.dll
|
||||
case_insensitive: true
|
||||
search_dir: '%DokanLibrary2%'
|
||||
passes_to: "nothing passed: checked before xbox-iso-vfs.exe mounts the image"
|
||||
fails_when_missing: Dokan 2 is required and is not installed
|
||||
depends_on_option: rom extension ".iso"
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:25-26, 33-45"
|
||||
- emulator: cxbx-reloaded
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
names:
|
||||
- EEPROM.bin
|
||||
case_insensitive: true
|
||||
search_dir: "<AppConfig.GetFullPath(\"cxbx-reloaded\")>"
|
||||
passes_to: "written from the launcher's eeprom resource when absent, then its language\
|
||||
\ set: the emulator reads it from its data folder"
|
||||
fails_when_missing: "never missing: the launcher writes it"
|
||||
depends_on_option: system == "xbox"
|
||||
source_ref: "emulatorLauncher/Generators/Cxbx.Generator.cs:216-223"
|
||||
- emulator: demul
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
@@ -5590,6 +5653,43 @@ launchers:
|
||||
fails_when_missing: "warning '[Generator] Chihiro media board flash missing next\
|
||||
\ to the BIOS.'"
|
||||
source_ref: "emulatorLauncher/Generators/Xemu.Generator.cs:438-441"
|
||||
- emulator: xemu
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
names:
|
||||
- eeprom.bin
|
||||
- xbox_hdd.qcow2
|
||||
case_insensitive: true
|
||||
search_dir: saves/<system>
|
||||
passes_to: "xemu.toml [sys.files] eeprom_path, hdd_path; written from the launcher's\
|
||||
\ eeprom and xbox_hdd_qcow2 resources when absent, the disk image unzipped"
|
||||
fails_when_missing: "never missing: the launcher writes both"
|
||||
depends_on_option: "the saves folder is set and exists, not (emulator == \"xemu-chihiro\"\
|
||||
\ or system == \"chihiro\")"
|
||||
source_ref: "emulatorLauncher/Generators/Xemu.Generator.cs:48, 82-106, 278, 281"
|
||||
- emulator: xemu, xemu-chihiro
|
||||
build: standalone
|
||||
kind: copies
|
||||
names:
|
||||
- chihiro_eeprom.bin
|
||||
case_insensitive: true
|
||||
search_dir: saves/chihiro
|
||||
passes_to: <emulator>/chihiro_eeprom.bin, restored when the saved copy is newer
|
||||
or the emulator folder holds none, copied back after the run
|
||||
fails_when_missing: false
|
||||
depends_on_option: emulator == "xemu-chihiro" or system == "chihiro"
|
||||
source_ref: "emulatorLauncher/Generators/Xemu.Generator.cs:48, 480-520"
|
||||
- emulator: xemu, xemu-chihiro
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
names:
|
||||
- chihiro_snapshots.qcow2
|
||||
case_insensitive: true
|
||||
search_dir: saves/chihiro
|
||||
passes_to: "xemu.toml [chihiro.roms] snapshot_store_path, created by the emulator"
|
||||
fails_when_missing: false
|
||||
depends_on_option: emulator == "xemu-chihiro" or system == "chihiro"
|
||||
source_ref: "emulatorLauncher/Generators/Xemu.Generator.cs:48, 446-449"
|
||||
- emulator: xm6pro
|
||||
build: standalone
|
||||
kind: copies
|
||||
|
||||
@@ -1097,6 +1097,11 @@ LAUNCHER_READS_KEY = "_launcher_reads_not_held"
|
||||
# A package record names no file: it records what a package builds.
|
||||
_NAMELESS_KINDS = frozenset({"package"})
|
||||
|
||||
# The folder of the platform's own launcher, as its scraper spells it: a
|
||||
# program the launcher runs from there (RetroBat's xbox-iso-vfs.exe) is part
|
||||
# of the platform, never a file to collect.
|
||||
PLATFORM_OWN_FOLDERS = frozenset({"<emulatorLauncher folder>"})
|
||||
|
||||
|
||||
def launcher_file_names(record: dict) -> list[str]:
|
||||
"""The concrete file names a launcher record reads, in code order.
|
||||
@@ -1221,7 +1226,8 @@ def launcher_reads_not_held(
|
||||
amiga-os-130.rom that exists (Amiberry.Generator.cs:674-699). A copy
|
||||
whose source lies outside the BIOS directory brings a file the platform
|
||||
installs itself, from its own package or written by its own script
|
||||
(RetroPie's lr-vecx copies $md_inst/system.bin). A file handed to the
|
||||
(RetroPie's lr-vecx copies $md_inst/system.bin), and so does a program
|
||||
the launcher runs from its own folder. A file handed to the
|
||||
setting a reader's profile entry is read from is that entry's file,
|
||||
which the pack places under the launcher's name.
|
||||
"""
|
||||
@@ -1250,6 +1256,8 @@ def launcher_reads_not_held(
|
||||
base = str(config.get("base_destination") or "bios")
|
||||
if record.get("kind") == "copies" and not launcher_directories(record, base):
|
||||
continue
|
||||
if str(record.get("search_dir") or "") in PLATFORM_OWN_FOLDERS:
|
||||
continue
|
||||
settings = name_settings(record, names)
|
||||
|
||||
def by_setting(name: str) -> bool:
|
||||
|
||||
@@ -26,6 +26,7 @@ SOURCE_FILES = (
|
||||
f"{GENERATORS}/Bizhawk.Generator.cs",
|
||||
f"{GENERATORS}/Blastem.Generator.cs",
|
||||
f"{GENERATORS}/Citron.Generator.cs",
|
||||
f"{GENERATORS}/Cxbx.Generator.cs",
|
||||
f"{GENERATORS}/Demul.Generator.cs",
|
||||
f"{GENERATORS}/Desmume.Generator.cs",
|
||||
f"{GENERATORS}/Dolphin.Generator.cs",
|
||||
@@ -1358,6 +1359,287 @@ def xemu(sources: dict[str, Source]) -> list[Record]:
|
||||
return records
|
||||
|
||||
|
||||
def xemu_saves(sources: dict[str, Source]) -> list[Record]:
|
||||
"""The files the xemu generator keeps below the saves folder.
|
||||
|
||||
An Xbox gets eeprom.bin and xbox_hdd.qcow2 in saves/<system>, written
|
||||
from the launcher's own resources when absent, and their paths in
|
||||
xemu.toml. A Chihiro keeps chihiro_eeprom.bin there, copied into the
|
||||
emulator folder before the run and back after it, and its snapshot
|
||||
store.
|
||||
"""
|
||||
src = sources[f"{GENERATORS}/Xemu.Generator.cs"]
|
||||
chihiro = src.find(r'(_chihiro) = \(emulator == "([\w-]+)" \|\| system == "(\w+)"\);', "Chihiro switch")
|
||||
chihiro_when = f'emulator == "{chihiro.group(2)}" or system == "{chihiro.group(3)}"'
|
||||
saves = src.find(
|
||||
r'if \(!string\.IsNullOrEmpty\(AppConfig\["saves"\]\) && Directory\.Exists\(AppConfig\.GetFullPath\("saves"\)\)\)'
|
||||
r'\s*\{\s*string savePath = Path\.Combine\(AppConfig\.GetFullPath\("saves"\), system\);',
|
||||
"Xbox save folder",
|
||||
)
|
||||
eeprom = src.find(
|
||||
r'if \(!File\.Exists\(Path\.Combine\(savePath, "([^"]+)"\)\)\)\s*\{[^{}]*?'
|
||||
r'File\.WriteAllBytes\(Path\.Combine\(savePath, "\1"\), Properties\.Resources\.(\w+)\);\s*\}',
|
||||
"EEPROM written from resources",
|
||||
saves.end(),
|
||||
)
|
||||
hdd = src.find(
|
||||
r'if \(!File\.Exists\(Path\.Combine\(savePath, "([^"]+)"\)\)\)\s*\{[^{}]*?'
|
||||
r'File\.WriteAllBytes\(zipFile, Properties\.Resources\.(\w+)\);[^{}]*?Zip\.Extract\(zipFile, savePath\);[^{}]*?\}',
|
||||
"hard disk image written from resources",
|
||||
eeprom.end(),
|
||||
)
|
||||
eeprom_key = src.find(
|
||||
r'ini\.WriteValue\("([\w.]+)", "(eeprom_path)", "\'" \+ eepromPath', "eeprom_path write"
|
||||
)
|
||||
hdd_key = src.find(r'ini\.WriteValue\("([\w.]+)", "(hdd_path)", "\'" \+ hddPath', "hdd_path write")
|
||||
records = [
|
||||
_record(
|
||||
"xemu",
|
||||
"standalone",
|
||||
"fixed_name",
|
||||
[eeprom.group(1), hdd.group(1)],
|
||||
source_ref(
|
||||
(
|
||||
src.path,
|
||||
[
|
||||
src.lines(chihiro.start(), chihiro.end()),
|
||||
src.lines(saves.start(), hdd.end()),
|
||||
src.lines(eeprom_key.start(), eeprom_key.end()),
|
||||
src.lines(hdd_key.start(), hdd_key.end()),
|
||||
],
|
||||
)
|
||||
),
|
||||
case_insensitive=True,
|
||||
search_dir="saves/<system>",
|
||||
passes_to=(
|
||||
f"xemu.toml [{eeprom_key.group(1)}] {eeprom_key.group(2)}, {hdd_key.group(2)};"
|
||||
f" written from the launcher's {eeprom.group(2)} and {hdd.group(2)} resources"
|
||||
" when absent, the disk image unzipped"
|
||||
),
|
||||
fails_when_missing="never missing: the launcher writes both",
|
||||
depends_on_option=_joined("the saves folder is set and exists", f"not ({chihiro_when})"),
|
||||
)
|
||||
]
|
||||
|
||||
setup = src.find(r"private void SetupChihiroEeprom\(string path\)", "SetupChihiroEeprom")
|
||||
body = src.block_at(setup.end())
|
||||
folder = src.find(
|
||||
r'string savePath = Path\.Combine\(AppConfig\.GetFullPath\("saves"\), "(\w+)"\);',
|
||||
"Chihiro save folder",
|
||||
body[0],
|
||||
body[1],
|
||||
)
|
||||
pair = src.find(
|
||||
r'_chihiroEeprom = Path\.Combine\(path, "([^"]+)"\);\s*'
|
||||
r'_chihiroEepromSave = Path\.Combine\(savePath, "\1"\);',
|
||||
"Chihiro EEPROM pair",
|
||||
folder.end(),
|
||||
body[1],
|
||||
)
|
||||
save = src.find(r"private void SaveChihiroEeprom\(\)", "SaveChihiroEeprom")
|
||||
save_body = src.block_at(save.end())
|
||||
records.append(
|
||||
_record(
|
||||
"xemu, xemu-chihiro",
|
||||
"standalone",
|
||||
"copies",
|
||||
[pair.group(1)],
|
||||
source_ref(
|
||||
(
|
||||
src.path,
|
||||
[
|
||||
src.lines(chihiro.start(), chihiro.end()),
|
||||
src.statement_span(body),
|
||||
src.statement_span(save_body),
|
||||
],
|
||||
)
|
||||
),
|
||||
case_insensitive=True,
|
||||
search_dir=f"saves/{folder.group(1)}",
|
||||
passes_to=(
|
||||
f"<emulator>/{pair.group(1)}, restored when the saved copy is newer or the"
|
||||
" emulator folder holds none, copied back after the run"
|
||||
),
|
||||
fails_when_missing=False,
|
||||
depends_on_option=chihiro_when,
|
||||
)
|
||||
)
|
||||
|
||||
store = src.find(
|
||||
r'string savePath = Path\.Combine\(AppConfig\.GetFullPath\("saves"\), "(\w+)"\);\s*'
|
||||
r'if \(!Directory\.Exists\(savePath\)\) try \{ Directory\.CreateDirectory\(savePath\); \} catch \{ \}\s*'
|
||||
r'if \(Directory\.Exists\(savePath\)\)\s*'
|
||||
r'ini\.WriteValue\("([\w.]+)", "(\w+)", "\'" \+ Path\.Combine\(savePath, "([^"]+)"\)',
|
||||
"Chihiro snapshot store",
|
||||
)
|
||||
records.append(
|
||||
_record(
|
||||
"xemu, xemu-chihiro",
|
||||
"standalone",
|
||||
"fixed_name",
|
||||
[store.group(4)],
|
||||
source_ref((src.path, [src.lines(chihiro.start(), chihiro.end()),
|
||||
src.lines(store.start(), store.end())])),
|
||||
case_insensitive=True,
|
||||
search_dir=f"saves/{store.group(1)}",
|
||||
passes_to=f"xemu.toml [{store.group(2)}] {store.group(3)}, created by the emulator",
|
||||
fails_when_missing=False,
|
||||
depends_on_option=chihiro_when,
|
||||
)
|
||||
)
|
||||
return records
|
||||
|
||||
|
||||
# What the Cxbx generator hands each build: the data folder is the one its
|
||||
# settings.ini sits in (Cxbx-Reloaded Settings::FindSettingsLocation), which
|
||||
# the launcher writes beside the binary.
|
||||
CXBX_DATA_FOLDER = "Settings::GetDataLocation"
|
||||
|
||||
|
||||
def cxbx(sources: dict[str, Source]) -> list[Record]:
|
||||
"""The folder each Cxbx build runs from, and the EEPROM written there.
|
||||
|
||||
The generator picks the emulator folder by core or emulator name, opens
|
||||
settings.ini in it, and for an Xbox writes EEPROM.bin into the
|
||||
cxbx-reloaded folder from its own resource when absent.
|
||||
"""
|
||||
src = sources[f"{GENERATORS}/Cxbx.Generator.cs"]
|
||||
named = src.find_all(
|
||||
r'(?:else )?if \(\(core != null && core == "([\w-]+)"\) \|\| '
|
||||
r'\(emulator != null && emulator == "\1"\)\)\s*\{\s*path = AppConfig\.GetFullPath\("([\w-]+)"\);',
|
||||
"emulator folder by name",
|
||||
)
|
||||
fallbacks = src.find_all(
|
||||
r'if \(string\.IsNullOrEmpty\(path\)\)\s*path = AppConfig\.GetFullPath\("([\w-]+)"\);',
|
||||
"default emulator folder",
|
||||
)
|
||||
settings = src.find(
|
||||
r'IniFile\.FromFile\(Path\.Combine\(path, "(settings\.ini)"\)', "settings.ini beside the binary"
|
||||
)
|
||||
settings_span = src.lines(settings.start(), settings.end())
|
||||
passes_to = (
|
||||
f"{CXBX_DATA_FOLDER}, the folder holding {settings.group(1)},"
|
||||
" which the launcher writes beside the binary"
|
||||
)
|
||||
records = []
|
||||
for match in named:
|
||||
records.append(
|
||||
_record(
|
||||
match.group(1),
|
||||
"standalone",
|
||||
"passes_path",
|
||||
[],
|
||||
source_ref((src.path, [src.lines(match.start(), match.end()), settings_span])),
|
||||
search_dir=f'<AppConfig.GetFullPath("{match.group(2)}")>',
|
||||
passes_to=passes_to,
|
||||
fails_when_missing=False,
|
||||
)
|
||||
)
|
||||
first, *rest = fallbacks
|
||||
others = "neither core nor emulator is " + " or ".join(f'"{m.group(1)}"' for m in named)
|
||||
records.append(
|
||||
_record(
|
||||
first.group(1),
|
||||
"standalone",
|
||||
"passes_path",
|
||||
[],
|
||||
source_ref(
|
||||
(
|
||||
src.path,
|
||||
[src.lines(first.start(), first.end()),
|
||||
*(src.lines(m.start(), m.end()) for m in rest), settings_span],
|
||||
)
|
||||
),
|
||||
search_dir=f'<AppConfig.GetFullPath("{first.group(1)}")>',
|
||||
passes_to=passes_to,
|
||||
fails_when_missing=False,
|
||||
depends_on_option=_joined(
|
||||
others,
|
||||
*(f'<AppConfig.GetFullPath("{m.group(1)}")> when "{first.group(1)}" is not set'
|
||||
for m in rest),
|
||||
),
|
||||
)
|
||||
)
|
||||
records.extend(_cxbx_mount(src, [*(m.group(1) for m in named), first.group(1)]))
|
||||
eeprom = src.find(
|
||||
r'if \(system == "(\w+)"\)\s*\{\s*string (\w+) = Path\.Combine\(AppConfig\.GetFullPath\("([\w-]+)"\), "([^"]+)"\);'
|
||||
r'\s*if \(!File\.Exists\(\2\)\)\s*File\.WriteAllBytes\(\2, Properties\.Resources\.(\w+)\);'
|
||||
r'\s*WriteXboxEEPROM\(\2\);\s*\}',
|
||||
"EEPROM written from resources",
|
||||
)
|
||||
records.append(
|
||||
_record(
|
||||
eeprom.group(3),
|
||||
"standalone",
|
||||
"fixed_name",
|
||||
[eeprom.group(4)],
|
||||
source_ref((src.path, [src.lines(eeprom.start(), eeprom.end())])),
|
||||
case_insensitive=True,
|
||||
search_dir=f'<AppConfig.GetFullPath("{eeprom.group(3)}")>',
|
||||
passes_to=(
|
||||
f"written from the launcher's {eeprom.group(5)} resource when absent,"
|
||||
" then its language set: the emulator reads it from its data folder"
|
||||
),
|
||||
fails_when_missing="never missing: the launcher writes it",
|
||||
depends_on_option=f'system == "{eeprom.group(1)}"',
|
||||
)
|
||||
)
|
||||
return records
|
||||
|
||||
|
||||
def _cxbx_mount(src: Source, emulators: list[str]) -> list[Record]:
|
||||
"""What the generator needs to mount an .iso before Cxbx opens it: its
|
||||
own xbox-iso-vfs.exe, run from the launcher's folder, and the Dokan 2
|
||||
runtime installed on the system."""
|
||||
iso = src.find(
|
||||
r'if \(Path\.GetExtension\(rom\)\.ToLowerInvariant\(\) != "(\.\w+)"\)\s*return rom;',
|
||||
"mount for disc images only",
|
||||
)
|
||||
vfs = src.find(
|
||||
r'string (\w+) = Path\.Combine\(Path\.GetDirectoryName\(typeof\(\w+\)\.Assembly\.Location\), "([^"]+)"\);'
|
||||
r'\s*if \(!File\.Exists\(\1\)\)\s*throw new ApplicationException\("([^"]+)"\);',
|
||||
"mount tool beside the launcher",
|
||||
iso.end(),
|
||||
)
|
||||
dokan = src.find(
|
||||
r'string (\w+) = Environment\.GetEnvironmentVariable\("(\w+)"\);.*?'
|
||||
r'\1 = Path\.Combine\(\1, "([^"]+)"\);\s*if \(!File\.Exists\(\1\)\)\s*\{[^{}]*?'
|
||||
r'throw new ApplicationException\("([^"]+)"\);\s*\}',
|
||||
"Dokan runtime check",
|
||||
vfs.end(),
|
||||
flags=re.S,
|
||||
)
|
||||
iso_span = src.lines(iso.start(), iso.end())
|
||||
when = f'rom extension "{iso.group(1)}"'
|
||||
emulator = ", ".join(emulators)
|
||||
return [
|
||||
_record(
|
||||
emulator,
|
||||
"standalone",
|
||||
"fixed_name",
|
||||
[vfs.group(2)],
|
||||
source_ref((src.path, [iso_span, src.lines(vfs.start(), vfs.end())])),
|
||||
case_insensitive=True,
|
||||
search_dir="<emulatorLauncher folder>",
|
||||
passes_to="exec",
|
||||
fails_when_missing=vfs.group(3),
|
||||
depends_on_option=when,
|
||||
),
|
||||
_record(
|
||||
emulator,
|
||||
"standalone",
|
||||
"fixed_name",
|
||||
[dokan.group(3)],
|
||||
source_ref((src.path, [iso_span, src.lines(dokan.start(), dokan.end())])),
|
||||
case_insensitive=True,
|
||||
search_dir=f"%{dokan.group(2)}%",
|
||||
passes_to=f"nothing passed: checked before {vfs.group(2)} mounts the image",
|
||||
fails_when_missing=dokan.group(4),
|
||||
depends_on_option=when,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def openmsx(sources: dict[str, Source]) -> list[Record]:
|
||||
src = sources[f"{GENERATORS}/OpenMSX.Generator.cs"]
|
||||
table = src.find(
|
||||
@@ -3521,6 +3803,7 @@ EXTRACTORS: tuple[Callable[[dict[str, Source]], list[Record]], ...] = (
|
||||
blastem,
|
||||
bsyndrome,
|
||||
capsimg,
|
||||
cxbx,
|
||||
demul,
|
||||
desmume,
|
||||
dolphin,
|
||||
@@ -3551,6 +3834,7 @@ EXTRACTORS: tuple[Callable[[dict[str, Source]], list[Record]], ...] = (
|
||||
value_folders,
|
||||
winuae,
|
||||
xemu,
|
||||
xemu_saves,
|
||||
xm6pro,
|
||||
xroar,
|
||||
)
|
||||
|
||||
@@ -77,6 +77,8 @@ LAUNCHERS = [
|
||||
_record("setemu", "copies", ["user.sf2"]),
|
||||
_record("caseemu", "fixed_name", ["mixed.rom"]),
|
||||
_record("foldemu", "fixed_name", ["MIXED.rom"], case_insensitive=True),
|
||||
_record("toolemu", "fixed_name", ["tool.exe"], search_dir="<emulatorLauncher folder>",
|
||||
passes_to="exec"),
|
||||
_record("labelemu", "core_option", ["labelled.rom (CDZ)"]),
|
||||
]
|
||||
|
||||
@@ -160,6 +162,11 @@ class LauncherGapTest(unittest.TestCase):
|
||||
)
|
||||
return {(r["platform"], r["name"]): r for r in rows}
|
||||
|
||||
def test_a_program_of_the_launcher_itself_is_not_reported(self) -> None:
|
||||
"""RetroBat runs its own xbox-iso-vfs.exe to mount an Xbox disc
|
||||
image: part of the platform, no file to collect."""
|
||||
self.assertNotIn("tool.exe", {name for _, name in self._rows()})
|
||||
|
||||
def test_a_held_name_is_not_reported(self) -> None:
|
||||
names = {name for _, name in self._rows()}
|
||||
self.assertNotIn("held.bin", names)
|
||||
|
||||
@@ -1103,6 +1103,150 @@ class FilesNeededTogether(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
XEMU_SAVES = """
|
||||
public override ProcessStartInfo Generate(string system, string emulator, string core, string rom)
|
||||
{
|
||||
_chihiro = (emulator == "xemu-chihiro" || system == "chihiro");
|
||||
if (!string.IsNullOrEmpty(AppConfig["saves"]) && Directory.Exists(AppConfig.GetFullPath("saves")))
|
||||
{
|
||||
string savePath = Path.Combine(AppConfig.GetFullPath("saves"), system);
|
||||
if (!_chihiro)
|
||||
{
|
||||
if (!File.Exists(Path.Combine(savePath, "eeprom.bin")))
|
||||
{
|
||||
File.WriteAllBytes(Path.Combine(savePath, "eeprom.bin"), Properties.Resources.eeprom);
|
||||
}
|
||||
if (!File.Exists(Path.Combine(savePath, "xbox_hdd.qcow2")))
|
||||
{
|
||||
string zipFile = Path.Combine(savePath, "xbox_hdd.qcow2.zip");
|
||||
File.WriteAllBytes(zipFile, Properties.Resources.xbox_hdd_qcow2);
|
||||
Zip.Extract(zipFile, savePath);
|
||||
File.Delete(zipFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupTOMLConfiguration(string eepromPath, string hddPath)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(eepromPath))
|
||||
ini.WriteValue("sys.files", "eeprom_path", "'" + eepromPath + "'");
|
||||
if (!string.IsNullOrEmpty(hddPath))
|
||||
ini.WriteValue("sys.files", "hdd_path", "'" + hddPath + "'");
|
||||
}
|
||||
|
||||
private void SetupChihiroConfiguration()
|
||||
{
|
||||
string savePath = Path.Combine(AppConfig.GetFullPath("saves"), "chihiro");
|
||||
if (!Directory.Exists(savePath)) try { Directory.CreateDirectory(savePath); } catch { }
|
||||
if (Directory.Exists(savePath))
|
||||
ini.WriteValue("chihiro.roms", "snapshot_store_path", "'" + Path.Combine(savePath, "chihiro_snapshots.qcow2") + "'");
|
||||
}
|
||||
|
||||
private void SetupChihiroEeprom(string path)
|
||||
{
|
||||
string savePath = Path.Combine(AppConfig.GetFullPath("saves"), "chihiro");
|
||||
_chihiroEeprom = Path.Combine(path, "chihiro_eeprom.bin");
|
||||
_chihiroEepromSave = Path.Combine(savePath, "chihiro_eeprom.bin");
|
||||
}
|
||||
|
||||
private void SaveChihiroEeprom()
|
||||
{
|
||||
if (File.Exists(_chihiroEeprom))
|
||||
File.Copy(_chihiroEeprom, _chihiroEepromSave, true);
|
||||
}
|
||||
"""
|
||||
|
||||
CXBX = """
|
||||
private string MountIso(string rom)
|
||||
{
|
||||
if (Path.GetExtension(rom).ToLowerInvariant() != ".iso")
|
||||
return rom;
|
||||
string xboxIsoVfsPath = Path.Combine(Path.GetDirectoryName(typeof(Installer).Assembly.Location), "xbox-iso-vfs.exe");
|
||||
if (!File.Exists(xboxIsoVfsPath))
|
||||
throw new ApplicationException("xbox-iso-vfs is required and is not installed");
|
||||
string dokan = Environment.GetEnvironmentVariable("DokanLibrary2");
|
||||
dokan = Path.Combine(dokan, "dokan2.dll");
|
||||
if (!File.Exists(dokan))
|
||||
{
|
||||
throw new ApplicationException("Dokan 2 is required and is not installed");
|
||||
}
|
||||
}
|
||||
|
||||
public override ProcessStartInfo Generate(string system, string emulator, string core, string rom)
|
||||
{
|
||||
string path = null;
|
||||
if ((core != null && core == "chihiro") || (emulator != null && emulator == "chihiro"))
|
||||
{
|
||||
path = AppConfig.GetFullPath("chihiro");
|
||||
}
|
||||
else if ((core != null && core == "chihiro-gun") || (emulator != null && emulator == "chihiro-gun"))
|
||||
{
|
||||
path = AppConfig.GetFullPath("chihiro-ds");
|
||||
}
|
||||
if (string.IsNullOrEmpty(path))
|
||||
path = AppConfig.GetFullPath("cxbx-reloaded");
|
||||
if (string.IsNullOrEmpty(path))
|
||||
path = AppConfig.GetFullPath("cxbx-r");
|
||||
using (var ini = IniFile.FromFile(Path.Combine(path, "settings.ini"), IniOptions.KeepEmptyValues))
|
||||
{
|
||||
}
|
||||
if (system == "xbox")
|
||||
{
|
||||
string eeprom = Path.Combine(AppConfig.GetFullPath("cxbx-reloaded"), "EEPROM.bin");
|
||||
if (!File.Exists(eeprom))
|
||||
File.WriteAllBytes(eeprom, Properties.Resources.eeprom);
|
||||
|
||||
WriteXboxEEPROM(eeprom);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class XboxFilesTheLauncherWrites(unittest.TestCase):
|
||||
def test_xemu_keeps_its_eeprom_and_disk_below_saves(self):
|
||||
records = rl.xemu_saves(_sources(**{f"{G}/Xemu.Generator.cs": XEMU_SAVES}))
|
||||
self.assertEqual(
|
||||
[(r["emulator"], r["kind"], r["names"], r["search_dir"], r["source_ref"])
|
||||
for r in records],
|
||||
[
|
||||
("xemu", "fixed_name", ["eeprom.bin", "xbox_hdd.qcow2"], "saves/<system>",
|
||||
f"{G}/Xemu.Generator.cs:3-19, 27-29"),
|
||||
("xemu, xemu-chihiro", "copies", ["chihiro_eeprom.bin"], "saves/chihiro",
|
||||
f"{G}/Xemu.Generator.cs:3, 40-51"),
|
||||
("xemu, xemu-chihiro", "fixed_name", ["chihiro_snapshots.qcow2"], "saves/chihiro",
|
||||
f"{G}/Xemu.Generator.cs:3, 34-37"),
|
||||
],
|
||||
)
|
||||
self.assertIn("eeprom_path, hdd_path", records[0]["passes_to"])
|
||||
self.assertIn('not (emulator == "xemu-chihiro" or system == "chihiro")',
|
||||
records[0]["depends_on_option"])
|
||||
|
||||
def test_cxbx_runs_from_its_folder_and_gets_the_eeprom_there(self):
|
||||
records = rl.cxbx(_sources(**{f"{G}/Cxbx.Generator.cs": CXBX}))
|
||||
self.assertEqual(
|
||||
[(r["emulator"], r["kind"], r["names"], r["search_dir"], r["source_ref"])
|
||||
for r in records],
|
||||
[
|
||||
("chihiro", "passes_path", [], '<AppConfig.GetFullPath("chihiro")>',
|
||||
f"{G}/Cxbx.Generator.cs:19-21, 31"),
|
||||
("chihiro-gun", "passes_path", [], '<AppConfig.GetFullPath("chihiro-ds")>',
|
||||
f"{G}/Cxbx.Generator.cs:23-25, 31"),
|
||||
("cxbx-reloaded", "passes_path", [], '<AppConfig.GetFullPath("cxbx-reloaded")>',
|
||||
f"{G}/Cxbx.Generator.cs:27-31"),
|
||||
("chihiro, chihiro-gun, cxbx-reloaded", "fixed_name", ["xbox-iso-vfs.exe"],
|
||||
"<emulatorLauncher folder>", f"{G}/Cxbx.Generator.cs:3-7"),
|
||||
("chihiro, chihiro-gun, cxbx-reloaded", "fixed_name", ["dokan2.dll"],
|
||||
"%DokanLibrary2%", f"{G}/Cxbx.Generator.cs:3-4, 8-13"),
|
||||
("cxbx-reloaded", "fixed_name", ["EEPROM.bin"],
|
||||
'<AppConfig.GetFullPath("cxbx-reloaded")>', f"{G}/Cxbx.Generator.cs:34-41"),
|
||||
],
|
||||
)
|
||||
self.assertTrue(all(r["passes_to"].startswith(rl.CXBX_DATA_FOLDER) for r in records[:3]))
|
||||
self.assertEqual(records[3]["passes_to"], "exec")
|
||||
self.assertEqual(records[5]["depends_on_option"], 'system == "xbox"')
|
||||
|
||||
|
||||
class HelpersAndCopies(unittest.TestCase):
|
||||
def test_blastem_one_record_per_helper_call(self):
|
||||
records = rl.blastem(_sources(**{f"{G}/Blastem.Generator.cs": BLASTEM}))
|
||||
|
||||
Reference in new issue
Block a user