Commit Graph
2351 Commits
Author SHA1 Message Date
Abdessamad Derraz 8633db0a22 chore: merge voxatron split and emulator folders 2026-11-09 18:56:51 +01:00
Abdessamad Derraz c8fe8d914d feat: install files into retrobat emulator folders
RetroBat's Pico8 generator runs pico8.exe from AppConfig.GetFullPath:
the emulatorLauncher.cfg key, else the first existing of four folders of
the RetroBat install. The registry describes that search
(emulators_directory) and the manifest writes such a file as
root: emulators. The installer places it only when the BIOS folder sits
beside RetroBat's launcher config and the config does not move the
folder, and names it no_emulators_directory otherwise. Packs skip it as
they skip root: roms.

The PICO-8 0.2.7 Windows build (pico8.exe, SDL2.dll) is collected from
the archive.org copy of pico-8_0.2.7_windows.zip, its pico8.dat being
the 0.2.7 one already held.
2026-11-09 18:55:49 +01:00
Abdessamad Derraz f47c8b8e5a fix: profile voxatron apart from pico-8
lexaloffle documented two programs, so every platform naming PICO-8
received Voxatron's files: ROCKNIX, RetroDECK and RetroBat run PICO-8
only. Voxatron is its own profile, named vox_official. A platform also
runs the emulators its standalone_cores list names: Batocera and KNULLI
list lexaloffle there and nowhere else.
2026-11-09 18:48:13 +01:00
Abdessamad Derraz ad424f796b chore: merge one-of sets 2026-11-09 18:33:21 +01:00
Abdessamad Derraz 2fe15e99f9 chore: merge launcher names 2026-11-09 18:29:52 +01:00
Abdessamad Derraz b5f82fdd29 chore: drop the lwmp dedup entry
splitwolf, already in NODEDUP_DIRS, covers bios/Other/splitwolf/lwmp.
2026-11-09 18:27:21 +01:00
Abdessamad Derraz 58735286a7 feat: let an archive join a set
Kronos reads kronos/stvbios.zip, else stvbios.zip at the root of the
system directory, and a ST-V game stops without either
(libretro.c:1608-1617, 1676-1681 at the pin). The archive under
archive_prefix and the root copy are one need, but only loose entries
could be members, so the required-only pack carried both.

An archive's own entry now joins a set like a loose file. verify
--emulator and the emulator pack settle archive units with the loose
entries, the required-only pick covers them, find_undeclared_files
and cross_reference record them, and the unit under archive_prefix
ranks before the same name at the root. Its members still settle the
archive by their contents. Kronos' stvbios.zip is grouped stv-bios.

No other profile reads one archive under two paths: odin and
tgpulse_next_m1 place their own entries at the prefix path, and
flycast's naomi.zip has one path per build.
2026-11-09 18:26:05 +01:00
Abdessamad Derraz 56ed37c3f0 chore: merge launcher placement 2026-11-09 18:23:46 +01:00
Abdessamad Derraz 5794ed4178 fix: drop the atari800 config key aliases
ROM_5200_A, ROM_BASIC_A and six more are atari800.cfg keys, not names
atari800 opens: MatchByName knows only atariosa.rom and its kin
(sysrom.c:278-294), and the keys are config_key since 969907e29. The
twelve labels the scan identifies by CRC32 are found_by: content, and a
platform declaration of a file such an entry accepts by hash, in the
folder the core scans, now meets it: RetroDECK's ROM_BASIC_A answers
atari-basic-rev-a.rom without the alias.
2026-11-09 18:22:55 +01:00
Abdessamad Derraz 65e1db9fe1 feat: place files outside the bios tree
A platform that binds part of a standalone layout leaves the entries no
binding covers in a folder outside the BIOS tree: they are no longer
packed at the BIOS root, and the manifest names them (root: emulator,
outside_bios_folder). A launcher that executes a profile's file binds
the program folder: in the BIOS tree, below the roms directory a registry
entry names (root: roms, installed into the folder holding the BIOS
folder), or nowhere a pack reaches. A moved entry resolves by its own
path as well as by its destination.

