mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-16 16:33:27 -05:00
fix: place libretro dolphin files where it reads
This commit is contained in:
1 parent
48b00730ff
commit
b173a2a851
9 files changed
+215
-81
No files matched your search
+37
-12
@@ -12,10 +12,13 @@ cores:
|
||||
- dolphin
|
||||
systems: [nintendo-gamecube, nintendo-wii, sega-triforce]
|
||||
|
||||
# File paths are relative to Dolphin User directory:
|
||||
# Standalone: User/GC/ and User/Wii/
|
||||
# Libretro (RetroArch): system/dolphin-emu/GC/ and system/dolphin-emu/Wii/
|
||||
# Sys/ is checked as fallback when not found in User/.
|
||||
# path: is where the libretro core reads a file, standalone_path: where the
|
||||
# standalone app reads it under its User directory.
|
||||
# Libretro: User is <save>/User, Sys is <system>/dolphin-emu/Sys
|
||||
# (Source/Core/DolphinLibretro/Boot.cpp:248-254). The GC ROMs and
|
||||
# segaboot.gcm fall back to Sys (Source/Core/Core/Config/MainSettings.cpp:761-768,
|
||||
# Source/Core/Core/HW/DVD/AMMediaboard.cpp:500-513); the Wii and GBA files
|
||||
# are read under User only.
|
||||
|
||||
pack_structure:
|
||||
libretro: "dolphin-emu"
|
||||
@@ -32,7 +35,8 @@ files:
|
||||
# Checked in User/GC/<region>/ then Sys/GC/<region>/
|
||||
# Regions: USA, EUR, JAP (legacy), JPN, DEV
|
||||
- name: "IPL.bin"
|
||||
path: "GC/USA/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/USA/IPL.bin"
|
||||
standalone_path: "GC/USA/IPL.bin"
|
||||
region: [north-america]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -41,7 +45,8 @@ files:
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:139, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:108"
|
||||
|
||||
- name: "IPL.bin"
|
||||
path: "GC/EUR/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/EUR/IPL.bin"
|
||||
standalone_path: "GC/EUR/IPL.bin"
|
||||
region: [europe]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -50,7 +55,8 @@ files:
|
||||
source_ref: "Source/Core/Core/Config/MainSettings.cpp:776-782"
|
||||
|
||||
- name: "IPL.bin"
|
||||
path: "GC/JAP/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/JAP/IPL.bin"
|
||||
standalone_path: "GC/JAP/IPL.bin"
|
||||
region: [japan]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -63,7 +69,8 @@ files:
|
||||
# Dolphin ships free replacement ROMs, but real dumps improve accuracy.
|
||||
# Searched in: User/GC/ then Sys/GC/
|
||||
- name: "dsp_rom.bin"
|
||||
path: "GC/dsp_rom.bin"
|
||||
path: "dolphin-emu/Sys/GC/dsp_rom.bin"
|
||||
standalone_path: "GC/dsp_rom.bin"
|
||||
size: 8192
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -74,7 +81,8 @@ files:
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117, Source/Core/Core/DSP/DSPCore.cpp:28-102"
|
||||
|
||||
- name: "dsp_coef.bin"
|
||||
path: "GC/dsp_coef.bin"
|
||||
path: "dolphin-emu/Sys/GC/dsp_coef.bin"
|
||||
standalone_path: "GC/dsp_coef.bin"
|
||||
size: 4096
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -89,7 +97,8 @@ files:
|
||||
# If IPL dump is present, fonts are extracted from it instead (preferred).
|
||||
# Searched in: Sys/GC/
|
||||
- name: "font_western.bin"
|
||||
path: "GC/font_western.bin"
|
||||
path: "dolphin-emu/Sys/GC/font_western.bin"
|
||||
standalone_path: "GC/font_western.bin"
|
||||
size: 9589
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -97,7 +106,8 @@ files:
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:133, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:130,202-239"
|
||||
|
||||
- name: "font_japanese.bin"
|
||||
path: "GC/font_japanese.bin"
|
||||
path: "dolphin-emu/Sys/GC/font_japanese.bin"
|
||||
standalone_path: "GC/font_japanese.bin"
|
||||
size: 303693
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -107,7 +117,8 @@ files:
|
||||
# -- Triforce firmware --
|
||||
# Loaded from User/Triforce/ only, no Sys fallback.
|
||||
- name: "segaboot.gcm"
|
||||
path: "Triforce/segaboot.gcm"
|
||||
path: "dolphin-emu/Sys/Triforce/segaboot.gcm"
|
||||
standalone_path: "Triforce/segaboot.gcm"
|
||||
system: sega-triforce
|
||||
required: true
|
||||
note: "SegaBoot, the Triforce system disc image. Read on every Triforce boot, min(size, 2 MiB) copied into the firmware buffer, nothing validated"
|
||||
@@ -118,6 +129,8 @@ files:
|
||||
# Loaded from User/GBA/gba_bios.bin (no Sys fallback).
|
||||
- name: "gba_bios.bin"
|
||||
path: "GBA/gba_bios.bin"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "GBA BIOS for GC-GBA link feature (uses integrated mGBA). Path configurable in settings"
|
||||
@@ -129,6 +142,8 @@ files:
|
||||
|
||||
- name: "SYSCONF"
|
||||
path: "Wii/shared2/sys/SYSCONF"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "Wii system configuration. Auto-generated by Dolphin, can be imported from NAND backup"
|
||||
@@ -136,6 +151,8 @@ files:
|
||||
|
||||
- name: "setting.txt"
|
||||
path: "Wii/title/00000001/00000002/data/setting.txt"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
size: 256
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -161,6 +178,8 @@ files:
|
||||
# -- Wii SD Card Image --
|
||||
- name: "WiiSD.raw"
|
||||
path: "Load/WiiSD.raw"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "Virtual SD card image for Wii homebrew. Auto-created by Dolphin, supports SD/SDHC up to 4GB"
|
||||
@@ -186,6 +205,8 @@ files:
|
||||
# -- NAND Certificates (auto-extracted) --
|
||||
- name: "clientca.pem"
|
||||
path: "Wii/clientca.pem"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "SSL client certificate. Auto-extracted from IOS13 content during NAND import"
|
||||
@@ -193,6 +214,8 @@ files:
|
||||
|
||||
- name: "clientcakey.pem"
|
||||
path: "Wii/clientcakey.pem"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "SSL client private key. Auto-extracted from IOS13 content during NAND import"
|
||||
@@ -200,6 +223,8 @@ files:
|
||||
|
||||
- name: "rootca.pem"
|
||||
path: "Wii/rootca.pem"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "SSL root CA certificate. Auto-extracted from IOS13 content during NAND import"
|
||||
|
||||
+24
-8
@@ -13,7 +13,10 @@ systems: [nintendo-gamecube, nintendo-wii]
|
||||
|
||||
# Ishiiruka is a performance-focused Dolphin fork (custom GPU backends, async shader compilation).
|
||||
# BIOS/firmware handling identical to Dolphin 5.0-era code.
|
||||
# Libretro core uses "dolphin-emu" subdirectory, not "ishiiruka".
|
||||
# Libretro: User is <save>/User, Sys is <system>/dolphin-emu/Sys
|
||||
# (Source/Core/DolphinLibretro/Boot.cpp:43-49). path: is where the libretro
|
||||
# core reads a file (the GC ROMs fall back to Sys), standalone_path: where
|
||||
# the standalone app reads it under its User directory.
|
||||
# Core options use "ishiiruka_" prefix (ishiiruka_dsp_hle, ishiiruka_efb_scale, etc.)
|
||||
|
||||
pack_structure:
|
||||
@@ -30,7 +33,8 @@ files:
|
||||
# Region-specific, placed in GC/<region>/IPL.bin
|
||||
# Checked in User/GC/<region>/ then Sys/GC/<region>/
|
||||
- name: "IPL.bin"
|
||||
path: "GC/USA/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/USA/IPL.bin"
|
||||
standalone_path: "GC/USA/IPL.bin"
|
||||
region: [north-america]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -39,7 +43,8 @@ files:
|
||||
source_ref: "Source/Core/Core/ConfigManager.cpp:876-883, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:105"
|
||||
|
||||
- name: "IPL.bin"
|
||||
path: "GC/EUR/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/EUR/IPL.bin"
|
||||
standalone_path: "GC/EUR/IPL.bin"
|
||||
region: [europe]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -48,7 +53,8 @@ files:
|
||||
source_ref: "Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:185"
|
||||
|
||||
- name: "IPL.bin"
|
||||
path: "GC/JAP/IPL.bin"
|
||||
path: "dolphin-emu/Sys/GC/JAP/IPL.bin"
|
||||
standalone_path: "GC/JAP/IPL.bin"
|
||||
region: [japan]
|
||||
size: 2097152
|
||||
required: false
|
||||
@@ -60,7 +66,8 @@ files:
|
||||
# Used by DSP LLE for accurate audio. dsp_coef.bin also used by HLE for polyphase resampling.
|
||||
# Searched in: User/GC/ then Sys/GC/
|
||||
- name: "dsp_rom.bin"
|
||||
path: "GC/dsp_rom.bin"
|
||||
path: "dolphin-emu/Sys/GC/dsp_rom.bin"
|
||||
standalone_path: "GC/dsp_rom.bin"
|
||||
size: 8192
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -71,7 +78,8 @@ files:
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67, Source/Core/Core/DSP/DSPCore.cpp:38-105"
|
||||
|
||||
- name: "dsp_coef.bin"
|
||||
path: "GC/dsp_coef.bin"
|
||||
path: "dolphin-emu/Sys/GC/dsp_coef.bin"
|
||||
standalone_path: "GC/dsp_coef.bin"
|
||||
size: 4096
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -86,7 +94,8 @@ files:
|
||||
# If IPL dump is present, fonts are extracted from it instead (preferred).
|
||||
# Loaded from: Sys/GC/
|
||||
- name: "font_western.bin"
|
||||
path: "GC/font_western.bin"
|
||||
path: "dolphin-emu/Sys/GC/font_western.bin"
|
||||
standalone_path: "GC/font_western.bin"
|
||||
size: 9589
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -94,7 +103,8 @@ files:
|
||||
source_ref: "Source/Core/Common/CommonPaths.h:109, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:123,193-227"
|
||||
|
||||
- name: "font_japanese.bin"
|
||||
path: "GC/font_japanese.bin"
|
||||
path: "dolphin-emu/Sys/GC/font_japanese.bin"
|
||||
standalone_path: "GC/font_japanese.bin"
|
||||
size: 303693
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -113,6 +123,8 @@ files:
|
||||
# Auto-generated/managed by Dolphin's Wii emulation.
|
||||
- name: "SYSCONF"
|
||||
path: "Wii/shared2/sys/SYSCONF"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "Wii system configuration. Auto-generated, can be imported from NAND backup"
|
||||
@@ -120,6 +132,8 @@ files:
|
||||
|
||||
- name: "setting.txt"
|
||||
path: "Wii/title/00000001/00000002/data/setting.txt"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
size: 256
|
||||
required: false
|
||||
hle_fallback: true
|
||||
@@ -129,6 +143,8 @@ files:
|
||||
# -- Wii SD Card Image --
|
||||
- name: "sd.raw"
|
||||
path: "Wii/sd.raw"
|
||||
load_from:
|
||||
libretro: save_dir
|
||||
required: false
|
||||
hle_fallback: true
|
||||
note: "Virtual SD card image for Wii homebrew. Auto-created (128MB) if not present"
|
||||
|
||||
@@ -433,7 +433,25 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"load_from": {
|
||||
"type": "string"
|
||||
"description": "Where the emulator reads the file when not from the system directory; keyed by build when the libretro and standalone builds read it from different places.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"minProperties": 1,
|
||||
"properties": {
|
||||
"libretro": {
|
||||
"type": "string"
|
||||
},
|
||||
"standalone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"priority": {
|
||||
"description": "Preference order among the BIOS a system accepts, lowest first. DuckStation's FindBIOSImageInDirectory keeps the image whose priority is lower; a search list the code walks in order maps onto it as 1, 2, 3.",
|
||||
|
||||
+31
-34
@@ -1303,33 +1303,8 @@ def generate_emulator_pack(
|
||||
db,
|
||||
standalone,
|
||||
)
|
||||
# A tree only one build reads follows that build, like a file.
|
||||
for dd in filter_files_by_mode(
|
||||
profile.get("data_directories", []), standalone
|
||||
):
|
||||
ref_key = dd.get("ref", "")
|
||||
if not ref_key or not data_registry or ref_key not in data_registry:
|
||||
if ref_key:
|
||||
data_dir_notices.append(ref_key)
|
||||
continue
|
||||
entry = data_registry[ref_key]
|
||||
local_cache = entry.get("local_cache", "")
|
||||
if not local_cache or not os.path.isdir(local_cache):
|
||||
data_dir_notices.append(ref_key)
|
||||
continue
|
||||
dd_dest = dd.get("destination", "")
|
||||
if pack_structure:
|
||||
mode_key = "standalone" if standalone else "libretro"
|
||||
prefix = pack_structure.get(mode_key, "")
|
||||
if prefix:
|
||||
dd_dest = f"{prefix}/{dd_dest}" if dd_dest else prefix
|
||||
total_files += _pack_data_tree(
|
||||
zf, local_cache, dd_dest, seen_destinations, seen_parents, seen_lower
|
||||
)
|
||||
|
||||
if not files:
|
||||
print(f" No files needed for {profile.get('emulator', emu_name)}")
|
||||
continue
|
||||
|
||||
# Collect archives as atomic units
|
||||
archives: set[str] = set()
|
||||
@@ -1393,7 +1368,7 @@ def generate_emulator_pack(
|
||||
continue
|
||||
if fe.get("archive"):
|
||||
continue
|
||||
dest = _resolve_destination(fe, pack_structure, standalone)
|
||||
dest = _resolve_destination(fe, standalone)
|
||||
if not dest:
|
||||
continue
|
||||
if region_drops and dest in region_drops:
|
||||
@@ -1541,6 +1516,33 @@ def generate_emulator_pack(
|
||||
packed_at[dest.lower()] = local_path
|
||||
total_files += 1
|
||||
|
||||
# The trees after the files, as in a platform pack: a dump the
|
||||
# profile declares wins over the copy a tree bundles at the same
|
||||
# path (Dolphin's real dsp_rom.bin over Sys/GC's free one).
|
||||
# A tree only one build reads follows that build, like a file.
|
||||
for dd in filter_files_by_mode(
|
||||
profile.get("data_directories", []), standalone
|
||||
):
|
||||
ref_key = dd.get("ref", "")
|
||||
if not ref_key or not data_registry or ref_key not in data_registry:
|
||||
if ref_key:
|
||||
data_dir_notices.append(ref_key)
|
||||
continue
|
||||
entry = data_registry[ref_key]
|
||||
local_cache = entry.get("local_cache", "")
|
||||
if not local_cache or not os.path.isdir(local_cache):
|
||||
data_dir_notices.append(ref_key)
|
||||
continue
|
||||
dd_dest = dd.get("destination", "")
|
||||
if pack_structure:
|
||||
mode_key = "standalone" if standalone else "libretro"
|
||||
prefix = pack_structure.get(mode_key, "")
|
||||
if prefix:
|
||||
dd_dest = f"{prefix}/{dd_dest}" if dd_dest else prefix
|
||||
total_files += _pack_data_tree(
|
||||
zf, local_cache, dd_dest, seen_destinations, seen_parents, seen_lower
|
||||
)
|
||||
|
||||
# Remove empty ZIP (no files packed and no missing = nothing to ship)
|
||||
if total_files == 0 and not (missing_files or rejected_files or instruction_files or unsourceable_files):
|
||||
os.unlink(zip_path)
|
||||
@@ -1884,7 +1886,6 @@ def generate_md5_pack(
|
||||
for fe in system.get("files", []):
|
||||
plat_file_index.setdefault(fe.get("name", "").lower(), []).append(fe)
|
||||
|
||||
emu_pack_structure = None
|
||||
emu_display = ""
|
||||
if emulator_name and emulators_dir:
|
||||
profiles = load_emulator_profiles(emulators_dir, skip_aliases=False)
|
||||
@@ -1899,7 +1900,6 @@ def generate_md5_pack(
|
||||
print(f"Error: {exc}", file=sys.stderr)
|
||||
return None
|
||||
emu_display = profile.get("emulator", emulator_name)
|
||||
emu_pack_structure = profile.get("pack_structure")
|
||||
for fe in profile.get("files", []):
|
||||
plat_file_index.setdefault(fe.get("name", "").lower(), []).append(fe)
|
||||
for alias in fe.get("aliases", []):
|
||||
@@ -1955,12 +1955,9 @@ def generate_md5_pack(
|
||||
|
||||
if matched_fe:
|
||||
if emulator_name:
|
||||
# Laid out as the emulator pack lays it out: a profile
|
||||
# without pack_structure still names its path and its
|
||||
# standalone_path, and --standalone has to reach them.
|
||||
dest = _resolve_destination(
|
||||
matched_fe, emu_pack_structure, standalone
|
||||
)
|
||||
# Laid out as the emulator pack lays it out: its path and
|
||||
# its standalone_path, which --standalone has to reach.
|
||||
dest = _resolve_destination(matched_fe, standalone)
|
||||
else:
|
||||
dest = matched_fe.get("destination", matched_fe.get("name", name))
|
||||
elif paths:
|
||||
|
||||
@@ -695,7 +695,7 @@ def _collect_emulator_extras(
|
||||
continue
|
||||
if file_mode == "libretro" and is_standalone:
|
||||
continue
|
||||
if not read_from_system_dir(f):
|
||||
if not read_from_system_dir(f, is_standalone):
|
||||
continue
|
||||
if is_standalone:
|
||||
raw = f.get("standalone_path") or f.get("path") or fname
|
||||
@@ -943,12 +943,11 @@ def emulator_region_drops(
|
||||
region_index = region_mod.build_region_index(dict(selected))
|
||||
region_groups: dict[str, list[tuple[str, str]]] = {}
|
||||
for emu_name, profile in sorted(selected):
|
||||
structure = profile.get("pack_structure")
|
||||
# Decided over what the pack keeps, as on the platform side: an
|
||||
# optional winner removed afterwards left its slot empty.
|
||||
entries = filter_files_by_mode(profile.get("files", []), standalone)
|
||||
for fe in _kept(entries, required_only):
|
||||
dest = _resolve_destination(fe, structure, standalone)
|
||||
dest = _resolve_destination(fe, standalone)
|
||||
if dest:
|
||||
group_id = _emulator_region_group(emu_name, profile, fe)
|
||||
region_groups.setdefault(group_id, []).append(
|
||||
|
||||
+11
-14
@@ -59,10 +59,16 @@ def _flat(arcname: str, prefix: str, flatten: bool) -> str:
|
||||
return arcname[len(prefix) + 1:]
|
||||
return arcname
|
||||
|
||||
def _resolve_destination(
|
||||
file_entry: dict, pack_structure: dict | None, standalone: bool
|
||||
) -> str:
|
||||
"""Resolve the ZIP destination path for a file entry."""
|
||||
def _resolve_destination(file_entry: dict, standalone: bool) -> str:
|
||||
"""Resolve the ZIP destination path for a file entry.
|
||||
|
||||
``path:`` is where the libretro build reads the file from the system
|
||||
directory and ``standalone_path:`` where the standalone app reads it, so
|
||||
a file's destination is written whole. ``pack_structure`` places a
|
||||
profile's data directories and archives: prefixing files with it gave
|
||||
PPSSPP/PPSSPP/ppge_atlas.zim, and the platform packs, which never read
|
||||
it, put libretro Dolphin's IPL at the root of system/.
|
||||
"""
|
||||
# 1. standalone_path override
|
||||
if standalone and file_entry.get("standalone_path"):
|
||||
rel = file_entry["standalone_path"]
|
||||
@@ -73,16 +79,7 @@ def _resolve_destination(
|
||||
else:
|
||||
rel = file_entry.get("name", "")
|
||||
|
||||
rel = sanitize_pack_path(rel)
|
||||
|
||||
# Prepend pack_structure prefix
|
||||
if pack_structure:
|
||||
mode_key = "standalone" if standalone else "libretro"
|
||||
prefix = pack_structure.get(mode_key, "")
|
||||
if prefix:
|
||||
rel = f"{prefix}/{rel}"
|
||||
|
||||
return rel
|
||||
return sanitize_pack_path(rel)
|
||||
|
||||
|
||||
def _archive_destination(
|
||||
|
||||
@@ -448,14 +448,18 @@ def validate_cli_modes(args, mode_attrs: list[str]) -> None:
|
||||
raise SystemExit(f"Options are mutually exclusive: --{' --'.join(mode_attrs)}")
|
||||
|
||||
|
||||
def read_from_system_dir(file_entry: dict) -> bool:
|
||||
def read_from_system_dir(file_entry: dict, standalone: bool = False) -> bool:
|
||||
"""Whether the emulator reads this entry from the system directory.
|
||||
|
||||
A file loaded from the save, content or working directory is not a BIOS:
|
||||
no platform lists it, no pack carries it, and the truth model must not
|
||||
ask a platform to declare it.
|
||||
ask a platform to declare it. Two builds can read one file from two
|
||||
places: libretro Dolphin keeps its User tree in the save directory, the
|
||||
standalone app in its own folder, so ``load_from`` can be keyed by build.
|
||||
"""
|
||||
load_from = file_entry.get("load_from", "")
|
||||
if isinstance(load_from, dict):
|
||||
load_from = load_from.get("standalone" if standalone else "libretro", "")
|
||||
return not load_from or load_from == "system_dir"
|
||||
|
||||
|
||||
@@ -478,7 +482,9 @@ def outside_gap_scope(file_entry: dict, is_standalone: bool) -> bool:
|
||||
mode == "libretro" and is_standalone
|
||||
):
|
||||
return True
|
||||
return not read_from_system_dir(file_entry) or bool(file_entry.get("agnostic"))
|
||||
return not read_from_system_dir(file_entry, is_standalone) or bool(
|
||||
file_entry.get("agnostic")
|
||||
)
|
||||
|
||||
|
||||
def filter_files_by_mode(files: list[dict], standalone: bool) -> list[dict]:
|
||||
|
||||
+3
-6
@@ -1512,11 +1512,10 @@ def verify_emulator(
|
||||
standalone,
|
||||
)
|
||||
if region_drops:
|
||||
structure = profile.get("pack_structure")
|
||||
files = [
|
||||
fe
|
||||
for fe in files
|
||||
if _resolve_destination(fe, structure, standalone) not in region_drops
|
||||
if _resolve_destination(fe, standalone) not in region_drops
|
||||
]
|
||||
|
||||
# Check data directories (only notice if not cached)
|
||||
@@ -1705,10 +1704,8 @@ def verify_emulator(
|
||||
result["hle_fallback"] = hle
|
||||
result["ground_truth"] = build_ground_truth(name, validation_index)
|
||||
# The slot the emulator pack places this entry in: standalone_path
|
||||
# under --standalone, the pack_structure prefix, the sanitised path.
|
||||
dest = _resolve_destination(
|
||||
file_entry, profile.get("pack_structure"), standalone
|
||||
) or name
|
||||
# under --standalone, the sanitised path.
|
||||
dest = _resolve_destination(file_entry, standalone) or name
|
||||
emu_results.setdefault(dest, []).append((result, required, hle))
|
||||
|
||||
for dest, alternatives in emu_results.items():
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
"""A profile's path: is where the libretro core reads the file.
|
||||
|
||||
pack_structure prefixed files as well as data directories: PPSSPP's
|
||||
`PPSSPP/ppge_atlas.zim` became PPSSPP/PPSSPP/, while the platform packs,
|
||||
which never read the field, put libretro Dolphin's IPL, DSP ROMs, fonts,
|
||||
segaboot and Wii user files at the root of system/. libretro Dolphin reads
|
||||
Sys from system/dolphin-emu/Sys and keeps User in the save directory.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
from packpaths import _resolve_destination # noqa: E402
|
||||
from validation import outside_gap_scope, read_from_system_dir # noqa: E402
|
||||
|
||||
|
||||
class PathIsTheDestination(unittest.TestCase):
|
||||
def test_no_prefix_on_a_file(self):
|
||||
entry = {"name": "ppge_atlas.zim", "path": "PPSSPP/ppge_atlas.zim"}
|
||||
self.assertEqual(_resolve_destination(entry, False), "PPSSPP/ppge_atlas.zim")
|
||||
dual = {"name": "IPL.bin", "path": "dolphin-emu/Sys/GC/USA/IPL.bin",
|
||||
"standalone_path": "GC/USA/IPL.bin"}
|
||||
self.assertEqual(_resolve_destination(dual, False), "dolphin-emu/Sys/GC/USA/IPL.bin")
|
||||
self.assertEqual(_resolve_destination(dual, True), "GC/USA/IPL.bin")
|
||||
|
||||
|
||||
class LoadFromPerBuild(unittest.TestCase):
|
||||
ENTRY = {"name": "SYSCONF", "path": "Wii/shared2/sys/SYSCONF",
|
||||
"load_from": {"libretro": "save_dir"}}
|
||||
|
||||
def test_each_build_reads_its_own_place(self):
|
||||
self.assertFalse(read_from_system_dir(self.ENTRY, False))
|
||||
self.assertTrue(read_from_system_dir(self.ENTRY, True))
|
||||
self.assertTrue(outside_gap_scope(self.ENTRY, False))
|
||||
self.assertFalse(outside_gap_scope(self.ENTRY, True))
|
||||
|
||||
def test_a_plain_value_holds_for_both(self):
|
||||
entry = {"name": "x", "load_from": "save_dir"}
|
||||
self.assertFalse(read_from_system_dir(entry, False))
|
||||
self.assertFalse(read_from_system_dir(entry, True))
|
||||
|
||||
|
||||
class RetroArchCarriesDolphinWhereItReads(unittest.TestCase):
|
||||
"""Reads the repository: skips when the database is absent."""
|
||||
|
||||
def test_no_dolphin_file_at_the_root(self):
|
||||
if not (REPO_ROOT / "database.json").exists():
|
||||
self.skipTest("database.json is not built")
|
||||
previous = os.getcwd()
|
||||
os.chdir(REPO_ROOT)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
from common import load_database, load_emulator_profiles, load_platform_config
|
||||
from packextras import _collect_emulator_extras
|
||||
|
||||
config = load_platform_config("retroarch")
|
||||
extras = _collect_emulator_extras(
|
||||
config, "emulators", load_database("database.json"), set(),
|
||||
config.get("base_destination", ""), load_emulator_profiles("emulators"),
|
||||
)
|
||||
dolphin = [
|
||||
e["destination"] for e in extras
|
||||
if e.get("source_emulator") in ("Dolphin", "Ishiiruka")
|
||||
]
|
||||
self.assertTrue(dolphin)
|
||||
self.assertEqual(
|
||||
[d for d in dolphin if not d.startswith("dolphin-emu/Sys/")], []
|
||||
)
|
||||
self.assertIn("dolphin-emu/Sys/Triforce/segaboot.gcm", dolphin)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user