mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 01:13:30 -05:00
fix: keep both cases on lakka and retropie
Both run on Linux but inherited RetroArch's case folding, so a core file differing from a platform name only by case left their packs: MesenCE's bios.col and np2kai's lowercase 2608_*.wav, which those cores open with that exact case. They are now case-sensitive, the shared groups fold only where the platform does, and Lakka gets its own pack instead of sharing RetroArch's.
This commit is contained in:
1 parent
08b239f22a
commit
6e8f2df24f
8 files changed
+91
-42
No files matched your search
@@ -283,6 +283,9 @@ platforms:
|
||||
scraper: libretro
|
||||
inherits_from: retroarch
|
||||
cores: all_libretro
|
||||
# Lakka is a Linux distribution: two names that differ by case are two
|
||||
# files there, not the one RetroArch's Windows and macOS builds see.
|
||||
case_insensitive_fs: false
|
||||
schedule: weekly
|
||||
target_scraper: lakka_targets
|
||||
target_source: https://buildbot.libretro.com/nightly/
|
||||
@@ -386,6 +389,8 @@ platforms:
|
||||
source: https://github.com/RetroPie/RetroPie-Setup
|
||||
# No cores here: the registry overrides the config, and RetroPie's own
|
||||
# scriptmodules are what say which packages it ships.
|
||||
# RetroPie runs on Linux, where case tells two files apart.
|
||||
case_insensitive_fs: false
|
||||
schedule: null
|
||||
target_scraper: retropie_targets
|
||||
target_source: https://retropie.org.uk/stats/pkgflags/
|
||||
|
||||
+39
-29
@@ -187,35 +187,6 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
|
||||
|
||||
# Resolve shared group includes
|
||||
shared_path = os.path.join(platforms_dir, "_shared.yml")
|
||||
if os.path.exists(shared_path):
|
||||
shared_real = os.path.realpath(shared_path)
|
||||
if shared_real not in _shared_yml_cache:
|
||||
with open(shared_path) as f:
|
||||
_shared_yml_cache[shared_real] = yaml_load(f) or {}
|
||||
shared = _shared_yml_cache[shared_real]
|
||||
shared_groups = shared.get("shared_groups", {})
|
||||
for system in config.get("systems", {}).values():
|
||||
for group_name in system.get("includes", []):
|
||||
if group_name in shared_groups:
|
||||
existing = {
|
||||
(f.get("name"), f.get("destination", f.get("name")))
|
||||
for f in system.get("files", [])
|
||||
}
|
||||
existing_lower = {
|
||||
f.get("destination", f.get("name", "")).lower()
|
||||
for f in system.get("files", [])
|
||||
}
|
||||
for gf in shared_groups[group_name]:
|
||||
key = (gf.get("name"), gf.get("destination", gf.get("name")))
|
||||
dest_lower = gf.get("destination", gf.get("name", "")).lower()
|
||||
if key not in existing and dest_lower not in existing_lower:
|
||||
# Marked as ours: the platform's own file does not
|
||||
# carry it, and an export must not count it kept.
|
||||
system.setdefault("files", []).append(
|
||||
{**gf, "shared_group": group_name}
|
||||
)
|
||||
existing.add(key)
|
||||
|
||||
# Merge metadata from _registry.yml. The registry is our curated source;
|
||||
# the scraped YAML may be incomplete (missing cores, metadata fields).
|
||||
# Registry fields supplement (not replace) the scraped config.
|
||||
@@ -252,6 +223,42 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
|
||||
if key != "cores" and key not in config:
|
||||
config[key] = val
|
||||
|
||||
# A shared group's file joins a system unless the platform already has
|
||||
# it there. Case only makes two names one where the filesystem folds it:
|
||||
# Lakka and RetroPie run on Linux, and np2kai opens 2608_bd.wav beside
|
||||
# System.dat's 2608_BD.WAV.
|
||||
def fold(destination: str) -> str:
|
||||
return destination.lower() if config.get("case_insensitive_fs") else destination
|
||||
|
||||
if os.path.exists(shared_path):
|
||||
shared_real = os.path.realpath(shared_path)
|
||||
if shared_real not in _shared_yml_cache:
|
||||
with open(shared_path) as f:
|
||||
_shared_yml_cache[shared_real] = yaml_load(f) or {}
|
||||
shared = _shared_yml_cache[shared_real]
|
||||
shared_groups = shared.get("shared_groups", {})
|
||||
for system in config.get("systems", {}).values():
|
||||
for group_name in system.get("includes", []):
|
||||
if group_name in shared_groups:
|
||||
existing = {
|
||||
(f.get("name"), f.get("destination", f.get("name")))
|
||||
for f in system.get("files", [])
|
||||
}
|
||||
existing_lower = {
|
||||
fold(f.get("destination", f.get("name", "")))
|
||||
for f in system.get("files", [])
|
||||
}
|
||||
for gf in shared_groups[group_name]:
|
||||
key = (gf.get("name"), gf.get("destination", gf.get("name")))
|
||||
dest_lower = fold(gf.get("destination", gf.get("name", "")))
|
||||
if key not in existing and dest_lower not in existing_lower:
|
||||
# Marked as ours: the platform's own file does not
|
||||
# carry it, and an export must not count it kept.
|
||||
system.setdefault("files", []).append(
|
||||
{**gf, "shared_group": group_name}
|
||||
)
|
||||
existing.add(key)
|
||||
|
||||
# Recalbox hashes a .zip by its members, so a plain md5 never answers one
|
||||
# of its archive declarations: the resolver reads the mark per entry.
|
||||
if config.get("zip_digest") == "composite":
|
||||
@@ -1513,6 +1520,9 @@ def group_identical_platforms(
|
||||
emulators = [
|
||||
cores if isinstance(cores, str) else sorted(map(str, cores or [])),
|
||||
sorted(map(str, config.get("standalone_cores") or [])),
|
||||
# One archive cannot serve a filesystem that folds case and one
|
||||
# that does not: Lakka keeps bios.col beside BIOS.col.
|
||||
bool(config.get("case_insensitive_fs")),
|
||||
]
|
||||
fp = hashlib.sha1(f"{fp}|{emulators}".encode()).hexdigest()
|
||||
if target_cores_cache:
|
||||
|
||||
@@ -8,7 +8,7 @@ as stored, never recompressed, so the parts depend on the pack alone.
|
||||
|
||||
Usage:
|
||||
python scripts/split_pack.py dist/
|
||||
python scripts/split_pack.py dist/RetroArch_Lakka_v1.22.2_BIOS_Pack.zip
|
||||
python scripts/split_pack.py dist/RetroArch_v1.22.2_BIOS_Pack.zip
|
||||
python scripts/split_pack.py dist/ --max-size 1900M
|
||||
"""
|
||||
|
||||
|
||||
@@ -62,5 +62,35 @@ class AChildLeavesItsParentAlone(unittest.TestCase):
|
||||
self.assertEqual(child["systems"]["sys-a"]["files"], [{"name": "child.bin"}])
|
||||
|
||||
|
||||
|
||||
class ALinuxPlatformKeepsBothCases(unittest.TestCase):
|
||||
"""Lakka and RetroPie inherited RetroArch's case folding although both
|
||||
run on Linux: np2kai opens 2608_bd.wav and MesenCE bios.col with that
|
||||
exact case, and only System.dat's 2608_BD.WAV and BIOS.col shipped."""
|
||||
|
||||
def setUp(self):
|
||||
self.addCleanup(common._platform_config_cache.clear)
|
||||
common._platform_config_cache.clear()
|
||||
|
||||
def test_the_linux_platforms_do_not_fold(self):
|
||||
platforms = str(REPO_ROOT / "platforms")
|
||||
self.assertTrue(common.load_platform_config("retroarch", platforms)["case_insensitive_fs"])
|
||||
for name in ("lakka", "retropie"):
|
||||
with self.subTest(platform=name):
|
||||
config = common.load_platform_config(name, platforms)
|
||||
self.assertFalse(config["case_insensitive_fs"])
|
||||
dests = {
|
||||
f.get("destination", f.get("name"))
|
||||
for system in config["systems"].values() for f in system["files"]
|
||||
}
|
||||
self.assertTrue({"np2kai/2608_BD.WAV", "np2kai/2608_bd.wav"} <= dests)
|
||||
|
||||
def test_lakka_does_not_share_retroarchs_pack(self):
|
||||
groups = common.group_identical_platforms(
|
||||
["retroarch", "lakka"], str(REPO_ROOT / "platforms")
|
||||
)
|
||||
self.assertEqual(sorted(g for g, _rep in groups), [["lakka"], ["retroarch"]])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -39,7 +39,7 @@ class VerifyPackChoice(unittest.TestCase):
|
||||
self.db = self.out / "db.json"
|
||||
self.db.write_text(json.dumps({"files": {}}))
|
||||
self.stem = generate_pack._platform_pack_stem(
|
||||
["retroarch", "lakka"], "retroarch", "platforms"
|
||||
["retroarch"], "retroarch", "platforms"
|
||||
)
|
||||
|
||||
def _args(self, **overrides) -> argparse.Namespace:
|
||||
|
||||
@@ -202,9 +202,9 @@ python scripts/generate_pack.py --all --all-variants --output-dir dist/
|
||||
```
|
||||
|
||||
`--all-variants` builds all six combinations in one run, producing names like
|
||||
`RetroArch_Lakka_v1.22.2_BIOS_Pack.zip`,
|
||||
`RetroArch_Lakka_v1.22.2_Platform_BIOS_Pack.zip` and
|
||||
`RetroArch_Lakka_v1.22.2_Truth_Required_BIOS_Pack.zip`.
|
||||
`RetroArch_v1.22.2_BIOS_Pack.zip`,
|
||||
`RetroArch_v1.22.2_Platform_BIOS_Pack.zip` and
|
||||
`RetroArch_v1.22.2_Truth_Required_BIOS_Pack.zip`.
|
||||
|
||||
Which one to pick: `full` is the one to ship, since it covers alternate cores
|
||||
and optional firmware. `platform` is much smaller and matches exactly what the
|
||||
|
||||
@@ -147,11 +147,13 @@ entries that are out of scope here.
|
||||
## Pack grouping
|
||||
|
||||
Platforms that produce identical packs are grouped automatically.
|
||||
Two platforms share a pack when they declare the same files and run the same
|
||||
emulators. RetroArch and Lakka do, so they produce one combined pack
|
||||
(`RetroArch_Lakka_BIOS_Pack.zip`). RetroPie inherits RetroArch's systems but
|
||||
ships its own package list, standalone emulators included, so it gets a
|
||||
separate pack and a separate install manifest.
|
||||
Two platforms share a pack when they declare the same files, run the same
|
||||
emulators and see file names the same way. Lakka declares RetroArch's files
|
||||
and cores but runs on Linux, where `bios.col` and `BIOS.col` are two files
|
||||
that different cores open; RetroArch's pack folds them for Windows and macOS.
|
||||
So Lakka gets its own pack. RetroPie inherits RetroArch's systems but ships its
|
||||
own package list, standalone emulators included, and is case-sensitive too, so
|
||||
it gets a separate pack and a separate install manifest.
|
||||
With `--target`, the fingerprint includes target cores so platforms
|
||||
with different hardware filters get separate packs. Emulator and system packs
|
||||
also retain system identity, `variant_group` and requested region; same-named
|
||||
|
||||
@@ -267,9 +267,11 @@ python scripts/download.py --list
|
||||
bash scripts/download.sh --list
|
||||
```
|
||||
|
||||
Some platforms share packs (Lakka uses the RetroArch pack). The installer handles
|
||||
this mapping automatically, but if you're downloading manually, check which pack
|
||||
name corresponds to your platform.
|
||||
A pack's name lists every platform it serves. Releases built before
|
||||
October 2026 ship RetroArch and Lakka as one `RetroArch_Lakka` pack; later
|
||||
ones give Lakka its own, since Lakka runs on Linux where two names that differ
|
||||
by case are two files. The installer and the download scripts find the right
|
||||
pack either way.
|
||||
|
||||
**A pack in several parts will not extract:**
|
||||
|
||||
|
||||
Reference in new issue
Block a user