uae4all gains kick.rom and rom.key in its working directory and loses a
not_bundled_on that named Recalbox, which runs uae4all-rpi. lexaloffle
declares that its programs read beside their executable, lists the
Windows build RetroBat runs and the pico8_dyn ROCKNIX runs on x86_64.
2026-11-09 18:22:34 +01:00
Abdessamad Derraz b5ee4ab09e feat: read pico-8 launchers of rocknix, retrobat
ROCKNIX's start_pico8.sh runs pico8_64 or pico8_dyn from
/storage/roms/pico-8 and RetroBat's Pico8 generator runs pico8.exe from
its pico8 emulator folder. Both are recorded as exec records, read from
the scripts at the revisions the platform files pin.
2026-11-09 18:22:26 +01:00
Abdessamad Derraz 315dab82b7 feat: give each set its requirement and one pick
Three changes to the search-list model, one commit because the readers
and the profiles must move together for the schema to hold.

Set requirement in a groups map. pom2 falls back on apple2.rom for the
][ and the ][+, and on apple2e.rom for the //e it boots and for the
unenhanced //e: one required on the file could not say both. A profile
now declares groups: {name: {required}}, a member writes no required
of its own (schema and validate_schemas refuse one) and load_emulator_
profiles derives it, true when one of its sets is. group takes a name,
a list, or a map from set to rank where the rank differs per set. pom2
is grouped from SystemProfile.cpp and MainWindow.cpp:246-296 at its pin.

One member per required set under --required-only. The pick is the
first the code reads among the held members the region filter leaves,
by rank then declaration order; a set the platform declares a member
of is carried by that declaration. The emulator pack, verify
--emulator, the platform pack, its manifest and verify --platform read
alternatives.required_only_spares or core_file_spares.

variant_group is now selection_slot: files a core chooses between by
a rule other than first found (disc territory for PicoDrive and
Pizza Boy SC, the o2em_bios option, a WebAssembly probe in SWF
Player). Where the code takes any one, the field became a group:
ARMSX1 (ArmSxBackend.java:149-157, name order), ePSXe (load_bios
0x433540-0x433621 of the 2.0.5 Linux x64 binary, one configured path,
HLE when BiosHLE is set), FPse and FPse-NG, DXX-Rebirth's HOGs
(inferno.cpp:472-512). odin and zesarux carried it with no effect.
slot.py compares ranks only between candidates that share a set.
2026-11-09 18:19:32 +01:00
Abdessamad Derraz a9fdf6eefc docs: state the scph10000 tie-break
The model fill picks the original revision when two primaries are
equally accepted, so every run ships the same file.
2026-11-09 18:15:48 +01:00
Abdessamad Derraz 47ae5aa601 feat: fill a launcher name from a settled entry
The gap report never offers an entry the platform's list settles, so
AmberELEC's amiberry configs, which pass kick34005.A500.rom and
kick40068.A1200.rom beside a declared kick34005.A500, got nothing. The
launcher layer now reads the entries it was not offered, through the
setting or the extended name only: by its own name an entry left out of
the report was left out for a reason.
2026-11-09 18:13:24 +01:00
Abdessamad Derraz 13bd4a3698 feat: pair each config name with its key
A record naming several files of one config lists their keys in the
same order (describe_keys). Each launcher place now carries its own
key, so AmberELEC's 5200a.rom receives the ROM_5200_A file.
2026-11-09 18:10:05 +01:00
Abdessamad Derraz 46fc4d5d15 chore: merge integ into fix-launch-names 2026-11-09 18:05:44 +01:00
Abdessamad Derraz 5073e4ea85 chore: merge knulli and amberelec launchers 2026-11-09 18:04:36 +01:00
Abdessamad Derraz 25e515f982 docs: quote the -rp flag in amberelec_launchers 2026-11-09 18:03:08 +01:00
Abdessamad Derraz 7ca7872fdc feat: record knulli's macintosh boot disk
MAME and libretro MAME pass /userdata/bios/<bootdisk>.img with -flop1
when the option is in the generator's list, else <bootdisk>.chd with
-hard. Each branch is a {bootdisk} template: the list the code tests
for the floppy, and for the hard disk the choices es_features.yml
offers that the list does not take. The menu offers macos3 while the
code tests macos30, so System 3.0 is passed as macos3.chd.
2026-11-09 18:03:08 +01:00
Abdessamad Derraz f0289e3624 feat: record pcsx2's relative bios folder
configureINI writes [Folders] Bios = ../../../bios/ps2 into
inis/PCSX2.ini, which PCSX2 and AetherSX2 resolve against the config
folder configgen hands it. relative_folders reads the call, the ini
path and the value, and records the resolved /userdata/bios/ps2 as a
passes_path for pcsx2 and aethersx2.
2026-11-09 17:59:09 +01:00
Abdessamad Derraz cedeee2254 refactor: one meaning for copy records
A copies record names its files under search_dir, the folder the code
copies from, and passes_to is the target, as the schema and RetroPie,
RetroDECK and AmberELEC already write it. KNULLI listed patches.zip
under the BIOS folder it is copied into, and KNULLI and RetroBat wrote
the target as prose with the condition. The condition of a copy now
goes in depends_on_option. Only launcher records change in knulli.yml
and retrobat.yml.
2026-11-09 17:58:37 +01:00
Abdessamad Derraz 8114f48e30 feat: fill a core option default by model
RetroDECK sets LRPS2's pcsx2_bios to scph10000.bin. The record names
the frontend, so the core is the one whose entry reads that setting.
Its entry is a placeholder, and the name spells a model: the held dump
the catalogues describe as SCPH-10000 goes in under that name in the
entry's directory, primaries first, then the earliest Redump revision
(ps2-0100j-20000117).
2026-11-09 17:53:48 +01:00
Abdessamad Derraz a6aea81c17 chore: merge integ into fix-launch-names 2026-11-09 17:47:35 +01:00
Abdessamad Derraz 21d34748e5 feat: list unsourceable launcher names apart
A launcher name that a reader's profile entry declares unsourceable is
no file left to find. Its row carries the reason and both reports
print it under its own count, never mixed with the names to acquire.
2026-11-09 17:47:26 +01:00
Abdessamad Derraz ffad06487c feat: read the amberelec launcher layer
amberelec_launchers reads runemu.py with ast and, at the commit the
scraper pins, the scripts its standalone table runs and the configs
their packages install: RetroArch and retrorun directories, the MAME
-rp path, atari800.cfg, Hatari's default TOS, amiberry's kickstarts
link and defaults, yabasanshiro, PICO-8, piemu, scummvm, freej2me and
easyrpg. 17 records.

The freej2me-lr.jar and pico8_64 notes now name the file in a sentence
about the emulator, as test_launcher_aliases asks once a launcher
records it.
2026-11-09 17:47:23 +01:00
Abdessamad Derraz 2c58f50a2d feat: read the knulli launcher layer
knulli_launchers reads KNULLI's configgen and the PICO-8 installer at
the tag the scraper pins: Batocera's extractors where the generator is
still Batocera's code, KNULLI's own for lexaloffle, libretroOptions and
knulli-install-pico8, and one AST reader for the BIOS paths the other
generators pass on a command line, in a config key or the environment,
copy or test for. 52 records.
2026-11-09 17:47:16 +01:00
Abdessamad Derraz 10e4d925d0 refactor: root the configgen reader at a package
Configgen takes the configgen package path and whether the importer has
a legacy map, so KNULLI's copy at package/system/knulli-configgen reads
with the same extractors. hatari accepts the bare filename KNULLI builds
and joins to BIOS, and options read by subscript or isOptSet. melonds
accepts a console type read by subscript. Batocera's records are
unchanged at batocera-43.1.
2026-11-09 17:47:09 +01:00
Abdessamad Derraz 768cc9fd6f chore: merge origin/main 2026-11-09 17:43:44 +01:00
Abdessamad Derraz 6024932846 feat: read a launcher name with an added extension
ROCKNIX's Amiberry configs pass kick34005.A500.rom and
kick40068.A1200.rom, Amiberry's names for Kickstart 1.3 and 3.1 with
.rom appended. Amiberry opens the path as given and boots AROS without
it, so the pack now ships the held ROM under the launcher's name.
2026-11-09 17:42:13 +01:00
Abdessamad Derraz 2c76cc7df9 feat: read a search list as one need
A core that loads the first of several names (yabause: saturn_bios.bin,
sega_101.bin, mpr-17933.bin) needs one of them. Profiles wrote this as
required on the first name and optional on the others, so verify and
the gap report called saturn_bios.bin a missing required file while
sega_101.bin was held, and a set held only through a name marked
optional read as a need met by an optional file.

Model: an explicit group on the file entry, mirroring the platform
field. priority was not reused: it is a rank, read by slot.py, region.py
and truth.py inside a (system, region) slot, and that slot is not the
set. px68k-sdl ranks its IPL list and its font list each from 1 in one
system, pom2 ranks one list per machine model, DuckStation ranks 105
images across every region and takes any of them. A rank cannot say
where one list ends. priority stays the order inside a group.

Readers, through alternatives.settle_sets:
- verify --emulator and the emulator pack: a held member fills the
  set, the others leave the report, a set nobody holds is one gap
  under its first member naming the others.
- find_undeclared_files (verify platform, core complement of packs and
  manifests): same rule, a platform declaration or launcher counts as
  answering the set.
- cross_reference: excused members are set aside as other versions.
- slot.py: ranks compare members of one set only.
- archive members: a required set inside an archive is met by one.
- truth: a member gives no requirement of its own, one_of and
  one_of_required carry the set, and the exporters and the diff leave
  such a line's required as the platform wrote it.
- validate_schemas: members of a group share required.
2026-11-09 17:39:46 +01:00
Abdessamad Derraz 7f04ed8096 chore: merge emuelec launchers 2026-11-09 17:34:40 +01:00
Abdessamad Derraz 82a6b2f833 feat: read the emuelec launchers
emuelec_launchers.py reads emuelecRunEmu.sh and the scripts and
configs it starts at the tag batocera-systems is read at (v4.8): 36
records for RetroArch, retrorun, freej2me, MAME, PICO-8, Flycast,
Amiberry, DuckStation, Yabasanshiro, jzIntv, Mupen64Plus, Hatari,
AdvanceMAME, ScummVM, Dolphin and the MIDI synths.
2026-11-09 17:34:03 +01:00
Abdessamad Derraz 979111f6f2 feat: settle launcher names the code fills
A search a launcher stops at the first held name of is filled, and a
copy from the platform's own package or script brings its own file:
neither is a name the collection lacks. A launcher that writes its
file into the setting a profile entry is read from (config_key) now
receives that entry's held file under its own name, in the report and
in the pack.
2026-11-09 17:31:18 +01:00
Abdessamad Derraz 6a9700489d feat: place standalone files through links
standalone_bindings maps each subfolder of a standalone layout to the
folder of the BIOS tree a platform's links and passed directories give
it, followed through a working directory. platform_layouts applies it,
so the pack, the manifest, verify and slots read one destination.

uae4all paths are now what the emulator reads, kickstarts/<name> below
its working directory, and RetroPie still receives them in amiga/.
2026-11-09 17:28:00 +01:00
Abdessamad Derraz a2bf1c6f8e feat: record the uae4all working directory
RetroPie starts UAE4All2 with pushd $md_inst, the directory whose
kickstarts folder it links to BIOS/amiga. The scriptmodule reader now
emits that working directory as it does for DraStic.
2026-11-09 17:28:00 +01:00
Abdessamad Derraz b270a24d7b feat: take a platform's own libretro builds
A list naming retroarch now takes the libretro profiles whose built_by names the platform: ROCKNIX ships yabadabadoo with its RetroArch and named it nowhere, so its files never reached the ROCKNIX pack. Only change across the registry: rocknix + yabadabadoo. Also quotes the installer's current unproven-drive message.
2026-11-09 17:18:44 +01:00
Abdessamad Derraz fed8bdddd8 feat: read the lexaloffle launcher for batocera
Batocera's lexaloffleGenerator runs bios/pico-8/pico8 and
bios/voxatron/vox, raises when the binary is missing or not
executable, and puts each folder on LD_LIBRARY_PATH. The new
extractor records both per system from the AST, with the lines
of batocera-43.1 that say it.
2026-11-09 17:06:09 +01:00
Abdessamad Derraz 63d94b9415 feat: collect splitwolf lwmp tree
lwmp.zip from the project's downloads (sha1 1145464c), 2308 files read by path. Equal files sit in one folder per rotation, so the tree is kept out of dedup.
2026-11-09 16:55:31 +01:00
Abdessamad Derraz 244bd11075 chore: merge origin/main 2026-11-09 16:46:40 +01:00
Abdessamad Derraz 87839ea6c0 chore: merge origin/main 2026-11-09 16:37:13 +01:00
Abdessamad Derraz 6c14468862 feat: say the installer and setup pages plainly
- The installer speaks without "you": the first screen asks "Where
  to install?", rows read "Copy the BIOS files from an old card or a
  folder", a close match reads "Close matches: ...". The handheld
  launchers and their port text follow, and the pronoun guard no
  longer lists any installer message.
- A setup that runs as an app opens on its one-line command, the
  folder table after it; a setup that runs on its own device keeps
  the network folder first, which its ZIP route needs.
- The home steps say what to do: "Its page gives one line to copy",
  "Paste it, press Enter".
2026-11-09 16:33:56 +01:00
Abdessamad Derraz 8268f03269 feat: report files only a launcher reads
cross_reference and verify list the names a platform's launch code reads that the collection holds under no name. Reported apart, never scored.
2026-11-09 16:16:38 +01:00
Abdessamad Derraz 232f27f5db docs: say a refused option writes no event
An agent reading the events learns that an option refused before the run starts ends on code 2 with no end event.
2026-11-09 14:25:51 +01:00
Abdessamad Derraz 4c0c480bdd docs: tell agents how to drive the installer
llms.txt now gives the package commands, the plan as JSON events from
--dry-run --events, the exit codes and the plan, consent, act pattern
with --yes. Tests hold each fact to install.py and to the exit code table
of the installer page.
2026-11-09 14:23:35 +01:00
Abdessamad Derraz 92546794e2 docs: archive recipes page and README badges
Every archive has a recipe in recipes/archives.json, and no page a user
reads said so. A short reference page says what a recipe is, how to
rebuild one archive and what exact and canonical mean. Its counts and the
README line are counted from the recipe file at each build.

The README gains a row of four badges: PyPI version, Python versions,
the Validation workflow on main and the license. Tests hold the badges,
the counts and the page's command.
2026-11-09 14:23:29 +01:00
Abdessamad Derraz 025fd08a72 chore: merge origin/main 2026-11-09 14:02:45 +01:00
Abdessamad Derraz 09b2fc6a95 chore: drop the unreached sharpx1 name 2026-11-09 13:44:24 +01:00
Abdessamad Derraz 51aa626028 fix: fetch platform originals without exporting
--fetch also exported and stopped on the absent dist/truth before any
download, so CI skipped every exporter fidelity case and tolerated the
step. --refresh-cache only downloads: the step can no longer fail
unseen.
2026-11-09 12:45:57 +01:00
Abdessamad Derraz eb8f60aef7 fix: write retrobat group and optional back
The export dropped the two fields Program.cs reads besides md5 and file:
an empty truth no longer handed RetroBat's list back as written.
2026-11-09 12:45:56 +01:00
Abdessamad Derraz 31132eb37e chore: merge origin/main 2026-11-09 12:28:14 +01:00