mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
fix: keep Batocera's save files apart from bios/
batocera-systems lists bios/saves/dolphin-emu/Triforce/segaboot.gcm, so the pack folder for the save directory is userdata-saves/. validate_schemas refuses a pack folder the BIOS tree already uses.
This commit is contained in:
1 parent
8db393f415
commit
bf22f1da47
7 files changed
+72
-7
No files matched your search
@@ -499,11 +499,14 @@ platforms:
|
||||
# libretroConfig.py:225-228 and batoceraPaths.py:22 at batocera-43.1).
|
||||
# <system> is the ES system name (Emulator.py:119, args.system), so a
|
||||
# file is placed once below each system es_systems.yml offers the core
|
||||
# for (libretro_systems in batocera.yml).
|
||||
# for (libretro_systems in batocera.yml). The pack keeps them in
|
||||
# userdata-saves/: batocera-systems lists bios/saves/dolphin-emu/
|
||||
# Triforce/segaboot.gcm, so saves/ already belongs to the BIOS tree.
|
||||
save_directory:
|
||||
folder: saves
|
||||
by_core: false
|
||||
by_system: true
|
||||
pack_folder: userdata-saves
|
||||
schedule: weekly
|
||||
target_scraper: batocera_targets
|
||||
target_source: https://github.com/batocera-linux/batocera.linux
|
||||
|
||||
@@ -1191,7 +1191,7 @@ def generate_pack(
|
||||
_pack_registry.get(platform_name, {}).get("install", {}) or {}
|
||||
).get("standalone_copies", []),
|
||||
launch_folders=len(config.get("core_system_dirs") or {}),
|
||||
save_folder=(save_layout(config).folder if save_count else ""),
|
||||
save_folder=(save_layout(config).in_pack if save_count else ""),
|
||||
save_where=(
|
||||
save_place(
|
||||
str(_pack_registry.get(platform_name, {}).get("extract_to") or ""),
|
||||
|
||||
@@ -1371,7 +1371,7 @@ def _save_fields(extra: dict, pack_path: str, placement: ExtraPlacement) -> None
|
||||
extra["pack_path"] = pack_path
|
||||
if placement.save is not None:
|
||||
# The path below the save directory, what the manifest writes.
|
||||
extra["save_dest"] = pack_path[len(placement.save.folder) + 1:]
|
||||
extra["save_dest"] = pack_path[len(placement.save.in_pack) + 1:]
|
||||
if not placement.save.by_core:
|
||||
extra.pop("core_folder", None)
|
||||
|
||||
|
||||
+13
-2
@@ -31,13 +31,23 @@ class SaveLayout:
|
||||
/userdata/saves/<system>): a file read there is placed once for each
|
||||
system that runs the core, the systems the platform file names in
|
||||
``libretro_systems``. ``by_core_for`` names the cores a launcher
|
||||
sorts by core where it sorts no other.
|
||||
sorts by core where it sorts no other. ``pack_folder`` renames the
|
||||
pack's folder when the BIOS tree holds one of the same name.
|
||||
"""
|
||||
|
||||
folder: str
|
||||
by_core: bool
|
||||
by_system: bool = False
|
||||
by_core_for: frozenset[str] = frozenset()
|
||||
pack_folder: str = ""
|
||||
|
||||
@property
|
||||
def in_pack(self) -> str:
|
||||
"""The pack folder holding these files: ``pack_folder`` where the
|
||||
platform's own BIOS tree already has a folder named ``folder``
|
||||
(Batocera lists bios/saves/dolphin-emu/Triforce/segaboot.gcm),
|
||||
``folder`` otherwise."""
|
||||
return self.pack_folder or self.folder
|
||||
|
||||
def sorts(self, names: Iterable[str]) -> bool:
|
||||
"""Whether the frontend inserts the core's folder for a core known
|
||||
@@ -64,6 +74,7 @@ def save_layout(config: dict) -> SaveLayout | None:
|
||||
return SaveLayout(
|
||||
folder, bool(block.get("by_core")), bool(block.get("by_system")),
|
||||
frozenset(str(core) for core in block.get("by_core_for") or []),
|
||||
sanitize_pack_path(str(block.get("pack_folder") or "")),
|
||||
)
|
||||
|
||||
|
||||
@@ -85,7 +96,7 @@ def save_destination(
|
||||
rel = sanitize_pack_path(path)
|
||||
if not rel:
|
||||
return None
|
||||
root = layout.folder
|
||||
root = layout.in_pack
|
||||
if layout.by_system:
|
||||
folder = sanitize_pack_path(system)
|
||||
if not folder or "/" in folder:
|
||||
|
||||
@@ -416,8 +416,10 @@ def _save_directory_blocks() -> list[str]:
|
||||
if (
|
||||
not isinstance(block, dict)
|
||||
or not {"folder", "by_core"} <= set(block) <= {
|
||||
"folder", "by_core", "by_system", "by_core_for",
|
||||
"folder", "by_core", "by_system", "by_core_for", "pack_folder",
|
||||
}
|
||||
or not isinstance(block.get("pack_folder", "x"), str)
|
||||
or "/" in str(block.get("pack_folder", ""))
|
||||
or not isinstance(folder, str)
|
||||
or not folder
|
||||
or "\\" in folder
|
||||
@@ -438,9 +440,37 @@ def _save_directory_blocks() -> list[str]:
|
||||
f"platforms/_registry.yml: {name}.save_directory.by_system and "
|
||||
f"platforms/{name}.yml lists no libretro_systems"
|
||||
)
|
||||
in_pack = block.get("pack_folder") or folder
|
||||
taken = _bios_tree_below(name, in_pack)
|
||||
if taken:
|
||||
out.append(
|
||||
f"platforms/_registry.yml: {name}.save_directory puts the save "
|
||||
f"files in {in_pack}/, which the BIOS tree uses ({taken}): "
|
||||
"name another pack_folder"
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
def _bios_tree_below(platform: str, folder: str) -> str:
|
||||
"""A destination the platform declares below ``folder``, or empty."""
|
||||
from common import load_platform_config
|
||||
|
||||
try:
|
||||
config = load_platform_config(platform, str(ROOT / "platforms"))
|
||||
except FileNotFoundError:
|
||||
return ""
|
||||
prefix = f"{folder}/".lower()
|
||||
return next(
|
||||
(
|
||||
str(entry["destination"])
|
||||
for system in (config.get("systems") or {}).values()
|
||||
for entry in system.get("files") or []
|
||||
if str(entry.get("destination") or "").lower().startswith(prefix)
|
||||
),
|
||||
"",
|
||||
)
|
||||
|
||||
|
||||
def _libretro_systems(platform: str) -> dict:
|
||||
"""The platform file's core -> systems table, inheritance included."""
|
||||
from common import load_platform_config
|
||||
|
||||
+20
-1
@@ -134,7 +134,7 @@ class ThePlatformNamesItsSaveDirectory(unittest.TestCase):
|
||||
|
||||
platforms = str(REPO_ROOT / "platforms")
|
||||
expected = {
|
||||
"batocera": SaveLayout("saves", False, True),
|
||||
"batocera": SaveLayout("saves", False, True, pack_folder="userdata-saves"),
|
||||
"knulli": SaveLayout("saves", False, True),
|
||||
"recalbox": SaveLayout("saves", False, True),
|
||||
"retrodeck": SaveLayout("saves", False, True),
|
||||
@@ -168,6 +168,25 @@ class ThePlatformNamesItsSaveDirectory(unittest.TestCase):
|
||||
"saves/wii/dolphin-emu/User/GBA/gba_bios.bin",
|
||||
)
|
||||
|
||||
def test_a_pack_folder_apart_from_the_bios_tree(self):
|
||||
"""Batocera's BIOS tree has a saves/ of its own: the pack keeps the
|
||||
save directory's files in another folder, the installer still
|
||||
writes them to /userdata/saves."""
|
||||
layout = save_layout({"save_directory": {
|
||||
"folder": "saves", "by_core": False, "by_system": True,
|
||||
"pack_folder": "userdata-saves"}})
|
||||
self.assertEqual(layout.in_pack, "userdata-saves")
|
||||
self.assertEqual(save_destination("stella/KVS1.WAV", None, layout, "atari2600"),
|
||||
"userdata-saves/atari2600/stella/KVS1.WAV")
|
||||
self.assertEqual(SaveLayout("saves", True).in_pack, "saves")
|
||||
try:
|
||||
from validate_schemas import _bios_tree_below
|
||||
except ImportError:
|
||||
self.skipTest("validate_schemas needs jsonschema")
|
||||
self.assertEqual(_bios_tree_below("batocera", "saves"),
|
||||
"saves/dolphin-emu/Triforce/segaboot.gcm")
|
||||
self.assertEqual(_bios_tree_below("batocera", "userdata-saves"), "")
|
||||
|
||||
def test_the_systems_a_core_runs_for(self):
|
||||
from packpaths import libretro_systems
|
||||
|
||||
|
||||
@@ -304,6 +304,8 @@ that text belongs in a guide field.
|
||||
# (Batocera, RetroBat): one copy per system in the
|
||||
# platform file's libretro_systems
|
||||
by_core_for: [dolphin] # cores the launcher alone sorts by core (RetroBat)
|
||||
pack_folder: userdata-saves # the pack's folder for them, where the BIOS tree
|
||||
# already has one named like folder (Batocera)
|
||||
# null when saves sit beside each game
|
||||
zip_digest: composite # the frontend hashes a .zip by its members only
|
||||
firmware_folder_flat: true # the frontend lists each system folder without
|
||||
|
||||
Reference in new issue
Block a user