fix: add flycast standalone data directory paths

The standalone build reads BIOS files from its data directory root, not from dc/ (core/oslib/oslib.cpp:118-196, core/stdclass.cpp:95-125, core/linux-dist/main.cpp:74-99). Each entry now carries standalone_path.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 10:50:12 +02:00
1 parent 3ca746478d
commit eb04fb50cc
3 files changed
+54 -1

No files matched your search

+22
View File
@@ -36,6 +36,18 @@ notes: |
(shell/libretro/libretro.cpp:2249-2250). All files below are relative to
system_dir/dc/.
The standalone emulator looks for each file in the BIOS paths the user
configures, then in its data directory, then in the system data
directories, then in the content directories, and writes the flash back to
the data directory (core/oslib/oslib.cpp:118-196,
core/stdclass.cpp:95-125). The data directory is $XDG_DATA_HOME/flycast/,
else ~/.local/share/flycast/, on Linux (core/linux-dist/main.cpp:74-99), and
the data/ folder of the configuration directory on Windows, Android and
macOS (core/windows/winmain.cpp:73-78, core/windows/winmain.cpp:86-89,
shell/android-studio/flycast/src/main/jni/src/Android.cpp:149-159,
shell/apple/emulator-osx/emulator-osx/osx-main.mm:97-101).
standalone_path is relative to the data directory.
Only the Dreamcast reads flat files. The prefix is dc_ for Dreamcast
(core/hw/flashrom/nvmem.cpp:35-50), and the boot ROM is searched as
{prefix}boot.bin then {prefix}bios.bin (core/hw/flashrom/nvmem.cpp:304).
@@ -65,6 +77,7 @@ files:
# -------------------------------------------------------
- name: "dc_boot.bin"
path: "dc/dc_boot.bin"
standalone_path: "dc_boot.bin"
aliases: ["dc_bios.bin"]
system: sega-dreamcast
required: false
@@ -75,6 +88,7 @@ files:
- name: "dc_nvmem.bin"
path: "dc/dc_nvmem.bin"
standalone_path: "dc_nvmem.bin"
system: sega-dreamcast
required: false
hle_fallback: true
@@ -87,6 +101,7 @@ files:
# -------------------------------------------------------
- name: "naomi.zip"
path: "dc/naomi.zip"
standalone_path: "naomi.zip"
system: sega-naomi
required: true
category: bios_zip
@@ -132,6 +147,7 @@ files:
- name: "airlbios.zip"
path: "dc/airlbios.zip"
standalone_path: "airlbios.zip"
system: sega-naomi
required: false
category: bios_zip
@@ -149,6 +165,7 @@ files:
- name: "f355bios.zip"
path: "dc/f355bios.zip"
standalone_path: "f355bios.zip"
system: sega-naomi
required: false
category: bios_zip
@@ -170,6 +187,7 @@ files:
- name: "f355dlx.zip"
path: "dc/f355dlx.zip"
standalone_path: "f355dlx.zip"
system: sega-naomi
required: false
category: bios_zip
@@ -191,6 +209,7 @@ files:
- name: "hod2bios.zip"
path: "dc/hod2bios.zip"
standalone_path: "hod2bios.zip"
system: sega-naomi
required: false
category: bios_zip
@@ -215,6 +234,7 @@ files:
# -------------------------------------------------------
- name: "naomi2.zip"
path: "dc/naomi2.zip"
standalone_path: "naomi2.zip"
system: sega-naomi2
required: true
category: bios_zip
@@ -259,6 +279,7 @@ files:
# -------------------------------------------------------
- name: "awbios.zip"
path: "dc/awbios.zip"
standalone_path: "awbios.zip"
system: sega-atomiswave
required: true
category: bios_zip
@@ -274,6 +295,7 @@ files:
# -------------------------------------------------------
- name: "segasp.zip"
path: "dc/segasp.zip"
standalone_path: "segasp.zip"
system: sega-systemsp
required: true
category: bios_zip
+31
View File
@@ -0,0 +1,31 @@
"""Flycast's two builds read the same files from two directories.
The libretro port looks in <system>/dc/ (shell/libretro/libretro.cpp:2249-2250).
The standalone emulator looks in its data directory, whose root holds the
files with no dc/ level (core/oslib/oslib.cpp:118-196, core/stdclass.cpp:95-125).
Without standalone_path the standalone layout of a pack fell back on path:
and put every file one directory too deep.
"""
from __future__ import annotations
import unittest
from pathlib import Path
import yaml
PROFILE = Path(__file__).resolve().parent.parent / "emulators" / "flycast.yml"
class FlycastStandaloneLayout(unittest.TestCase):
def test_every_entry_has_the_data_directory_layout(self) -> None:
profile = yaml.safe_load(PROFILE.read_text(encoding="utf-8"))
self.assertEqual(profile["type"], "standalone + libretro")
for entry in profile["files"]:
with self.subTest(entry=entry["name"]):
self.assertTrue(entry["path"].startswith("dc/"))
self.assertEqual(entry.get("standalone_path"), entry["path"][len("dc/"):])
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -39,7 +39,7 @@ Every module in `tests/`, by the area it guards.
|------|----------|---------|
| Core regression suites | synthetic | `test_e2e`, `test_audit_regressions`, `test_tool_messages` |
| File resolution and identity | synthetic + collection | `test_adler32_resolution`, `test_agnostic_scan`, `test_agnostic_scan_mode`, `test_agnostic_scope`, `test_agnostic_substitute`, `test_archive_choice`, `test_bios_companions`, `test_bundled_identity`, `test_casefold_cache`, `test_db_aliases`, `test_declared_names`, `test_derivations`, `test_directory_entries`, `test_extra_identity`, `test_foreign_tree`, `test_foreign_tree_names`, `test_frontend_digest`, `test_game_data_homonyms`, `test_hashing`, `test_identity`, `test_md5_pack_context`, `test_name_tiebreak`, `test_nec_filing`, `test_owner_resolution`, `test_path_suffix`, `test_resolution_evidence`, `test_shipped_content`, `test_twin_declarations`, `test_validated_choice`, `test_variant_choice`, `test_variant_identity`, `test_zipped_member` |
| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` |
| Verification, cross-reference and profile checks | synthetic + profiles | `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_cross_reference_sources`, `test_file_consumers`, `test_fileless_audit`, `test_gap_settlement`, `test_hidden_extras`, `test_flycast_layout`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice` |
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_required_only_archives`, `test_required_only_twins`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
| Slots and regions | synthetic + profiles | `test_region`, `test_region_agnostic_scan`, `test_region_groups`, `test_region_held`, `test_region_platform_index`, `test_region_required_only`, `test_slot`, `test_slots`, `test_slots_shipped_file` |
| Hardware targets and systems | synthetic + target files | `test_extract_targets`, `test_lakka_targets`, `test_libretro_slugs`, `test_system_ids`, `test_system_selection`, `test_target_names`, `test_target_scrapers`, `test_target_systems`, `test_target_verify` |