The rom line renderer upper-cased every crc, so Dinothawr.zip's
683ed4ad, the one lower-case crc libretro writes, changed with no
correction behind it. A line whose values match ours now keeps its
bytes, a corrected crc follows the case of its own line, and an added
line keeps the file's upper case. An empty truth hands System.dat back
byte for byte for RetroArch and Lakka.
A changed element was rendered again, losing its alignment and the
place of its attributes, and an element whose md5 list was only
reordered (neogeo.zip, the same 24 digests) was rewritten too: Recalbox
accepts any digest of the list (Bios.cpp:109-130), so the order is not
content. A changed attribute is now replaced where it stands, one
dropped goes with its space, one added goes before />, and each system's
opening tag keeps its own indentation. An empty truth gives back the
cached es_bios.xml byte for byte.
An entry with one md5 to correct was written again whole: atarist lost
its eight blank lines, every '"x"},' became '"x" },', and most of the
819 lines Batocera's export changed were layout. Each item now keeps
its own text and only the md5 inside it changes; an addition follows
the last item in its indentation and spacing. The patched entry must
read as the one that would have been written, or that one is written.
Batocera's diff to the original drops to 273 lines, ROCKNIX's to 3.
RetroBat separates every system after the first with a blank line.
json.dumps dropped all 100 of them: 100 hunks of noise in a diff meant
to show corrections. The separator is written again where the original
has it, and an added system takes it too where the original separates
them all. An empty truth gives back the cached file byte for byte.
The BiosDB is published as a single line of JSON without a final
newline. Written with indent=2 it came out as 1499 changed lines for a
database whose content had not changed, which would bury any real
correction. It is now written in MiSTer's own form: an empty truth
gives back the cached database byte for byte.
With nothing to correct, nine of ten manifests still changed: a final
newline was added where the original ends without one, "md5": null was
written 39 times where no md5 key was, and PPSSPP's single bios object
became a list rebuilt from our data. A manifest now ends as the
original does, keeps no key it did not have, and a single object stays
one while nothing is added. An empty truth gives back every cached
manifest byte for byte.
write_text translated line ends on Windows, so FirmwareDatabase.cs's
CRLF would have come out CR CR LF; it replaced the published file in
place, so a run stopped mid-write left it truncated; and it dropped the
mode, while rocknix-systems is 100755 in ROCKNIX's tree. Files are
written atomically as UTF-8 bytes, and an exporter states the mode of
any file the platform does not publish as 0644.
Eight scriptmodules write "bios" in lower case (xm7, np2pi, quasi88,
minivmac, px68k...) and none was examined. A module reported "left as
is" for a name no profile documents was written all the same: the skip
had no continue. The cap of six names came from that case-sensitive
reading, where xm7 writes thirteen: a sentence now grows no longer than
the longest RetroPie writes. lr- was stripped whatever the build, so the
standalone minivmac package matched the libretro profile, which reads
another file. A file of a system RetroPie lacks is proposed to no
package: lr-geargrafx adds pcengine only (lr-geargrafx.sh:41-42) and
was given the LaserActive's pac-n1.bin and pac-n10.bin.
The pack leaves out what an emulator installs itself
(validation.deliverable); the truth did not. RetroPie's gngeopi help
asked users to copy gngeo_data.zip, which make install puts in the
package's data directory, and amiberry's whdboot tree, scummvm's extra
data and dosbox-x's FREECG98.BMP went into platform lists as files to
bring.
The truth applies deliverable per platform and per build: an entry
nobody has to bring is kept and marked bundled, never added, still
corrected where the platform declares it. A rebuilt archive is
installed only when every member is. The runner written beside an
addition is the build that needs the file (_brought_by), and the
RetroPie sentence names only what its package's core must be given.
libretro titles each section with the system as it spells it,
"Commodore - Amiga". An addition for a system it has no section for
opened one under our slug: 21 sections came out as commodore-c64,
quake, laseractive or xrick, which no libretro DAT carries. An addition
now lands only in a section the original holds and is otherwise counted
as left out, so the export keeps the original's 66 sections. A platform
entry is always written, under its own section.
DuckStation identifies its BIOS by MD5 in a folder it scans
(bios.cpp:208), so its entries' names are labels. The export wrote them
into Batocera's and ROCKNIX's lists as files to hold: a user with only
scph5501.bin read 104 missing BIOS where DuckStation boots. Labels also
lent their md5 to a name another core opens, and paired by name they
replaced System.dat's scph5000.bin hashes.
found_by: name | content, on a profile or a file and keyed by build like
load_from. The truth records which cores open each name (_named_by). A
label pairs with a platform entry by hash only, is never added, merges
with an opened name only on a shared hash, and is counted in the export
report rather than listed as missing.
validate() ran after the files were written, so an export the
exporter's own validator refused still replaced the published one in
exports/, and only the exit code said so. The platform now fails before
anything is cleared or written.
pinned_base returned an empty base when the platform's source named no
revision or no longer ended in the exported file, and the exporter's
own branch URL was then patched without a word. Every file an export
reads must now carry the revision the platform YAML records, or the
platform fails and asks for a rescrape. The check covers every file of
every platform: ROCKNIX's second file, RetroDECK's manifests and
RetroPie's tarball were checked by nothing before.
A cached bios_db.json.zip that was not a zip raised BadZipFile out of
run(): --all stopped and the platforms after it were never exported.
fetch() also cached any 200 reply, so an error page replaced a good
archive and was served on every later run, and an IncompleteRead or an
oversized reply escaped the same way. An archive is now read before it
is cached, and an unreadable file fails its own platform with the
--refresh-cache remedy.
System.dat, RomM, Recalbox and RetroBat were rebuilt from our data when
their file was not cached: libretro's quoted names, Recalbox's comments
and one of its two zxspectrum blocks were lost, and the run said OK.
needs_original now follows native_sources, so every format we patch
fails without the file it patches and writes nothing.
dist/ is not committed and exports/ is. On a fresh clone, or with a
mistyped --truth-dir, the export copied each platform's file back
uncorrected, said OK and replaced the corrected export in exports/.
check_freshness then reported a stale export instead of the missing
model. The platform now fails, writes nothing, and names the
generate_truth command.
validation: names what the code verifies. dosbox checks
MT32_CONTROL.ROM against nine sha1 and size; the truth's one md5 and
crc32 describe one of those revisions, and the export wrote them beside
System.dat's own sha1, a rom line no file satisfies, and replaced
Batocera's md5. pcsx_rearmed and DuckStation check scph1001.bin by size,
and the v2.0 md5 platforms name was replaced by v4.1's.
checked_hashes keeps a hash the code does not name only where a checked
hash pins one content. Otherwise it still pairs a renamed file but never
corrects or fills a value the platform wrote. Additions keep every hash.
diff_truth reads the same rule.
Each truth entry claimed its platform line in turn, so the first one to
arrive won. dosbox-x's system.rom (alias bios.rom, no path) took
Batocera's np2kai/BIOS.ROM by name before np2kai's own np2kai/bios.rom
was tried, and the export wrote an IBM PCjr md5 on it. A path also
outranked a contradicting hash: the truth's MSX.rom joins bluemsx's path
and fmsx's md5, which replaced the blueMSX dump on Recalbox's and
System.dat's Machines/Shared Roms/MSX.rom while fmsx's own line held it.
pair_entries runs each test over every entry before the next, tests that
contradict no hash first. export_native and diff_truth both read it.
Every <bios> element the model held was rendered again, so attribute order, alignment, a line break inside md5 and the case of a digest changed in 222 elements that stated the same thing. The diff deleted 451 lines for 136 corrections. An element whose attributes say what Recalbox wrote now keeps Recalbox's own text: 175 lines, the corrections.
Notes were keyed by file path, so a comment before one of the items reading an archive came back before every item reading it: bk's '# MAME' twelve times. A comment after the list's opening bracket matched neither rule and was dropped (enterprise's ep128emu-core). Notes are now keyed by file and archive member, written once, and a head-line comment goes with the first item.
Additions took the component their system's entries sit in, whatever core reads them. 104 armsx2 and yaps2 files went into PCSX2's manifest, beetle_psx and rustation dumps into DuckStation's, a directxbox image into xemu's, all counted as added. An addition now lands only where a core reading it is that component's emulator: 132 additions instead of 581.
ROCKNIX registers DuckStation twice, as the libretro core under retroarch and as duckstation-sa under its own emulator. The exporter looked a standalone runner up as a core name, so standalone DuckStation's 98 additions were written for users of the libretro core, PS2 images included, and standalone ARMSX2 was refused. A libretro runner now answers with the retroarch pair, a standalone with its emulator's own.
Profiles, the wiki, comments, docstrings, command output and schema descriptions carried em-dashes, clause-joining semicolons, unicode arrows, box-drawing banners and check-mark glyphs. Each sentence was rewritten rather than having its character swapped. Hashes, paths, source_ref values and every cited file:line are unchanged, which a comparison of each parsed profile against the previous revision confirms.
validate_pr comments now say PASS and FAIL in words, and source_ref values in a profile's structured blocks render as code. test_prose_style fails if any of these comes back, in tracked files or in the generated site.
An export wrote into its platform directory without removing what an
earlier run left there, so RetroPie scriptmodules and RetroDECK
manifests the current truth no longer corrects stayed beside a
report saying they were untouched. Files the run does not produce
are now removed first.
The RomM export fetched known_bios_files.json and never read it: the
fixture was rebuilt in our own order, so three corrections came out
as a diff of the whole file and a key we had not transcribed was
deleted. The export now starts from RomM's file, keeps its order and
fields, and only changes the values it corrects.
libretro indents 39 rom lines of System.dat with spaces. The export
read tab-indented lines only, so those left the base and came back
re-rendered at the end of their section, and one our transcription
lacked would have been deleted. Any indentation is read and kept.
The export only indexed firmware BizHawk leaves unhashed on purpose,
per-console dumps declared with SHA1Checksum.Dummy, and could only
apply that hash to a same-named call of another system. Every hash
the file states is BizHawk's own, so nothing is rewritten and no
correction is reported.
A truth that accepts several sizes left an export with no size even
where the platform states one of them for the same dump, and RomM's
fixture then received the string None, which RomM cannot parse. A
size list now admits the platform's own size, RomM keeps its value
when nothing settles one, and validation requires a number.
The export cache wrote an original's bytes, then recorded the URL
that produced them under a separate lock, so two runs wanting two
revisions of one file could pair one's bytes with the other's URL.
Both now change under the one index lock.
generate_pack kept a private .gitignore parser whose cache ignored the
root it was asked about, and generate_db a copy of the shared one. Both
now read largefiles.load_registered_paths, cached per root. Test modules
whose main block preceded their last class end with it again.
Batocera, ROCKNIX and Recalbox find a file through the core that wants
it. Additions now carry that core under the platform's own name: the
emulator/core pair checkBios reads (ROCKNIX's from its emulators
package), or Recalbox's core attribute. One with no nameable core, or
filed in a system gated on another core, is counted as not stated.
export_native turns the profile data back into each platform's own
file, for a maintainer there to pick up and use, and none of the ten
exporters had a test. Coverage goes from 0 to 83%.
Writing them found the EmuDeck exporter rejecting its own output: its
export skips placeholder entries, its validate looked for them anyway
and reported the omission as a missing hash. Both sides apply the same
filter now.
The placeholder assertion initially passed for the wrong reason twice
over -- the fixture entry had no hash, so it was dropped as incomplete
rather than as a placeholder, and the assertion then read the name
while the exporters write the path. It is pinned on an unmistakable
destination now, and removing the guard fails two tests.