From 4a5c693b6651df31dc22ec7aa360a64ff88d977f Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 13:06:35 +0100 Subject: [PATCH] fix: place GZDoom's IWADs in RetroDECK's roms/doom GZDoom collects its IWAD candidates from [IWADSearch.Directories], reads the support WAD there and the Load files from the IWAD's own folder (src/d_iwad.cpp:456-476, 593-624, 862-901). RetroDECK lists RETRODECKROMSDIR/doom there (gzdoom/rd_assets/rd_config/gzdoom.ini:9), which component_prepare.sh:27 rewrites to $roms_path/doom. The extractor read only the BIOS placeholder of a preset: it now records every line naming the BIOS or the roms folder the script rewrites, with that sed line in its source. $roms_path, whose default is the roms root (config/retrodeck/retrodeck.json:5), is read as that root. The profile names IWADSearch.Directories as a pool and lays its IWADs and their support and Load files out at its top. On RetroDECK the 20 held IWADs land in roms/doom, the 23 others are named missing there. The root copies stay for prboom and uzdoom, which claim them. No other platform hands GZDoom that list, so none changes. --- emulators/gzdoom.yml | 46 +++++++ platforms/retrodeck.yml | 159 +++++++++++-------------- scripts/launchers.py | 14 ++- scripts/scraper/retrodeck_launchers.py | 33 +++-- tests/test_launcher_placement.py | 20 ++++ tests/test_launchers_retrodeck.py | 2 +- 6 files changed, 176 insertions(+), 98 deletions(-) diff --git a/emulators/gzdoom.yml b/emulators/gzdoom.yml index 94a554604..212441074 100644 --- a/emulators/gzdoom.yml +++ b/emulators/gzdoom.yml @@ -13,6 +13,9 @@ version_basis: display_name: "GZDoom" cores: ["GZDoom", "gzdoom-sa"] systems: [doom, heretic, hexen, strife, chex] +standalone_pools: + "[IWADSearch.Directories] Path": "" + "[IWADSearch.Directories] RecursivePath": "" notes: | Doom-engine source port by Christoph Oelckers. Supports Doom, Heretic, @@ -161,6 +164,7 @@ files: - name: "doom.wad" category: game_data system: doom + path: "doom.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:420, 437, 659" note: "The Ultimate DOOM and DOOM Registered both use this name and are told apart by their lumps." @@ -168,108 +172,126 @@ files: - name: "doom2.wad" category: game_data system: doom + path: "doom2.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:640, 653" - name: "doom2f.wad" category: game_data system: doom + path: "doom2f.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:625, 657" - name: "doombfg.wad" category: game_data system: doom + path: "doombfg.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:332, 666" - name: "doom2bfg.wad" category: game_data system: doom + path: "doom2bfg.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:560, 667" - name: "doomunity.wad" category: game_data system: doom + path: "doomunity.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:369, 661" - name: "doom2unity.wad" category: game_data system: doom + path: "doom2unity.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:592, 655" - name: "doomkex.wad" category: game_data system: doom + path: "doomkex.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:350, 662" - name: "doom2kex.wad" category: game_data system: doom + path: "doom2kex.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:576, 656" - name: "doomxbox.wad" category: game_data system: doom + path: "doomxbox.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:403, 660" - name: "doom2xbox.wad" category: game_data system: doom + path: "doom2xbox.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:608, 654" - name: "doom_complete.pk3" category: game_data system: doom + path: "doom_complete.pk3" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:389, 652" - name: "plutonia.wad" category: game_data system: doom + path: "plutonia.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:545, 670" - name: "plutoniaunity.wad" category: game_data system: doom + path: "plutoniaunity.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:514, 671" - name: "plutoniakex.wad" category: game_data system: doom + path: "plutoniakex.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:529, 672" - name: "tnt.wad" category: game_data system: doom + path: "tnt.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:499, 673" - name: "tntunity.wad" category: game_data system: doom + path: "tntunity.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:468, 674" - name: "tntkex.wad" category: game_data system: doom + path: "tntkex.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:483, 675" - name: "nerve.wad" category: game_data system: doom + path: "nerve.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:565, 614, src/d_iwad.cpp:877-895" note: "No Rest for the Living. Autoloaded by Doom 2 BFG and Xbox editions." @@ -277,6 +299,7 @@ files: - name: "nerveunity.wad" category: game_data system: doom + path: "nerveunity.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:598, src/d_iwad.cpp:877-895" note: "Loaded from the IWAD directory by DOOM 2: Unity Edition." @@ -284,6 +307,7 @@ files: - name: "extras.wad" category: game_data system: doom + path: "extras.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:357, 376, 488, 534, 582, 598" note: "Loaded from the IWAD directory by the KEX and Unity editions." @@ -291,6 +315,7 @@ files: - name: "soundtrack" category: game_data system: doom + path: "soundtrack" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:376, 598, src/d_iwad.cpp:877-895" note: "Loaded from the IWAD directory by the DOOM and DOOM 2 Unity editions." @@ -298,6 +323,7 @@ files: - name: "id24res.wad" category: game_data system: doom + path: "id24res.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:341, 360, 379, src/d_iwad.cpp:862-875" note: "id24 resource WAD. SupportWAD of every id IWAD block, loaded when found and i_loadsupportwad is set." @@ -307,6 +333,7 @@ files: - name: "freedoom1.wad" category: game_data system: doom + path: "freedoom1.wad" required: false installed_on: [retropie] source_ref: "wadsrc_extra/static/iwadinfo.txt:307, 676" @@ -314,6 +341,7 @@ files: - name: "freedoom2.wad" category: game_data system: doom + path: "freedoom2.wad" required: false installed_on: [retropie] source_ref: "wadsrc_extra/static/iwadinfo.txt:294, 677" @@ -321,6 +349,7 @@ files: - name: "freedm.wad" category: game_data system: doom + path: "freedm.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:281, 680" @@ -329,6 +358,7 @@ files: - name: "heretic.wad" category: game_data system: heretic + path: "heretic.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:241, 244, 254, 257, 681" note: "Both Heretic and Shadow of the Serpent Riders use this name and are told apart by the EXTENDED lump." @@ -337,6 +367,7 @@ files: aliases: ["blasphemer.wad"] category: game_data system: heretic + path: "blasphem.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:228, 692-693" @@ -345,12 +376,14 @@ files: - name: "hexen.wad" category: game_data system: hexen + path: "hexen.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:188, 684" - name: "hexdd.wad" category: game_data system: hexen + path: "hexdd.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:196-207, 685" note: "Deathkings expansion. Requires hexen.wad (Required = Hexen: Beyond Heretic)." @@ -360,12 +393,14 @@ files: - name: "strife1.wad" category: game_data system: strife + path: "strife1.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:151, 688" - name: "sve.wad" category: game_data system: strife + path: "sve.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:136, 140, 689" note: "Veteran Edition. Required = Strife: Quest for the Sigil (loads voices.wad)." @@ -373,6 +408,7 @@ files: - name: "voices.wad" category: game_data system: strife + path: "voices.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:142, 155" @@ -381,12 +417,14 @@ files: - name: "chex.wad" category: game_data system: chex + path: "chex.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:123, 694" - name: "chex3.wad" category: game_data system: chex + path: "chex3.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:109, 695" @@ -395,12 +433,14 @@ files: - name: "hacx.wad" category: game_data system: doom + path: "hacx.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:83, 698" - name: "hacx2.wad" category: game_data system: doom + path: "hacx2.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:65-75, 699, src/d_iwad.cpp:351-394, src/common/filesystem/source/resourcefile.cpp:156-174" note: "Identified by the MAP01 map and the HACX-E lump, whatever the container: every candidate is opened by its magic, so a zip under this name is read as a pk3. The Hacx 2.0 repository builds that zip from src/, where hacx-e.txt is the HACX-E lump and maps/MAP01.wad the first map." @@ -408,18 +448,21 @@ files: - name: "action2.wad" category: game_data system: doom + path: "action2.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:97, 696" - name: "harm1.wad" category: game_data system: doom + path: "harm1.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:57, 697" - name: "square.pk3" category: game_data system: doom + path: "square.pk3" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:33" note: "Absent from the Names block: picked up only when named with -iwad." @@ -427,17 +470,20 @@ files: - name: "square1.pk3" category: game_data system: doom + path: "square1.pk3" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:45, 700" - name: "delaweare.wad" category: game_data system: doom + path: "delaweare.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:22, 701" - name: "rotwb.wad" category: game_data system: doom + path: "rotwb.wad" required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:9, 702" diff --git a/platforms/retrodeck.yml b/platforms/retrodeck.yml index 0d801412c..3592a2537 100644 --- a/platforms/retrodeck.yml +++ b/platforms/retrodeck.yml @@ -16756,6 +16756,24 @@ launchers: passes_to: "settings.ini [BIOS] SearchDirectory" fails_when_missing: false source_ref: "duckstation/component_prepare.sh:15, 33" +- emulator: gzdoom + build: standalone + kind: passes_path + names: [] + search_dir: $roms_path/doom + passes_to: "gzdoom.ini [IWADSearch.Directories] Path" + fails_when_missing: false + source_ref: "gzdoom/rd_assets/rd_config/gzdoom.ini:9, gzdoom/component_prepare.sh:23,\ + \ 27-28" +- emulator: gzdoom + build: standalone + kind: passes_path + names: [] + search_dir: $roms_path/doom + passes_to: "gzdoom.ini [FileSearch.Directories] Path" + fails_when_missing: false + source_ref: "gzdoom/rd_assets/rd_config/gzdoom.ini:18, gzdoom/component_prepare.sh:23,\ + \ 27-28" - emulator: gzdoom build: standalone kind: passes_path @@ -16765,6 +16783,15 @@ launchers: fails_when_missing: false source_ref: "gzdoom/rd_assets/rd_config/gzdoom.ini:19, gzdoom/component_prepare.sh:23,\ \ 28" +- emulator: gzdoom + build: standalone + kind: passes_path + names: [] + search_dir: $roms_path/bios/gzdoom + passes_to: "gzdoom.ini [SoundfontSearch.Directories] Path" + fails_when_missing: false + source_ref: "gzdoom/rd_assets/rd_config/gzdoom.ini:31, gzdoom/component_prepare.sh:23,\ + \ 27-28" - emulator: mame build: standalone kind: passes_path @@ -16996,8 +17023,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: xroar.conf rompath fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:290, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:290, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17007,8 +17033,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:291, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:291, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17023,8 +17048,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist d64_1 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:292, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:292, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17038,8 +17062,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist d64_2 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:293, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:293, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17052,8 +17075,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist d32 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:294, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:294, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17065,8 +17087,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist d200e_1 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:295, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:295, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17078,8 +17099,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist d200e_2 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:296, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:296, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17095,8 +17115,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon64 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:297, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:297, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17110,8 +17129,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon64_alt fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:298, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:298, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17125,8 +17143,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon32 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:299, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:299, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17145,8 +17162,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon200e fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:300, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:300, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17163,8 +17179,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon200e_alt fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:301, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:301, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17175,8 +17190,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragon200e_charset fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:302, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:302, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17190,8 +17204,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragonpro_boot fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:303, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:303, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17209,8 +17222,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragonpro_basic fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:304, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:304, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17224,8 +17236,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:305, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:305, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17238,8 +17249,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco_ext fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:306, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:306, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17253,8 +17263,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco1 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:307, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:307, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17268,8 +17277,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco1e fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:308, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:308, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17282,8 +17290,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco1e_ext fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:309, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:309, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17297,8 +17304,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco2 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:310, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:310, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17311,8 +17317,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco2_ext fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:311, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:311, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17326,8 +17331,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco2b fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:312, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:312, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17338,8 +17342,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist deluxecoco fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:313, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:313, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17349,8 +17352,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist deluxecoco1 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:314, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:314, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17360,8 +17362,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist deluxecoco2 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:315, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:315, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17372,8 +17373,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist deluxecoco3 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:316, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:316, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17384,8 +17384,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist mx1600 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:317, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:317, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17395,8 +17394,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist mx1600ext fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:318, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:318, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17406,8 +17404,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco3 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:319, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:319, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17417,8 +17414,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist coco3p fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:320, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:320, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17429,8 +17425,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist glenside_ide fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:321, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:321, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17440,8 +17435,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist mc10 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:322, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:322, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17451,8 +17445,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist alice fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:323, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:323, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17467,8 +17460,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragondos fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:324, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:324, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17481,8 +17473,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dosplus fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:325, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:325, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17495,8 +17486,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist superdos fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:326, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:326, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17508,8 +17498,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist cumana fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:327, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:327, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17535,8 +17524,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist dragondos_compat fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:328, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:328, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17547,8 +17535,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist rsdos fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:329, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:329, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17563,8 +17550,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist delta fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:330, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:330, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17574,8 +17560,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist rsdos_becker fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:331, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:331, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17586,8 +17571,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist mcx128 fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:332, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:332, xroar/component_prepare.sh:13-15" - emulator: xroar build: standalone kind: names_searched @@ -17598,8 +17582,7 @@ launchers: search_dir: "$roms_path/coco:$roms_path/dragon32:$roms_path/tanodragon:$bios_path" passes_to: romlist mcx128_azerty fails_when_missing: false - source_ref: "xroar/rd_assets/rd_config/xroar.conf:333, xroar/component_prepare.sh:13,\ - \ 15" + source_ref: "xroar/rd_assets/rd_config/xroar.conf:333, xroar/component_prepare.sh:13-15" - emulator: retroarch build: libretro kind: core_option diff --git a/scripts/launchers.py b/scripts/launchers.py index 4e3c103f4..6d959339a 100644 --- a/scripts/launchers.py +++ b/scripts/launchers.py @@ -312,6 +312,11 @@ def launcher_places(config: dict) -> list[LauncherPlace]: # component scripts $bios_path. BIOS_ROOT_VARIABLES = ("$biosdir", "$home/RetroPie/BIOS", "${biosPath}", "$bios_path") +# The name a platform's launch code gives its roms root: RetroDECK's +# component scripts write $roms_path (retrodeck_launchers), the setting whose +# default is the roms root (config/retrodeck/retrodeck.json:5). +ROMS_ROOT_VARIABLES = ("$roms_path", "${roms_path}") + # The kinds that hand an emulator a whole directory. A scans_dir record sets # the directory the emulator picks its file from: ROCKNIX writes ARMSX2's # [Folders] Bios, EmuDeck PCSX2's. @@ -591,8 +596,15 @@ def folder_in_roms(directory: str, config: dict) -> str | None: (``roms_root.path``): ROCKNIX's /storage/roms, which holds its BIOS folder and the folders its launchers run programs from. """ - from common import ROMS_ROOT # noqa: PLC0415 + from common import ROMS_ROOT, outer_layout # noqa: PLC0415 + spelled = directory.strip().rstrip("/") + for variable in ROMS_ROOT_VARIABLES: + if outer_layout(config, ROMS_ROOT) and ( + spelled == variable or spelled.startswith(variable + "/") + ): + rest = spelled[len(variable) + 1:] + return None if re.search(r"[\s<>$:;]", rest) else rest return folder_in_root(directory, config, ROMS_ROOT) diff --git a/scripts/scraper/retrodeck_launchers.py b/scripts/scraper/retrodeck_launchers.py index fb838c1b1..51b6cf06b 100644 --- a/scripts/scraper/retrodeck_launchers.py +++ b/scripts/scraper/retrodeck_launchers.py @@ -30,6 +30,10 @@ except ImportError: BIOS = "$bios_path" PLACEHOLDER = "RETRODECKBIOSDIR" +# The roms folder in the same presets: GZDoom's IWADSearch.Directories holds +# RETRODECKROMSDIR/doom (gzdoom/rd_assets/rd_config/gzdoom.ini:9), which +# gzdoom/component_prepare.sh:27 rewrites to $roms_path. +ROMS_PLACEHOLDER = "RETRODECKROMSDIR" CORE_OPTIONS = "retroarch/rd_assets/rd_config/retroarch-core-options.cfg" # The component that runs libretro cores. LIBRETRO_COMPONENT = "retroarch" @@ -282,7 +286,11 @@ class Component: ) def _preset(self, script: Script, number: int, words: list[str]) -> None: - """`sed -i "s#RETRODECKBIOSDIR#${bios_path}#g" "$cfg"` on a preset copied just above.""" + """`sed -i "s#RETRODECKBIOSDIR#${bios_path}#g" "$cfg"` on a preset copied just above. + + Each line naming the BIOS or the roms folder is a record: a search + list can mix them (XRoar's rompath, GZDoom's IWAD directories). + """ target = words[-1] substitutions = self._substitutions(script, target) copied = None @@ -302,17 +310,25 @@ class Component: stripped = line.strip() if re.fullmatch(r"\[[^\]]+\]", stripped): section = stripped - if PLACEHOLDER not in stripped or stripped.startswith("#"): + if stripped.startswith("#") or not any( + p in stripped for p in (PLACEHOLDER, ROMS_PLACEHOLDER) + ): continue setting = re.match(r"^([\w.$()-]+)\s*(?:=|\s)\s*(.+)$", stripped) if setting is None: raise LauncherPatternMissing(f"{preset}:{line_no}", f"placeholder in {stripped}") + named = [p for p in substitutions if p in stripped] + if PLACEHOLDER not in stripped and not named: + # A roms placeholder the script leaves as written. + continue key, value = setting.group(1), _unquote(setting.group(2)) - for placeholder, variable in substitutions.items(): + for placeholder, (variable, _line) in substitutions.items(): value = value.replace(placeholder, variable) where = f"{section} {key}" if section else key - found += 1 - applied = [(script.path, copied[0]), (script.path, number)] + found += PLACEHOLDER in stripped + applied = [(script.path, copied[0]), (script.path, number)] + [ + (script.path, substitutions[p][1]) for p in named + ] self.record( "passes_path", [], [(preset, line_no)] + applied, search_dir=value, passes_to=f"{self.config_name(target)} {where}", @@ -324,12 +340,13 @@ class Component: raise LauncherPatternMissing(preset, f"no {PLACEHOLDER} line") @staticmethod - def _substitutions(script: Script, target: str) -> dict[str, str]: + def _substitutions(script: Script, target: str) -> dict[str, tuple[str, int]]: + """Each placeholder sed rewrites in ``target``: (variable, line).""" found = {} - for line in script.lines: + for line_no, line in enumerate(script.lines, 1): for m in re.finditer(r"s#(RETRODECK\w+)#\$\{?(\w+)\}?#g[\"']?\s+\"([^\"]+)\"", line): if m.group(3) == target: - found[m.group(1)] = f"${m.group(2)}" + found[m.group(1)] = (f"${m.group(2)}", line_no) return found def romlists( diff --git a/tests/test_launcher_placement.py b/tests/test_launcher_placement.py index 0cf499fe6..2ffa4d23c 100644 --- a/tests/test_launcher_placement.py +++ b/tests/test_launcher_placement.py @@ -859,5 +859,25 @@ class MameSearchPaths(unittest.TestCase): self.assertEqual(entry["standalone_path"], "psxmame/bios/" + entry["name"]) +class GzdoomOnRetroDECK(unittest.TestCase): + """RetroDECK writes RETRODECKROMSDIR/doom into [IWADSearch.Directories] + (gzdoom.ini:9, component_prepare.sh:27).""" + + def test_the_iwads_land_in_roms_doom(self) -> None: + view = standalone_view("gzdoom", "retrodeck") + iwads = [e for e in view["files"] if e.get("system")] + self.assertEqual(len(iwads), 43) + for entry in iwads: + self.assertEqual(entry["standalone_path"], "roms/doom/" + entry["name"]) + self.assertTrue(entry.get("unprefixed")) + # The engine pk3s are read beside the executable first. + (pk3,) = [e for e in view["files"] if e["name"] == "gzdoom.pk3"] + self.assertNotIn("standalone_path", pk3) + + def test_another_platform_keeps_them(self) -> None: + view = standalone_view("gzdoom", "batocera") + self.assertFalse(any(e.get("standalone_path") for e in view["files"])) + + if __name__ == "__main__": unittest.main() diff --git a/tests/test_launchers_retrodeck.py b/tests/test_launchers_retrodeck.py index 96401837c..e894d6838 100644 --- a/tests/test_launchers_retrodeck.py +++ b/tests/test_launchers_retrodeck.py @@ -289,7 +289,7 @@ class Presets(unittest.TestCase): self.assertEqual(lists["dragon64"]["names"][-1], "dragon") self.assertEqual( lists["d64_1"]["source_ref"], - "xroar/rd_assets/rd_config/xroar.conf:292, xroar/component_prepare.sh:13, 15", + "xroar/rd_assets/rd_config/xroar.conf:292, xroar/component_prepare.sh:13-15", ) def test_a_reference_to_an_unknown_romlist_raises(self):