mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-12 04:53:52 -06:00
fix: place xroar ROMs in each rompath
XRoar reads a ROM by name from the directories of rompath. The entries
take their file name as path, relative to ~/.xroar/roms or
${prefix}/share/xroar/roms, and rompath and -rompath are declared as
search lists.
Batocera records its rompath line, Recalbox -rompath bios/<system>
(the placeholder its extractor already writes), RetroBat its -rompath
as two records, bios/dragon and bios/coco for coco. An entry whose
name the platform list does not declare follows the launch its
profile system is listed under: Recalbox lists mc10.rom under
trs80coco, so alice.rom is read there.
Batocera ROMs move from the BIOS root to bios/xroar, Recalbox ROMs to
bios/dragon and bios/trs80coco, RetroBat ROMs to bios/dragon and
bios/coco. RetroDECK and RetroPie keep them at the BIOS root.
This commit is contained in:
1 parent
e6dbbe69ed
commit
8ec0c5482c
13 files changed
+279
-19
No files matched your search
+60
-3
@@ -1,5 +1,6 @@
|
||||
emulator: XRoar
|
||||
type: standalone
|
||||
core_classification: other
|
||||
source: "https://www.6809.org.uk/git/xroar.git"
|
||||
upstream: "https://www.6809.org.uk/xroar/"
|
||||
version_source:
|
||||
@@ -21,13 +22,23 @@ systems:
|
||||
- coco
|
||||
- coco3
|
||||
- mc10
|
||||
standalone_directories:
|
||||
- "~/.xroar/roms"
|
||||
- "${prefix}/share/xroar/roms"
|
||||
standalone_pools:
|
||||
rompath: ""
|
||||
"-rompath": ""
|
||||
|
||||
notes: |
|
||||
XRoar by Ciaran Anscomb emulates Dragon 32/64, Tandy CoCo 1/2/3,
|
||||
MC-10, Alice, and clones (MX-1600, CP-400, Dragon 200-E, Deluxe CoCo).
|
||||
ROM files are searched in a configurable rompath directory with automatic
|
||||
extension appending (.rom, .ROM, .dgn, .DGN). Batocera sets rompath to
|
||||
/userdata/bios/xroar/.
|
||||
A ROM is looked up by name in the directories of rompath, a colon-separated
|
||||
list searched in order: the name as given first, then with .rom, .ROM, .dgn
|
||||
and .DGN appended, and the first file found is read (src/romlist.c:47-49,
|
||||
124-143, src/path.c:158-219). rompath is set in xroar.conf or with
|
||||
-rompath (src/xroar.c:3266). A Unix build defaults to
|
||||
~/.xroar/roms:$(datadir)/xroar/roms, $(datadir) being ${prefix}/share
|
||||
unless configure is told otherwise (src/Makefile.am:236).
|
||||
|
||||
The romlist mechanism defines fallback filenames per ROM slot. Each machine
|
||||
type has a default romlist that tries filenames in priority order. CRC32 is
|
||||
@@ -44,6 +55,7 @@ files:
|
||||
# ---- Dragon 32 ----
|
||||
|
||||
- name: "d32.rom"
|
||||
path: "d32.rom"
|
||||
system: dragon32
|
||||
description: "Dragon 32 BASIC ROM"
|
||||
required: true
|
||||
@@ -57,6 +69,7 @@ files:
|
||||
# ---- Dragon 64 ----
|
||||
|
||||
- name: "d64_1.rom"
|
||||
path: "d64_1.rom"
|
||||
system: dragon64
|
||||
description: "Dragon 64 32K mode BASIC ROM"
|
||||
required: true
|
||||
@@ -68,6 +81,7 @@ files:
|
||||
note: "IC17 ROM. Required for the machine to start. Romlist d64_1 tries d64_1, d64rom1, Dragon Data Ltd - Dragon 64 - IC17, Dragon Data Ltd - TANO IC18, Eurohard S.A. - Dragon 200 IC18, dragrom."
|
||||
|
||||
- name: "d64_2.rom"
|
||||
path: "d64_2.rom"
|
||||
system: dragon64
|
||||
description: "Dragon 64 64K mode BASIC ROM"
|
||||
required: false
|
||||
@@ -81,6 +95,7 @@ files:
|
||||
# ---- Dragon 200-E ----
|
||||
|
||||
- name: "d200e_1.rom"
|
||||
path: "d200e_1.rom"
|
||||
system: dragon64
|
||||
description: "Dragon 200-E BASIC IC18 (Spanish)"
|
||||
required: true
|
||||
@@ -92,6 +107,7 @@ files:
|
||||
note: "Required for Dragon 200-E. Falls back to d64_1 then generic dragon if not found. Romlist d200e_1 tries d200e_1, d200e_rom1, ic18_v1.4e.ic34."
|
||||
|
||||
- name: "d200e_2.rom"
|
||||
path: "d200e_2.rom"
|
||||
system: dragon64
|
||||
description: "Dragon 200-E BASIC IC17 (Spanish)"
|
||||
required: false
|
||||
@@ -102,6 +118,7 @@ files:
|
||||
note: "64K mode alternate. Falls back to d64_2 if not found. Romlist d200e_2 tries d200e_2, d200e_rom2, ic17_v1.4e.ic37."
|
||||
|
||||
- name: "d200e_26.rom"
|
||||
path: "d200e_26.rom"
|
||||
system: dragon64
|
||||
description: "Dragon 200-E external character generator ROM"
|
||||
required: false
|
||||
@@ -114,6 +131,7 @@ files:
|
||||
# ---- Dragon Professional (Alpha) ----
|
||||
|
||||
- name: "alpha-boot-v1.0.rom"
|
||||
path: "alpha-boot-v1.0.rom"
|
||||
system: dragon64
|
||||
description: "Dragon Professional (Alpha) boot ROM v1.0"
|
||||
required: true
|
||||
@@ -129,6 +147,7 @@ files:
|
||||
Romlist dragonpro_boot tries alpha-boot-v1.0, alpha_bt_10, Dragon Data Ltd - Dragon Alpha Boot v1.0 150584, alpha-boot-v0.4, alpha_bt_04.
|
||||
|
||||
- name: "alpha-boot-v0.4.rom"
|
||||
path: "alpha-boot-v0.4.rom"
|
||||
system: dragon64
|
||||
description: "Dragon Professional (Alpha) boot ROM v0.4"
|
||||
required: false
|
||||
@@ -145,6 +164,7 @@ files:
|
||||
Romlist dragonpro_boot tries alpha-boot-v1.0, alpha_bt_10, Dragon Data Ltd - Dragon Alpha Boot v1.0 150584, alpha-boot-v0.4, alpha_bt_04.
|
||||
|
||||
- name: "alpha-basic.rom"
|
||||
path: "alpha-basic.rom"
|
||||
system: dragon64
|
||||
description: "Dragon Professional (Alpha) BASIC ROM"
|
||||
required: true
|
||||
@@ -158,6 +178,7 @@ files:
|
||||
# ---- Tandy CoCo (Colour BASIC) ----
|
||||
|
||||
- name: "bas13.rom"
|
||||
path: "bas13.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Colour BASIC 1.3"
|
||||
required: true
|
||||
@@ -168,6 +189,7 @@ files:
|
||||
note: "Default Colour BASIC. First tried in the @coco romlist. 8K ROM loaded into slot 1 of a 2-slot rombank."
|
||||
|
||||
- name: "bas12.rom"
|
||||
path: "bas12.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Colour BASIC 1.2"
|
||||
required: false
|
||||
@@ -179,6 +201,7 @@ files:
|
||||
note: "Alternative to bas13. Second in fallback order. Romlist coco tries bas13, bas12, Color Basic v1.2 (1982)(Tandy), bas11, bas10. Romlist coco2 tries bas12, @coco."
|
||||
|
||||
- name: "bas11.rom"
|
||||
path: "bas11.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Colour BASIC 1.1"
|
||||
required: false
|
||||
@@ -189,6 +212,7 @@ files:
|
||||
note: "Used by CoCo 1E. Third in fallback order."
|
||||
|
||||
- name: "bas10.rom"
|
||||
path: "bas10.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Colour BASIC 1.0"
|
||||
required: false
|
||||
@@ -201,6 +225,7 @@ files:
|
||||
# ---- Tandy CoCo (Extended Colour BASIC) ----
|
||||
|
||||
- name: "extbas11.rom"
|
||||
path: "extbas11.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Extended Colour BASIC 1.1"
|
||||
required: true
|
||||
@@ -211,6 +236,7 @@ files:
|
||||
note: "Default Extended BASIC. 8K ROM loaded into slot 0 of a 2-slot rombank."
|
||||
|
||||
- name: "extbas10.rom"
|
||||
path: "extbas10.rom"
|
||||
system: coco
|
||||
description: "Tandy CoCo Extended Colour BASIC 1.0"
|
||||
required: false
|
||||
@@ -223,6 +249,7 @@ files:
|
||||
# ---- Tandy CoCo 3 ----
|
||||
|
||||
- name: "coco3.rom"
|
||||
path: "coco3.rom"
|
||||
system: coco3
|
||||
description: "CoCo 3 Super Extended Colour BASIC (NTSC)"
|
||||
required: true
|
||||
@@ -233,6 +260,7 @@ files:
|
||||
note: "32K combined ROM. Single required ROM for CoCo 3 NTSC."
|
||||
|
||||
- name: "coco3p.rom"
|
||||
path: "coco3p.rom"
|
||||
system: coco3
|
||||
description: "CoCo 3 Super Extended Colour BASIC (PAL)"
|
||||
required: true
|
||||
@@ -245,6 +273,7 @@ files:
|
||||
# ---- Tandy MC-10 ----
|
||||
|
||||
- name: "mc10.rom"
|
||||
path: "mc10.rom"
|
||||
system: mc10
|
||||
description: "Tandy MC-10 Microcolour BASIC"
|
||||
required: true
|
||||
@@ -255,6 +284,7 @@ files:
|
||||
note: "Single required ROM for MC-10."
|
||||
|
||||
- name: "alice.rom"
|
||||
path: "alice.rom"
|
||||
system: mc10
|
||||
description: "Matra & Hachette Alice Microcolour BASIC"
|
||||
required: true
|
||||
@@ -267,6 +297,7 @@ files:
|
||||
# ---- Deluxe CoCo (prototype) ----
|
||||
|
||||
- name: "deluxe.rom"
|
||||
path: "deluxe.rom"
|
||||
system: coco
|
||||
description: "Tandy Deluxe CoCo Advanced BASIC (bank 0)"
|
||||
required: true
|
||||
@@ -277,18 +308,21 @@ files:
|
||||
note: "Primary ROM for the Deluxe CoCo prototype. Loaded as extbas_rom. Romlist deluxecoco tries adv070_u24, deluxe."
|
||||
|
||||
- name: "adv071_u24.rom"
|
||||
path: "adv071_u24.rom"
|
||||
system: coco
|
||||
description: "Tandy Deluxe CoCo ROM bank 1"
|
||||
required: false
|
||||
source_ref: "src/xroar.c:681 (romlist deluxecoco1), src/dragon/deluxecoco.c:223-226 (load)"
|
||||
|
||||
- name: "adv072_u24.rom"
|
||||
path: "adv072_u24.rom"
|
||||
system: coco
|
||||
description: "Tandy Deluxe CoCo ROM bank 2"
|
||||
required: false
|
||||
source_ref: "src/xroar.c:682 (romlist deluxecoco2), src/dragon/deluxecoco.c:230-233 (load)"
|
||||
|
||||
- name: "adv073-2_u24.rom"
|
||||
path: "adv073-2_u24.rom"
|
||||
system: coco
|
||||
description: "Tandy Deluxe CoCo ROM bank 3"
|
||||
required: false
|
||||
@@ -299,6 +333,7 @@ files:
|
||||
# ---- Dynacom MX-1600 (Brazilian clone) ----
|
||||
|
||||
- name: "mx1600bas.rom"
|
||||
path: "mx1600bas.rom"
|
||||
system: coco
|
||||
description: "Dynacom MX-1600 Colour BASIC"
|
||||
required: true
|
||||
@@ -309,6 +344,7 @@ files:
|
||||
note: "Required for MX-1600. Zephyr-patched variant (CRC32 d11b1c96) is an alias. Romlist mx1600 tries mx1600bas, mx1600bas_zephyr."
|
||||
|
||||
- name: "mx1600extbas.rom"
|
||||
path: "mx1600extbas.rom"
|
||||
system: coco
|
||||
description: "Dynacom MX-1600 Extended Colour BASIC"
|
||||
required: true
|
||||
@@ -319,6 +355,7 @@ files:
|
||||
# ---- Prologica CP-400 (Brazilian clone) ----
|
||||
|
||||
- name: "cp400bas.rom"
|
||||
path: "cp400bas.rom"
|
||||
system: coco
|
||||
description: "Prologica CP-400 Colour BASIC"
|
||||
required: true
|
||||
@@ -327,6 +364,7 @@ files:
|
||||
source_ref: "src/xroar.c:688 (romlist cp400), src/xroar.c:755 (crclist cp400)"
|
||||
|
||||
- name: "cp400ext.rom"
|
||||
path: "cp400ext.rom"
|
||||
system: coco
|
||||
description: "Prologica CP-400 Extended Colour BASIC"
|
||||
required: true
|
||||
@@ -337,6 +375,7 @@ files:
|
||||
# ---- DOS cartridge ROMs (all optional) ----
|
||||
|
||||
- name: "disk11.rom"
|
||||
path: "disk11.rom"
|
||||
system: coco
|
||||
description: "Tandy RS-DOS 1.1 (CoCo floppy disk controller)"
|
||||
required: false
|
||||
@@ -346,6 +385,7 @@ files:
|
||||
note: "Primary CoCo disk controller ROM. disk10.rom (RS-DOS 1.0) is an earlier version used as fallback."
|
||||
|
||||
- name: "disk10.rom"
|
||||
path: "disk10.rom"
|
||||
system: coco
|
||||
description: "Tandy RS-DOS 1.0 (CoCo floppy disk controller)"
|
||||
required: false
|
||||
@@ -355,6 +395,7 @@ files:
|
||||
note: "Second name in the rsdos romlist, opened when disk11.rom is absent."
|
||||
|
||||
- name: "hdbdw3bck.rom"
|
||||
path: "hdbdw3bck.rom"
|
||||
system: coco
|
||||
description: "RS-DOS with Becker port (DriveWire)"
|
||||
required: false
|
||||
@@ -362,6 +403,7 @@ files:
|
||||
note: "For CoCo with Becker port hardware. Enables DriveWire connectivity."
|
||||
|
||||
- name: "ddos12a.rom"
|
||||
path: "ddos12a.rom"
|
||||
system: dragon64
|
||||
description: "DragonDOS 1.2a (Dragon floppy disk controller)"
|
||||
required: false
|
||||
@@ -369,6 +411,7 @@ files:
|
||||
note: "Latest DragonDOS version. Fallback chain tries DOSPlus -> SuperDOS -> DragonDOS -> Cumana. Older versions: ddos12, ddos40, ddos15, ddos10."
|
||||
|
||||
- name: "ddos40.rom"
|
||||
path: "ddos40.rom"
|
||||
system: dragon64
|
||||
description: "DragonDOS 4.0 (Eurohard S.A.)"
|
||||
required: false
|
||||
@@ -378,6 +421,7 @@ files:
|
||||
note: "Third name in the dragondos romlist, which @dragondos_compat tries after the dosplus and superdos lists."
|
||||
|
||||
- name: "ddos10.rom"
|
||||
path: "ddos10.rom"
|
||||
system: dragon64
|
||||
description: "DragonDOS 1.0 (Dragon Data Ltd)"
|
||||
required: false
|
||||
@@ -388,6 +432,7 @@ files:
|
||||
note: "Fifth name in the dragondos romlist, which @dragondos_compat tries after the dosplus and superdos lists. Romlist dragondos tries ddos12a, ddos12, ddos40, ddos15, ddos10, Dragon Data Ltd - DragonDOS 1.0."
|
||||
|
||||
- name: "dplus49b.rom"
|
||||
path: "dplus49b.rom"
|
||||
system: dragon64
|
||||
description: "DOSPlus 4.9b (Dragon compatible DOS)"
|
||||
required: false
|
||||
@@ -397,6 +442,7 @@ files:
|
||||
note: "First tried in DragonDOS-compatible cartridge. Enhanced Dragon DOS. Older version: dplus48 (alias: dosplus-4.8, DOSPLUS)."
|
||||
|
||||
- name: "dplus48.rom"
|
||||
path: "dplus48.rom"
|
||||
system: dragon64
|
||||
description: "DOSPlus 4.8 (Dragon compatible DOS)"
|
||||
required: false
|
||||
@@ -407,6 +453,7 @@ files:
|
||||
note: "Second name in the dosplus romlist, the first list @dragondos_compat tries. Romlist dosplus tries dplus49b, dplus48, dosplus-4.8, DOSPLUS."
|
||||
|
||||
- name: "sdose6.rom"
|
||||
path: "sdose6.rom"
|
||||
system: dragon64
|
||||
description: "SuperDOS E6 (Dragon compatible DOS)"
|
||||
required: false
|
||||
@@ -417,6 +464,7 @@ files:
|
||||
note: "Latest SuperDOS. Older versions: sdose5, sdose4. Romlist superdos tries sdose6, PNP - SuperDOS E6, sdose5, sdose4."
|
||||
|
||||
- name: "cdos20.rom"
|
||||
path: "cdos20.rom"
|
||||
system: dragon64
|
||||
description: "Cumana DOS 2.0 (Dragon compatible DOS)"
|
||||
required: false
|
||||
@@ -425,6 +473,7 @@ files:
|
||||
note: "Romlist cumana tries cdos20, CDOS20, CumanaDOSv2.0."
|
||||
|
||||
- name: "delta2.rom"
|
||||
path: "delta2.rom"
|
||||
system: dragon64
|
||||
description: "Delta System 2 (Premier Microsystems disk controller)"
|
||||
required: false
|
||||
@@ -435,6 +484,7 @@ files:
|
||||
note: "Latest Delta version. Older versions: delta1a, delta19, delta, deltados. Romlist delta tries delta2, delta1a, delta19, delta, deltados, Premier Micros - DeltaDOS."
|
||||
|
||||
- name: "cp450dsk.rom"
|
||||
path: "cp450dsk.rom"
|
||||
system: coco
|
||||
description: "Prologica CP-450 DOS cartridge"
|
||||
required: false
|
||||
@@ -444,6 +494,7 @@ files:
|
||||
# ---- Other cartridge ROMs (all optional) ----
|
||||
|
||||
- name: "orch90.rom"
|
||||
path: "orch90.rom"
|
||||
system: coco
|
||||
description: "Orchestra-90 CC sound cartridge ROM"
|
||||
required: false
|
||||
@@ -453,6 +504,7 @@ files:
|
||||
note: "Sound synthesis cartridge. Loaded directly (no romlist fallback)."
|
||||
|
||||
- name: "mcx128.rom"
|
||||
path: "mcx128.rom"
|
||||
system: mc10
|
||||
description: "MCX128 memory expansion BASIC ROM"
|
||||
required: false
|
||||
@@ -461,6 +513,7 @@ files:
|
||||
note: "128K memory expansion for MC-10. Adds enhanced BASIC. Romlist mcx128 tries mcx128, MCX_Basic_21."
|
||||
|
||||
- name: "mcx128a.rom"
|
||||
path: "mcx128a.rom"
|
||||
system: mc10
|
||||
description: "MCX128 memory expansion BASIC ROM (AZERTY)"
|
||||
required: false
|
||||
@@ -469,6 +522,7 @@ files:
|
||||
note: "AZERTY keyboard variant for Alice. Same MCX128 hardware. Romlist mcx128_azerty tries mcx128a, MCX_Basic_21_AZERTY."
|
||||
|
||||
- name: "yados.rom"
|
||||
path: "yados.rom"
|
||||
system: coco
|
||||
description: "YADOS (Glenside IDE interface ROM)"
|
||||
required: false
|
||||
@@ -476,6 +530,7 @@ files:
|
||||
note: "IDE hard disk interface. Fallback: hdblba.rom (alternative IDE ROM)."
|
||||
|
||||
- name: "sdbdos.rom"
|
||||
path: "sdbdos.rom"
|
||||
system: dragon64
|
||||
description: "SDBDOS (MOOH memory cartridge ROM)"
|
||||
required: false
|
||||
@@ -483,6 +538,7 @@ files:
|
||||
note: "SD card boot DOS for MOOH cartridge. Loaded directly."
|
||||
|
||||
- name: "dragonfly-2.3.rom"
|
||||
path: "dragonfly-2.3.rom"
|
||||
system: dragon64
|
||||
description: "Ikon Ultra Drive Dragonfly ROM 2.3"
|
||||
required: false
|
||||
@@ -490,6 +546,7 @@ files:
|
||||
note: "Experimental, compiled only with WANT_EXPERIMENTAL. Ikon Ultra Drive storage interface. First candidate of the ikon romlist. No crclist entry names it."
|
||||
|
||||
- name: "dragonfly-1.3.rom"
|
||||
path: "dragonfly-1.3.rom"
|
||||
system: dragon64
|
||||
description: "Ikon Ultra Drive Dragonfly ROM 1.3"
|
||||
required: false
|
||||
|
||||
@@ -6580,6 +6580,14 @@ launchers:
|
||||
\ -position 2"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/openmsx/openmsxGenerator.py:89"
|
||||
- emulator: xroar
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/xroar
|
||||
passes_to: "written: rompath /userdata/bios/xroar"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/xroar/xroarGenerator.py:31-32"
|
||||
- emulator: o2em
|
||||
build: libretro
|
||||
kind: core_option
|
||||
|
||||
@@ -4171,6 +4171,14 @@ launchers:
|
||||
fails_when_missing: false
|
||||
depends_on_option: system 64dd
|
||||
source_ref: "projects/configgen/configgen/generators/mupen/mupenConfig.py:118-121"
|
||||
- emulator: xroar
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /recalbox/share/bios/<system>
|
||||
passes_to: command line -rompath
|
||||
fails_when_missing: false
|
||||
source_ref: "projects/configgen/configgen/generators/xroar/xroarGenerator.py:25"
|
||||
- emulator: dolphin, dolphin-gui
|
||||
build: standalone
|
||||
kind: fixed_name
|
||||
|
||||
+12
-2
@@ -5373,10 +5373,20 @@ launchers:
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: bios/dragon, or bios/coco when system == "coco"
|
||||
passes_to: command line -rompath bios/dragon, or bios/coco when system == "coco"
|
||||
search_dir: bios/dragon
|
||||
passes_to: command line -rompath bios/dragon
|
||||
fails_when_missing: false
|
||||
source_ref: "emulatorLauncher/Generators/Xroar.Generator.cs:76-80"
|
||||
- emulator: xroar
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: bios/coco
|
||||
passes_to: command line -rompath bios/coco
|
||||
fails_when_missing: false
|
||||
systems:
|
||||
- coco
|
||||
source_ref: "emulatorLauncher/Generators/Xroar.Generator.cs:76-80"
|
||||
- emulator: xroar
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
},
|
||||
"search_dir": {
|
||||
"type": "string",
|
||||
"description": "Directory the launcher looks in, as the code resolves it. {system} stands for the platform system the emulator is launched for"
|
||||
"description": "Directory the launcher looks in, as the code resolves it. <system> stands for the platform system the emulator is launched for"
|
||||
},
|
||||
"passes_to": {
|
||||
"type": "string",
|
||||
|
||||
+14
-1
@@ -2945,9 +2945,22 @@ def platform_layouts(
|
||||
profile.get("standalone_directories") or profile.get("standalone_pools")
|
||||
) and any(h.systems and h.emulator in names for h in _handed(standalone_cores))
|
||||
index = system_file_index(standalone_cores) if per_system else {}
|
||||
# A profile system the platform launches under a system of its own, as
|
||||
# its list says for one entry, is launched there for every entry:
|
||||
# Recalbox lists mc10.rom under trs80coco, so alice.rom is read there.
|
||||
family: dict[str, set[str]] = {}
|
||||
for f in (profile.get("files") or []) if per_system else []:
|
||||
if isinstance(f, dict):
|
||||
own = entry_launch_systems(f, {})
|
||||
for system in own:
|
||||
family.setdefault(system, set()).update(entry_launch_systems(f, index) - own)
|
||||
|
||||
def bindings_of(entry: dict) -> dict[str, tuple[str, str]]:
|
||||
systems = entry_launch_systems(entry, index) if per_system else frozenset()
|
||||
systems = frozenset()
|
||||
if per_system:
|
||||
systems = entry_launch_systems(entry, index)
|
||||
if systems == entry_launch_systems(entry, {}):
|
||||
systems = systems.union(*(family.get(s, set()) for s in systems))
|
||||
if systems not in by_systems:
|
||||
by_systems[systems] = standalone_bindings_for(
|
||||
emu_name, profile, standalone_cores, systems
|
||||
|
||||
@@ -399,8 +399,9 @@ class HandedDirectory:
|
||||
|
||||
|
||||
# The placeholder a launcher record writes for the system it is launched
|
||||
# for: Recalbox passes -rompath os.path.join(BIOS, args.system) to XRoar.
|
||||
SYSTEM_PLACEHOLDER = "{system}"
|
||||
# for, as Recalbox's extractor spells it: Recalbox passes XRoar -rompath
|
||||
# os.path.join(BIOS, args.system).
|
||||
SYSTEM_PLACEHOLDER = "<system>"
|
||||
|
||||
|
||||
def native_systems(config: dict) -> dict[str, str]:
|
||||
@@ -442,7 +443,7 @@ def handed_directories(config: dict) -> list[HandedDirectory]:
|
||||
describing several directories in prose names no single one. A search
|
||||
path (XRoar's rompath) gives each of its directories, in order. A record
|
||||
naming systems applies to those systems only, and one whose search_dir
|
||||
holds {system} gives one directory per system the platform declares.
|
||||
holds <system> gives one directory per system the platform declares.
|
||||
"""
|
||||
base = str(config.get("base_destination") or "bios")
|
||||
natives = native_systems(config)
|
||||
|
||||
@@ -901,8 +901,8 @@ def environment_directories(cg: Configgen) -> list[Launcher]:
|
||||
|
||||
# Generators that hand the emulator a /userdata/bios directory through its
|
||||
# configuration: a line written to the file it reads (openMSX's script.tcl
|
||||
# filepool entries) or a key saved to it.
|
||||
CONFIG_DIRECTORY_GENERATORS = ("openmsx.openmsxGenerator",)
|
||||
# filepool entries, xroar.conf rompath) or a key saved to it.
|
||||
CONFIG_DIRECTORY_GENERATORS = ("openmsx.openmsxGenerator", "xroar.xroarGenerator")
|
||||
|
||||
|
||||
def config_directories(
|
||||
|
||||
@@ -39,6 +39,7 @@ CORES = f"{GENERATORS}/libretro/libretroCores.py"
|
||||
LIBRETRO_GENERATOR = f"{GENERATORS}/libretro/libretroGenerator.py"
|
||||
HATARI = f"{GENERATORS}/hatari/hatariGenerator.py"
|
||||
GSPLUS = f"{GENERATORS}/gsplus/gsplusGenerator.py"
|
||||
XROAR = f"{GENERATORS}/xroar/xroarGenerator.py"
|
||||
AMIBERRY_GENERATOR = f"{GENERATORS}/amiberry/amiberryGenerator.py"
|
||||
AMIBERRY_KICKSTARTS = f"{GENERATORS}/amiberry/amiberryKickstarts.py"
|
||||
AMIBERRY_SUBSYSTEMS = f"{GENERATORS}/amiberry/amiberrySubSystems.py"
|
||||
@@ -52,7 +53,7 @@ MUPEN_CONFIG = f"{GENERATORS}/mupen/mupenConfig.py"
|
||||
SOURCE_FILES = (
|
||||
FILES_MODULE, LAUNCHER, RETROARCH, CORES, LIBRETRO_GENERATOR, HATARI, GSPLUS,
|
||||
AMIBERRY_KICKSTARTS, AMIBERRY_SUBSYSTEMS, AMIBERRY_CONFIG, PCSX2, DOLPHIN, XEMU,
|
||||
MUPEN_CONFIG,
|
||||
MUPEN_CONFIG, XROAR,
|
||||
)
|
||||
|
||||
# Recalbox's system.ini runs every libretro core as `emulator = libretro`:
|
||||
@@ -1171,8 +1172,32 @@ def core_file_options(cg: Configgen, directories: list[Launcher]) -> list[Launch
|
||||
return launchers
|
||||
|
||||
|
||||
def xroar(cg: Configgen) -> list[Launcher]:
|
||||
"""-rompath os.path.join(recalboxFiles.BIOS, args.system) on the command line."""
|
||||
src = cg.source(XROAR)
|
||||
generate = src.function("generate")
|
||||
# args.system is the ES system name, as self.system.Name is elsewhere.
|
||||
env = {**cg.env(src, generate), "args.system": SYSTEM_PLACEHOLDER}
|
||||
found = [
|
||||
(flag, value)
|
||||
for node in ast.walk(generate)
|
||||
if isinstance(node, ast.List)
|
||||
for flag, value in zip(node.elts, node.elts[1:])
|
||||
if isinstance(flag, ast.Constant) and flag.value == "-rompath"
|
||||
]
|
||||
if len(found) != 1:
|
||||
src.fail(f"expected one -rompath on the command line, found {len(found)}")
|
||||
flag, value = found[0]
|
||||
directory = cg.bios_dir(spell(value, env), src, "-rompath")
|
||||
return [Launcher(
|
||||
emulator=cg.emulator(XROAR), build="standalone", kind="passes_path", names=[],
|
||||
search_dir=directory, passes_to="command line -rompath",
|
||||
source_ref=src.ref([(flag.lineno, value.end_lineno)]),
|
||||
)]
|
||||
|
||||
|
||||
STANDALONE: tuple[Callable[[Configgen], list[Launcher]], ...] = (
|
||||
hatari, gsplus, amiberry, pcsx2, xemu, mupen64plus,
|
||||
hatari, gsplus, amiberry, pcsx2, xemu, mupen64plus, xroar,
|
||||
)
|
||||
LIBRETRO: tuple[Callable[[Configgen], list[Launcher]], ...] = (
|
||||
core_assets, hatari_libretro, content_files,
|
||||
|
||||
@@ -2976,7 +2976,11 @@ def xroar(sources: dict[str, Source]) -> list[Record]:
|
||||
found = _argument_paths(src, "xroar", "standalone")
|
||||
if not found:
|
||||
raise LauncherPatternMissing(src.path, "rompath argument")
|
||||
records = [_with_conditions(record, conditions) for record, conditions in found]
|
||||
records = [
|
||||
split
|
||||
for record, conditions in found
|
||||
for split in _per_system(src, _with_conditions(record, conditions))
|
||||
]
|
||||
line = src.find(r'string (\w+) = ("rompath (?:[^"\\\n]|\\.)*");', "config rompath line")
|
||||
written = _unescape(line.group(2)[1:-1])
|
||||
relative = re.fullmatch(r'rompath "(.*)"', written)
|
||||
@@ -3003,6 +3007,37 @@ def xroar(sources: dict[str, Source]) -> list[Record]:
|
||||
return _covered(src, records)
|
||||
|
||||
|
||||
_SYSTEM_BRANCH = re.compile(r'(\S+), or (\S+) when system == "([\w.-]+)"')
|
||||
|
||||
|
||||
def _per_system(src: Source, record: Record) -> list[Record]:
|
||||
"""A directory chosen by the system, one record per choice.
|
||||
|
||||
`romPath = <a>; if (system == "coco") romPath = <b>;` renders as "<a>, or
|
||||
<b> when system == "coco"": <b> is passed for that system, <a> for every
|
||||
other one.
|
||||
"""
|
||||
rendered = str(record.get("search_dir", ""))
|
||||
branch = _SYSTEM_BRANCH.fullmatch(rendered)
|
||||
if branch is None:
|
||||
if " or " in rendered:
|
||||
raise LauncherPatternMissing(src.path, f"directory choice {rendered!r}")
|
||||
return [record]
|
||||
default, chosen, system = branch.groups()
|
||||
flag = str(record["passes_to"]).removesuffix(rendered).strip()
|
||||
out = []
|
||||
for directory, systems in ((default, None), (chosen, [system])):
|
||||
split = {k: v for k, v in record.items() if k != "source_ref"}
|
||||
split.update(
|
||||
names=list(record["names"]), search_dir=directory, passes_to=f"{flag} {directory}"
|
||||
)
|
||||
if systems:
|
||||
split["systems"] = systems
|
||||
split["source_ref"] = record["source_ref"]
|
||||
out.append(split)
|
||||
return out
|
||||
|
||||
|
||||
def pico8(sources: dict[str, Source]) -> list[Record]:
|
||||
"""The PICO-8 binary the generator runs, from an emulator folder.
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ from scraper.recalbox_launchers import ( # noqa: E402
|
||||
RETROARCH,
|
||||
SOURCE_FILES,
|
||||
XEMU,
|
||||
XROAR,
|
||||
Configgen,
|
||||
Launcher,
|
||||
LauncherShapeError,
|
||||
@@ -57,6 +58,7 @@ from scraper.recalbox_launchers import ( # noqa: E402
|
||||
pcsx2,
|
||||
system_directories,
|
||||
xemu,
|
||||
xroar,
|
||||
)
|
||||
|
||||
from tests.test_launchers import placed # noqa: E402
|
||||
@@ -109,6 +111,9 @@ LAUNCHER_BLOCKS = {
|
||||
80: ''' elif emulator == "pcsx2":
|
||||
module = __import__("configgen.generators.pcsx2.pcsx2Generator", fromlist=["Pcsx2Generator"])
|
||||
generatorClass = getattr(module, "Pcsx2Generator")''',
|
||||
122: ''' elif emulator == "xroar":
|
||||
module = __import__("configgen.generators.xroar.xroarGenerator", fromlist=["XroarGenerator"])
|
||||
generatorClass = getattr(module, "XroarGenerator")''',
|
||||
125: ''' elif emulator == "xemu":
|
||||
module = __import__("configgen.generators.xemu.xemuGenerator", fromlist=["XemuGenerator"])
|
||||
generatorClass = getattr(module, "XemuGenerator")''',
|
||||
@@ -1184,6 +1189,22 @@ from configgen.controllers.controller import InputItem, ControllerPerPlayer, Con
|
||||
mupenSettings.setString(section, "IPL-ROM", "")''',
|
||||
}
|
||||
|
||||
# xroarGenerator.py:1-26 at 10.1.1
|
||||
XROAR_BLOCKS = {
|
||||
8: '''class XroarGenerator(Generator):
|
||||
|
||||
def generate(self, system: Emulator, playersControllers: ControllerPerPlayer, recalboxOptions: keyValueSettings, args) -> Command:
|
||||
|
||||
# Make save dir
|
||||
import os
|
||||
import configgen.recalboxFiles as recalboxFiles''',
|
||||
22: ''' snapFile: str = os.path.basename(args.rom) + ".sna"
|
||||
commandArray: List[str] = [recalboxFiles.recalboxBins[system.Emulator],
|
||||
"-vo", "sdl", "-ui", "sdl", "-ao", "pulse",
|
||||
"-rompath", os.path.join(recalboxFiles.BIOS, args.system),
|
||||
"-snappath", os.path.join(snapshotFolder, snapFile)]''',
|
||||
}
|
||||
|
||||
BLOCKS = {
|
||||
FILES_MODULE: FILES_MODULE_BLOCKS,
|
||||
LAUNCHER: LAUNCHER_BLOCKS,
|
||||
@@ -1199,6 +1220,7 @@ BLOCKS = {
|
||||
DOLPHIN: DOLPHIN_BLOCKS,
|
||||
XEMU: XEMU_BLOCKS,
|
||||
MUPEN_CONFIG: MUPEN_CONFIG_BLOCKS,
|
||||
XROAR: XROAR_BLOCKS,
|
||||
}
|
||||
|
||||
|
||||
@@ -1220,6 +1242,21 @@ def ref(path: str, lines: str) -> str:
|
||||
return f"{path}:{lines}"
|
||||
|
||||
|
||||
class XroarRomPath(unittest.TestCase):
|
||||
def test_the_rom_path_is_the_bios_folder_of_the_system(self):
|
||||
(record,) = xroar(configgen())
|
||||
self.assertEqual(
|
||||
(record.emulator, record.kind, record.search_dir, record.passes_to, record.source_ref),
|
||||
("xroar", "passes_path", "/recalbox/share/bios/<system>", "command line -rompath",
|
||||
ref(XROAR, "25")),
|
||||
)
|
||||
|
||||
def test_a_rom_path_built_another_way_raises(self):
|
||||
cg = configgen(XROAR, "os.path.join(recalboxFiles.BIOS, args.system)", "args.rompath")
|
||||
with self.assertRaises(LauncherShapeError):
|
||||
xroar(cg)
|
||||
|
||||
|
||||
class SystemDirectoryPerCore(unittest.TestCase):
|
||||
"""libretroRetroarch.py:431-529, the directory RetroArch is given."""
|
||||
|
||||
@@ -1511,7 +1548,7 @@ class ExtractionNeverEmpty(unittest.TestCase):
|
||||
|
||||
records = extract_launchers(reader)
|
||||
self.assertEqual(sorted(set(read)), sorted(SOURCE_FILES))
|
||||
self.assertEqual(len(records), 85)
|
||||
self.assertEqual(len(records), 86)
|
||||
|
||||
def test_records_fit_the_schema(self):
|
||||
schema = json.loads((REPO_ROOT / "schemas" / "platform.schema.json").read_text())
|
||||
|
||||
@@ -1149,8 +1149,17 @@ class FolderArguments(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_xroar_reassigned_folder_and_config_line(self):
|
||||
argument, config = rl.xroar(_sources(**{f"{G}/Xroar.Generator.cs": XROAR}))
|
||||
self.assertEqual(argument["search_dir"], 'bios/dragon, or bios/coco when system == "coco"')
|
||||
# romPath is bios/dragon, rewritten to bios/coco for the coco system.
|
||||
default, coco, config = rl.xroar(_sources(**{f"{G}/Xroar.Generator.cs": XROAR}))
|
||||
self.assertEqual(
|
||||
(default["search_dir"], default["passes_to"], default.get("systems")),
|
||||
("bios/dragon", "command line -rompath bios/dragon", None),
|
||||
)
|
||||
self.assertEqual(
|
||||
(coco["search_dir"], coco["passes_to"], coco["systems"]),
|
||||
("bios/coco", "command line -rompath bios/coco", ["coco"]),
|
||||
)
|
||||
self.assertEqual(coco["source_ref"], default["source_ref"])
|
||||
self.assertEqual(config["search_dir"], "bios/dragon")
|
||||
self.assertEqual(
|
||||
config["passes_to"], 'xroar.conf rompath ".\\\\..\\\\..\\\\bios\\\\dragon"'
|
||||
|
||||
@@ -259,7 +259,7 @@ class PerSystem(unittest.TestCase):
|
||||
def test_a_system_placeholder_gives_one_directory_per_system(self) -> None:
|
||||
# Recalbox passes -rompath os.path.join(BIOS, args.system).
|
||||
cfg = {
|
||||
**config(passes("emu", "/recalbox/share/bios/{system}", "command line -rompath")),
|
||||
**config(passes("emu", "/recalbox/share/bios/<system>", "command line -rompath")),
|
||||
"systems": {
|
||||
"coco": {"native_id": "trs80coco", "files": []},
|
||||
"dragon64": {"native_id": "dragon", "files": []},
|
||||
@@ -285,6 +285,29 @@ class PerSystem(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class SystemFamily(unittest.TestCase):
|
||||
def test_an_entry_follows_the_launch_its_system_is_listed_under(self) -> None:
|
||||
# Recalbox lists mc10.rom under trs80coco: alice.rom, of the same
|
||||
# profile system, is read there too.
|
||||
profile = {
|
||||
"emulator": "Emu", "type": "standalone", "standalone_pools": {"-rompath": ""},
|
||||
"files": [
|
||||
{"name": "mc10.rom", "path": "mc10.rom", "system": "mc10"},
|
||||
{"name": "alice.rom", "path": "alice.rom", "system": "mc10"},
|
||||
],
|
||||
}
|
||||
cfg = {
|
||||
**config(passes("emu", "/recalbox/share/bios/<system>", "-rompath")),
|
||||
"systems": {"coco": {"native_id": "trs80coco",
|
||||
"files": [{"name": "mc10.rom"}]}},
|
||||
}
|
||||
((view, _standalone),) = platform_layouts("emu", profile, standalone_set(cfg))
|
||||
self.assertEqual(
|
||||
[f.get("standalone_path") for f in view["files"]],
|
||||
["trs80coco/mc10.rom", "trs80coco/alice.rom"],
|
||||
)
|
||||
|
||||
|
||||
class Layout(unittest.TestCase):
|
||||
LINKED = link("emu", "$biosdir/dc", "$home/.local/share/emu is a symlink to it")
|
||||
|
||||
@@ -537,3 +560,37 @@ class OpenmsxOnEachPlatform(unittest.TestCase):
|
||||
self.assertTrue(
|
||||
entry["standalone_path"].startswith("openmsx/"), entry["standalone_path"]
|
||||
)
|
||||
|
||||
|
||||
class XroarOnEachPlatform(unittest.TestCase):
|
||||
"""XRoar reads each ROM from a directory of rompath. Batocera writes
|
||||
rompath bios/xroar, RetroDECK lists $bios_path in it, RetroPie links
|
||||
the build's ${prefix}/share/xroar/roms to $biosdir, RetroBat passes
|
||||
-rompath bios/coco for coco and bios/dragon otherwise, Recalbox
|
||||
-rompath bios/<system>."""
|
||||
|
||||
# Platform -> profile system -> folder, "" for the BIOS root.
|
||||
EXPECTED = {
|
||||
"batocera": dict.fromkeys(("dragon32", "dragon64", "coco", "coco3", "mc10"), "xroar"),
|
||||
"retrodeck": dict.fromkeys(("dragon32", "dragon64", "coco", "coco3", "mc10"), ""),
|
||||
"retropie": dict.fromkeys(("dragon32", "dragon64", "coco", "coco3", "mc10"), ""),
|
||||
"retrobat": {**dict.fromkeys(("dragon32", "dragon64", "coco3", "mc10"), "dragon"),
|
||||
"coco": "coco"},
|
||||
"recalbox": {**dict.fromkeys(("dragon32", "dragon64"), "dragon"),
|
||||
**dict.fromkeys(("coco", "coco3", "mc10"), "trs80coco")},
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.profile = load_emulator_profiles(str(REPO_ROOT / "emulators"))["xroar"]
|
||||
|
||||
def test_each_rom_lands_where_its_launch_reads_it(self) -> None:
|
||||
for platform, folders in self.EXPECTED.items():
|
||||
cfg = load_platform_config(platform, str(REPO_ROOT / "platforms"))
|
||||
(view, _standalone), = platform_layouts("xroar", self.profile, standalone_set(cfg))
|
||||
for entry in view["files"]:
|
||||
with self.subTest(platform=platform, name=entry["name"]):
|
||||
self.assertNotIn("unplaced", entry)
|
||||
folder = folders[entry["system"]]
|
||||
expected = f"{folder}/{entry['name']}" if folder else entry["name"]
|
||||
self.assertEqual(entry["standalone_path"], expected)
|
||||
Reference in new issue
Block a user