diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml index 136a7666..45ec7700 100644 --- a/.github/workflows/deploy-site.yml +++ b/.github/workflows/deploy-site.yml @@ -80,7 +80,7 @@ jobs: with: python-version: "3.12" - # mkdocs-material >= 9.7.5 caps mkdocs < 2; the upper bound keeps a major + # mkdocs-material >= 9.7.5 caps mkdocs < 2, and the upper bound keeps a major # theme release from changing the site without a deliberate bump here. - run: pip install pyyaml "jsonschema[format-nongpl]==4.26.0" "mkdocs-material>=9.7.5,<10" "pymdown-extensions>=10.14" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index d6d195a1..94b4c64f 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,7 +17,7 @@ on: - "install.py" - "install.sh" - "install.ps1" - # Spelled out twice because the workflow parser reads no YAML anchor; a test + # Spelled out twice because the workflow parser reads no YAML anchor. A test # holds the two lists equal. push: branches: [main] @@ -118,7 +118,7 @@ jobs: run: python scripts/validate_schemas.py --source-only # A profile written from a clone can cite lines that do not hold the value - # it declares; schemas and tests pass it. Each profile a change adds is + # it declares, and schemas and tests pass it. Each profile a change adds is # confronted with its upstream, both roads into main. An edited profile is # not held to it: the backlog of older refs is reviewed by hand. check-new-profiles: @@ -141,7 +141,7 @@ jobs: BEFORE: ${{ github.event.before }} run: | # A pull request is checked out as a merge commit whose first - # parent is the base; a push names the commit it moved main from. + # parent is the base, while a push names the commit it moved main from. if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then base=HEAD^1 elif [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff78b245..4ed74f74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,8 +36,8 @@ Full walkthrough: [profiling guide](https://abdess.github.io/retrobios/wiki/prof - `bios/Manufacturer/Console/.variants/filename.sha1prefix` for alternate versions - Files >50 MB go in GitHub release assets (`large-files` release) - RPG Maker and ScummVM directories are excluded from deduplication -- Two paths differing only by case break clones on Windows and macOS; - `tests/test_no_case_collisions.py` enforces this +- Two paths differing only by case break clones on Windows and macOS, + and `tests/test_no_case_collisions.py` enforces this ## Before opening a PR diff --git a/NOTICE b/NOTICE index 70191bcd..0d06ec96 100644 --- a/NOTICE +++ b/NOTICE @@ -38,4 +38,4 @@ can open an issue at identifying the file by path or hash. Requests are handled on receipt, and a file whose removal is requested by its rights holder is removed from the repository and from the next release without requiring a formal notice. State -the file and the basis of the claim; no particular format is needed. +the file and the basis of the claim. No particular format is needed. diff --git a/README.md b/README.md index 67f3241b..f7d83aaf 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ The script auto-detects your platform, downloads only missing files, and verifie ## Download BIOS packs -One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file. At a terminal it asks whether to install everything or to choose systems, cores and regions, and `--system`, `--core`, `--region` and `--target` make the same choice without questions; for a bare minimum, build your own pack below. -Files is how many the pack holds once extracted, the figure a file manager shows for the folder. It differs from one platform to the next because a pack carries only what that platform's emulators load. The size is what the files occupy once extracted; the ZIP itself downloads smaller. +One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file. At a terminal it asks whether to install everything or to choose systems, cores and regions, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below. +Files is how many the pack holds once extracted, the figure a file manager shows for the folder. It differs from one platform to the next because a pack carries only what that platform's emulators load. The size is what the files occupy once extracted, and the ZIP itself downloads smaller. A pack over 2 GB comes in several parts, and every part is needed. How to open them depends on their name: @@ -64,16 +64,16 @@ The RetroDECK pack already carries its own `bios/` folder, so it extracts into ` ## What's included BIOS, firmware, and system files for consoles from Atari to PlayStation 3. -These are the files an emulator loads from disk instead of carrying inside itself. Some are required to boot a system, others improve accuracy or unlock a feature; the packs carry both. +These are the files an emulator loads from disk instead of carrying inside itself. Some are required to boot a system, others improve accuracy or unlock a feature, and the packs carry both. Each file is checked the way your platform checks it. Most compare a checksum, the fingerprint of a file's contents, which catches a corrupt or unexpected copy. RetroArch, Lakka and RetroPie only look for the filename, because that is all their code does: the Coverage table says which applies to you. Independently of that, the collection records five fingerprints per file, and wherever an emulator's code states an expected size or hash, that value is read from its source and rechecked here. -- **425 files** the platforms' emulators load are still to be found, and 55 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made); both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/) +- **425 files** the platforms' emulators load are still to be found, and 55 more cannot be sourced at all (per-user keys, user-filled slots, dumps nobody has made). Both are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/) - **12 platforms** supported with platform-specific verification - **530 emulators** profiled from source (RetroArch cores + standalone) - **513 systems** handled by those emulators (NES, SNES, PlayStation, Saturn, Dreamcast, ...) - **19,081 files in the collection**, each with its SHA1, MD5, SHA256, CRC32 and Adler-32 fingerprints: 5,339 system files, 2,813 arcade ROM sets, 10,929 game and engine data files. That is every platform and emulator together, so no pack holds them all: each carries what its own emulators load, counted in the download table -- **563 of 5,339 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC); arcade sets and engine data fall outside what those catalogs index +- **563 of 5,339 system files** matched to dump-preservation catalogs (No-Intro, Redump, TOSEC). Arcade sets and engine data fall outside what those catalogs index - **16755 MB** total collection size ## Supported systems @@ -147,9 +147,9 @@ The [documentation site](https://abdess.github.io/retrobios/) provides: ## How it works Documentation and metadata can drift from what emulators actually load. -To keep packs accurate, platform lists are checked against emulator source code, file by file where a profile exists; when the two disagree, the code wins. +To keep packs accurate, platform lists are checked against emulator source code, file by file where a profile exists. When the two disagree, the code wins. -Hashes document what emulator code loads and accepts, not dump provenance; that boundary, and how it relates to preservation catalogs such as No-Intro, is drawn in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#are-these-files-verified-against-original-hardware-dumps). +Hashes document what emulator code loads and accepts, not dump provenance. That boundary, and how it relates to preservation catalogs such as No-Intro, is drawn in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#are-these-files-verified-against-original-hardware-dumps). 1. **Read emulator source code** - trace every file the code loads, its expected hash and size 2. **Cross-reference with platforms** - match against what each platform declares diff --git a/emulators/2600-emu.yml b/emulators/2600-emu.yml index b9679229..12bcf588 100644 --- a/emulators/2600-emu.yml +++ b/emulators/2600-emu.yml @@ -29,7 +29,7 @@ notes: | (2600.emu/src/stella/emucore/CartAR.cxx:263-278). The build defines EMU_EX_PLATFORM, SOUND_SUPPORT and THUMB_SUPPORT - (2600.emu/CMakeLists.txt:22); DEBUGGER_SUPPORT and CHEATCODE_SUPPORT are + (2600.emu/CMakeLists.txt:22). DEBUGGER_SUPPORT and CHEATCODE_SUPPORT are absent, so the cheat database and the debugger are not compiled. PropertiesSet is constructed on CompositeKeyValueRepositoryNoop (2600.emu/src/stella/emucore/PropsSet.cxx:29-32), so cartridge properties come diff --git a/emulators/81.yml b/emulators/81.yml index d699275f..b0fe3e4a 100644 --- a/emulators/81.yml +++ b/emulators/81.yml @@ -32,7 +32,7 @@ notes: | files: # --- Machine ROMs --- - # All mode: standalone — libretro core embeds what it needs + # All mode: standalone, the libretro core embeds what it needs # ZX81 (default machine for both libretro and standalone) - name: zx81.edition3.rom diff --git a/emulators/a7800.yml b/emulators/a7800.yml index ceb0bf9d..b6545b99 100644 --- a/emulators/a7800.yml +++ b/emulators/a7800.yml @@ -33,7 +33,7 @@ notes: | machines fall back to the a7800 set, and the manual documents one merged archive at bios/a7800.zip. Inside an archive the search tries name with CRC, then CRC alone, then name (fileio.cpp:692-701), so a ROM whose filename - differs from the driver still resolves; loose files under rompath/a7800/ + differs from the driver still resolves. Loose files under rompath/a7800/ match by name only. Loaded ROMs are checked for exact length and against the declared CRC32 and SHA1, and a mismatch is a warning (romload.cpp:417-455). diff --git a/emulators/abuse.yml b/emulators/abuse.yml index cc36cad7..ad812711 100644 --- a/emulators/abuse.yml +++ b/emulators/abuse.yml @@ -14,7 +14,7 @@ verification: existence notes: | Side-scrolling 1995 action game by Crack dot Com, SDL2 fork from the Xenoveritas branch. The port ships its own game data in-tree under data/ (14 MB), including - the Lisp scripts, levels, art and freedesktop metadata; the fRaBs expansion was + the Lisp scripts, levels, art and freedesktop metadata. The fRaBs expansion was removed from this fork over licensing uncertainty. Entry point abuse.lsp is loaded relative to the data directory. The data root @@ -42,7 +42,7 @@ files: bundled: true source_ref: "src/loader2.cpp:284 (lsf default), src/netcfg.cpp:204 (lsf override)" note: > - Shipped in the source tree under data/. Loader2 reads it via load(); the + Shipped in the source tree under data/. Loader2 reads it via load(), and the file in turn chain-loads the rest of the Lisp data (english.lsp, common.lsp, startup.lsp, options.lsp, input.lsp, startup). diff --git a/emulators/ace-dl.yml b/emulators/ace-dl.yml index 86582286..ebbe075b 100644 --- a/emulators/ace-dl.yml +++ b/emulators/ace-dl.yml @@ -25,14 +25,14 @@ notes: | Machines are CPC 464, 664 and 6128 plus the Plus range, which boots from a cartridge and covers the GX-4000. An operating system is one 32 KB file - holding the 16 KB firmware ROM followed by the 16 KB BASIC ROM; the AMSDOS + holding the 16 KB firmware ROM followed by the 16 KB BASIC ROM. The AMSDOS disc ROM is a separate 16 KB file mapped in slot 7. The upstream MorphOS release keeps the three ROMs apart under System/ and composes them at startup, ACE-DL ships them pre-joined under private/firmware/ with one file per machine and language. The pairs are exact: OS464_UK.rom Firmware v1 + BASIC 1.00 - OS464_FR.rom Firmware f1 + French BASIC 1.0 (md5 824f5213…) + OS464_FR.rom Firmware f1 + French BASIC 1.0 (md5 824f5213...) OS664_UK.rom Firmware v2 + BASIC 1.10 OS6128_UK.rom Firmware v3 + BASIC 1.20 OS6128_FR.rom Firmware f3 + BASIC 1.23 @@ -77,8 +77,8 @@ notes: | snapshot, Dandanator and X-MASS images are user content the same way, and the Nova plugin regenerates its 32 KB private/Nova/nova.nvram when the file is absent. Outside emulation the binary loads its own payload: seventeen QOI - images, fatal with "Error loading QOI file please reinstall"; seventeen WAV - drive and monitor samples, each merely reported as not found; and the + images (fatal with "Error loading QOI file please reinstall"), seventeen WAV + drive and monitor samples (each merely reported as not found), and the private/messages catalog holding the French, English and Spanish translations. private/sounds/hitachi_long_seek.wav ships with every package but appears in no path constant and is never opened. diff --git a/emulators/advancemame.yml b/emulators/advancemame.yml index 8ffcc660..5e155faf 100644 --- a/emulators/advancemame.yml +++ b/emulators/advancemame.yml @@ -68,14 +68,14 @@ notes: | Where a system offers several BIOS revisions, SYSTEM_BIOS_ADD names them and misc_bios selects one, entry 0 being the default (doc/advmame.d:2086-2094). - Only the selected revision is read; the others share the archive as + Only the selected revision is read, and the others share the archive as alternatives. Neo Geo lists MVS revisions alone, the AES, Universe and debug entries being commented out (src/drivers/neogeo.c:1420-1423,1439-1442). The support files sit directly in $home or $data (advance/osd/fileio.c:81,88-90, advance/linux/file.c:249-256). A language file is read too, under whatever name misc_languagefile carries - (advance/osd/glue.c:715-716); the project ships none, English being built + (advance/osd/glue.c:715-716). The project ships none, English being built into the binary (src/ui_text.c:263-265). Samples and artwork are per-game archives under dir_sample and dir_artwork, ZIP only, named after the driver: WAV members for samples diff --git a/emulators/aethersx2.yml b/emulators/aethersx2.yml index 8e99fbd1..366e676b 100644 --- a/emulators/aethersx2.yml +++ b/emulators/aethersx2.yml @@ -19,7 +19,7 @@ resources_directory: "resources/" notes: | PlayStation 2 emulator for ARM, built on PCSX2 and carrying its own AArch64 - recompilers. The application itself is closed source; the PCSX2-derived files + recompilers. The application itself is closed source. The PCSX2-derived files were released separately as an LGPL tarball in which pcsx2/libAetherSX2.a holds the parts that stayed closed, and that drop sits on an earlier code line than any released build, with no Vulkan renderer in its GS tree and the older @@ -37,7 +37,7 @@ notes: | Detection is by content. The scan lists the BIOS folder with a *.* mask, keeps files between 4 and 8 MB, and accepts an image whose romdir carries a RESET - entry followed by a readable ROMVER; the fifth ROMVER character gives the + entry followed by a readable ROMVER, and the fifth ROMVER character gives the zone among T10K, Test, Japan, USA, Europe, HK, Free and China. An image named in the configuration is opened at its own path, without the size filter and without the romdir test. No name and no hash is matched anywhere. The image is @@ -76,7 +76,7 @@ notes: | sources each GS backend compiles at startup, the OSD and fullscreen interface fonts, the flag and placeholder textures, and the achievement notification sounds. The macOS build keeps the folder at AetherSX2.app/Contents/Resources - and adds its Metal libraries; the Android build carries the shaders, fonts, + and adds its Metal libraries. The Android build carries the shaders, fonts, icons and sounds as APK assets and draws its own interface. ref: AetherSX2-release AetherSX2.app/Contents/Resources, aethersx2 v1.5-3668 xyz.aethersx2.android assets @@ -89,7 +89,7 @@ files: max_size: 8388608 validation: [size] description: "PS2 BIOS image" - note: "Any image whose romdir holds RESET and ROMVER is accepted, whatever its name. The 4 to 8 MB range gates the folder scan; an image named in the configuration skips both that range and the romdir test." + note: "Any image whose romdir holds RESET and ROMVER is accepted, whatever its name. The 4 to 8 MB range gates the folder scan, while an image named in the configuration skips both that range and the romdir test." source_ref: "aethersx2/pcsx2/ps2/BiosTools.cpp:27-28, aethersx2/pcsx2/ps2/BiosTools.cpp:235-260, aethersx2/pcsx2/ps2/BiosTools.cpp:272-316, aethersx2 v1.5-3606 usr/share/aethersx2 0xa45ffc" - name: ps2-0230a-20080220.rom1 @@ -159,14 +159,14 @@ files: path: resources/cheats_ws.zip required: false description: "Widescreen patch archive" - note: "Per-game pnach entries matched on the disc CRC, loaded when widescreen patches are enabled. The cheats_ws folder takes precedence and the archive is skipped when it holds a match. Shipped by the Linux and Android builds; the macOS build looks for it without carrying one." + note: "Per-game pnach entries matched on the disc CRC, loaded when widescreen patches are enabled. The cheats_ws folder takes precedence and the archive is skipped when it holds a match. Shipped by the Linux and Android builds, while the macOS build looks for it without carrying one." source_ref: "aethersx2/pcsx2/Patch.cpp:202-231, AetherSX2-release MacOS/AetherSX2" - name: cheats_ni.zip path: resources/cheats_ni.zip required: false description: "No-interlacing patch archive" - note: "Same form as cheats_ws.zip, loaded when no-interlacing patches are enabled, with the cheats_ni folder taking precedence. Shipped by the Linux and Android builds; the macOS build looks for it without carrying one." + note: "Same form as cheats_ws.zip, loaded when no-interlacing patches are enabled, with the cheats_ni folder taking precedence. Shipped by the Linux and Android builds, while the macOS build looks for it without carrying one." source_ref: "aethersx2/pcsx2/Patch.cpp:202-231, AetherSX2-release MacOS/AetherSX2" - name: game_controller_db.txt diff --git a/emulators/altirra.yml b/emulators/altirra.yml index d8219425..cc1efd01 100644 --- a/emulators/altirra.yml +++ b/emulators/altirra.yml @@ -10,7 +10,7 @@ cores: [altirra] systems: [atari-400-800, xegs, atari-5200] # Altirra emulates the Atari 400/800, 1200XL, 600XL/800XL, 130XE, XEGS and 5200. -# Windows only; ES-DE launches Altirra64.exe or Altirra.exe. +# Windows only. ES-DE launches Altirra64.exe or Altirra.exe. # # Firmware is identified by content, never by filename. ATUIScanForFirmware # (uifirmwarescan.cpp:29-113) walks a folder the user picks, keeps every file whose @@ -24,7 +24,7 @@ systems: [atari-400-800, xegs, atari-5200] # below carries aliases. # # Every external image is optional. Altirra links replacement ROMs into the binary -# as resources (ATLoadInternalFirmware, firmwaremanager.cpp:189-295; res/Altirra.rc:4260-4292) +# as resources (ATLoadInternalFirmware, firmwaremanager.cpp:189-295, res/Altirra.rc:4260-4292) # and GetCompatibleFirmware selects them when nothing is registered # (firmwaremanager.cpp:502-549). The setup wizard states it: "Altirra has internal # replacements for all standard ROMs" (uisetupwizard.cpp:134-138). The internal set @@ -395,10 +395,10 @@ files: - name: happy-810-prev7-3k.rom description: "Happy 810 pre-v7 firmware, functional 3K inside a 6K image (serial $4B9B)" note: > - The image is 6144 bytes; Altirra identifies it by a checksum taken over + The image is 6144 bytes. Altirra identifies it by a checksum taken over the functional 3K, which its firmware list reports as the size. The checksum skips the hidden 1K of a 4K image and the 2-byte serial, so any - serial is recognised; a file it does not recognise can still be given + serial is recognised, and a file it does not recognise can still be given the Happy 810 type by hand. system: atari-400-800 required: false @@ -424,7 +424,7 @@ files: size: 6144 crc32: "9cc7a207" validation: [size, crc32] - note: "Functional 6K region only; the loader also accepts 3K, 4K and 8K dumps." + note: "Functional 6K region only. The loader also accepts 3K, 4K and 8K dumps." source_ref: "src/Altirra/source/firmwaredetect.cpp:63, src/Altirra/source/diskdrivefull.cpp:1165-1234" - name: happy-810-v7-8k.rom @@ -674,7 +674,7 @@ files: size: 8192 crc32: "fc02766b" validation: [size, crc32] - note: "8K image; the loader reads the first 4K and splits it into two 2K banks." + note: "8K image: the loader reads the first 4K and splits it into two 2K banks." source_ref: "src/Altirra/source/firmwaredetect.cpp:93, src/Altirra/source/diskdrivexf551.cpp:269-276" - name: xf551-7.7.rom @@ -684,7 +684,7 @@ files: size: 8192 crc32: "38b97ae3" validation: [size, crc32] - note: "8K image; the loader reads the first 4K and splits it into two 2K banks." + note: "8K image: the loader reads the first 4K and splits it into two 2K banks." source_ref: "src/Altirra/source/firmwaredetect.cpp:94, src/Altirra/source/diskdrivexf551.cpp:269-276" - name: xf551-7.7-density-hack.rom @@ -704,7 +704,7 @@ files: size: 8192 crc32: "0e117428" validation: [size, crc32] - note: 'Modified for 720K 3.5" drives. 8K image; the loader reads the first 4K and splits it into two 2K banks.' + note: 'Modified for 720K 3.5" drives. 8K image: the loader reads the first 4K and splits it into two 2K banks.' source_ref: "src/Altirra/source/firmwaredetect.cpp:96, src/Altirra/source/diskdrivexf551.cpp:269-276" - name: 1400xl-handler-v1.rom @@ -750,7 +750,7 @@ files: size: 4096 crc32: "e8f9c8a7" validation: [size, crc32] - note: "The image is 4K; the loader reads its first 2K into mFirmware (1450xld.h:179)." + note: "The image is 4K, and the loader reads its first 2K into mFirmware (1450xld.h:179)." source_ref: "src/Altirra/source/firmwaredetect.cpp:103, src/Altirra/source/1450xld.cpp:738-742" - name: 1450xld-disk-handler-rev-f.rom @@ -760,7 +760,7 @@ files: size: 4096 crc32: "4bb7fa3a" validation: [size, crc32] - note: "The image is 4K; the loader reads its first 2K into mFirmware (1450xld.h:179)." + note: "The image is 4K, and the loader reads its first 2K into mFirmware (1450xld.h:179)." source_ref: "src/Altirra/source/firmwaredetect.cpp:104, src/Altirra/source/1450xld.cpp:738-742" - name: 1450xld-disk-handler-post-rev-f.rom @@ -770,7 +770,7 @@ files: size: 4096 crc32: "29359910" validation: [size, crc32] - note: "The image is 4K; the loader reads its first 2K into mFirmware (1450xld.h:179)." + note: "The image is 4K, and the loader reads its first 2K into mFirmware (1450xld.h:179)." source_ref: "src/Altirra/source/firmwaredetect.cpp:105, src/Altirra/source/1450xld.cpp:738-742" - name: atari-835-internal.rom @@ -868,7 +868,7 @@ files: source_ref: "src/Altirra/source/firmwaredetect.cpp:120, src/Altirra/source/diskdrivespeedyxf.cpp:353-364" # -- Types with no row in the detect table. Registered by hand with an explicit - # type from the menu in uifirmware.cpp:498-585; max_size is the read length + # type from the menu in uifirmware.cpp:498-585. max_size is the read length # at the load site. -- - name: 810-archiver.rom @@ -989,7 +989,7 @@ files: - name: kmkjz-ide2-sdx.rom description: "KMK/JZ IDE 2 (IDEPlus) SpartaDOS X firmware" - note: "Two revisions circulate, SDX 4.45 and 4.47; the collection carries 4.47." + note: "Two revisions circulate, SDX 4.45 and 4.47, and the collection carries 4.47." system: atari-400-800 required: false max_size: 524288 diff --git a/emulators/amiarcadia.yml b/emulators/amiarcadia.yml index c09800c8..65ddf6e4 100644 --- a/emulators/amiarcadia.yml +++ b/emulators/amiarcadia.yml @@ -24,8 +24,8 @@ systems: # all code runs from the game cartridge. The core auto-identifies known # ROMs by CRC32 via games.h lookup table. # -# source_ref: src/libretro.c:497-624 (retro_load_game — no file I/O) -# source_ref: DroidArcadia/app/src/main/cpp/android.c:893-1052 (parse_bytes — ROM-only) +# source_ref: src/libretro.c:497-624 (retro_load_game, no file I/O) +# source_ref: DroidArcadia/app/src/main/cpp/android.c:893-1052 (parse_bytes, ROM-only) # source_ref: DroidArcadia/app/src/main/cpp/da.h:3-5 (version 4.42) # source_ref: amiarcadia_libretro.info (firmware_count=0) diff --git a/emulators/aps3e.yml b/emulators/aps3e.yml index 4d8dc55b..55b86cc2 100644 --- a/emulators/aps3e.yml +++ b/emulators/aps3e.yml @@ -24,7 +24,7 @@ notes: | app/src/main/cpp/rpcs3/rpcs3/rpcs3_version.cpp:29 Source drops land on successive branches, not on the default one. Release 2.43 - of 2026-10-05 is the commit titled 2.43 at the head of main4; the lightweight + of 2026-10-05 is the commit titled 2.43 at the head of main4. The lightweight tags 2.39 to 2.43 all sit on the head of main2, the default branch, an April tree that predates every one of those releases and whose generated git-version.h was never filled in. main4 is the tree read here. No versionName is usable either: @@ -35,7 +35,7 @@ notes: | Emulator paths derive from APS3E_DATA_DIR, set by the Java layer to the external files directory of the package. The config directory holds dev_flash, - dev_hdd0, custom_cfg and the global config.yml; caches live beside it. The + dev_hdd0, custom_cfg and the global config.yml, with caches beside it. The custom font directory sits at the data root, and the custom GPU driver directory sits in internal storage because the external filesystem cannot carry an executable mapping. @@ -73,7 +73,7 @@ notes: | Vulkan is reached through a loader chosen before the emulator starts. The global config YAML is read directly for Use Custom Driver and Custom Driver Library Path, and the named library is opened through libadrenotools as a - custom driver when both are set and the path exists; otherwise the system + custom driver when both are set and the path exists. Otherwise the system libvulkan.so is dlopened. Drivers are imported either as a bare shared object or as a zip whose meta.json names the library. ref: app/src/main/cpp/aps3e_emu.cpp:952-976, @@ -116,7 +116,7 @@ files: rejects an empty file, a wrong magic, a declared size the file does not reach, an unreadable entry table and a failed entry hash. Segment 0x300 carries the installation package database and segment 0x100 the version - string; the packages whose names contain dev_flash_ are decrypted with the + string. The packages whose names contain dev_flash_ are decrypted with the SCEPKG keys and their inner TARs extracted over dev_flash. The Java layer creates dev_flash/.installed once the native call returns true. No digest of the file itself is compared against anything. @@ -133,8 +133,8 @@ files: note: >- Resolved as a sidecar of the image being launched, .dkey first then .key, and passed down as a second descriptor. Up to 32 bytes are read: a full - 32-byte read is taken as a hex string and converted, a 16-byte file as raw; - any other length fails the key check. An image whose odd regions are + 32-byte read is taken as a hex string and converted, a 16-byte file as raw. + Any other length fails the key check. An image whose odd regions are encrypted does not boot without it. source_ref: "app/src/main/java/aenu/aps3e/Utils.java:185-205, app/src/main/cpp/rpcs3/rpcs3/Loader/iso.cpp:362-408, app/src/main/cpp/rpcs3/rpcs3/Loader/iso.cpp:855-882" @@ -206,7 +206,7 @@ dev_flash: path: "dev_flash/sys/external/" source_ref: "app/src/main/cpp/rpcs3/rpcs3/Emu/Cell/PPUModule.cpp:2703-2705, app/src/main/cpp/rpcs3/rpcs3/Emu/Cell/lv2/sys_prx.cpp:208, app/src/main/cpp/rpcs3/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp:1031" note: >- - Firmware SPRX modules. liblv2.sprx gates the boot and pulls the rest in; + Firmware SPRX modules. liblv2.sprx gates the boot and pulls the rest in, and each module can be forced to LLE or HLE through Libraries Control, which the shipped configuration leaves empty. flashATRAC.pic is named by cellSysmodule for the ATRAC module path. diff --git a/emulators/arcadeflashweb.yml b/emulators/arcadeflashweb.yml index 70759448..7ea9b422 100644 --- a/emulators/arcadeflashweb.yml +++ b/emulators/arcadeflashweb.yml @@ -18,7 +18,7 @@ notes: | ArcadeFlashWeb.exe -fullscreen -source:, RetroBat adds -nodatetime, -savedataflash: and -picturesfolder: and sets the working directory to the program folder. The repository carries the Qt and QML sources and the - releases; arcadeflashweb.com no longer resolves and holds no archived + releases. arcadeflashweb.com no longer resolves and holds no archived capture. Every string quoted below was also read back from the shipped v1.0.2 executable, which matches the sources. ref: src/ArcadeFlashWeb.pro:1-5, src/main.qml:34-35 @@ -27,7 +27,7 @@ notes: | QTWEBENGINE_CHROMIUM_FLAGS to "--enable-pepper-testing --ppapi-flash-path=./pepflashplayer.dll" before QtWebEngine::initialize, so Chromium takes the plugin from that path. It is the one file resolved - against the process working directory; everything else below hangs off + against the process working directory, and everything else below hangs off applicationDirPath. No --ppapi-flash-version accompanies it, and nothing reads the manifest.json sitting beside the library: QtWebEngine builds the plugin entry from the two switches alone and the library never names that @@ -85,7 +85,7 @@ files: Handed to Chromium as --ppapi-flash-path and resolved against the process working directory. Without it no plugin is registered, SWFObject finds no player and the movie is never embedded. The page asks for a reported - version of at least 32.0.0; the build that ships is the 32-bit 32.0.0.371. + version of at least 32.0.0, and the build that ships is the 32-bit 32.0.0.371. source_ref: "src/main.cpp:40, ArcadeFlashWeb-release flash/flash.html:102" - name: flash.html @@ -150,8 +150,8 @@ files: bundled: true description: "AntiMicro mapping profile" note: >- - Passed to AntiMicro as --profile under the name -profilantimicro: gives; - the name that ships is the one the built-in help quotes. With + Passed to AntiMicro as --profile under the name -profilantimicro: gives. + The name that ships is the one the built-in help quotes. With -controleurantimicro: also set the call carries --profile-controller instead and no profile file is read. source_ref: "src/main.qml:309-312" diff --git a/emulators/ares.yml b/emulators/ares.yml index cc46b11d..324c04c8 100644 --- a/emulators/ares.yml +++ b/emulators/ares.yml @@ -55,7 +55,7 @@ notes: | accuracy and preservation. 41 emulators registered at this pin (desktop-ui/emulator/emulators.cpp). - Firmware identification uses SHA256 hashes. Filenames are user-defined; ares + Firmware identification uses SHA256 hashes. Filenames are user-defined: ares scans a configured directory and matches by hash. EmuDeck installs ares as Flatpak (dev.ares.ares), configures biosPath in settings.bml. ref: desktop-ui/settings/firmware.cpp:116-136 @@ -144,7 +144,7 @@ files: sha256: "477617917a12a30f9f43844909dc2de6e6a617430f5c9a36306c86414a670d50" validation: [sha256] description: "Master System BIOS (US)" - note: "Picked for NTSC-U, which the code gives every export cart outside its PAL list through the Boot/Prefer setting; the header does not tell US from Europe (mia/medium/master-system.cpp:54-63, desktop-ui/emulator/emulator.cpp:40-60)." + note: "Picked for NTSC-U, which the code gives every export cart outside its PAL list through the Boot/Prefer setting. The header does not tell US from Europe (mia/medium/master-system.cpp:54-63, desktop-ui/emulator/emulator.cpp:40-60)." source_ref: "desktop-ui/emulator/master-system.cpp:14, mia/system/master-system.cpp:8 (//optional)" - name: bios_J.sms @@ -193,7 +193,7 @@ files: sha256: "fe608a2a07676a23ab5fd5eee2f53c9e2526d69a28aa16ccd85c0ec42e6933cb" validation: [sha256] description: "Mega CD BIOS (Europe)" - note: "Picked for PAL, set when the boot code matches the EU security block; the code has no other PAL branch for Australian discs (mia/medium/mega-cd.cpp:47-56, desktop-ui/emulator/mega-cd.cpp:70-74)." + note: "Picked for PAL, set when the boot code matches the EU security block. The code has no other PAL branch for Australian discs (mia/medium/mega-cd.cpp:47-56, desktop-ui/emulator/mega-cd.cpp:70-74)." source_ref: "desktop-ui/emulator/mega-cd.cpp:19" # --- Mega LD (LaserActive SEGA PAC) --- diff --git a/emulators/armsx1.yml b/emulators/armsx1.yml index 67913562..6a9d3c4b 100644 --- a/emulators/armsx1.yml +++ b/emulators/armsx1.yml @@ -35,7 +35,7 @@ notes: | psxe_cfg_get_bios_path answers in three steps: the override file when it exists, then a scan of the search folder, then the override path unchanged. The override is [bios].override_file or -b and defaults to bios.bin under the - preference path SDL_GetPrefPath("nanodata", "armsx"); the search folder is + preference path SDL_GetPrefPath("nanodata", "armsx"). The search folder is [bios].search_path or -B and defaults to the relative path bios. ref: frontend/config.c:1540-1559, frontend/config.c:1385-1404, frontend/config.c:677-683, frontend/config.c:54-57 @@ -65,7 +65,7 @@ notes: | chosen dump to user_bios.bin and writes its absolute path into [bios].override_file. EmulatorActivity passes --bios /bios.bin when the package carries an assets/bios.bin, and the in-process launcher repeats - that check with stat; release 0.1.3 ships no such asset. + that check with stat. Release 0.1.3 ships no such asset. ref: android/app/src/main/java/com/armsx2/core/Ps1Config.kt:20-41, android/app/src/main/java/com/armsx2/ui/settings/Ps1BiosTab.kt:38-48, android/app/src/main/java/com/nanodata/armsx/EmulatorActivity.java:58-61, @@ -73,9 +73,9 @@ notes: | frontend/android_jni.cpp:1708-1743, ARMSX1-0.1.3-release.apk assets The remaining paths the core opens are per game, and are written by the - emulator or picked by the user: memory cards, created blank at first use; - save states, rewind snapshots and screenshots; a GameShark .cht catalogue - named by [cheats].cheats_file; and content-addressed PNG packs under the + emulator or picked by the user: memory cards (created blank at first use), + save states, rewind snapshots and screenshots, a GameShark .cht catalogue + named by [cheats].cheats_file, and content-addressed PNG packs under the replacements folder of [video].texture_dir. ref: psx/dev/mcd.c:139-154, psx/cheats.c:346-390, psx/texrep.c:846-848 @@ -91,7 +91,7 @@ files: whole and mapped at its own size. 524288 is the region psx_bios_init declares before the load, and 1048576 the SCPH-5903 image the loader names as the exception. The folder scan reaches an image only under the - name bios.bin; [bios].override_file, -b and the Android picker open a + name bios.bin. [bios].override_file, -b and the Android picker open a path directly. source_ref: "psx/dev/bios.c:21-54, psx/dev/bios.h:8-10, frontend/config.c:292-357, frontend/config.c:1540-1559, frontend/main.cpp:2529-2535" diff --git a/emulators/armsx2.yml b/emulators/armsx2.yml index 99c842e9..eb24e1b3 100644 --- a/emulators/armsx2.yml +++ b/emulators/armsx2.yml @@ -37,7 +37,7 @@ notes: | Detection is by content. The scan lists the BIOS folder, keeps files between 4 and 8 MB, and accepts an image whose romdir carries a RESET entry followed by a - readable ROMVER; the fifth ROMVER character gives the zone among Japan, USA, + readable ROMVER. The fifth ROMVER character gives the zone among Japan, USA, Europe, Asia, China, T10K, COH-H, Test and Free, and an EXTINFO entry supplies the serial. The console scan passes over a COH-H image. An image named in the configuration is opened at its own path, without the size filter. No name and @@ -51,7 +51,7 @@ notes: | An arcade session, opened from an .acgame manifest carrying an NM game id, takes a Namco System 246 or 256 board BIOS instead. Filenames/ArcadeBIOS names - it; when that is empty or is not a COH-H image the BIOS folder is scanned for + it. When that is empty or is not a COH-H image the BIOS folder is scanned for images between 2 and 8 MB whose zone is COH-H, the one with EXTINFO serial 20040519-145634, the System 256 board, being preferred. Boot stops when none is found. The boot ELF, the media image and the SRAM the manifest names are @@ -95,7 +95,7 @@ notes: | matches the binary. The libretro core reads the same tree from /pcsx2/resources, with the BIOS folder at /pcsx2/bios. Its build also compiles in the shaders under shaders/common, shaders/opengl and - shaders/vulkan, GameIndex.yaml and a patches.zip fetched at configure time; the + shaders/vulkan, GameIndex.yaml and a patches.zip fetched at configure time. The copy in the resources folder wins and the compiled-in one stands in when the file is absent. ref: pcsx2/Pcsx2Config.cpp:2400-2414, pcsx2/Pcsx2Config.cpp:2563, @@ -139,7 +139,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and ROMVER is accepted, whatever its - name. The 4 to 8 MB range gates the folder scan; an image named in the + name. The 4 to 8 MB range gates the folder scan, while an image named in the configuration skips that range. Read into the 4 MB ROM region and truncated to it. Shorter than 2465792 bytes disables the OSDSys parameter HLE. A COH-H image is passed over by the console scan. @@ -291,7 +291,7 @@ files: Second pass over the game database, merged onto the entries GameIndex.yaml declares. Carries GS and JIT tuning correct on tiler GPUs. Kept outside the shipped resources folder and copied in only for arm64 Linux, Android and - iOS; the loader no-ops where it is absent. + iOS. The loader no-ops where it is absent. source_ref: "pcsx2/GameDatabase.cpp:54, pcsx2/GameDatabase.cpp:1379-1382, cmake/BuildParameters.cmake:227-240, pcsx2/CMakeLists.txt:1828-1837, platforms/android/app/build.gradle.kts:73-85" - name: RedumpDatabase.yaml @@ -386,7 +386,7 @@ files: note: >- First entry of the emoji script table, resolved under UserResources then the resources folder and downloaded into UserResources/fonts when neither holds - it. Read by the Qt builds only; the Android asset step leaves it out. + it. Read by the Qt builds only, and the Android asset step leaves it out. source_ref: "pcsx2-qt/Translations.cpp:340-347, pcsx2-qt/Translations.cpp:407-424, pcsx2-qt/Translations.cpp:541-549, platforms/android/app/build.gradle.kts:79-81" - name: NotoSansJP-Regular.ttf @@ -608,7 +608,7 @@ files: note: >- The OpenGL backend is one of those the renderer setting selects, and it is what an Android device falls back to when Vulkan is not chosen. Its device - creation fails without this source; a Vulkan session is unaffected. + creation fails without this source, while a Vulkan session is unaffected. source_ref: "pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp:891-895, pcsx2/GS/GS.cpp:97-133" - name: tfx_fs.glsl @@ -617,7 +617,7 @@ files: required: false bundled: true description: "OpenGL texture function fragment shader" - note: "Read with tfx_vgs.glsl; the OpenGL device fails without it." + note: "Read with tfx_vgs.glsl. The OpenGL device fails without it." source_ref: "pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp:891-895" - name: convert.glsl diff --git a/emulators/ax360e.yml b/emulators/ax360e.yml index 0960205f..8f770345 100644 --- a/emulators/ax360e.yml +++ b/emulators/ax360e.yml @@ -90,7 +90,7 @@ files: note: >- Imported through a picker that keeps only names ending in .zip. The archive is read whole, meta.json names the library to keep, and a single .so is - taken instead when no meta.json is present; the .so files and meta.json are + taken instead when no meta.json is present. The .so files and meta.json are unpacked into a directory named after the archive, in internal storage. The configured path is read before the instance is created and opened through adrenotools when it exists, otherwise the system libvulkan.so is used. The diff --git a/emulators/azahar.yml b/emulators/azahar.yml index 8decbb48..21bb6636 100644 --- a/emulators/azahar.yml +++ b/emulators/azahar.yml @@ -40,7 +40,7 @@ files: hle_fallback: true sha1: "5fab786695311433602028cd89898689c5df0898" md5: "cb52d323b13129a2f0bc3e3e911e567f" - note: "embedded encrypted fallback if missing: default_keys_enc, AES-CBC with a zero key and IV; the hashes are those of the decrypted text without its PKCS#7 block" + note: "embedded encrypted fallback if missing: default_keys_enc, AES-CBC with a zero key and IV. The hashes are those of the decrypted text without its PKCS#7 block" source_ref: "src/core/hw/aes/key.cpp:283-300, src/common/common_paths.h:83, src/core/hw/default_keys.h:4-5" - name: shared_font.bin @@ -48,7 +48,7 @@ files: system: nintendo-3ds required: false hle_fallback: true - note: "legacy load path; embedded open-source font used if missing" + note: "legacy load path, embedded open-source font used if missing" source_ref: "src/core/hle/service/apt/apt.cpp:263-278" - name: seeddb.bin @@ -74,7 +74,7 @@ files: size: [288, 320] validation: [size, signature] on_mismatch: {signature: warn} - note: "console-unique key seed; 288 bytes without the AES MAC block, 320 with it" + note: "console-unique key seed, 288 bytes without the AES MAC block, 320 with it" source_ref: "src/core/hw/unique_data.cpp:170-200, src/core/hw/unique_data.cpp:217, src/core/hw/unique_data.h:103-133" - name: SecureInfo_A diff --git a/emulators/azaharplus.yml b/emulators/azaharplus.yml index d341f643..68941289 100644 --- a/emulators/azaharplus.yml +++ b/emulators/azaharplus.yml @@ -58,7 +58,7 @@ files: hle_fallback: true sha1: "5288772be438b86978a801e6dcb14228ad3a20af" md5: "4812e96097b7fc1bdd7b40366208b7a7" - note: "AES key slots, common keys and NFC secrets; embedded encrypted blob used if missing: default_keys_enc, AES-CBC with a zero key and IV, the hashes are those of the decrypted text" + note: "AES key slots, common keys and NFC secrets. Embedded encrypted blob used if missing: default_keys_enc, AES-CBC with a zero key and IV, the hashes are those of the decrypted text" source_ref: "src/core/hw/aes/key.cpp:225-364, src/core/hw/aes/key.cpp:473-613, src/core/hw/default_keys.h:11" - name: aes_keys.txt @@ -90,7 +90,7 @@ files: system: nintendo-3ds required: false hle_fallback: true - note: "game seed database for 9.6+ titles; written out from the embedded seeds if absent" + note: "game seed database for 9.6+ titles, written out from the embedded seeds if absent" source_ref: "src/core/file_sys/seed_db.cpp:50-101" - name: otp.bin @@ -108,7 +108,7 @@ files: required: false size: [288, 320] validation: [size, signature] - note: "console-unique key seed; 288 bytes without the AES MAC block, 320 with it" + note: "console-unique key seed, 288 bytes without the AES MAC block, 320 with it" source_ref: "src/core/hw/unique_data.cpp:276-318, src/core/hw/unique_data.h:103-133" - name: SecureInfo_A @@ -117,7 +117,7 @@ files: required: false size: 273 validation: [size, signature] - note: "console serial and region; a failed signature is retried against every region" + note: "console serial and region. A failed signature is retried against every region" source_ref: "src/core/hw/unique_data.cpp:122-180, src/core/hw/unique_data.h:57" - name: LocalFriendCodeSeed_B diff --git a/emulators/b2.yml b/emulators/b2.yml index 990cc8db..3e9ea707 100644 --- a/emulators/b2.yml +++ b/emulators/b2.yml @@ -39,7 +39,7 @@ notes: | Libretro port embeds all ROMs as hex arrays in src/libretro/roms.hpp. create_core() loads OS and sideways ROMs from static machine_types[] arrays. - GetAssetPath() and LoadFile() are stubbed — no file I/O at runtime. + GetAssetPath() and LoadFile() are stubbed: no file I/O at runtime. ref: zoltanvb/b2-libretro/src/libretro/roms.hpp ref: src/libretro/core.cpp:275-305 ref: src/libretro/adapters.cpp:74-78 @@ -62,7 +62,7 @@ files: md5: "0a59a5ba15fe8557b5f7fee32bbd393a" crc32: "3c14fc70" description: "OS 1.20" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window. The B/Acorn 1770 configuration is the one b2 falls back to when no saved configuration loads, so a missing file stops startup." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window. The B/Acorn 1770 configuration is the one b2 falls back to when no saved configuration loads, so a missing file stops startup." source_ref: "src/b2/roms.cpp:16, src/b2/BeebConfig.cpp:220, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57, src/b2/b2.cpp:1599-1607" - name: "B+MOS.rom" @@ -76,7 +76,7 @@ files: md5: "47a1eff6c7fbb47be780c87dfd50ece1" crc32: "66c8d893" description: "B+ MOS" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:17, src/b2/BeebConfig.cpp:243, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "BASIC2.ROM" @@ -300,7 +300,7 @@ files: md5: "9087f772447038a00178488b3591347b" crc32: "aa317ef5" description: "MOS 3.20 MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:39, src/b2/BeebConfig.cpp:266, src/b2/BeebConfig.cpp:314, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "dfs.rom" @@ -412,7 +412,7 @@ files: md5: "d7a046b1e6a9991748cee05332f1e258" crc32: "f8b84874" description: "MOS 3.50 MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:51, src/b2/BeebConfig.cpp:290, src/b2/BeebConfig.cpp:340, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "adfs.rom" @@ -468,7 +468,7 @@ files: md5: "5d1b635e39aa461f17db2344870dda36" crc32: "12c5f709" description: "MOS 5.00 MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:59, src/b2/BeebConfig.cpp:377, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "adfs.rom" @@ -524,7 +524,7 @@ files: md5: "f65eb89c7044e328b79f2ef8e51b7fd8" crc32: "56c83755" description: "MOS 5.10 MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:67, src/b2/BeebConfig.cpp:398, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "adfs.rom" @@ -580,7 +580,7 @@ files: md5: "5e16a38bd7fd6f07f26b5a64826e4ec6" crc32: "440f411f" description: "MOS I5.10C MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:75, src/b2/BeebConfig.cpp:442, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "adfs.rom" @@ -636,7 +636,7 @@ files: md5: "e0da7278637754841dfd6b2b847783bc" crc32: "3f81574e" description: "MOS 5.11i MOS (OS)" - note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration; a shorter image is placed at the top of the 16 KiB window." + note: "OS ROM of the configurations that select it. A failed load, or an image over 16 KiB, aborts loading the configuration, while a shorter image is placed at the top of the 16 KiB window." source_ref: "src/b2/roms.cpp:83, src/b2/BeebConfig.cpp:419, src/b2/BeebConfig.cpp:542-546, src/b2/BeebConfig.cpp:35-57" - name: "arabic.rom" diff --git a/emulators/bbkemu.yml b/emulators/bbkemu.yml index f5750e0b..e8d44da3 100644 --- a/emulators/bbkemu.yml +++ b/emulators/bbkemu.yml @@ -28,16 +28,16 @@ notes: | so only BBKEmu/A4980/ is ever read from RetroArch. Both reads are std::fs::read guarded by `if let Ok`: a missing file is skipped without any message to the frontend. The image is copied into a 2 MiB - zero-filled buffer (crates/bbkemu-core/src/memory.rs:197-209); nothing + zero-filled buffer (crates/bbkemu-core/src/memory.rs:197-209), and nothing checks its size or contents. Without E.BIN, run_os_init (crates/bbkemu-core/src/emulator.rs:231-252) sets PC to 0x350, reads zeros from the ROM window, never sees - _MTCT=0xFE and gives up after 10 million cycles; the bank registers + _MTCT=0xFE and gives up after 10 million cycles. The bank registers stay unmapped and the game exits at its first OS call. Measured by running run_os_init from bbkemu-core against a dump: 1 092 023 cycles to completion with E.BIN, timeout without it. Without 8.BIN the font - window reads as 0x00 and every glyph the OS draws is blank; execution + window reads as 0x00 and every glyph the OS draws is blank, but execution continues. The standalone binary takes -8/--rom8 and -e/--rome explicit paths and @@ -50,7 +50,7 @@ notes: | During init the OS maps its own bank at logical bank D: 0xEA8 for the A4980 OS, 0xE88 for the A4988 OS (crates/bbkemu-core/src/model.rs:11-13). - The core never reads that value back; detect_model + The core never reads that value back: detect_model (crates/bbkemu-core/src/model.rs:37-49) has no caller. The include_bytes! font in crates/bbkemu-core/src/font.rs is not declared in lib.rs and is not compiled. Content arrives through the frontend buffer @@ -68,9 +68,9 @@ files: description: "BBK A-series font ROM" note: >- Read whole from {system}/BBKEmu/A4980/8.BIN into the 2 MiB window at - physical 0x800000. A missing file is skipped silently; the window + physical 0x800000. A missing file is skipped silently, and the window then reads as 0x00 and text drawn through the OS is blank. No size - or hash check; size is the window the image fills. + or hash check. Size is the window the image fills. source_ref: "crates/bbkemu-libretro/src/lib.rs:187-199, crates/bbkemu-libretro/src/lib.rs:470-471, crates/bbkemu-core/src/memory.rs:8, crates/bbkemu-core/src/memory.rs:197-202, crates/bbkemu-core/src/memory.rs:384-390, crates/bbkemu/src/main.rs:147-158" - name: E.BIN @@ -82,10 +82,10 @@ files: description: "BBK A-series OS ROM" note: >- Read whole from {system}/BBKEmu/A4980/E.BIN into the 2 MiB window at - physical 0xE00000; the last 256 bytes also serve as the interrupt + physical 0xE00000. The last 256 bytes also serve as the interrupt vector page at 0x0300. A missing file is skipped silently, the OS init loop times out after 10 million cycles and no game runs. No - size or hash check; size is the window the image fills. + size or hash check. Size is the window the image fills. source_ref: "crates/bbkemu-libretro/src/lib.rs:187-193, crates/bbkemu-libretro/src/lib.rs:201-206, crates/bbkemu-libretro/src/lib.rs:470-471, crates/bbkemu-core/src/memory.rs:9, crates/bbkemu-core/src/memory.rs:204-209, crates/bbkemu-core/src/memory.rs:224-226, crates/bbkemu-core/src/memory.rs:391-397, crates/bbkemu-core/src/emulator.rs:231-252, crates/bbkemu/src/main.rs:159-170" - name: 8.BIN @@ -120,5 +120,5 @@ platform_details: note: | Physical space seen through sixteen 4 KiB bank registers: RAM below 0x8000, 2 MiB flash at 0x200000, 8.BIN at 0x800000, E.BIN at - 0xE00000. Reads outside a loaded image return 0x00; ROM windows + 0xE00000. Reads outside a loaded image return 0x00, and ROM windows ignore writes. diff --git a/emulators/beebem.yml b/emulators/beebem.yml index f367d8d8..43d65c1d 100644 --- a/emulators/beebem.yml +++ b/emulators/beebem.yml @@ -21,7 +21,7 @@ notes: | ref: Src/Model.h:24-32 Two file roots. GetUserDataPath() defaults to \BeebEm and falls back - to \UserData; it holds BeebFile/ and the .cfg and .kmap files. GetAppPath() + to \UserData. It holds BeebFile/ and the .cfg and .kmap files. GetAppPath() is the program directory and holds Teletext.fnt and the sound samples. ref: Src/BeebWin.cpp:5813-5851 @@ -51,7 +51,7 @@ notes: | BeebFile/ also carries an application ROM library (word processors, drawing packages, language ROMs) and DiscIms/ carries the disc images supplied with the - Master 512, ARM and Z80 co-processors. No code path names them; they load only + Master 512, ARM and Z80 co-processors. No code path names them: they load only through the file browser in Edit ROM Configuration, the same way a disc image does. ref: Src/RomConfigDialog.cpp:179-215 @@ -86,7 +86,7 @@ files: sha1: 0d9bcaf6a393c9ce2359ed700ddb53c232c2c45d validation: [size] on_mismatch: warn - note: "OS ROM slot. Read into 0xc000; an error is reported unless 16384 bytes are read." + note: "OS ROM slot. Read into 0xc000. An error is reported unless 16384 bytes are read." source_ref: "Src/BeebMem.cpp:1291-1308, Src/RomConfigFile.cpp:43" - name: BASIC2.rom @@ -496,7 +496,7 @@ files: on_mismatch: warn note: > Loaded for TubeDevice::AcornZ80. An error is reported unless 4096 bytes are - read. Jonathan Harston's v1.21; the Acorn v1.20 ships as Z80-1.20.rom and is + read. Jonathan Harston's v1.21. The Acorn v1.20 ships as Z80-1.20.rom and is used by renaming it onto this path. source_ref: "Src/Z80Support.cpp:243-267, Help/z80copro.html" diff --git a/emulators/beetle_gba.yml b/emulators/beetle_gba.yml index 84c23e42..95a44cf9 100644 --- a/emulators/beetle_gba.yml +++ b/emulators/beetle_gba.yml @@ -1,4 +1,4 @@ -# Beetle GBA (Mednafen) — Game Boy Advance (libretro) +# Beetle GBA (Mednafen), Game Boy Advance (libretro) # ref: beetle-gba-libretro/mednafen/gba, docs.libretro.com/library/beetle_gba # Same BIOS as mGBA/VBA-M. Read only with the gba_hle core option disabled. emulator: Beetle GBA (Mednafen) @@ -17,6 +17,6 @@ files: validation: [size] source_ref: "mednafen/gba/GBA.cpp:2639-2673, mednafen/settings.cpp:81-82, libretro.cpp:223-230" note: > - Read only when the gba_hle core option is disabled; it is enabled by + Read only when the gba_hle core option is disabled. It is enabled by default and the core then uses its built-in HLE BIOS. A file of any size other than 16384 bytes is ignored and the core falls back to HLE. diff --git a/emulators/beetle_lynx.yml b/emulators/beetle_lynx.yml index 6130604d..135f369c 100644 --- a/emulators/beetle_lynx.yml +++ b/emulators/beetle_lynx.yml @@ -22,8 +22,8 @@ notes: > The cart database in cart.cpp includes the BIOS CRC32 0x0d973c9d for identification purposes, not validation. Upstream Mednafen throws an exception if the BIOS is missing or - undersized; the libretro port silently degrades. Upstream supports - custom palette loading (lynx.pal); the libretro port does not. + undersized, while the libretro port silently degrades. Upstream supports + custom palette loading (lynx.pal), but the libretro port does not. files: - name: "lynxboot.img" diff --git a/emulators/beetle_psx.yml b/emulators/beetle_psx.yml index 35cb4d15..fb584a55 100644 --- a/emulators/beetle_psx.yml +++ b/emulators/beetle_psx.yml @@ -12,12 +12,12 @@ systems: [sony-playstation] notes: > Region-based BIOS selection: the core picks JP/NA/EU firmware based on disc region. SHA1 validated with warning on mismatch (does not block loading). - SHA1 and alternate filenames sourced from MAME (mame src/mame/sony/psx.cpp); - the lists and the checksum search live in libretro.c:448-502,510-602. + SHA1 and alternate filenames sourced from MAME (mame src/mame/sony/psx.cpp). + The lists and the checksum search live in libretro.c:448-502,510-602. Override option allows using PSP, PS3, or OpenBIOS as region-free alternative. Embedded OpenBIOS (512KB) compiled into the binary serves as HLE fallback when no BIOS found. "Skip BIOS" option patches BIOS ROM but causes compatibility issues. - Upstream Mednafen loads the same 3 region BIOS; override BIOS and HLE fallback are libretro additions. + Upstream Mednafen loads the same 3 region BIOS. Override BIOS and HLE fallback are libretro additions. Two BIOS geometries are accepted: the stock 512 KB kernel and the 1 MB SCPH-5903 part, selected by file size at load time (libretro.c:3203-3217). A 1 MB image switches Video CD from HLE to daughterboard emulation (libretro.c:6159). Reached through the BIOS path diff --git a/emulators/beetle_saturn.yml b/emulators/beetle_saturn.yml index b5867839..6f9b4123 100644 --- a/emulators/beetle_saturn.yml +++ b/emulators/beetle_saturn.yml @@ -47,7 +47,7 @@ notes: | ST-V content is a game ZIP or a bare ROM matched against the ST-V game table (libretro.c:1207-1227, libretro.c:1261-1281). The cabinet region of the matched game selects one of three ST-V BIOS images - (mednafen/ss/ss.c:1829-1843); the beetle_saturn_region option is not + (mednafen/ss/ss.c:1829-1843), and the beetle_saturn_region option is not applied on that path (libretro.c:1217, libretro.c:1275). The image is read as a bare file from the system directory or, when that file is absent, as the member of the same name in stvbios.zip there, matched without regard @@ -75,7 +75,7 @@ files: size: 524288 validation: {core: [size], upstream: [size, sha256]} sha256: "dcfef4b99605f872b6c3b6d05c045385cdea3d1b702906a0ed930df7bcb7deac" - note: "Saturn BIOS v1.01 (Japan), loaded for the Japan and Asia NTSC areas. The port checks the size only; the sha256 is the value upstream Mednafen 1.32.1 holds for this filename in its ss.bios_sanity table (src/ss/ss.cpp, BIOSDB)." + note: "Saturn BIOS v1.01 (Japan), loaded for the Japan and Asia NTSC areas. The port checks the size only. The sha256 is the value upstream Mednafen 1.32.1 holds for this filename in its ss.bios_sanity table (src/ss/ss.cpp, BIOSDB)." source_ref: "mednafen/ss/ss.c:1845-1846 (region filename), mednafen/ss/ss.c:1867-1873 (open), mednafen/ss/ss.c:1961-1984 (size check, read), mednafen/ss/ss.c:1988 (sha256 for save states)" - name: "mpr-17933.bin" @@ -85,7 +85,7 @@ files: size: 524288 validation: {core: [size], upstream: [size, sha256]} sha256: "96e106f740ab448cf89f0dd49dfbac7fe5391cb6bd6e14ad5e3061c13330266f" - note: "Saturn BIOS v1.00a (North America and Europe), loaded for every area other than Japan and Asia NTSC, and when no content is loaded. Disc area E maps to EU_PAL and the code has no Oceania area (disc.c:162-165). The port checks the size only; the sha256 is the value upstream Mednafen 1.32.1 holds for this filename in its ss.bios_sanity table (src/ss/ss.cpp, BIOSDB)." + note: "Saturn BIOS v1.00a (North America and Europe), loaded for every area other than Japan and Asia NTSC, and when no content is loaded. Disc area E maps to EU_PAL and the code has no Oceania area (disc.c:162-165). The port checks the size only. The sha256 is the value upstream Mednafen 1.32.1 holds for this filename in its ss.bios_sanity table (src/ss/ss.cpp, BIOSDB)." source_ref: "mednafen/ss/ss.c:1847-1848 (region filename), mednafen/ss/ss.c:1867-1873 (open), mednafen/ss/ss.c:1961-1984 (size check, read), mednafen/ss/ss.c:1988 (sha256 for save states), libretro.c:1103 (default area)" - name: "mpr-18811-mx.ic1" @@ -93,7 +93,7 @@ files: required: false min_size: 2097152 validation: [size] - note: "King of Fighters '95 ROM cart. Selected by the game table for MK-81088 and T-3101G or by the beetle_saturn_cart option. The first 0x200000 bytes are read; a shorter file installs a zeroed cart, an absent file leaves the slot empty." + note: "King of Fighters '95 ROM cart. Selected by the game table for MK-81088 and T-3101G or by the beetle_saturn_cart option. The first 0x200000 bytes are read. A shorter file installs a zeroed cart, an absent file leaves the slot empty." source_ref: "mednafen/settings.c:62-63 (filename), mednafen/ss/cart.c:197-216 (open), mednafen/ss/cart/rom.c:67-68 (read), mednafen/ss/db.c:90-91 (game table), libretro.c:527 (option)" - name: "mpr-19367-mx.ic1" @@ -101,7 +101,7 @@ files: required: false min_size: 2097152 validation: [size] - note: "Ultraman: Hikari no Kyojin Densetsu ROM cart. Selected by the game table for T-13308G or by the beetle_saturn_cart option. The first 0x200000 bytes are read; a shorter file installs a zeroed cart, an absent file leaves the slot empty." + note: "Ultraman: Hikari no Kyojin Densetsu ROM cart. Selected by the game table for T-13308G or by the beetle_saturn_cart option. The first 0x200000 bytes are read. A shorter file installs a zeroed cart, an absent file leaves the slot empty." source_ref: "mednafen/settings.c:64-65 (filename), mednafen/ss/cart.c:197-216 (open), mednafen/ss/cart/rom.c:67-68 (read), mednafen/ss/db.c:92 (game table), libretro.c:529 (option)" - name: "epr-20091.ic8" @@ -136,7 +136,7 @@ files: system: sega-stv required: false description: "ST-V BIOS archive" - note: "Opened only when the bare ST-V BIOS file for the cabinet region is absent. The member of the same name is matched without regard to case and must be 131072 or 524288 bytes; no hash is checked." + note: "Opened only when the bare ST-V BIOS file for the cabinet region is absent. The member of the same name is matched without regard to case and must be 131072 or 524288 bytes. No hash is checked." source_ref: "mednafen/ss/ss.c:1888-1941 (open, member lookup, size check, extract), zip_reader.c:358-365 (case-insensitive lookup)" contents: - name: "epr-20091.ic8" @@ -150,7 +150,7 @@ files: system: sega-saturn required: false size: 524288 - note: "Video CD Card program ROM, opened when beetle_saturn_mpeg_card is enabled. The card carries a 512 KiB mask ROM; the core keeps at most 0x80000 bytes, pads a shorter image with zeros and checks nothing else. The image is never mapped: its presence is what makes the card authenticate, and without it the card answers commands but does not authenticate." + note: "Video CD Card program ROM, opened when beetle_saturn_mpeg_card is enabled. The card carries a 512 KiB mask ROM. The core keeps at most 0x80000 bytes, pads a shorter image with zeros and checks nothing else. The image is never mapped: its presence is what makes the card authenticate, and without it the card answers commands but does not authenticate." source_ref: "mednafen/settings.c:68-69 (filename), mednafen/ss/cdb.c:1315-1332 (open), mednafen/ss/mpeg.c:67-71 (size), mednafen/ss/mpeg.c:423-450 (read), mednafen/ss/mpeg.c:667-675 (authentication)" - name: "satar4mp.bin" @@ -158,5 +158,5 @@ files: required: false min_size: 262144 validation: [size] - note: "Action Replay 4M Plus firmware. The first 0x40000 bytes are read as big-endian words and a shorter file leaves the cart slot empty; no hash is checked. Unfinished in source (mednafen/ss/cart/ar4mp.c:22-24), needs CPU UBC emulation. Neither the beetle_saturn_cart option (libretro.c:512-530) nor the game table of mednafen/ss/db.c yields CART_AR4MP, so the case is not reached." + note: "Action Replay 4M Plus firmware. The first 0x40000 bytes are read as big-endian words and a shorter file leaves the cart slot empty. No hash is checked. Unfinished in source (mednafen/ss/cart/ar4mp.c:22-24), needs CPU UBC emulation. Neither the beetle_saturn_cart option (libretro.c:512-530) nor the game table of mednafen/ss/db.c yields CART_AR4MP, so the case is not reached." source_ref: "mednafen/settings.c:66-67 (filename), mednafen/ss/cart.c:218-236 (CART_AR4MP case), mednafen/ss/cart/ar4mp.c:181 (0x40000-byte read)" diff --git a/emulators/beetle_vb.yml b/emulators/beetle_vb.yml index 5e2772db..f263ec8d 100644 --- a/emulators/beetle_vb.yml +++ b/emulators/beetle_vb.yml @@ -13,10 +13,10 @@ systems: [nintendo-virtualboy] notes: | Libretro port of Mednafen's Virtual Boy emulation module. No external BIOS or firmware files. The Virtual Boy has no boot - ROM; the V810 CPU executes directly from the game ROM mapped at + ROM: the V810 CPU executes directly from the game ROM mapped at 0x07000000. Load() in libretro.cpp:1810 takes only ROM data. Upstream Mednafen supports an optional vb.pal palette file - (Documentation/vb.html); the libretro port handles palette via + (Documentation/vb.html), while the libretro port handles palette via core options instead. files: [] diff --git a/emulators/bk.yml b/emulators/bk.yml index 9f929101..a8ad9d37 100644 --- a/emulators/bk.yml +++ b/emulators/bk.yml @@ -32,7 +32,7 @@ systems: # Files are loaded from {system_dir}/bk/{filename} (libretro.c:720-728). # If not found with original casing, the loader retries with lowercase # filename (libretro.c:1071-1081). -# Size is validated (min/max bounds); no hash validation. +# Size is validated (min/max bounds), no hash validation. # # All ROM files are required for their respective model. The core calls # environ_cb(RETRO_ENVIRONMENT_SHUTDOWN) if any ROM file is missing. diff --git a/emulators/blastem.yml b/emulators/blastem.yml index c876d064..9e62e0ea 100644 --- a/emulators/blastem.yml +++ b/emulators/blastem.yml @@ -34,9 +34,9 @@ notes: | files: # rom.db is embedded in the libretro binary (libblastem.c:1295,1302-1303, # extern const char rom_db_data[]). The external file is an optional - # override — .info lists it as firmware0_opt=true. + # override. The .info lists it as firmware0_opt=true. # .info sha1 E5414FB1C4CC7D7F5101C07E4547316779BA3D97 does not match - # the version in our repo (sha1 02c287d1...) — rom.db changes between + # the version in our repo (sha1 02c287d1...): rom.db changes between # BlastEm releases. - name: rom.db system: sega-megadrive @@ -45,7 +45,7 @@ files: note: "ROM feature database (game-specific mapper/save config). Embedded in core, external is optional override." source_ref: "libblastem.c:1438-1455 read_bundled_file()" - # TMSS ROM — only used in standalone mode with tmss-enabled model + # TMSS ROM, only used in standalone mode with tmss-enabled model # libretro build returns NULL for tmss.md (libblastem.c:541) - name: tmss.md system: sega-megadrive diff --git a/emulators/bluemsx.yml b/emulators/bluemsx.yml index 9d86d476..376997b1 100644 --- a/emulators/bluemsx.yml +++ b/emulators/bluemsx.yml @@ -58,7 +58,7 @@ notes: | data_directories: # 302 files: 296 in Machines/ (200 machine configs + ROMs) + 6 in Databases/ # buildbot source: https://buildbot.libretro.com/assets/system/blueMSX.zip - # ref: libretro.c:1118-1119 — system_dir/Machines/ + system_dir/Databases/ + # ref: libretro.c:1118-1119: system_dir/Machines/ + system_dir/Databases/ - ref: bluemsx source_ref: "libretro.c:1119-1120" diff --git a/emulators/boytacean.yml b/emulators/boytacean.yml index 75aff30c..e2c7ac6b 100644 --- a/emulators/boytacean.yml +++ b/emulators/boytacean.yml @@ -26,7 +26,7 @@ notes: | file. load_boot_file() with hardcoded ./res/boot/*.bin paths exists in src/gb.rs:1477 but is not called from any frontend. - Boot ROM defaults: DmgBootix (DMG), CgbBoytacean (CGB) — open-source. + Boot ROM defaults: DmgBootix (DMG), CgbBoytacean (CGB), both open-source. files: - name: dmg_boot.bin diff --git a/emulators/bsnes-jg.yml b/emulators/bsnes-jg.yml index 93fd3e6c..74f30e78 100644 --- a/emulators/bsnes-jg.yml +++ b/emulators/bsnes-jg.yml @@ -135,11 +135,11 @@ files: aliases: [arm6.data.rom] # Embedded (no external file needed): -# SGB1BootROM[256] — src/coprocessor/icd.cpp:249 -# SGB2BootROM[256] — src/coprocessor/icd.cpp:260 -# hitachidspStaticDataROM[3072] — src/cartridge.cpp:62 -# CX4 HLE — src/cartridge.cpp:705-720 (preferHLE path for HG51BS169) -# boards_bml — libretro/boards_bml.hpp -# SuperFamicom_bml — libretro/SuperFamicom_bml.hpp -# BSMemory_bml — libretro/BSMemory_bml.hpp -# SufamiTurbo_bml — libretro/SufamiTurbo_bml.hpp +# SGB1BootROM[256]: src/coprocessor/icd.cpp:249 +# SGB2BootROM[256]: src/coprocessor/icd.cpp:260 +# hitachidspStaticDataROM[3072]: src/cartridge.cpp:62 +# CX4 HLE: src/cartridge.cpp:705-720 (preferHLE path for HG51BS169) +# boards_bml: libretro/boards_bml.hpp +# SuperFamicom_bml: libretro/SuperFamicom_bml.hpp +# BSMemory_bml: libretro/BSMemory_bml.hpp +# SufamiTurbo_bml: libretro/SufamiTurbo_bml.hpp diff --git a/emulators/bsnes_cplusplus98.yml b/emulators/bsnes_cplusplus98.yml index 2ea55578..c62ab2fd 100644 --- a/emulators/bsnes_cplusplus98.yml +++ b/emulators/bsnes_cplusplus98.yml @@ -32,6 +32,6 @@ exclusion_note: > firmware_count=0 in .info is correct. DSP firmware (NEC uPD7725/uPD96050, Hitachi CX4) is loaded from the ROM directory via game XML markup, not from system_dir. RetroArch cannot pre-populate firmware in the ROM directory. - Upstream byuu.org is defunct; this libretro port is the preserved v085 code. + Upstream byuu.org is defunct, and this libretro port is the preserved v085 code. files: [] diff --git a/emulators/bsnes_hd_beta.yml b/emulators/bsnes_hd_beta.yml index 474b01dd..9ccd6c68 100644 --- a/emulators/bsnes_hd_beta.yml +++ b/emulators/bsnes_hd_beta.yml @@ -67,12 +67,12 @@ files: - name: dsp3.program.rom system: nintendo-snes required: false - note: "no HLE — required for SD Gundam GX" + note: "no HLE, required for SD Gundam GX" source_ref: "bsnes/sfc/cartridge/load.cpp:490-494, bsnes/sfc/cartridge/load.cpp:531-534" - name: dsp3.data.rom system: nintendo-snes required: false - note: "no HLE — required for SD Gundam GX" + note: "no HLE, required for SD Gundam GX" source_ref: "bsnes/sfc/cartridge/load.cpp:498-503, bsnes/sfc/cartridge/load.cpp:531-534" - name: dsp4.program.rom system: nintendo-snes @@ -109,12 +109,12 @@ files: - name: st011.program.rom system: nintendo-snes required: false - note: "no HLE — required for Hayazashi Nidan Morita Shougi" + note: "no HLE, required for Hayazashi Nidan Morita Shougi" source_ref: "bsnes/sfc/cartridge/load.cpp:570-574, bsnes/sfc/cartridge/load.cpp:599-602" - name: st011.data.rom system: nintendo-snes required: false - note: "no HLE — required for Hayazashi Nidan Morita Shougi" + note: "no HLE, required for Hayazashi Nidan Morita Shougi" source_ref: "bsnes/sfc/cartridge/load.cpp:578-583, bsnes/sfc/cartridge/load.cpp:599-602" # ARM6 coprocessor (ST018) @@ -122,12 +122,12 @@ files: - name: st018.program.rom system: nintendo-snes required: false - note: "no HLE — required for Hayazashi Nidan Morita Shougi 2" + note: "no HLE, required for Hayazashi Nidan Morita Shougi 2" source_ref: "bsnes/sfc/cartridge/load.cpp:379-384" - name: st018.data.rom system: nintendo-snes required: false - note: "no HLE — required for Hayazashi Nidan Morita Shougi 2" + note: "no HLE, required for Hayazashi Nidan Morita Shougi 2" source_ref: "bsnes/sfc/cartridge/load.cpp:387-393" # SGB cartridge ROMs (boot ROMs embedded in icd/boot-roms.cpp) diff --git a/emulators/bstone.yml b/emulators/bstone.yml index 5c264606..643dd76a 100644 --- a/emulators/bstone.yml +++ b/emulators/bstone.yml @@ -33,7 +33,7 @@ notes: | 4. the GOG install directories (Windows registry) 5. the Steam install directories (Windows registry) One complete set is enough. With none the engine stops on "Content not - found." (src/bstone/src/jm_free.cpp:754); with several games found it asks + found." (src/bstone/src/jm_free.cpp:754). With several games found it asks which one to play. No single file is required on its own. Each file is opened under its upper-case name first, then under the @@ -55,7 +55,7 @@ files: - "0c3de403b524107809fa9308b730d60e8e41ba93" - "e2c101f9fd4bc7e22ddbfa3f019c9303877de4e2" validation: [sha1] - note: "sha1 values in order: v1.0 and v2.0; v2.1 and v3.0" + note: "sha1 values in order: v1.0 and v2.0, then v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1497, 1518, 1539, 1560" - name: "AUDIOT.BS1" @@ -67,7 +67,7 @@ files: - "3d4e8b62aa4683671027513ad9720f76f176ba5b" - "b79e7afcb4e4b29e59660ec261f72ff1ab4d3a25" validation: [sha1] - note: "sha1 values in order: v1.0 and v2.0; v2.1 and v3.0" + note: "sha1 values in order: v1.0 and v2.0, then v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1498, 1519, 1540, 1561" - name: "IANIM.BS1" @@ -88,7 +88,7 @@ files: - "55b9eb9ed555b0f249c2cefd54ecc3f511bfcd55" - "04a8e4e7c360f6033dc70f7b09edbc4a6447e462" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1500, 1521, 1542, 1563" - name: "MAPTEMP.BS1" @@ -100,7 +100,7 @@ files: - "293464e7143ff7e6faf5f5b20799e76a394d65bf" - "bbb3cd6ab3e742eada427862504eba06437036d0" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1501, 1522, 1543, 1564" - name: "SANIM.BS1" @@ -123,7 +123,7 @@ files: - "ed1ab61ad2529e046f966d9c1627508f76693ef8" - "537676ddcafeee415c22bb9d00097b25bc7e13c5" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1503, 1524, 1545, 1566" - name: "VGAGRAPH.BS1" @@ -137,7 +137,7 @@ files: - "b59cbe3793b4612b06254ece48bf8e961ab6f528" - "9f9f4c40c9637af472ce5e1a360e51364c3a418a" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1504, 1525, 1546, 1567" - name: "VGAHEAD.BS1" @@ -151,7 +151,7 @@ files: - "0635a4a2b823eef2904ed1d590d98362fb16621d" - "e7fb8f241b8fa94739c3bd09ea05c1afc7bbfc95" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1505, 1526, 1547, 1568" - name: "VSWAP.BS1" @@ -163,7 +163,7 @@ files: - "37412ca9139562fc31330d72470822de4d9ceb4a" - "dbde907ba1110bef445d6daae283c4520d6951b4" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1506, 1527, 1548, 1569" # Aliens of Gold registered @@ -221,7 +221,7 @@ files: - "6f19a144d8985e90f096fc1c67ade58e9051235c" - "028f624e150f84ffc8336336cb0ecea0932cc22d" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1586, 1609, 1632, 1655" - name: "MAPTEMP.BS6" @@ -233,7 +233,7 @@ files: - "4d00c5f5c843f99a266bd938648192a6eff17b5a" - "8b48e7eb859382a4c84948c5a62899194288e853" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1587, 1610, 1633, 1656" - name: "SANIM.BS6" @@ -256,7 +256,7 @@ files: - "e4ae3ef9a3ac158a832092b7b5487227337c6f13" - "60da35e506d57753f83cca5f232a76dd1cf074ba" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1589, 1612, 1635, 1658" - name: "VGAGRAPH.BS6" @@ -270,7 +270,7 @@ files: - "6868e6cc4f8cb9160a218c5bce680a11f64c675a" - "001037fafdff124befb5437c563d0b9c613b3c00" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1590, 1613, 1636, 1659" - name: "VGAHEAD.BS6" @@ -284,7 +284,7 @@ files: - "1a3864cd12de4b8fd6be023b73d2d79e91b9018d" - "ff165ca5924d738853587a7e4ab1cd239e10e359" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0; v2.1; v3.0" + note: "sha1 values in order: v1.0, v2.0, v2.1, v3.0" source_ref: "src/bstone/src/id_ca.cpp:1591, 1614, 1637, 1660" - name: "VSWAP.BS6" @@ -296,7 +296,7 @@ files: - "0a700732ccbc72f95318a6226a7e1ad78ac713bb" - "6fcc6e007b02b2e55892cfa7acfd42966ef9c9fb" validation: [sha1] - note: "sha1 values in order: v1.0; v2.0 and v2.1 and v3.0" + note: "sha1 values in order: v1.0, then v2.0 and v2.1 and v3.0" source_ref: "src/bstone/src/id_ca.cpp:1592, 1615, 1638, 1661" # Planet Strike diff --git a/emulators/c64-emu.yml b/emulators/c64-emu.yml index 09eb43a0..2cfe8698 100644 --- a/emulators/c64-emu.yml +++ b/emulators/c64-emu.yml @@ -81,7 +81,7 @@ notes: | longer with a warning (C64.emu/src/main/sysfile.cc:30-71). SHA-1s are those hardcoded in c64/c64rom.h:88-96. c64rom.c:120-131 hashes the - loaded kernal and matches that table to identify the revision; an unmatched + loaded kernal and matches that table to identify the revision, and an unmatched image is reported and accepted. VICE distributes C128/kernal64-901227-03.bin and C128/basic64-901226-01.bin with the same bytes as the C64 Rev 3 kernal and BASIC, so those two entries carry the same hashes. @@ -93,7 +93,7 @@ notes: | machine directory and sets both resources (C64.emu/src/main/EmuMenuViews.cc:186,1058,1074-1083, C64.emu/src/main/options.cc:38-51). Only the code-named default of each chip - is listed here; palette_load appends the .vpl extension itself + is listed here, and palette_load appends the .vpl extension itself (palette.c:228-248). Keymaps are named from KBD_PORT_PREFIX, which the app sets to gtk3 @@ -105,7 +105,7 @@ notes: | Four subsystems are compiled but cannot reach their files. Printer ROMs and the PRINTER/ palettes load from drv_mps803_open and drv_nl10_open, which require Printer4, Printer5 or Printer6 to leave PRINTER_DEVICE_NONE - (printerdrv/interface-serial.c:145-149); the app writes no printer resource, + (printerdrv/interface-serial.c:145-149). The app writes no printer resource, and neither main.c nor initcmdline.c is compiled, so the resource file and the command line that would set one do not exist. Romset .vrs files, the monitor command file and joystick .vjm maps have no default name at all @@ -1106,7 +1106,7 @@ files: description: "CMD HD boot ROM" note: >- The MAME dump cmd_hd_bootrom_v280.bin reads the chip over 32 KB and its - two halves are identical; the image here is the first half, the 16 KB the + two halves are identical. The image here is the first half, the 16 KB the loader asks for. source_ref: "C64.emu/src/vice/drive/driverom.h:49,100, C64.emu/src/vice/drive/iec/iecrom.c:145,218" diff --git a/emulators/cap32.yml b/emulators/cap32.yml index 5ecab371..5020b2d3 100644 --- a/emulators/cap32.yml +++ b/emulators/cap32.yml @@ -54,7 +54,7 @@ notes: | and loads it via snapshot_load_mem() in cap32/slots.c:71-90. files: - # Standalone loads from rom_path/; libretro embeds all as C arrays + # Standalone loads from rom_path/, libretro embeds all as C arrays - name: cpc464.rom system: amstrad-cpc required: false @@ -80,7 +80,7 @@ files: size: 32768 md5: b96280dc6c95a48857b4b8eb931533ae sha1: 5977adbad3f7c1e0e082cd02fe76a700d9860c30 - note: "CPC 6128 OS + BASIC 1.1, default model=2; missing file returns ERR_CPC_ROM_MISSING" + note: "CPC 6128 OS + BASIC 1.1, default model=2. A missing file returns ERR_CPC_ROM_MISSING" source_ref: "src/cap32.cpp:212-217, src/cap32.cpp:1013-1027, src/cap32.cpp:1799, rom/cpc6128.rom" - name: amsdos.rom system: amstrad-cpc @@ -89,7 +89,7 @@ files: size: 16384 md5: 25629dfe870d097469c217b95fdc1c95 sha1: 39102c8e9cb55fcc0b9b62098780ed4a3cb6a4bb - note: "AMSDOS disc ROM, shipped cap32.cfg sets slot07=DEFAULT, skipped on the 464; missing file clears the slot" + note: "AMSDOS disc ROM, shipped cap32.cfg sets slot07=DEFAULT, skipped on the 464. A missing file clears the slot" source_ref: "src/cap32.cpp:1170-1178, src/cap32.cpp:1245-1249, cap32.cfg:205-206, 215, rom/amsdos.rom" - name: system.cpr system: amstrad-cpc @@ -107,7 +107,7 @@ files: size: 8192 md5: 4c9f014e91d407cc6509fad0095ab909 sha1: 1431ec628d38f000715545dd2186b684c5fe5a6f - note: "Multiface 2 ROM, read when mf2=1; checks the \"MULTIFACE 2\" signature at 0x0d32" + note: "Multiface 2 ROM, read when mf2=1. Checks the \"MULTIFACE 2\" signature at 0x0d32" source_ref: "src/cap32.cpp:1252-1278, rom/MF2.rom" platform_details: @@ -116,7 +116,7 @@ platform_details: note: | All ROMs are embedded. emulator_select_ROM() copies the ROM array for CPC.model into pbROM. No filesystem lookup occurs in the libretro - port; retro_system_bios_directory is set in + port. retro_system_bios_directory is set in libretro/libretro-core.c:1617-1636 and no ROM is read from it. embedded_roms: diff --git a/emulators/catacombgl.yml b/emulators/catacombgl.yml index d5f15a31..eff25478 100644 --- a/emulators/catacombgl.yml +++ b/emulators/catacombgl.yml @@ -48,7 +48,7 @@ notes: | (src/Engine/EgaGraph.cpp:50-70, src/Engine/AudioRepository.cpp:43-58). The SHP files are the intro pictures (src/Abyss/IntroViewAbyss.cpp:48-90, src/Armageddon/IntroViewArmageddon.cpp:27-76, - src/Apocalypse/IntroViewApocalypse.cpp:27-76); Abyss v1.12 uses SDLOGO, + src/Apocalypse/IntroViewApocalypse.cpp:27-76). Abyss v1.12 uses SDLOGO, TITLE, CREDITS, BEGIN and FINALE instead (src/Abyss/IntroViewAbyss.cpp:28-45, src/Abyss/GameAbyss.cpp:53-58). SHP10.ABS, SHP13.ARM and SHP13.APC are never opened but belong to the detection tables. diff --git a/emulators/cdogs.yml b/emulators/cdogs.yml index 1723cb11..1ab8e0fd 100644 --- a/emulators/cdogs.yml +++ b/emulators/cdogs.yml @@ -17,7 +17,7 @@ notes: | missions/, dogfights/, music/, sounds/ and doc/. The data root is baked into the binary through -DCDOGS_DATA_DIR. The - source default is "../" ("./" on GCW0), CMakeLists.txt:141-147; Batocera + source default is "../" ("./" on GCW0), CMakeLists.txt:141-147. Batocera sets it to /userdata/roms/cdogs/. GetDataFilePath(), src/cdogs/utils.c:392, returns an absolute request as it is, and otherwise joins CDOGS_DATA_DIR (under the working directory when it is relative) with the requested path. diff --git a/emulators/cemu.yml b/emulators/cemu.yml index 24bbce9c..d1839233 100644 --- a/emulators/cemu.yml +++ b/emulators/cemu.yml @@ -49,7 +49,7 @@ notes: | portable directory next to the executable when it exists, otherwise %APPDATA%/Cemu on Windows, XDG_DATA_HOME/Cemu and XDG_CONFIG_HOME/Cemu on Linux, and the MLC defaults to /mlc01. path: entries below are - the libretro destination under the system directory; standalone_path: is + the libretro destination under the system directory, and standalone_path: is relative to the Cemu user data directory. ref: src/libretro/CemuLibretro.cpp:1647-1707, src/libretro/CemuLibretro.cpp:3264-3272, @@ -57,7 +57,7 @@ notes: | src/config/ActiveSettings.cpp:295-321 keys.txt is read once from the user data path. A missing file is created - with a comment header and an example key; each line is stripped of + with a comment header and an example key. Each line is stripped of comments, spaces, dashes and underscores and must then be 32 hex characters, otherwise an error is raised for that line. FindDiscKey tries every key in order against the encrypted partition header of a .wud/.wux @@ -87,11 +87,11 @@ notes: | src/resource/CafeDefaultFont.cpp:2562-2569 Online files. iosuCrypto_init reads otp.bin and seeprom.bin from the user - data path and rejects any size other than 1024 and 512 bytes; without a + data path and rejects any size other than 1024 and 512 bytes. Without a valid OTP no certificate is loaded and online mode is off. The certificate table names 8 client certificates with their AES-encrypted RSA keys and 39 CA certificates, all under sys/title/0005001b/10054000/content/ of the - MLC; olive and wood appear twice under distinct ids, so 7 distinct client + MLC, and olive and wood appear twice under distinct ids, so 7 distinct client pairs and 39 CA files are read. A key file must be a non-empty multiple of 16 bytes and is decrypted with the key at OTP offset 0x120. Online mode is only enabled when every file of the table is present. For the libretro @@ -105,7 +105,7 @@ notes: | .rpl in cafeLibs/ under the user data path and loads it in place of Cemu's own implementation, as long as the game profile does not set loadSharedLibraries to false (the default is true). Any Cafe OS module can - be placed there; the code names snd_user.rpl and snduser2.rpl as the ones + be placed there. The code names snd_user.rpl and snduser2.rpl as the ones to dump when a title uses an unsupported audio effect, and gates swkbd.rpl and erreula.rpl on the presence of their data packs in the MLC (swkbd.pack of title 0005001b-1004f000, erreula.pack of 0005001b-10051000), @@ -116,7 +116,7 @@ notes: | Data directories. A title's game profile is read from gameProfiles/.ini under the config path, then from gameProfiles/default/<title - id>.ini under the data path; upstream ships 236 of them in + id>.ini under the data path. Upstream ships 236 of them in bin/gameProfiles/default and the libretro data path is <system_dir>/Cemu. Standalone loads as a graphic pack every directory holding a rules.txt under graphicPacks/ of the user data path, and its downloader extracts the @@ -179,7 +179,7 @@ files: validation: [size] description: "Wii U OTP dump" note: >- - Read into the OTP mirror at init; any other size is rejected and + Read into the OTP mirror at init. Any other size is rejected and online mode stays off. Its keys decrypt the client certificate keys and sign the device certificate. source_ref: "src/Cafe/IOSU/legacy/iosu_crypto.cpp:553-577, src/Cafe/IOSU/legacy/iosu_crypto.cpp:619-626" @@ -192,7 +192,7 @@ files: validation: [size] description: "Wii U SEEPROM dump" note: >- - Read into the SEEPROM mirror at init; any other size is rejected and + Read into the SEEPROM mirror at init. Any other size is rejected and online mode stays off. source_ref: "src/Cafe/IOSU/legacy/iosu_crypto.cpp:579-600, src/Cafe/IOSU/legacy/iosu_crypto.cpp:627-632" @@ -301,7 +301,7 @@ files: included. Nothing about it is validated. The region holds the SharedDataEntry table (0xFFCAFE01 to 0xFFCAFE04, type 2) followed by CafeCn.ttf, CafeKr.ttf, CafeStd.ttf and CafeTw.ttf, byte-identical to - the console dumps of title 0005001b-10042400 above; every other byte + the console dumps of title 0005001b-10042400 above, and every other byte is zero. source_ref: "src/Cafe/CafeSystem.cpp:268-291, src/Cafe/CafeSystem.cpp:357-365" @@ -335,8 +335,8 @@ files: hle_fallback: true description: "Cafe OS software keyboard applet library" note: >- - Loaded from cafeLibs/ only when swkbd.pack is present in the MLC; - otherwise the built-in keyboard is used and the file is ignored. + Loaded from cafeLibs/ only when swkbd.pack is present in the MLC. + Otherwise the built-in keyboard is used and the file is ignored. source_ref: "src/Cafe/OS/RPL/rpl.cpp:1929-1933, src/Cafe/OS/RPL/rpl.cpp:1978-1988" - name: erreula.rpl @@ -346,8 +346,8 @@ files: hle_fallback: true description: "Cafe OS error viewer applet library" note: >- - Loaded from cafeLibs/ only when erreula.pack is present in the MLC; - otherwise the built-in error viewer is used and the file is ignored. + Loaded from cafeLibs/ only when erreula.pack is present in the MLC. + Otherwise the built-in error viewer is used and the file is ignored. source_ref: "src/Cafe/OS/RPL/rpl.cpp:1935-1939, src/Cafe/OS/RPL/rpl.cpp:1978-1988" - name: swkbd.pack @@ -358,7 +358,7 @@ files: description: "Software keyboard applet data, title 0005001b-1004f000" note: >- Its presence in the MLC is what lets a swkbd.rpl from cafeLibs/ be - used; the applet then reads it through the Cafe filesystem. + used, and the applet then reads it through the Cafe filesystem. source_ref: "src/Cafe/OS/RPL/rpl.cpp:1929-1933" - name: erreula.pack @@ -369,7 +369,7 @@ files: description: "Error viewer applet data, title 0005001b-10051000" note: >- Its presence in the MLC is what lets an erreula.rpl from cafeLibs/ be - used; the applet then reads it through the Cafe filesystem. + used, and the applet then reads it through the Cafe filesystem. source_ref: "src/Cafe/OS/RPL/rpl.cpp:1935-1939" - name: OfflineDB.zar @@ -476,7 +476,7 @@ files: source_ref: "src/Cafe/IOSU/legacy/iosu_crypto.cpp:475, src/Cafe/IOSU/legacy/iosu_crypto.cpp:477, src/Cafe/IOSU/legacy/iosu_crypto.cpp:312-326" # CA certificates, same title, scerts/. Parsed as DER X.509 and added to - # the SSL store; every one of them must load for online mode. + # the SSL store. Every one of them must load for online mode. - name: CACERT_NINTENDO_CA.der path: Cemu/mlc01/sys/title/0005001b/10054000/content/scerts/CACERT_NINTENDO_CA.der standalone_path: mlc01/sys/title/0005001b/10054000/content/scerts/CACERT_NINTENDO_CA.der diff --git a/emulators/cgenius.yml b/emulators/cgenius.yml index 46866009..2b968880 100644 --- a/emulators/cgenius.yml +++ b/emulators/cgenius.yml @@ -22,7 +22,7 @@ notes: | src/engine/CGameLauncher.cpp:134-141, 64-78). A file name containing keenN.exe, keenNe.exe, keenN.lua or kNdemo.exe (N from 1 to 6) or kdreams makes the folder a game (src/engine/CGameLauncher.cpp:437-487). Folder names - are free; the paths below use the folder names of the packages the project + are free. The paths below use the folder names of the packages the project publishes for its in-app downloader, which unpacks under games/ (src/engine/gamedownloader.cpp:455-491). File lookups are case-insensitive. @@ -42,20 +42,20 @@ notes: | properties are known for Keen 1 v1.1, v1.31, v1.34, Keen 2 and 3 v1.0 and v1.31, Keen 4 and 5 v1.4, Keen 6 v1.4 and v1.5, Keen Dreams and the Keen 6 demo (src/fileio/CTileLoader.cpp:68-88). The constructor also holds a - support map keyed by the same sizes (src/fileio/CExeFile.cpp:29-50); its + support map keyed by the same sizes (src/fileio/CExeFile.cpp:29-50). Its result and the CRC comparison of getEXECrc are stored in the launcher entry and read nowhere else (src/engine/CGameLauncher.cpp:546-548). Vorticon episodes open egahead, egalatch and egasprit, one levelNN file per - map (80 is the world map, 81 the ending map, 90 the title map; the other + map (80 is the world map, 81 the ending map, 90 the title map, and the other numbers come from the world map data) and finale.ckN. Episode 1 also reads its story, help and ending texts, its sounds and its preview screens from - files; episodes 2 and 3 take texts and sounds from the executable + files, while episodes 2 and 3 take texts and sounds from the executable (src/engine/keen/vorticon/CStory.cpp:35-76, src/engine/keen/vorticon/CHelp.cpp:38-81, src/engine/keen/vorticon/CAudioVorticon.cpp:40-60). A sounds.ckN file, when present, replaces the embedded sounds. Without the three EGA files or a - level file nothing is drawn or the map load fails; the text, finale, sound + level file nothing is drawn or the map load fails. The text, finale, sound and preview files are skipped when absent. High scores are kept in the engine's own highscoreepN.dat, SCORES.CKN is not read (src/engine/keen/vorticon/CHighScores.cpp:394-397). @@ -78,7 +78,7 @@ notes: | (src/engine/keen/dreams/dreamsengine.cpp:103-114, 226-283, 438) and opens KDREAMS.EGA, KDREAMS.MAP and KDREAMS.AUD, quitting when one is missing. The same file lists a size and CRC-32 for each file of that release - (src/engine/keen/dreams/dreamsengine.cpp:93-101); the routine that compared + (src/engine/keen/dreams/dreamsengine.cpp:93-101), but the routine that compared them is commented out (src/engine/refkeen/be_cross_fs.cpp:660-679), so nothing is verified. LAST.SHL is in that list and is never opened. @@ -813,7 +813,7 @@ files: description: "Keen 6 EGA graphics" required: false source_ref: "src/engine/keen/galaxy/res/CEGAGraphicsGalaxy.cpp:754-763" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "gamemaps.ck6" path: "games/keen6/gamemaps.ck6" @@ -822,7 +822,7 @@ files: description: "Keen 6 level maps" required: false source_ref: "src/fileio/KeenFiles.h:47, src/engine/keen/galaxy/common/CMapLoaderGalaxy.cpp:249-257" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "audio.ck6" path: "games/keen6/audio.ck6" @@ -831,7 +831,7 @@ files: description: "Keen 6 sounds and music" required: false source_ref: "src/fileio/KeenFiles.h:44, src/engine/keen/galaxy/res/CAudioGalaxy.cpp:358-366, src/fileio/CExeFile.cpp:709-716" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # Commander Keen 6: Aliens Ate My Baby Sitter! (demo) - name: "k6demo.exe" diff --git a/emulators/citron.yml b/emulators/citron.yml index 12aa6366..2ff13f8f 100644 --- a/emulators/citron.yml +++ b/emulators/citron.yml @@ -4,7 +4,7 @@ core_classification: community_fork source: "https://git.citron-emu.org/citron-emu/Citron" upstream: "https://git.citron-emu.org/citron-emu/Citron" profiled_date: "2026-03-26" -upstream_gone: "git.citron-emu.org no longer resolves, and git.citron-emu.com redirects to an unrelated survey site, the domain having been taken. Observed 2026-09-04; no mirror found." +upstream_gone: "git.citron-emu.org no longer resolves, and git.citron-emu.com redirects to an unrelated survey site, the domain having been taken. Observed 2026-09-04, no mirror found." core_version: "2026.03.12" display_name: "Citron (Nintendo Switch)" cores: @@ -17,7 +17,7 @@ mode: standalone # Citron is a community fork of yuzu, continued by Zephyron after yuzu's takedown. # Key files loaded from <data_dir>/keys/ (fs_paths.h:18, path_util.cpp:124). # On Linux: $XDG_DATA_HOME/citron/keys/ -# On Batocera: XDG_DATA_HOME=/userdata/saves/switch → /userdata/saves/switch/citron/keys/ +# On Batocera: XDG_DATA_HOME=/userdata/saves/switch -> /userdata/saves/switch/citron/keys/ # Firmware NCAs are installed into NAND via UI (main.cpp:1808), not placed as files. # HLE fallbacks exist for fonts, timezone, system version, mii model, ng word lists. diff --git a/emulators/clk.yml b/emulators/clk.yml index 779012c3..537db3fd 100644 --- a/emulators/clk.yml +++ b/emulators/clk.yml @@ -242,7 +242,7 @@ files: # ------------------------------------------------------- # Amstrad CPC (machine_name: "AmstradCPC") - # Built into binary; external files override built-in copies + # Built into binary. External files override built-in copies # ------------------------------------------------------- - name: os464.rom path: AmstradCPC/os464.rom @@ -506,7 +506,7 @@ files: Conditional: needed for disk controller. Also used by Oric Pravetz. The catalogue accepts 9796a238 and b72a2c70, the same PROM in two byte orders. set_state_machine() takes an image whose first byte is 0x18 as already in - Beneath Apple ProDOS order (b72a2c70) and only reorders its addresses; any + Beneath Apple ProDOS order (b72a2c70) and only reorders its addresses. Any other image is read as the unadulterated P6 PROM (9796a238), its address lines and the top nibble of each value remapped into that order. Both give the same internal table. @@ -695,7 +695,7 @@ files: required: true note: > Required for Macintosh 512ke and Plus models. The catalogue accepts three - images, 4fa5b399, 7cacd18f and b2102e8e; b2102e8e carries the ROM + images, 4fa5b399, 7cacd18f and b2102e8e, and b2102e8e carries the ROM checksum 4D1F8172 of the third Mac Plus revision. The machine copies whichever is supplied into its 128 KiB ROM without reading the revision. @@ -747,7 +747,7 @@ files: size: 32768 crc32: "ee229390" required: false - note: "Alternative to msx.rom for the Japan region, which the analyser never sets; only the user picks it (Analyser/Static/MSX/Target.hpp:34, Analyser/Static/MSX/StaticAnalyser.cpp:217-219)." + note: "Alternative to msx.rom for the Japan region, which the analyser never sets. Only the user picks it (Analyser/Static/MSX/Target.hpp:34, Analyser/Static/MSX/StaticAnalyser.cpp:217-219)." source_ref: "Machines/Utility/ROMCatalogue.cpp:785-792" - name: msx-american.rom @@ -1176,7 +1176,7 @@ files: size: 4096 crc32: "7fc11454" required: false - note: "Required for the Danish region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Danish region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1250-1257" - name: kernel-danish.bin @@ -1186,7 +1186,7 @@ files: size: 8192 crc32: "02adaf16" required: false - note: "Required for the Danish region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Danish region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1258-1265" - name: characters-japanese.bin @@ -1196,7 +1196,7 @@ files: size: 4096 crc32: "fcfd8a4b" required: false - note: "Required for the Japanese region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Japanese region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1266-1273" - name: kernel-japanese.bin @@ -1206,7 +1206,7 @@ files: size: 8192 crc32: "336900d7" required: false - note: "Required for the Japanese region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Japanese region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1274-1281" - name: characters-swedish.bin @@ -1216,7 +1216,7 @@ files: size: 4096 crc32: "d808551d" required: false - note: "Required for the Swedish region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Swedish region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1282-1289" - name: kernel-swedish.bin @@ -1226,12 +1226,12 @@ files: size: 8192 crc32: "b2a60662" required: false - note: "Required for the Swedish region, which only the user picks; the analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." + note: "Required for the Swedish region, which only the user picks. The analyser sets American or European alone (Analyser/Static/Commodore/StaticAnalyser.cpp:350-380, Machines/Commodore/Vic-20/Vic20.cpp:334-345)." source_ref: "Machines/Utility/ROMCatalogue.cpp:1290-1297" # ------------------------------------------------------- # Sinclair ZX Spectrum (machine_name: "ZXSpectrum") - # Built into binary; external files override built-in copies + # Built into binary. External files override built-in copies # ------------------------------------------------------- - name: 48.rom path: ZXSpectrum/48.rom @@ -1275,7 +1275,7 @@ files: # ------------------------------------------------------- # Sinclair ZX80/ZX81 (machine_name: "ZX8081") - # Built into binary; external files override built-in copies + # Built into binary. External files override built-in copies # ------------------------------------------------------- - name: zx80.rom path: ZX8081/zx80.rom diff --git a/emulators/colem.yml b/emulators/colem.yml index fd2bd5eb..556d137b 100644 --- a/emulators/colem.yml +++ b/emulators/colem.yml @@ -17,7 +17,7 @@ notes: | ColecoVision and Coleco Adam emulator by Marat Fayzullin, published as versioned archives on a personal site rather than a repository. The 5.6 source archive carries the portable core (ColEm/, EMULib/, Z80/) and the - Unix port; Windows and Android builds are binary-only. + Unix port. Windows and Android builds are binary-only. Three system ROMs are read by StartColeco (Coleco.c:266-300) before the hardware reset and before the cartridge. Lookup runs in the directory @@ -41,7 +41,7 @@ notes: | 1502). SmartWriter maps at 0000h on boot and EOS at 4000h once port 20h enables it (Coleco.c:628-646). - No hash or magic number is checked on the three ROMs; the read length is + No hash or magic number is checked on the three ROMs: the read length is the only gate. CRC32 is computed for cartridges alone, feeding the GuessROM hardware heuristics (Coleco.c:482-486). diff --git a/emulators/coolbaremu.yml b/emulators/coolbaremu.yml index fcd1c24d..37ef0198 100644 --- a/emulators/coolbaremu.yml +++ b/emulators/coolbaremu.yml @@ -26,7 +26,7 @@ notes: | (crates/coolbaremu-core/src/cbe/archive.rs:68-73). Files next to the .cbe (pay kernels, records, update data) are indexed as the guest filesystem (crates/coolbaremu-core/src/machine/mod.rs:1022-1024, - crates/coolbaremu-core/src/machine/virtual_fs.rs:58-103); they belong to + crates/coolbaremu-core/src/machine/virtual_fs.rs:58-103), and they belong to the game. The only system directory read is coolbaremu_orientation.csv, an optional @@ -40,5 +40,5 @@ files: [] exclusion_note: > The firmware services are reimplemented in the core and the font is the - embedded unifont crate; the system directory holds only an optional + embedded unifont crate. The system directory holds only an optional user-written orientation list. diff --git a/emulators/corsixth.yml b/emulators/corsixth.yml index e7cd2341..e4ce3a83 100644 --- a/emulators/corsixth.yml +++ b/emulators/corsixth.yml @@ -31,7 +31,7 @@ notes: | QDATA/SPointer.dat Any missing file aborts init with "Invalid Theme Hospital folder specified in config file..." (:1526). - 3. DataM/Demo.dat (:1535) marks the shareware demo install; its + 3. DataM/Demo.dat (:1535) marks the shareware demo install. Its presence switches a different corruption-size check on ANIMS/WINLEVEL.SMK (243188), LEVELS/LEVEL.L1 (163948) and DATA/BUTTON01.DAT (252811) at :1559-1561. Full installs instead @@ -51,7 +51,7 @@ notes: | The sound/music path uses the game's XMI tracks when a SoundFont is available (App:findSoundFont at :1589 probes GeneralUser-GS.sf2, - FluidR3_GM.sf2, FluidR3.sf3 and three Linux system paths); the + FluidR3_GM.sf2, FluidR3.sf3 and three Linux system paths), and the SoundFont is a user preference, not game data. files: @@ -63,14 +63,14 @@ files: required: true description: "Theme Hospital install directory (full game or demo)" source_ref: "CorsixTH/Lua/filesystem.lua:64-76, CorsixTH/Lua/app.lua:1435-1447, 1454, 1499" - note: "Accepted as an install when it holds data, levels and qdata subdirectories; the rest of the tree is opened by name on demand." + note: "Accepted as an install when it holds data, levels and qdata subdirectories. The rest of the tree is opened by name on demand." - name: "VBLK-0.TAB" path: "corsixth/DATA/VBLK-0.TAB" system: theme-hospital category: game_data required: true - description: "Theme Hospital core sprite index; sentinel checked at startup" + description: "Theme Hospital core sprite index, sentinel checked at startup" source_ref: "CorsixTH/Lua/app.lua:1521" note: "Looked up as Data/VBlk-0.tab." @@ -79,7 +79,7 @@ files: system: theme-hospital category: game_data required: true - description: "First Theme Hospital level file; sentinel checked at startup" + description: "First Theme Hospital level file, sentinel checked at startup" source_ref: "CorsixTH/Lua/app.lua:1522, 1560" note: "Looked up as Levels/Level.L1. With the demo marker present, a size more than 1024 bytes away from 163948 is reported as corrupt and the game still starts." @@ -88,7 +88,7 @@ files: system: theme-hospital category: game_data required: true - description: "Sprite pointer table; sentinel checked at startup" + description: "Sprite pointer table, sentinel checked at startup" source_ref: "CorsixTH/Lua/app.lua:1523" note: "Looked up as QData/SPointer.dat." @@ -97,7 +97,7 @@ files: system: theme-hospital category: game_data required: true - description: "Theme Hospital font; CRC32 selects charset (mik vs cp437)" + description: "Theme Hospital font, its CRC32 selects charset (mik vs cp437)" source_ref: "CorsixTH/Lua/app.lua:1576-1584" note: "Looked up as QData/Font00V.dat." @@ -106,6 +106,6 @@ files: system: theme-hospital category: game_data required: false - description: "Demo marker; its presence selects the demo graphics set and the demo size checks" + description: "Demo marker: its presence selects the demo graphics set and the demo size checks" source_ref: "CorsixTH/Lua/app.lua:1535-1539, 1558-1561" note: "Looked up as DataM/Demo.dat. Absent from a full install." diff --git a/emulators/cpcemu.yml b/emulators/cpcemu.yml index 1f22f03c..bdcaba9b 100644 --- a/emulators/cpcemu.yml +++ b/emulators/cpcemu.yml @@ -15,7 +15,7 @@ mode: standalone notes: | Amstrad CPC emulator by Marco Vieth and Rainer Loritz, closed-source freeware for Windows, macOS, Linux, Android and iOS. Machines are the CPC 464, 664 and - 6128; the firmware identifier and the message catalogue also know the 464+, + 6128. The firmware identifier and the message catalogue also know the 464+, the 6128+ and the KC compact. Two packages were used. The 3.0.2 Windows portable and macOS builds of @@ -28,7 +28,7 @@ notes: | truncating and patching each file and reading the emulator's own messages. ROMs live in ROM_PATH, "./ROM/" in the shipped configuration, resolved against - the working directory; the macOS build reads them from the application bundle + the working directory, while the macOS build reads them from the application bundle Resources folder. Slots are filled by ROM_BLOCK lines naming a ROM number, a file in ROM_PATH and a 16 KB block position inside that file: @@ -42,7 +42,7 @@ notes: | for types 2, 4 and 5, and adds the M4 line once for all types. A file named by a ROM_BLOCK line that cannot be opened prints "ROM: Cannot open file" and ends the process with status 3 before audio initialisation, whichever slot it fills - and whether or not the matching device is enabled; deleting the line instead + and whether or not the matching device is enabled. Deleting the line instead lets the emulator start. The machine is identified from the foreground ROM, not from the lower half and @@ -65,18 +65,18 @@ notes: | M4 board emulation is on by default. HACK.ROM, the board's lower ROM, is opened at every startup whatever M4_ENABLED holds, after M4_SD_PATH + NMIROM.BIN has been tried, so a NMIROM.BIN placed on the emulated SD card - replaces it; with neither present the emulator prints "Unable to load + replaces it. With neither present the emulator prints "Unable to load HACK.ROM" and keeps running. M4.ROM contents are checked, a zeroed file boots the CPC and reports "M4 ROM not valid." The firmware updater downloads M4FIRM.BIN from spinpoint.org and rewrites M4.ROM and HACK.ROM in place. Alongside the ROMs the binary reads its own payload from the program - directory: cpcemu.msg, the message catalogue, whose absence leaves every - message unprinted; cpcemu.dat, colours and key tables; cpcemu.hlp, the online - help opened on F1; cpcemu.dbf, the poke database opened from the poke menu; - and cpcemu0.cfg, the template used when no user configuration exists. + directory. cpcemu.msg is the message catalogue, and its absence leaves every + message unprinted. cpcemu.dat holds colours and key tables, cpcemu.hlp is the + online help opened on F1, cpcemu.dbf is the poke database opened from the poke + menu, and cpcemu0.cfg is the template used when no user configuration exists. Configuration is looked up first in the user profile, ~/.CPCemu/cpcemu.cfg on - Linux, then cpcemu0.cfg in the working directory; with neither, startup stops + Linux, then cpcemu0.cfg in the working directory. With neither, startup stops on "CPCEMU: Use INSTALL first". The disc, tape and snapshot folders and the M4 SD card folder hold user content. @@ -133,7 +133,7 @@ files: note: >- AMSDOS disc ROM, the 8 KB image zero-padded to 16 KB. Declared for every machine by the shipped configuration, so startup ends on status 3 without - it; dropping the ROM_BLOCK line instead boots with "ROM: No AMSDOS ROM + it. Dropping the ROM_BLOCK line instead boots with "ROM: No AMSDOS ROM found." and no disc support. Length is not checked, an 8 KB file installs the AMSDOS speedup all the same. diff --git a/emulators/craft.yml b/emulators/craft.yml index 840cc7ba..146223f9 100644 --- a/emulators/craft.yml +++ b/emulators/craft.yml @@ -19,7 +19,7 @@ files: [] notes: > Libretro port of Craft, a simple Minecraft clone by Michael Fogleman. All textures, fonts, and shaders are embedded in the binary (header arrays). - Upstream loads textures from external PNG files; libretro port compiles them in. + Upstream loads textures from external PNG files, while the libretro port compiles them in. Uses system directory only for craft.db/auth.db (core-generated save data). Source has zero fopen calls. .info declares no firmware. source_ref: "libretro/libretro.c, src/main.c:2680-2698, src/main.c:3315-3345" diff --git a/emulators/cxbx-reloaded.yml b/emulators/cxbx-reloaded.yml index 07fb4f9b..eac2ee85 100644 --- a/emulators/cxbx-reloaded.yml +++ b/emulators/cxbx-reloaded.yml @@ -53,7 +53,7 @@ notes: | Chihiro, and each one ends the run when it cannot be opened. Byte 0x1F00 of the QC firmware carries the region, rewritten to one the title's BootID accepts so the board does not reject the game. Titles read and write all four images - through the JVS patches at offsets of their own choosing; no size, bound or + through the JVS patches at offsets of their own choosing, and no size, bound or hash check exists anywhere in that path. ref: src/core/hle/JVS/JVS.cpp:129-145, src/core/hle/JVS/JVS.cpp:174-213, @@ -79,7 +79,7 @@ files: validation: [size] description: "Chihiro media board flash ROM" note: >- - Checked for existence, opened, and rejected unless it is exactly 2 MB; each + Checked for existence, opened, and rejected unless it is exactly 2 MB. Each failure ends the run with a message naming the file and the EmuMediaBoard folder. Read once, to write out the two SEGABOOT halves when they are absent. It is also the target a Chihiro title returns to when it reboots @@ -183,7 +183,7 @@ files: validation: [size] description: "Xbox EEPROM image" note: >- - Opened at startup and mapped read/write; the file is created and filled + Opened at startup and mapped read/write. The file is created and filled with defaults when it does not exist, and a file that is not 256 bytes ends the run. Section checksums are recomputed on every load. The encrypted section is read as plaintext: the stored checksum is compared with the @@ -206,7 +206,7 @@ files: as produced by dump-xbox. A file of any other length is refused with a warning naming the expected length, and an absent file only costs the ability to read save data from a real console. The certificate key derives - the LAN, signature and alternate signature keys of the running title; the + the LAN, signature and alternate signature keys of the running title, and the EEPROM key checks the EEPROM header and is read again by the EEPROM editor to recompute the checksum it writes. source_ref: "src/common/FilePaths.cpp:139-172, src/core/kernel/common/types.h:2232, src/core/kernel/init/CxbxKrnl.cpp:113-132, src/common/EmuEEPROM.cpp:184-191, src/gui/DlgEepromConfig.cpp:200-207" diff --git a/emulators/daedalusx64.yml b/emulators/daedalusx64.yml index 0111fe91..b465f1c2 100644 --- a/emulators/daedalusx64.yml +++ b/emulators/daedalusx64.yml @@ -16,7 +16,7 @@ systems: notes: | High-level Nintendo 64 emulator. The boot sequence and the RSP are emulated at high level: no PIF ROM or other console firmware is opened. The code - carries no version string; the tree is 837 commits past tag 1.1.8. + carries no version string, and the tree is 837 commits past tag 1.1.8. Every data file is resolved against baseDir, which on Linux is the working directory at startup. ROCKNIX copies the package to /storage/.config/DaedalusX64 @@ -26,7 +26,7 @@ notes: | Linux builds pick the renderer by architecture: OpenGL ES on aarch64 and arm, desktop OpenGL elsewhere. Each renderer installs its own n64.psh, the fragment shader library prepended to every shader the renderer compiles. The ES - renderer fails graphics init without it; the desktop one goes on with an + renderer fails graphics init without it, while the desktop one goes on with an empty library and its shaders do not compile. ref: Source/CMakeLists.txt:132-137, Source/SysPosix/CMakeLists.txt:12-18, Source/SysGLES/HLEGraphics/RendererGL.cpp:77-110, @@ -80,5 +80,5 @@ files: md5: "78609089d3dad36318ae0190321e6f3e" bundled: true description: "UI font" - note: "Opened through SDL_ttf for the on-screen menus; a failure is printed and emulation is not affected." + note: "Opened through SDL_ttf for the on-screen menus. A failure is printed and emulation is not affected." source_ref: "Source/SysGL/Graphics/DrawTextSDL.cpp:30-41, Source/SysGLES/Graphics/DrawTextSDL.cpp:30-41" diff --git a/emulators/demul.yml b/emulators/demul.yml index 297d6b52..4fa629b3 100644 --- a/emulators/demul.yml +++ b/emulators/demul.yml @@ -147,7 +147,7 @@ files: required: false hle_fallback: true category: bios_zip - note: "MIE (Maple-JVS bridge) Z80 MCU firmware (315-6146.bin). HLE mode available; LLE mode requires this archive." + note: "MIE (Maple-JVS bridge) Z80 MCU firmware (315-6146.bin). HLE mode available, LLE mode requires this archive." - name: jvs13551.zip required: true diff --git a/emulators/desmume.yml b/emulators/desmume.yml index b2d8d3c6..cad778d8 100644 --- a/emulators/desmume.yml +++ b/emulators/desmume.yml @@ -11,7 +11,7 @@ cores: [desmume] systems: [nintendo-ds] notes: | - Full HLE of ARM7/ARM9 SWI routines; BIOS files optional for most games. + Full HLE of ARM7/ARM9 SWI routines, so BIOS files are optional for most games. External BIOS enables SWI-from-BIOS mode. Firmware boot requires both BIOS files loaded and interpreter mode (JIT incompatible). No DSi support. Core option: desmume_use_external_bios. @@ -43,4 +43,4 @@ files: required: false hle_fallback: true source_ref: "desmume/src/firmware.cpp:249-280, desmume/src/frontend/libretro/libretro.cpp:765" - note: "Loaded only if both BIOS files present; needed for boot animation, wifi config, user settings" + note: "Loaded only if both BIOS files present. Needed for boot animation, wifi config, user settings" diff --git a/emulators/desmume2015.yml b/emulators/desmume2015.yml index ffce462b..96960fd8 100644 --- a/emulators/desmume2015.yml +++ b/emulators/desmume2015.yml @@ -15,7 +15,7 @@ notes: | Frozen 2015 snapshot of DeSmuME. The core emulator code supports external BIOS/firmware (PrepareBiosARM7/ARM9 in desmume/src/NDSSystem.cpp:1957-2033), but UseExtBIOS defaults to false (desmume/src/NDSSystem.h:497) and the libretro frontend - never sets it — no desmume_use_external_bios core option exists in this + never sets it: no desmume_use_external_bios core option exists in this version. Uses HLE BIOS stubs when external BIOS not loaded. files: [] diff --git a/emulators/devilutionx.yml b/emulators/devilutionx.yml index c4ae37f4..1b585894 100644 --- a/emulators/devilutionx.yml +++ b/emulators/devilutionx.yml @@ -28,7 +28,7 @@ notes: | LoadModArchives() (:703) - mods/<name>.mpq for each active mod diabdat.mpq is matched uppercase first ("DIABDAT.MPQ", GOG/retail CD - convention, line 538), then lowercase (line 542); if neither is found + convention, line 538), then lowercase (line 542). If neither is found the loader falls back to spawn.mpq (line 544). Missing BOTH triggers the "diabdat.mpq or spawn.mpq" InsertCDDlg dialog and the game cannot start. @@ -42,7 +42,7 @@ notes: | CMakeLists.txt:192-204). CMake/Assets.cmake:46-238 lists the packed files (ASSETS_VERSION, arena, data, fonts, gendata, levels, lua, plrgfx, txtdata and ui_art, plus data/inv/objcurs-widths.txt and the - ui_art PNGs outside SDL1 and Vita builds); each Translations/<lang>.po + ui_art PNGs outside SDL1 and Vita builds), and each Translations/<lang>.po is compiled with msgfmt to <lang>.gmo and appended (CMake/Assets.cmake:8-29, 268-272). The archive is written with "smpq -A -M 1 -C BZIP2 -c" from the staged assets directory @@ -57,7 +57,7 @@ notes: | to fonts.mpq when it is loaded (Source/init.cpp:98-114). fonts.mpq is the CJK + language assets add-on from the - devilutionx-assets release; English installs do not need it. + devilutionx-assets release. English installs do not need it. files: - name: diabdat.mpq @@ -67,7 +67,7 @@ files: required: true description: "Diablo retail or GOG MPQ (contains all game data)" aliases: [DIABDAT.MPQ] - note: "primary game archive; GOG CD convention uses uppercase" + note: "primary game archive, the GOG CD convention uses uppercase" source_ref: "Source/engine/assets.cpp:537-542" - name: spawn.mpq @@ -76,7 +76,7 @@ files: category: game_data required: false description: "Diablo shareware archive, used when diabdat.mpq is absent" - note: "freely redistributable shareware; triggers gbIsSpawn mode" + note: "freely redistributable shareware, triggers gbIsSpawn mode" source_ref: "Source/engine/assets.cpp:544" - name: hellfire.mpq @@ -92,7 +92,7 @@ files: system: diablo category: game_data required: false - description: "Hellfire monk class assets; mandatory when hellfire.mpq is present" + description: "Hellfire monk class assets, mandatory when hellfire.mpq is present" source_ref: "Source/engine/assets.cpp:583" - name: hfmusic.mpq @@ -100,7 +100,7 @@ files: system: diablo category: game_data required: false - description: "Hellfire music; mandatory when hellfire.mpq is present" + description: "Hellfire music, mandatory when hellfire.mpq is present" source_ref: "Source/engine/assets.cpp:584" - name: hfvoice.mpq @@ -108,7 +108,7 @@ files: system: diablo category: game_data required: false - description: "Hellfire voices; mandatory when hellfire.mpq is present" + description: "Hellfire voices, mandatory when hellfire.mpq is present" source_ref: "Source/engine/assets.cpp:585" - name: "hfbard.mpq" @@ -150,7 +150,7 @@ files: category: game_data required: false description: "Spanish voice pack" - note: "The archive named after the selected language code is loaded; English loads none." + note: "The archive named after the selected language code is loaded. English loads none." source_ref: "Source/engine/assets.cpp:521-528" - name: "pl.mpq" @@ -159,7 +159,7 @@ files: category: game_data required: false description: "Polish voice pack" - note: "The archive named after the selected language code is loaded; English loads none." + note: "The archive named after the selected language code is loaded. English loads none." source_ref: "Source/engine/assets.cpp:521-528" - name: "ru.mpq" @@ -168,7 +168,7 @@ files: category: game_data required: false description: "Russian voice pack" - note: "The archive named after the selected language code is loaded; English loads none." + note: "The archive named after the selected language code is loaded. English loads none." source_ref: "Source/engine/assets.cpp:521-528" - name: "hf.mpq" @@ -177,5 +177,5 @@ files: category: game_data required: false description: "Hellfire mod archive packed from the repository's mods/hf directory" - note: "mods/<name>.mpq is opened for each active mod; hf is activated when hellfire.mpq is present. A mod with no archive and no loose directory is served from the core archives. Built by CMake with smpq (MPQ version 1, BZIP2, no attributes) from the hellfire_mod file list." + note: "mods/<name>.mpq is opened for each active mod, and hf is activated when hellfire.mpq is present. A mod with no archive and no loose directory is served from the core archives. Built by CMake with smpq (MPQ version 1, BZIP2, no attributes) from the hellfire_mod file list." source_ref: "Source/engine/assets.cpp:748-764, Source/options.cpp:77-79, CMakeLists.txt:204, CMake/Mods.cmake:8-33, 58-66" diff --git a/emulators/dhewm3.yml b/emulators/dhewm3.yml index 218cb99a..38a002c3 100644 --- a/emulators/dhewm3.yml +++ b/emulators/dhewm3.yml @@ -35,7 +35,7 @@ notes: | files: # ================================================================ # base/ - Doom 3 retail paks - # README.md:136 names "pak000.pk4 to pak008.pk4"; the engine itself + # README.md:136 names "pak000.pk4 to pak008.pk4", but the engine itself # loads every .pk4 found in the gamedir, so the exact set depends on # which patch level the user owns (1.3.1 ships 008). # ================================================================ @@ -53,7 +53,7 @@ files: path: "base/pak001.pk4" required: true source_ref: "neo/framework/FileSystem.cpp:2125" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold. A same-named file of another game must not stand in" - name: "pak002.pk4" category: game_data @@ -82,7 +82,7 @@ files: path: "base/pak005.pk4" required: false source_ref: "neo/framework/FileSystem.cpp:2125" - note: "Shipped with 1.1 patch; absent on 1.0 install." + note: "Shipped with 1.1 patch, absent on 1.0 install." - name: "pak006.pk4" category: game_data @@ -106,7 +106,7 @@ files: path: "base/pak008.pk4" required: false source_ref: "neo/framework/FileSystem.cpp:2125, neo/framework/FileSystem.cpp:893-897" - note: "Shipped with 1.3.1 patch; path handling explicitly names it." + note: "Shipped with 1.3.1 patch. Path handling explicitly names it." - name: "zpak001.pk4" category: game_data diff --git a/emulators/dingooemu.yml b/emulators/dingooemu.yml index 5a63c0a3..edfc41f6 100644 --- a/emulators/dingooemu.yml +++ b/emulators/dingooemu.yml @@ -17,17 +17,17 @@ notes: | Dingoo A320 and Gemei A330 emulator written in Rust by AloysHF. The libretro core and the dingoo-emu standalone binary share the dingooemu-core crate. Content is read from its full path (need_fullpath - = true, crates/dingooemu-libretro/src/api.rs:87; - crates/dingooemu/src/main.rs:226; crates/dingooemu-core/src/emulator.rs:33-37; + = true, crates/dingooemu-libretro/src/api.rs:87, + crates/dingooemu/src/main.rs:226, crates/dingooemu-core/src/emulator.rs:33-37, crates/dingooemu-core/src/package.rs:124-135). The CCDL package's load address selects the runtime: a .app loaded in the 0x8xxxxxxx range runs on the MIPS32 interpreter as an A320, a .cc, .c2s or .c3s loaded at 0x10100000 (retail SDK) or 0x13800000 (homebrew SDK) runs on the ARM32/Thumb interpreter as an A330 - (crates/dingooemu-core/src/content.rs:66-74, 104-121; + (crates/dingooemu-core/src/content.rs:66-74, 104-121, crates/dingooemu-core/src/emulator.rs:44-55). Both runtimes bind the package's imports to Rust implementations of the device SDK - (crates/dingooemu-core/src/a320/runtime/sdk_hle/mod.rs:22-30; + (crates/dingooemu-core/src/a320/runtime/sdk_hle/mod.rs:22-30, crates/dingooemu-core/src/a330/runtime/sdk_hle/mod.rs:226-234). No firmware code is executed and no font or system file backs those calls. @@ -47,7 +47,7 @@ notes: | resolves a name in five steps: a file under the save directory, a host file relative to the content's directory, a resource packed inside the package, the zip payload appended to the package, then an entry of the - firmware archive mounted from the content's directory; a name none of + firmware archive mounted from the content's directory. A name none of them answers fails the open. fsys_findfirst enumerates the content's directory and refuses to leave it (crates/dingooemu-core/src/a330/runtime/sdk_hle/files.rs:381-395). @@ -59,7 +59,7 @@ notes: | (crates/dingooemu-core/src/a320/runtime.rs:372, crates/dingooemu-core/src/a330/runtime.rs:415-417). The core queries RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY only - (crates/dingooemu-libretro/src/constants.rs:30); no system directory + (crates/dingooemu-libretro/src/constants.rs:30), and no system directory constant exists in the crate. With the diagnostic core option on, dingooemu-diagnostic.txt is written @@ -88,15 +88,15 @@ files: (crates/dingooemu-core/src/a330/runtime.rs:415-418): the content's directory is scanned and the first entry whose extension is hxf, in any case, is read whole. The file must start with WADF0100 and declare at offset - 20 a size within its own length; each record is a u32 name length, + 20 a size within its own length. Each record is a u32 name length, the name, one byte, a u32 data length and the data, and a zero name length ends the table. Names are lowercased, backslashes turned to slashes and a leading drive letter dropped, so Z:\SYSTEM\nls\c_936.nls and system/nls/c_936.nls reach the same entry. The archive is the last source consulted when a game opens a file the save directory, the content directory, the package's resources and its appended zip - payload do not hold; without it such an open fails and the runtime + payload do not hold. Without it such an open fails and the runtime goes on. The image itself is never hashed, and the hashes here name - the last firmware Gemei published; the V1.10 image of 2011-01-25 + the last firmware Gemei published, and the V1.10 image of 2011-01-25 indexes the same way. source_ref: "crates/dingooemu-core/src/a330/firmware_archive.rs:16-50, 54-58, 63-96, 117-124, crates/dingooemu-core/src/a330/runtime/sdk_hle/files.rs:108-133" diff --git a/emulators/dinothawr.yml b/emulators/dinothawr.yml index 6cd6a857..4ce7a768 100644 --- a/emulators/dinothawr.yml +++ b/emulators/dinothawr.yml @@ -17,7 +17,7 @@ notes: | Two loading modes: 1. Load dinothawr.game as content (data in content directory) 2. supports_no_game=true: loads from system_dir/dinothawr/ - ref: libretro.c:476-479 — + ref: libretro.c:476-479 game_path_dir = join(system_dir, "/", "dinothawr") game_path = join(game_path_dir, "/", "dinothawr.game") @@ -29,4 +29,4 @@ data_directories: source_ref: "libretro.c:479" files: [] -# no BIOS/firmware — game data loaded via data_directories or content +# no BIOS/firmware, game data loaded via data_directories or content diff --git a/emulators/directxbox.yml b/emulators/directxbox.yml index ba4f37fc..3cbe8379 100644 --- a/emulators/directxbox.yml +++ b/emulators/directxbox.yml @@ -49,7 +49,7 @@ files: Xbox MCPX ROM (secret boot ROM on the southbridge). Contains the initial boot vector that loads the flash BIOS. Overlaid at the last 512 bytes of the 16 MB flash region (0xFFFFFE00-0xFFFFFFFF). Only needed for retail - machine types; Debug and Chihiro skip this file. + machine types. Debug and Chihiro skip this file. source_ref: "src/xbox.cpp:186-207, src/libretro/libretro.cpp:202" - name: "cromwell_1024.bin" diff --git a/emulators/dirksimple.yml b/emulators/dirksimple.yml index b6f045ca..d897d9ce 100644 --- a/emulators/dirksimple.yml +++ b/emulators/dirksimple.yml @@ -17,7 +17,7 @@ notes: | and libretro backends (source == upstream). Libretro port loads from system_dir/DirkSimple/. - ref: dirksimple_libretro.c:782,794 — + ref: dirksimple_libretro.c:782,794 sysdir from RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY basedir = sysdir + "/DirkSimple/" DirkSimple_startup(basedir, info->path, ...) at line 799 @@ -38,5 +38,5 @@ data_directories: source_ref: "dirksimple_libretro.c:794" files: [] -# no BIOS/firmware — game data via data_directories +# no BIOS/firmware, game data via data_directories # user provides OGV video as content diff --git a/emulators/dolphin-mmjr.yml b/emulators/dolphin-mmjr.yml index ca3a1cf7..3ba23985 100644 --- a/emulators/dolphin-mmjr.yml +++ b/emulators/dolphin-mmjr.yml @@ -17,7 +17,7 @@ mode: standalone notes: | Android-only Dolphin fork continuing the MMJ line, published as the org.mm.jr package. The repositories it released from are gone, including the - Dolphin-MMJR1 link in its own README; this reading is taken from a surviving + Dolphin-MMJR1 link in its own README. This reading is taken from a surviving copy that carries the release build metadata of the app, applicationId org.mm.jr and versionCode 15808. ref: Source/Android/app/build.gradle:23-29, @@ -27,7 +27,7 @@ notes: | storage. The Sys directory is extracted from the APK assets into the app's internal files directory, and the first run after a versionCode change deletes it and extracts it again, so nothing placed there survives an update. - Paths below are relative to the user directory; entries with no path are read + Paths below are relative to the user directory. Entries with no path are read only from the Sys directory and name their location in their note. ref: Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java:93-134, Source/Core/Common/CommonPaths.h:22-24, Source/Core/Common/FileUtil.cpp:756-807 @@ -43,7 +43,7 @@ notes: | Fonts follow the IPL. When a dump is present the Shift JIS and Windows-1252 fonts are read out of it at offsets 0x1aff00 and 0x1fcf00, for 0x4a24d and - 0x2575 bytes; otherwise the standalone font files are loaded whole, and the + 0x2575 bytes. Otherwise the standalone font files are loaded whole, and the bundled ones have different padding from the console fonts. ref: Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:99-127, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:159-172, @@ -147,7 +147,7 @@ files: adler32_pairs_with: "dsp_coef.bin" adler32_pairs: [["0x66f334fe", "0xf3b93527"], ["0x128ea7a2", "0xa4a575f5"]] description: "DSP instruction ROM" - note: "DSP LLE only, and LLE aborts when the file is absent or not 8192 bytes. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; five replacement pairs are also accepted." + note: "DSP LLE only, and LLE aborts when the file is absent or not 8192 bytes. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair. Five replacement pairs are also accepted." source_ref: "Source/Core/Common/CommonPaths.h:108, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:120-152, Source/Core/Core/DSP/DSPCore.h:35, Source/Core/Core/DSP/DSPCore.cpp:38-80" - name: dsp_coef.bin @@ -168,7 +168,7 @@ files: path: null required: false description: "Gecko code handler" - note: "Read from the root of the Sys directory when cheats are enabled, and written into guest memory between the installer bounds; too large a file is refused and cheats stay off." + note: "Read from the root of the Sys directory when cheats are enabled, and written into guest memory between the installer bounds. Too large a file is refused and cheats stay off." source_ref: "Source/Core/Common/CommonPaths.h:124, Source/Core/Core/GeckoCode.cpp:121-136" - name: keys.bin @@ -190,7 +190,7 @@ files: size: 16384 validation: [size] description: "Wii system configuration" - note: "Opened through the emulated filesystem and accepted only at 0x4000 bytes; anything else is replaced by a freshly generated one." + note: "Opened through the emulated filesystem and accepted only at 0x4000 bytes, and anything else is replaced by a freshly generated one." source_ref: "Source/Core/Common/CommonPaths.h:90, Source/Core/Core/SysConf.cpp:20, Source/Core/Core/SysConf.cpp:55-66" - name: setting.txt @@ -210,7 +210,7 @@ files: required: false hle_fallback: true description: "Wii SD card image" - note: "Opened read-write when the SD device is opened; a 128 MB image is created when the file is missing." + note: "Opened read-write when the SD device is opened, and a 128 MB image is created when the file is missing." source_ref: "Source/Core/Common/CommonPaths.h:119, Source/Core/Common/FileUtil.cpp:802, Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp:60-79" - name: wiitdb.txt diff --git a/emulators/dolphin-mmjr2.yml b/emulators/dolphin-mmjr2.yml index 929bc9d6..e116c928 100644 --- a/emulators/dolphin-mmjr2.yml +++ b/emulators/dolphin-mmjr2.yml @@ -16,7 +16,7 @@ mode: standalone notes: | Android-only Dolphin fork published as the org.dolphinemu.mmjr package. The - repositories it was developed and released from are gone; this reading is + repositories it was developed and released from are gone. This reading is taken from a surviving copy carrying the whole maintainer commit line, up to the last one, which sets the version string to 2.0-18025. The tree is a selective merge of Dolphin Official carrying that label rather than a @@ -30,7 +30,7 @@ notes: | files directory, and a change of git revision deletes it and extracts it again, so nothing placed there survives an update. The build drops Resources and Themes from the assets copy. Paths below are relative to the user - directory; entries with no path are read only from the Sys directory and name + directory. Entries with no path are read only from the Sys directory and name their location in their note. ref: Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java:103, Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java:138-155, @@ -53,7 +53,7 @@ notes: | Fonts follow the IPL. When a dump is present the Shift JIS and Windows-1252 fonts are read out of it at offsets 0x1aff00 and 0x1fcf00, for 0x4a24d and - 0x2575 bytes; otherwise the standalone font files are loaded whole, and the + 0x2575 bytes. Otherwise the standalone font files are loaded whole, and the bundled ones have different padding from the console fonts. ref: Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:102-131, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:175-187, @@ -88,7 +88,7 @@ notes: | boot, one file at a time, and a file already present in the NAND is left alone. Copies placed under Wii/shared2/wc24 are therefore the ones that survive, and the shipped blanks only fill what is still missing. Dolphin - itself reads nwc24msg.cfg and nwc24dl.bin back out of the NAND; the rest are + itself reads nwc24msg.cfg and nwc24dl.bin back out of the NAND, and the rest are there because titles expect them. ref: Source/Core/Core/WiiRoot.cpp:288-322, Source/Core/Core/WiiRoot.cpp:330-335, Source/Core/Core/IOS/Network/KD/NWC24Config.cpp:24-38, @@ -125,7 +125,7 @@ files: validation: [crc32] on_mismatch: warn description: "GameCube boot ROM, NTSC-U directory" - note: "Read whole into a 2 MiB buffer with no size check, then descrambled from 0x100 for 0x1afe00 bytes. The crc32 gate runs when the IPL itself is booted and only warns; the four non-PAL dumps, the Brazilian MPAL one included, pass here without complaint." + note: "Read whole into a 2 MiB buffer with no size check, then descrambled from 0x100 for 0x1afe00 bytes. The crc32 gate runs when the IPL itself is booted and only warns: the four non-PAL dumps, the Brazilian MPAL one included, pass here without complaint." source_ref: "Source/Core/Core/Config/MainSettings.cpp:594-600, Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp:105-113, Source/Core/Core/HW/EXI/EXI_DeviceIPL.h:43, Source/Core/Core/Boot/Boot.cpp:408-442, Source/Core/Core/Boot/Boot.cpp:444-449" - name: IPL.bin @@ -183,7 +183,7 @@ files: adler32_pairs_with: "dsp_coef.bin" adler32_pairs: [["0x66f334fe", "0xf3b93527"], ["0xe789b5a5", "0xa4a575f5"]] description: "DSP instruction ROM" - note: "DSP LLE only, and a file that is absent or not 8192 bytes fails initialisation, which aborts the emulation thread. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair; six replacement pairs are also accepted." + note: "DSP LLE only, and a file that is absent or not 8192 bytes fails initialisation, which aborts the emulation thread. The adler32 is taken over the byte-swapped image and the value here is the Nintendo pair. Six replacement pairs are also accepted." source_ref: "Source/Core/Common/CommonPaths.h:120, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-105, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:107-120, Source/Core/Core/DSP/DSPCore.h:44, Source/Core/Core/DSP/DSPCore.cpp:28-71" - name: dsp_coef.bin @@ -204,7 +204,7 @@ files: path: null required: false description: "Gecko code handler" - note: "Read from the root of the Sys directory when cheats are enabled, and written into guest memory between the installer bounds; too large a file is refused and cheats stay off." + note: "Read from the root of the Sys directory when cheats are enabled, and written into guest memory between the installer bounds. Too large a file is refused and cheats stay off." source_ref: "Source/Core/Common/CommonPaths.h:139, Source/Core/Core/GeckoCode.cpp:120-134, Source/Core/Core/GeckoCode.cpp:142-144" - name: keys.bin @@ -226,7 +226,7 @@ files: size: 16384 validation: [size] description: "Wii system configuration" - note: "Opened through the emulated filesystem and accepted only at 0x4000 bytes; anything else is replaced by a freshly generated one." + note: "Opened through the emulated filesystem and accepted only at 0x4000 bytes, and anything else is replaced by a freshly generated one." source_ref: "Source/Core/Common/CommonPaths.h:102, Source/Core/Core/SysConf.cpp:19, Source/Core/Core/SysConf.cpp:54-65" - name: setting.txt @@ -246,7 +246,7 @@ files: required: false hle_fallback: true description: "Wii SD card image" - note: "Opened read-write when the SD device is opened; a 128 MB image is created when the file is missing. The configured override is empty by default, so the file stays under Load/." + note: "Opened read-write when the SD device is opened, and a 128 MB image is created when the file is missing. The configured override is empty by default, so the file stays under Load/." source_ref: "Source/Core/Common/CommonPaths.h:134, Source/Core/Common/FileUtil.cpp:998, Source/Core/Core/Config/MainSettings.cpp:289, Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp:90-107" - name: clientca.pem @@ -268,7 +268,7 @@ files: sha256: "723be9b32c3afb83a4a3757adf352529e90c0ad6fad52509963ba8942ae625df" validation: [sha256] description: "console SSL client private key" - note: "Read alongside the client certificate and parsed as the private key for it; either one failing leaves the connection without a client certificate." + note: "Read alongside the client certificate and parsed as the private key for it. Either one failing leaves the connection without a client certificate." source_ref: "Source/Core/Core/IOS/Network/SSL.cpp:139-142, Source/Core/Core/IOS/Network/SSL.cpp:383-395, Source/Core/DiscIO/NANDImporter.cpp:225" - name: rootca.pem @@ -365,7 +365,7 @@ files: system: nintendo-wii required: false description: "WiiConnect24 receive mailbox" - note: "Placed in the NAND by the Sys/Wii copy. The bundled file is a stub; the note shipped beside it gives 0x700000 as the size on a console." + note: "Placed in the NAND by the Sys/Wii copy. The bundled file is a stub, and the note shipped beside it gives 0x700000 as the size on a console." source_ref: "Source/Core/Core/WiiRoot.cpp:288-322, Data/Sys/Wii/shared2/wc24/mbox/Readme.txt" - name: wc24send.ctl @@ -381,7 +381,7 @@ files: system: nintendo-wii required: false description: "WiiConnect24 send mailbox" - note: "Placed in the NAND by the Sys/Wii copy. The bundled file is a stub; the note shipped beside it gives 0x200000 as the size on a console." + note: "Placed in the NAND by the Sys/Wii copy. The bundled file is a stub, and the note shipped beside it gives 0x200000 as the size on a console." source_ref: "Source/Core/Core/WiiRoot.cpp:288-322, Data/Sys/Wii/shared2/wc24/mbox/Readme.txt" - name: Readme.txt @@ -391,7 +391,7 @@ files: size: 103 sha256: "e5a888912968050c6c1d46d1c364c324684e1d15aaa62cfe36cf7fce2c687b21" description: "note on the truncated mailboxes, copied into the NAND" - note: "The Sys/Wii copy walks the directory and takes every entry, so this file lands in the NAND with the mailboxes. It records the console sizes of the two mbx files. The hash names the file carried in the source tree, the only form it has, and is not a check the code performs; without it the name alone matches any readme." + note: "The Sys/Wii copy walks the directory and takes every entry, so this file lands in the NAND with the mailboxes. It records the console sizes of the two mbx files. The hash names the file carried in the source tree, the only form it has, and is not a check the code performs. Without it the name alone matches any readme." source_ref: "Source/Core/Core/WiiRoot.cpp:291-319, Data/Sys/Wii/shared2/wc24/mbox/Readme.txt" - name: wiitdb.txt @@ -399,7 +399,7 @@ files: aliases: [titles.txt] required: false description: "user title database" - note: "One title id equals name pair per line, ids of four characters and up. titles.txt is read only when wiitdb.txt yields nothing. Overlays the per-language databases shipped in the Sys directory, which cover ten languages; the Portuguese and Russian files also present there are never registered." + note: "One title id equals name pair per line, ids of four characters and up. titles.txt is read only when wiitdb.txt yields nothing. Overlays the per-language databases shipped in the Sys directory, which cover ten languages. The Portuguese and Russian files also present there are never registered." source_ref: "Source/Core/Core/TitleDatabase.cpp:29-51, Source/Core/Core/TitleDatabase.cpp:54-58, Source/Core/Core/TitleDatabase.cpp:63-79" - name: mios-ipl.map diff --git a/emulators/dolphin.yml b/emulators/dolphin.yml index 10876858..e129821c 100644 --- a/emulators/dolphin.yml +++ b/emulators/dolphin.yml @@ -18,7 +18,7 @@ systems: [nintendo-gamecube, nintendo-wii, sega-triforce] # Libretro: User is <save>/User, Sys is <system>/dolphin-emu/Sys # (Source/Core/DolphinLibretro/Boot.cpp:248-254). The GC ROMs and # segaboot.gcm fall back to Sys (Source/Core/Core/Config/MainSettings.cpp:761-768, -# Source/Core/Core/HW/DVD/AMMediaboard.cpp:500-513); the Wii and GBA files +# Source/Core/Core/HW/DVD/AMMediaboard.cpp:500-513). The Wii and GBA files # are read under User only. pack_structure: diff --git a/emulators/dolphin_launcher.yml b/emulators/dolphin_launcher.yml index 6dae3ea2..b94a9981 100644 --- a/emulators/dolphin_launcher.yml +++ b/emulators/dolphin_launcher.yml @@ -1,7 +1,7 @@ emulator: "Dolphin Launcher" type: launcher core_classification: launcher -exclusion_note: "stub core calls standalone Dolphin — all BIOS in Dolphin's own directory" +exclusion_note: "stub core calls standalone Dolphin, all BIOS in Dolphin's own directory" source: "https://github.com/RobLoach/libretro-dolphin-launcher" upstream: "https://github.com/dolphin-emu/dolphin" profiled_date: "2026-03-23" diff --git a/emulators/dosbox-staging.yml b/emulators/dosbox-staging.yml index 7e8dc497..6d387b36 100644 --- a/emulators/dosbox-staging.yml +++ b/emulators/dosbox-staging.yml @@ -34,7 +34,7 @@ notes: | ref: src/midi/midi.cpp:794-850 MT-32/CM-32L: libmt32emu identifies every candidate by file size then SHA1, - so file names carry no meaning; a directory scan caches which ROM ids each + so file names carry no meaning. A directory scan caches which ROM ids each directory holds and logs anything unrecognised. ref: src/midi/mt32_lasynth_model.cpp:36-97, munt ROMInfo.cpp:206-213 A model needs one control ROM and one PCM ROM, supplied either as a full @@ -44,11 +44,11 @@ notes: | ref: src/midi/mt32_lasynth_model.cpp:114-151, munt ROMInfo.cpp:312-331 model = auto resolves the first available of cm32l_102, cm32l_100, cm32ln_100, mt32_107, mt32_106, mt32_105, mt32_104, mt32_bluer, mt32_207, - mt32_206, mt32_204, mt32_203; the aliases cm32l, mt32, mt32_old and mt32_new + mt32_206, mt32_204, mt32_203. The aliases cm32l, mt32, mt32_old and mt32_new restrict that list. MIXER /LISTMIDI prints what was found. ref: src/midi/mt32.cpp:278-331, 504-557 Search order is romdir, then mt32-roms in the configuration directory, then - the platform locations (C:\mt32-rom-data on Windows; + the platform locations (C:\mt32-rom-data on Windows, ~/Library/Audio/Sounds/MT32-Roms and /usr/{local/,}share/mt32-rom-data on macOS; $XDG_DATA_HOME/dosbox/mt32-roms, $XDG_DATA_HOME/mt32-rom-data, $XDG_DATA_DIRS/mt32-rom-data and $XDG_CONFIG_HOME/dosbox/mt32-roms on Linux). @@ -60,7 +60,7 @@ notes: | from a plugins directory next to the executable, in the configuration directory or under the XDG data directories. DOSBox Staging resolves the ROM directory candidates, canonicalises the ones that exist and exports them as - SOUNDCANVAS_ROM_PATH; the plugin appends the per-model subdirectory, hashes + SOUNDCANVAS_ROM_PATH. The plugin appends the per-model subdirectory, hashes every file under 4 MB it finds there and matches SHA256 against its table. ref: src/midi/soundcanvas.cpp:326-373, src/misc/support.cpp:351-379, Nuked-SC55-CLAP nuked_sc55.cpp:117-215, @@ -221,7 +221,7 @@ files: source_ref: "src/midi/mt32.cpp:145, src/midi/mt32.cpp:242-248, munt ROMInfo.cpp:79, munt ROMInfo.cpp:109" # -- MT-32 control ROM chip dumps (32768 bytes each) -- - # The _a dump holds the even bytes, the _b dump the odd ones; munt + # The _a dump holds the even bytes, the _b dump the odd ones, and munt # interleaves the pair into the full 65536 byte image. # MAME dumps mt32_1.0.X.ic27.bin (_a) and mt32_1.0.X.ic26.bin (_b), # blue_ridge__mt32a.bin (_a) and blue_ridge__mt32b.bin (_b). @@ -595,14 +595,14 @@ files: path: "soundfonts/default.sf2" description: "SoundFont named by the default soundfont setting" required: false - unsourceable: "a link the operating system creates to the SoundFont it installs as default, FluidR3_GM.sf2 on Fedora; no file of this name is distributed, and a same-named file of another program must not stand in" + unsourceable: "a link the operating system creates to the SoundFont it installs as default, FluidR3_GM.sf2 on Fedora. No file of this name is distributed, and a same-named file of another program must not stand in" note: > default value of the soundfont setting: the name picks the default SoundFont when the operating system installs one, usually Fluid R3. Where it exists the name is a link, found as soundfonts/default.sf2 - under an XDG data directory; the link is resolved before the name + under an XDG data directory, and the link is resolved before the name test, so a link to FluidR3_GM.sf2 is identified as Fluid R3. - Any SoundFont loads; GeneralUser GS, Fluid R3, the AWE32 4MB GM/GS/MT + Any SoundFont loads. GeneralUser GS, Fluid R3, the AWE32 4MB GM/GS/MT bank and the Trevor0402 SC-55 SoundFont are recognised by filename or RIFF INFO name and get their own reverb, chorus and filter presets source_ref: "src/midi/fluidsynth.cpp:133-154, src/midi/fluidsynth.cpp:672-689, src/midi/fluidsynth.cpp:816-883, src/midi/fluidsynth.cpp:1227-1242" @@ -614,7 +614,7 @@ files: aliases: ["GeneralUser_GS.sf2"] note: > opened only when the soundfont setting names it, with or without the - .sf2 extension; MIXER /LISTMIDI lists every .sf2 file found in the + .sf2 extension. MIXER /LISTMIDI lists every .sf2 file found in the SoundFont directories. A file whose stem or RIFF INFO name contains GeneralUser is identified as GeneralUser GS, whatever the rest of the name, and gets its own chorus and reverb parameters in auto mode @@ -642,7 +642,7 @@ files: validation: [size] note: > read during PCjr cartridge boot from the current DOS drive, then from - the host working directory; bytes 0x3000 to 0xDFFF are copied to + the host working directory. Bytes 0x3000 to 0xDFFF are copied to physical F3000. A short read leaves the region untouched and the cartridge still boots source_ref: "src/dos/programs/boot.cpp:379-397, src/dos/programs/boot.cpp:83-124" @@ -672,6 +672,6 @@ files: validation: [size] note: > accepted when the file is 16384 bytes or larger, starts with 55 AA, - has byte 3 masked to E8 and carries the string IBM at offset 0x1E; + has byte 3 masked to E8 and carries the string IBM at offset 0x1E, needs an EGA or better machine type source_ref: "src/dos/programs/loadrom.cpp:56-75, src/dos/programs/loadrom.cpp:88-93" diff --git a/emulators/dosbox-x.yml b/emulators/dosbox-x.yml index af335678..fcf2b7a9 100644 --- a/emulators/dosbox-x.yml +++ b/emulators/dosbox-x.yml @@ -44,7 +44,7 @@ notes: | Configuration: -conf and -userconf name the files to read. Otherwise dosbox-x.conf then dosbox.conf is tried in the working directory, then in the program directory, then in the configuration directory, which is last tried - for dosbox-x-<version>.conf; that file is written with the defaults when it + for dosbox-x-<version>.conf. That file is written with the defaults when it does not exist. ref: src/gui/sdlmain.cpp:8667-8743, src/misc/cross.cpp:229-245 @@ -54,13 +54,13 @@ notes: | image list only, which rejects the interleaved chip dumps. ref: src/gui/midi_mt32.h:74-109, src/libs/mt32/c_interface/c_interface.cpp:442-462, src/libs/mt32/ROMInfo.cpp:206-215 mt32.model = auto opens CM32L_CONTROL.ROM then MT32_CONTROL.ROM, and - CM32L_PCM.ROM then MT32_PCM.ROM; cm32l keeps only the CM32L names, mt32 only + CM32L_PCM.ROM then MT32_PCM.ROM. cm32l keeps only the CM32L names, mt32 only the MT32 names. The directory is mt32.romdir, then the working directory, then the resource directory, then the configuration directory. A missing pair logs the accepted file names and disables the device. ref: src/gui/midi_mt32.h:246-275, src/dosbox.cpp:3607-3617 - FluidSynth reads fluid.soundfont; fluid_synth_sfload is the only check. With + FluidSynth reads fluid.soundfont, and fluid_synth_sfload is the only check. With the setting empty it probes /usr/share/soundfonts/default.sf2, /usr/share/sounds/sf2/FluidR3_GM.sf2 and GeneralUser_GS.sf2 on Linux, and C:\soundfonts\default.sf2 then the two same names under C:\DOSBox-X on Windows. @@ -93,13 +93,13 @@ notes: | ref: src/dos/dos_programs.cpp:2227-2228, 2261-2350 BIOSTEST.COM loads an image of up to 64 KB at F000:0 and restarts the CPU at - the reset vector; it is compiled only when the debugger is enabled. The + the reset vector. It is compiled only when the debugger is enabled. The settings call binary on reset and call binary on boot load blobs of up to 128 KB into the ROM BIOS area for CPU testing. ref: src/dos/dos_programs.cpp:3666-3719, src/ints/bios.cpp:13298-13374 A build configured with --enable-dosbox_agent reads the key=value file named - by -agent-config to start the RPC debugger agent; the file names the + by -agent-config to start the RPC debugger agent. The file names the transport and endpoint, nothing else is read from disk. ref: configure.ac:1441-1448, src/gui/sdlmain.cpp:8490-8496, src/agent/protocol/agent_protocol.cpp:477-632 @@ -267,13 +267,13 @@ files: - name: "default.sf2" description: "SoundFont the operating system installs as FluidSynth default" required: false - unsourceable: "a link the operating system creates to the SoundFont it installs as default, FluidR3_GM.sf2 on Fedora; no file of this name is distributed, and a same-named file of another program must not stand in" + unsourceable: "a link the operating system creates to the SoundFont it installs as default, FluidR3_GM.sf2 on Fedora. No file of this name is distributed, and a same-named file of another program must not stand in" note: > first probe when fluid.soundfont is empty: /usr/share/soundfonts/default.sf2, or C:\soundfonts\default.sf2 on Windows. The source marks the first path as the Red Hat and Fedora one, where the name links to FluidR3_GM.sf2, the file of the second - probe. Any SF2 or SF3 file loads; fluid.soundfont names it and + probe. Any SF2 or SF3 file loads: fluid.soundfont names it and fluid_synth_sfload is the only check source_ref: "src/gui/midi_synth.h:346-352, src/gui/midi_synth.h:364-368, src/gui/midi_synth.h:381-384, src/gui/midi_synth.h:462-473, src/dosbox.cpp:3746-3747" @@ -294,7 +294,7 @@ files: third probe when fluid.soundfont is empty: /usr/share/sounds/sf2/GeneralUser_GS.sf2, or C:\DOSBox-X\GeneralUser_GS.sf2 on Windows. Elsewhere the file loads - when fluid.soundfont gives its path; the setting's help text names this + when fluid.soundfont gives its path, and the setting's help text names this file as its example. The synth device probes the same paths source_ref: "src/gui/midi_synth.h:356-358, src/gui/midi_synth.h:373-375, src/gui/midi_synth.h:179-181, src/gui/midi_synth.h:196-198, src/dosbox.cpp:3747" @@ -308,7 +308,7 @@ files: validation: [size] note: > 256 8x8 cells at 0x0, 256 8x16 cells at 0x800, 96 by 92 16x16 cells at - 0x1800; a file of any other length is rejected. Enabled by + 0x1800. A file of any other length is rejected. Enabled by pc-98 try font rom, on by default source_ref: "src/ints/int10.cpp:1487-1549, src/dosbox.cpp:2494-2495" @@ -318,7 +318,7 @@ files: hle_fallback: true note: > 2048 by 2048 monochrome Windows bitmap, biSize 40, one plane, one bit per - pixel, no compression, inverse colour scheme; the first row is the 8x16 + pixel, no compression, inverse colour scheme. The first row is the 8x16 single-width set and the rest is 16x16 full-width. Also reachable through the pc-98 anex86 font setting, which is tried before FONT.ROM source_ref: "src/ints/int10.cpp:1555-1647, src/dosbox.cpp:2498-2501" @@ -328,7 +328,7 @@ files: required: false hle_fallback: true note: > - same bitmap layout as ANEX86.BMP and tried after it; ships in the resource + same bitmap layout as ANEX86.BMP and tried after it, ships in the resource directory source_ref: "src/ints/int10.cpp:1577-1580, src/Makefile.am:17" @@ -358,7 +358,7 @@ files: note: > tried by the TTF output on PC-98 and on double-byte code pages when ttf.font is unset, and by the printer when the selected typeface file is - missing; ships in the resource directory + missing. Ships in the resource directory source_ref: "src/output/output_ttf.cpp:655-668, src/hardware/parport/printer.cpp:354-380, src/Makefile.am:21" # -- Printer typefaces -- @@ -444,7 +444,7 @@ files: max_size: 32768 validation: [size] note: > - read by LOADROM.COM from a mounted local drive; accepted when the file + read by LOADROM.COM from a mounted local drive, accepted when the file starts with 55 AA, byte 3 masked with 0xFC equals 0xE8 and the string IBM appears at offset 0x1E, and the machine is EGA or better source_ref: "src/dos/dos_programs.cpp:3606-3632, src/dos/dos_programs.cpp:3643-3649" @@ -461,7 +461,7 @@ files: validation: [size] note: > the ibm rom basic setting maps it just below the ROM BIOS and accepts - 32 KB to 64 KB in 4 KB steps; LOADROM.COM maps the same image at F600:0 + 32 KB to 64 KB in 4 KB steps. LOADROM.COM maps the same image at F600:0 when it is exactly 32768 bytes, starts with E9 8F 7E and carries the string IBM at offset 0x4CD4 source_ref: "src/ints/bios.cpp:13230-13250, src/dos/dos_programs.cpp:3633-3637, src/dosbox.cpp:1948-1950" @@ -476,7 +476,7 @@ files: min_size: 57344 validation: [size] note: > - read during PCjr cartridge boot; bytes 0x3000 to 0xDFFF are copied to + read during PCjr cartridge boot, and bytes 0x3000 to 0xDFFF are copied to physical F3000. A short read leaves the region untouched and the cartridge still boots source_ref: "src/dos/dos_programs.cpp:3079-3088" @@ -488,7 +488,7 @@ files: required: false note: > loaded at the top of the first megabyte, rounded up to a paragraph and - truncated to 128 KB, or to 96 KB on PC-98; a larger image is clamped + truncated to 128 KB, or to 96 KB on PC-98, and a larger image is clamped rather than rejected source_ref: "src/dos/dos_programs.cpp:2261-2311" @@ -498,7 +498,7 @@ files: max_size: 32768 validation: [size] note: > - served through the port 43Dh bank switch alongside a BOOT -bios image; + served through the port 43Dh bank switch alongside a BOOT -bios image. <image>.itf.rom is tried before the bare name so one directory can hold several source_ref: "src/dos/dos_programs.cpp:2313-2344" diff --git a/emulators/dosbox.yml b/emulators/dosbox.yml index 23ce7907..4cd5e647 100644 --- a/emulators/dosbox.yml +++ b/emulators/dosbox.yml @@ -12,7 +12,7 @@ systems: [dos] notes: | Rebuilt on the dosbox-core tree (DOSBox SVN r4494) with ZIP content and the Nuked-SC55 driver. No BIOS. Every file below belongs to a MIDI driver picked - by the core option; the default driver is "none". + by the core option, and the default driver is "none". ref: libretro/src/libretro_core_options.cpp:1684-1702 A driver that fails to open is replaced by the first handler that opens. ref: src/gui/midi.cpp:241-243 @@ -34,9 +34,9 @@ notes: | size, wave ROMs by the last 1, 2 or 3 in their name. No hash is checked. ref: src/gui/midi_sc55.h:43-52, src/gui/midi_sc55.h:98-133 Byte 67 of ROM1 selects the model and the sizes the other ROMs must have: - SC-55mkII/SC-55st need ROM_SM, a 2 MiB WAVEROM1 and a 1 MiB WAVEROM2; + SC-55mkII/SC-55st need ROM_SM, a 2 MiB WAVEROM1 and a 1 MiB WAVEROM2. SC-55/SC-155 and CM-300/SCC-1 need a 256 KiB ROM2 and three 1 MiB wave - ROMs; JV-880 needs a 256 KiB ROM2 and two 2 MiB wave ROMs; SCB-55 needs a + ROMs. JV-880 needs a 256 KiB ROM2 and two 2 MiB wave ROMs. SCB-55 needs a 2 MiB WAVEROM1. ref: src/gui/midi_sc55.h:151-175 fluidsynth and bassmidi: the soundfont option lists the files found in diff --git a/emulators/dosbox_core.yml b/emulators/dosbox_core.yml index 7da671b2..c0627e05 100644 --- a/emulators/dosbox_core.yml +++ b/emulators/dosbox_core.yml @@ -192,5 +192,5 @@ files: # -- General MIDI SoundFont -- # Placed in system/soundfonts/ directory. Core scans for .sf2/.sf3/.sfz/.dls/.gig. - # FluidSynth reads .sf2/.sf3/.dls/.gig; BASSMIDI reads .sf2/.sfz. + # FluidSynth reads .sf2/.sf3/.dls/.gig, BASSMIDI reads .sf2/.sfz. # No specific filename required - all found files appear in the core option dropdown. diff --git a/emulators/dosbox_pure.yml b/emulators/dosbox_pure.yml index 70943b1b..edf7fff8 100644 --- a/emulators/dosbox_pure.yml +++ b/emulators/dosbox_pure.yml @@ -21,7 +21,7 @@ notes: | MT-32 requires matched pair: *_CONTROL.ROM + *_PCM.ROM (PCM name derived from CONTROL name by replacing CONTROL with PCM, preserving case). ref: src/gui/midi_mt32.h:189-199 - ZIP archives also supported — scanned for files by size (65536/131072 = + ZIP archives also supported, scanned for files by size (65536/131072 = control, 524288/1048576 = PCM), not by name. ref: src/gui/midi_mt32.h:160-166 Files can also be on mounted C: drive (DOSBOX.SF2, MT32_CONTROL.ROM, @@ -46,7 +46,7 @@ notes: | ref: src/gui/mt32emu.h:2982-2988,3016-3019,5183-5187 12 full control ROMs + 2 PCM ROMs supported (no split ROMs in this MUNT). TinySoundFont (tsf.h) for SF2/SF3 playback. - No firmware entries in .info file — all MIDI files optional. + No firmware entries in .info file, all MIDI files optional. DBP_STANDALONE build mode exists (same MIDI logic, different I/O layer). ref: dosbox_pure_libretro.cpp:81,1588,2302 @@ -223,7 +223,7 @@ files: source_ref: "dosbox_pure_libretro.cpp:1405, src/gui/midi_sc55.h:71-75, src/gui/midi_sc55.h:97-101" note: >- Any name ending in ROM1.BIN anywhere under the system directory is - listed; byte 67 selects the emulated model. + listed. Byte 67 selects the emulated model. - name: "ROM2.BIN" path: "SC-55/ROM2.BIN" diff --git a/emulators/drastic.yml b/emulators/drastic.yml index 248b17ae..86fde156 100644 --- a/emulators/drastic.yml +++ b/emulators/drastic.yml @@ -19,7 +19,7 @@ notes: | r2.6.0.4a build 109, package com.dsemu.drastic, apk md5 7df979ef9420c5053b27c838e6a7e20c, whose loader is lib/arm64-v8a/libdrastic_arm64.so and whose installer is the smali of - DraSticActivity; and the Linux AArch64 build r2.5.2.2, md5 + DraSticActivity. The second is the Linux AArch64 build r2.5.2.2, md5 17550db727f3b59d36b57746ad1944be, which ships unstripped with 2731 named functions and is cited by function name. r2.5.2.2 predates the firmware editor and the user database, and that is the whole of the divergence. Every @@ -29,7 +29,7 @@ notes: | /home/odroid/nds_emu/src/linux_odroid64), DraSticActivity.smali One root holds everything. On Android it is a directory named DraStic at the - root of shared storage; on Linux it is the working directory. Startup creates + root of shared storage, on Linux it is the working directory. Startup creates backup, savestates, config, unzip_cache, system, input_record, cheats, slot2, microphone and scripts below it, and the Android build adds backgrounds, icon_cache, users, shaders and virtual_controller. Paths below are relative to @@ -42,13 +42,13 @@ notes: | load_system_file builds <root>/system/<name>, opens it read only, measures it by seeking to the end, refuses any length other than the one its caller asks for with "System file %s is the wrong size (should be %d bytes, is %d)", then - reads it whole. Size is the only test; no hash is computed on any file. + reads it whole. Size is the only test: no hash is computed on any file. ref: drastic r2.5.2.2 load_system_file 0xea80-0xebe4, libdrastic_arm64.so 0x1b4d4-0x1b510 Each BIOS slot has two candidates. The ARM9 slot takes nds_bios_arm9.bin, and on failure logs "Can't find Nintendo ARM9 BIOS. Trying free DraStic ARM9 - BIOS." and takes drastic_bios_arm9.bin; the ARM7 slot does the same with + BIOS." and takes drastic_bios_arm9.bin. The ARM7 slot does the same with nds_bios_arm7.bin then drastic_bios_arm7.bin. A slot left empty returns -1 from initialize_memory, and initialize_system answers that with the on-screen warning naming the two Nintendo files and their sizes, the line "FATAL: Could @@ -65,7 +65,7 @@ notes: | Firmware is answered in code when no file loads: the 256 KB region is zeroed and patch_firmware_header_data writes the header, the console identity and the - user settings block into it. r2.5.2.2 reads nds_firmware.bin alone; r2.6.0.4a + user settings block into it. r2.5.2.2 reads nds_firmware.bin alone, while r2.6.0.4a reads nds_firmware_modified.bin first, which is what its firmware editor writes back, and falls through to nds_firmware.bin. ref: drastic r2.5.2.2 initialize_memory 0x1c3e0-0x1c3f8, @@ -84,7 +84,7 @@ notes: | Two databases sit at the root. game_database.xml carries the save type per title and a failed open only logs "Error: could not load game database file - %s."; r2.6.0.4a reads game_database_user.xml after it as a user overlay. + %s." r2.6.0.4a reads game_database_user.xml after it as a user overlay. usrcheat.dat is the Action Replay library, read by load_cheat_directory. ref: drastic r2.5.2.2 initialize_gamecard 0x709bc-0x70a30, drastic r2.5.2.2 initialize_game_database 0x73180, @@ -267,7 +267,7 @@ files: bundled: true category: game_data description: "lookup texture named by a chain" - note: "Android only. Loaded when a texture tag names a file instead of the framebuffer or an FBO, with the dimensions and the format taken from the tag. SMAA is the one shipped chain that names any, taking smaa/AreaTexRGB.raw and smaa/SearchTexRGB.raw; the package also carries the non-RGB pair of the same two tables, which no shipped chain names." + note: "Android only. Loaded when a texture tag names a file instead of the framebuffer or an FBO, with the dimensions and the format taken from the tag. SMAA is the one shipped chain that names any, taking smaa/AreaTexRGB.raw and smaa/SearchTexRGB.raw. The package also carries the non-RGB pair of the same two tables, which no shipped chain names." source_ref: "assets/shaders/_shader_format_.txt:42-56, assets/shaders/SMAA.dfx:1-6" - name: "<name>.zip" diff --git a/emulators/dreamm.yml b/emulators/dreamm.yml index b58a9f2f..f81074b5 100644 --- a/emulators/dreamm.yml +++ b/emulators/dreamm.yml @@ -32,7 +32,7 @@ notes: | $XDG_DATA_HOME/Aaron Giles/DREAMM on Linux. Paths below are relative to that directory. Startup writes config.json and creates install, gamedelta, screenshots, logs and sounddata. - ref: SDL_GetPrefPath; strace of DREAMM 4.0 linux-x64 with a clean HOME + ref: SDL_GetPrefPath, strace of DREAMM 4.0 linux-x64 with a clean HOME Audio hardware is set per game and per variant: speaker, cms, adlib, sb16, tandy, mt32 and gmidi. MT-32 and General MIDI output can go to an external @@ -52,7 +52,7 @@ notes: | both halves. The CM-32L sets name cm32l_pcm.rom as the full image, mt32_pcm_l.rom as the low half and cm32l_pcm_h.rom as the high half. munt identifies each file by size then SHA1 before opening the synth. - ref: set table 0x23db4a8, id lookup 0x164d050, availability 0x164d2a8; + ref: set table 0x23db4a8, id lookup 0x164d050, availability 0x164d2a8, munt ROMInfo.cpp:206-214 ROMInfo::getROMInfo The SC-55 is emulated by the Nuked SC-55 CLAP plug-in, unpacked to @@ -61,7 +61,7 @@ notes: | v1.20, v1.21, v2.00 and SC-55mk2 v1.01. The plug-in identifies a set by hashing the directory contents, so its own loader does not depend on the file names. - ref: strace of DREAMM 4.0 linux-x64; Nuked-SC55-CLAP nuked_sc55.cpp:145-212 + ref: strace of DREAMM 4.0 linux-x64, Nuked-SC55-CLAP nuked_sc55.cpp:145-212 GetRomBasePaths and Init, rom_loader.cpp:31-80 DetectRomsetsByHash Both families install by dropping files on the Manage Sound Fonts & ROMs @@ -72,7 +72,7 @@ notes: | sizes agree with the bundled munt ROM table. mt32_ctrl_2_03.rom is named by the v2.03 set but has no manifest entry, so it loads from sounddata and cannot be installed by drag and drop. - ref: manifest 0x23daf78, name match 0x16456a0, reverse lookup 0x1645880; + ref: manifest 0x23daf78, name match 0x16456a0, reverse lookup 0x1645880, "To install Sound Fonts (.sf2 files) or ROMs for Roland MIDI emulation, drop them onto this screen." @@ -365,7 +365,7 @@ files: source_ref: "DREAMM 4.0 linux-x64: ROM manifest 0x23dafb8, set table 0x23db4a8; sounddata/mt32emu-dreamm.so ROM table" # -- Roland SC-55, sounddata/Nuked-SC55-Resources/ROMs -- - # One complete set per model directory; the plugin loads a single directory. + # One complete set per model directory, the plugin loads a single directory. - name: sc55_rom1.bin path: "sounddata/Nuked-SC55-Resources/ROMs/SC-55-v1.00/sc55_rom1.bin" description: "Roland SC-55 v1.00 program ROM (ROM1)" diff --git a/emulators/dsmile.yml b/emulators/dsmile.yml index f978dbc9..ef0d5530 100644 --- a/emulators/dsmile.yml +++ b/emulators/dsmile.yml @@ -17,15 +17,15 @@ notes: | V.Smile emulator for Android, package com.dsmile.emulator, built on an SPG200 (unSP) core of its own. Frontends launch the exported EmuActivity either with ACTION_VIEW and a content or file Uri, or with the LAUNCH_GAME action and a - rom, ROM, path or uri string extra carrying a path; ES-DE uses the first form. + rom, ROM, path or uri string extra carrying a path. ES-DE uses the first form. ref: AndroidManifest.xml:34-51, EmuActivity.kt:123-145, docs/iisu-integration.md:42-51 The machine never boots from the system ROM. UnSP::Reset takes the program counter from 0xFFF7, and the FIQ, IRQ n and BREAK vectors are read from - 0xFFF6, 0xFFF8+n and 0xFFF5; all four sit in bank 0, which ExtRead answers + 0xFFF6, 0xFFF8+n and 0xFFF5. All four sit in bank 0, which ExtRead answers from the cartridge under every decode mode. The system ROM sits on bank 3 and - is reachable only once cartridge code selects decode mode 2 or 3; + is reachable only once cartridge code selects decode mode 2 or 3. extmem_ctrl_ resets to 0x0028, which is decode 0, so nothing but the cartridge is mapped at power on. ref: unsp.cpp:49,67,77,253, spg200.cpp:188-209, spg200.cpp:37 @@ -53,7 +53,7 @@ notes: | Region is a jumper, never a file. Port C carries the region code in its low nibble and the intro jumper in bit 4. The code is fixed at 0xF and SetRegion - has no caller, so one image serves every session; the jumper is exposed only + has no caller, so one image serves every session, and the jumper is exposed only as the Game intros setting, passed through nativeInit. ref: vsmile.cpp:365-369, vsmile.h:76, vsmile.h:77, vsmile.h:116, jni_bridge.cpp:39, MainActivity.kt:309,320 diff --git a/emulators/dsperate.yml b/emulators/dsperate.yml index e7521e6d..968bae68 100644 --- a/emulators/dsperate.yml +++ b/emulators/dsperate.yml @@ -27,17 +27,17 @@ notes: | DS BIOS: both halves or neither, the ARM9 image 4 KB and the ARM7 image 16 KB exactly. Without them the built-in FreeBIOS runs games by direct boot. The - firmware may be any non-empty file; without one a firmware is generated from + firmware may be any non-empty file. Without one a firmware is generated from the [user] settings. Booting the DS menu needs both BIOS dumps and a real - firmware. No hash is checked; an FNV-1a of the loaded regions only tags save + firmware. No hash is checked: an FNV-1a of the loaded regions only tags save states. ref: src/core/nds.cpp:101-133, src/core/mem/bus.h:121-131, src/frontend/sdl/main.cpp:1410, src/frontend/sdl/main.cpp:1440-1447 DSi: DSiWare and --dsi-mode need the DSi BIOS pair, 64 KB each, and the DS - BIOS dumps as well; FreeBIOS cannot run a DSi session. dsi_firmware replaces + BIOS dumps as well. FreeBIOS cannot run a DSi session. dsi_firmware replaces firmware for a DSi session when no --firmware is given. The NAND is needed by - --dsi-mode and by NAND title shortcuts only; it must carry the nocash footer + --dsi-mode and by NAND title shortcuts only, and it must carry the nocash footer (at the end, or at 0x000FF800). DSiWare without a NAND runs on a generated console whose system font is DSperate's own unless dsi_font names a TWLFontTable.dat. @@ -89,7 +89,7 @@ files: validation: [size] config_key: "paths.bios9i" description: "DSi ARM9 BIOS" - note: "Loaded only together with dsi_bios7.bin. Without the pair DSiWare and --dsi-mode are refused; DS games do not use it." + note: "Loaded only together with dsi_bios7.bin. Without the pair DSiWare and --dsi-mode are refused, while DS games do not use it." source_ref: "src/core/nds_dsi.cpp:95-106, src/core/mem/bus.h:121, src/frontend/sdl/main.cpp:1301-1308" - name: "dsi_bios7.bin" @@ -99,7 +99,7 @@ files: validation: [size] config_key: "paths.bios7i" description: "DSi ARM7 BIOS" - note: "Loaded only together with dsi_bios9.bin. Without the pair DSiWare and --dsi-mode are refused; DS games do not use it." + note: "Loaded only together with dsi_bios9.bin. Without the pair DSiWare and --dsi-mode are refused, while DS games do not use it." source_ref: "src/core/nds_dsi.cpp:95-106, src/core/mem/bus.h:122, src/frontend/sdl/main.cpp:1301-1308" - name: "dsi_firmware.bin" @@ -115,7 +115,7 @@ files: required: false config_key: "paths.dsi_nand" description: "DSi NAND image with nocash footer" - note: "Read only by --dsi-mode and NAND title shortcuts; DSiWare run from the game list does without it. Opened read-only, rejected without the \"DSi eMMC CID/CPU\" footer." + note: "Read only by --dsi-mode and NAND title shortcuts. DSiWare run from the game list does without it. Opened read-only, rejected without the \"DSi eMMC CID/CPU\" footer." source_ref: "src/frontend/sdl/main.cpp:1263-1272, src/core/nds_dsi.cpp:121-127, src/core/io/dsi_sd.cpp:111-140" - name: "TWLFontTable.dat" @@ -133,5 +133,5 @@ files: category: game_data config_key: "paths.cheats" description: "Action Replay cheat database" - note: "Looked up by game code and header checksum; nothing is enabled by its presence." + note: "Looked up by game code and header checksum. Nothing is enabled by its presence." source_ref: "src/frontend/sdl/main.cpp:709-735" diff --git a/emulators/duckstation.yml b/emulators/duckstation.yml index 5e957a9e..c2baa4d0 100644 --- a/emulators/duckstation.yml +++ b/emulators/duckstation.yml @@ -14,7 +14,7 @@ bios_size: 524288 # 0x80000 (512 KB), also accepts PS2 (4 MB) and PS3 (0x3E66F0 verification: md5 notes: | DuckStation auto-detects BIOS by MD5 hash from a flat scan of the BIOS directory. - ref: src/core/bios.cpp:460-482 (FindBIOSImagesInDirectory — scans all files by size) + ref: src/core/bios.cpp:460-482 (FindBIOSImagesInDirectory, scans all files by size) ref: src/core/bios.cpp:208 (MD5Digest::HashData identification) Accepts PS1 (512 KB), PS2 (4 MB), and PS3 (0x3E66F0) BIOS images. diff --git a/emulators/dxx-rebirth.yml b/emulators/dxx-rebirth.yml index ddd0ef06..48f51af1 100644 --- a/emulators/dxx-rebirth.yml +++ b/emulators/dxx-rebirth.yml @@ -41,18 +41,18 @@ notes: | one of the PIG graphics families (groupa.pig / alien1.pig / alien2.pig / fire.pig / ice.pig / water.pig for retail, d2demo.pig for shareware) plus the sampled sound bank (descent2.s11 for 11 kHz or descent2.s22 - for 22 kHz; similar/main/piggy.cpp:79). Mac shareware additionally bundles exit.ham. + for 22 kHz, similar/main/piggy.cpp:79). Mac shareware additionally bundles exit.ham. d2x.hog is the Descent 2: Vertigo expansion mission, probed in the MISSION_DIR by similar/main/inferno.cpp:542 to toggle the "Vertigo Enhanced" title. - The movie libraries are named from three stems (intro, other, robots; + The movie libraries are named from three stems (intro, other, robots, d2x-rebirth/main/movie.cpp:93-95) and a resolution letter: <stem>-h.mvl is tried first, then <stem>-l.mvl (d2x-rebirth/main/movie.cpp:660, - 672-677). A library that fails to mount is logged and skipped; the + 672-677). A library that fails to mount is logged and skipped, and the game plays without movies. Only the free PC shareware pair (desc14sw.tar.gz = descent.hog + - descent.pig; d2shar10.tar.gz = d2demo.hog/pig/ham) is redistributable; - the retail archives listed below are commercial GOG files. + descent.pig, d2shar10.tar.gz = d2demo.hog/pig/ham) is redistributable. + The retail archives listed below are commercial GOG files. files: # ------ Descent 1 shareware (free) ------ @@ -86,7 +86,7 @@ files: validation: [size] description: "Descent 1 PC retail v1.5 HOG (GOG)" variant_group: d1-hog - note: "commercial; alternative sizes 6856183 (v1.5 alt), 7261423 (v1.0), 7456179 (Mac retail)" + note: "commercial, alternative sizes 6856183 (v1.5 alt), 7261423 (v1.0), 7456179 (Mac retail)" source_ref: "common/main/mission.h:61-64" - name: descent.pig @@ -136,7 +136,7 @@ files: validation: [size] description: "Descent 2 PC full v1.1-1.2 HOG (GOG)" variant_group: d2-hog - note: "commercial; alternative sizes 7107354 (v1.0), 7110007 (Mac full), 6132957 (OEM v1.1), 4292746 (Mac shareware)" + note: "commercial, alternative sizes 7107354 (v1.0), 7110007 (Mac full), 6132957 (OEM v1.1), 4292746 (Mac shareware)" source_ref: "common/main/mission.h:73-76" - name: descent2.ham @@ -245,7 +245,7 @@ files: # ------ Add-on archives ------ # add_archives_to_search_path() mounts every *.dxa found at the root of - # the search path; the code names the extension, not the files. The names + # the search path. The code names the extension, not the files. The names # below are the add-ons the project publishes. Each build has its own data # directory (d1x-rebirth, d2x-rebirth), so an archive is seen by one game. - name: "d1xr-hires.dxa" @@ -254,7 +254,7 @@ files: category: game_data required: false description: "High resolution title, briefing and ending screens for Descent 1" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d1xr-briefings-ger.dxa" @@ -263,7 +263,7 @@ files: category: game_data required: false description: "German briefing texts for Descent 1" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d1xr-mac-demo-sounds.dxa" @@ -272,7 +272,7 @@ files: category: game_data required: false description: "Sound set of the Macintosh Descent 1 demo" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d1xr-opl3-music.dxa" @@ -281,7 +281,7 @@ files: category: game_data required: false description: "Descent 1 music as Ogg Vorbis files, OPL3 rendering" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d1xr-sc55-music.dxa" @@ -290,7 +290,7 @@ files: category: game_data required: false description: "Descent 1 music as Ogg Vorbis files, Roland SC-55 rendering" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "editor.dxa" @@ -308,7 +308,7 @@ files: category: game_data required: false description: "German briefing texts for Descent 2" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d2xr-opl3-music.dxa" @@ -317,7 +317,7 @@ files: category: game_data required: false description: "Descent 2 music as Ogg Vorbis files, OPL3 rendering" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "d2xr-sc55-music.dxa" @@ -326,7 +326,7 @@ files: category: game_data required: false description: "Descent 2 music as Ogg Vorbis files, Roland SC-55 rendering" - note: "Mounted at startup when present; its files extend or replace the game content." + note: "Mounted at startup when present, and its files extend or replace the game content." source_ref: "common/misc/physfsx.cpp:23, 377-394, similar/main/inferno.cpp:603, SConstruct:4362" - name: "editor.dxa" diff --git a/emulators/ecwolf.yml b/emulators/ecwolf.yml index 870c2b23..9590afcc 100644 --- a/emulators/ecwolf.yml +++ b/emulators/ecwolf.yml @@ -14,7 +14,7 @@ notes: | Spear of Destiny (sod/sdm), Super 3D Noah's Ark (n3d), and community pk3 mods. Blake Stone and Rise of the Triad support flagged as Preview in upstream. - Requires ecwolf.pk3 — engine data package built from wadsrc/static/. + Requires ecwolf.pk3, the engine data package built from wadsrc/static/. Contains IWADINFO (game detection rules), palettes, sprites, map configs, DECORATE actor definitions, MAPINFO, SNDINFO, fonts, and localization strings. Without this file: "Could not open ecwolf.pk3!" fatal error. diff --git a/emulators/eduke32.yml b/emulators/eduke32.yml index 74b22f5b..ad6ea73e 100644 --- a/emulators/eduke32.yml +++ b/emulators/eduke32.yml @@ -16,7 +16,7 @@ notes: | Platoon Leader. Startup scans the search path for registered GRPs by CRC32 (source/duke3d/src/grpscan.cpp:39-76 internalgrpfiles[]). Each GRP carries a game flag (DUKE / NAM / NAPALM / WW2GI) and optional addon - dependency; EDuke32 picks the user selection, mounts it with + dependency. EDuke32 picks the user selection, mounts it with initgroupfile and loads the DEF / CON / RTS the GRP points to. G_DefaultGrpFile (source/duke3d/src/common.cpp:60-73) returns the base @@ -25,12 +25,12 @@ notes: | NAPALM.CON / WW2GI.CON and DUKE.RTS / NAM.RTS / NAPALM.RTS / WW2GI.RTS. CRCs listed in source/duke3d/src/grpscan.h match the retail GRP byte - for byte; the loader only checks CRC32 (not MD5) and only to pick the + for byte, but the loader only checks CRC32 (not MD5) and only to pick the entry, never to refuse an unknown GRP. CON / RTS / addon files are referenced from the chosen entry but their contents are not validated. The scan checksums every *.grp, *.ssi, *.dat and *.zip file of the - search path and matches size and CRC32 against the table; the table + search path and matches size and CRC32 against the table, and the table holds no file name (source/duke3d/src/grpscan.cpp:360-370, 486-492). An addon whose dependency is not found is removed from the list (source/duke3d/src/grpscan.cpp:503-517). @@ -53,15 +53,15 @@ files: grpscan.h:41), World Tour (DUKEWT_CRC 0x982AFE4A, grpscan.h:37), Plutonium Pak (DUKEPP_CRC 0xF514A6AC, grpscan.h:36), South Korean censored (DUKEKR_CRC 0xAA4F6A40, grpscan.h:34). CRC32 identifies - the variant and selects the matching entry in internalgrpfiles[]; - no MD5 or SHA1 is read. + the variant and selects the matching entry in internalgrpfiles[], + and no MD5 or SHA1 is read. - name: "EDUKE.CON" category: game_data system: duke3d required: false source_ref: "source/duke3d/src/common.cpp:38 (defaultgameconfilename GAME_DUKE)" - note: "EDuke32 CON script. Shipped inside the GRP by default; external copy only when the user overrides it." + note: "EDuke32 CON script. Shipped inside the GRP by default, external copy only when the user overrides it." - name: "DUKE.RTS" category: game_data @@ -103,7 +103,7 @@ files: crc32: "c7efbfa9" validation: [size, crc32] source_ref: "source/duke3d/src/grpscan.cpp:66 (Duke: Nuclear Winter Demo, GAMEFLAG_ADDON), 366 (crc and size compare)" - note: "Addon of the Atomic Edition (dependency DUKE15_CRC); dropped from the list when that GRP is not found." + note: "Addon of the Atomic Edition (dependency DUKE15_CRC), dropped from the list when that GRP is not found." - name: "DZ2.GRP" category: game_data diff --git a/emulators/eightyone.yml b/emulators/eightyone.yml index ae9dbc34..00c1705b 100644 --- a/emulators/eightyone.yml +++ b/emulators/eightyone.yml @@ -46,7 +46,7 @@ notes: | ref: 81/Source/zx81/snap.cpp:1189-1199, 81/Source/zx81/snap.cpp:1285-1299, 81/Source/zx81/snap.cpp:1317-1328, 81/Source/zx81config.cpp:161-210, 81/Source/zx81config.cpp:259-284 Didaktik D40/D80 tests for eightyone/FDCs/didaktik.gama.rom and stores its - full path in CurRom when present; memory_load reduces the path to its + full path in CurRom when present, and memory_load reduces the path to its basename and serves the embedded copy. ref: libretro/libretro_core.cpp:2953-2968, 81/Source/Spectrum/spec48.cpp:361-362 @@ -54,7 +54,7 @@ notes: | directory when it is absent. ref: 81/Source/zxpand/smbsd.cpp:75-98 - Digitalker is a stub and its SSR ROM loader is not compiled; CapsImg is + Digitalker is a stub and its SSR ROM loader is not compiled. CapsImg is linked statically. ref: libretro/eo_stubs.cpp:67-68, CMakeLists.txt:267-291 diff --git a/emulators/eka2l1.yml b/emulators/eka2l1.yml index 15a5506b..cf571870 100644 --- a/emulators/eka2l1.yml +++ b/emulators/eka2l1.yml @@ -26,7 +26,7 @@ notes: | device to emulate is built from a firmware dump. Covers the N-Gage and N-Gage 2.0 libraries and the game libraries from S60v1 to Symbian Belle. One tree builds the Qt desktop frontend, the Android and iOS applications, and a - libretro core; the core lives on the libretro branch of the WizzardSK fork, + libretro core. The core lives on the libretro branch of the WizzardSK fork, rebased on the upstream revision named in its upstream.version, 11f5b6cd. content.cpp passes isolate_drives false to install_firmware and install_rom_with_optional_rpkg, so drives C, D and E are shared between @@ -40,7 +40,7 @@ notes: | A device is registered in <storage>/devices.yml and holds its ROM image at <storage>/roms/<firmware code, lower case>/SYM.ROM with the unpacked ROFS tree beside it under <storage>/drives/z/<firmware code>/. Selecting the - device opens that SYM.ROM; a parse failure or a missing file makes set_device + device opens that SYM.ROM, and a parse failure or a missing file makes set_device return false and nothing runs. The image is parsed for its root directory list and never checked against a size or a hash. <storage> is the data-storage option, "data" by default, relative to the working directory. @@ -58,7 +58,7 @@ notes: | the RPKG made by the Dumber tool beside it, which supplies the ROFS. A .vpl variant packing list names the .fpsx flash images of a factory firmware, from which the core image, the ROFS and the drive contents are extracted. - The names of the dump files are free; SYM.ROM is the name the installers + The names of the dump files are free. SYM.ROM is the name the installers give the resident copy. ref: src/emu/system/src/installation/rpkg.cpp:44-68, src/emu/system/src/software.cpp:396-408, @@ -71,13 +71,13 @@ notes: | src/emu/system/src/installation/firmware.cpp:480-515 Standalone, the Qt frontend installs through its device dialog, from a ROM, - a ROM with its RPKG, or a VPL; the settings dialog can also rescan drives/z/ + a ROM with its RPKG, or a VPL, and the settings dialog can also rescan drives/z/ and rebuild devices.yml from the directories that still hold a SYM.ROM. A device installed with the isolate-drives box ticked keeps drives C, D and E under <storage>/drives/<firmware code>/ instead of <storage>/drives/. On Linux and macOS the working directory is the EKA2L1 folder of the user data location and the shipped patch, resources, scripts and compat folders are - copied there at startup; on Windows it is the directory the executable is + copied there at startup. On Windows it is the directory the executable is started from. ref: src/emu/qt/src/device_install_dialog.cpp:162-172, src/emu/qt/src/device_install_dialog.cpp:181-185, @@ -118,8 +118,8 @@ notes: | directory. Patch libraries: every patch/*.map is parsed, the DLL is <map name>_<version suffix>.dll for the device's Symbian version upward, stopping at 8.1a on an EKA1 device, then <map name>_general.dll on EKA2 - only; a map naming a source picks that DLL prefix; a map requiring host-tls - is skipped below S60v3 FP1; a missing folder is skipped. A map routes exports + only. A map naming a source picks that DLL prefix, a map requiring host-tls + is skipped below S60v3 FP1, and a missing folder is skipped. A map routes exports of the original DLL to the patch DLL and is dropped when it holds no route for the device's version. A map whose requirements carry replace holds no route: its DLL is loaded in place of the image of that name, and with @@ -130,13 +130,13 @@ notes: | the eight files under resources are compiled by the OpenGL driver at start and an unreadable one leaves the program without source. The upscale filter named in an application's screen-upscale setting is read from - resources/upscale/<name>.frag; the 21 filters ship from the upscale-shaders + resources/upscale/<name>.frag, and the 21 filters ship from the upscale-shaders submodule, pinned at 49dd304c. MIDI: resources/defaultbank.sf2 feeds the TinySoundFont player and resources/defaultbank.hsb the miniBAE player, the paths being the sf2-bank-path and hsb-bank-path options. SDL2 controller mappings come from resources/gamecontrollerdb.txt. compat/panicBlackList.json names thread panics to swallow and compat/<UID>.yml carries per-application - settings; panic.json holds the panic category descriptions. Lua scripts under + settings. panic.json holds the panic category descriptions. Lua scripts under scripts/ are loaded when the build carries LuaJIT and require the eka2l1.* modules from scripts/eka2l1/; the libretro recipe builds without it. Fonts the user imports live in <storage>/fonts and are added to the font store diff --git a/emulators/emucorex.yml b/emulators/emucorex.yml index b5012bfb..84a6d3d9 100644 --- a/emulators/emucorex.yml +++ b/emulators/emucorex.yml @@ -24,7 +24,7 @@ notes: | minSdk 29. A Kotlin and Compose front end drives a PCSX2 tree vendored under app/src/main/cpp/pcsx2 and pinned to v2.8.0, reached through the ARM_ANDROID adapter that owns the JNI entry points. Frontends start the exported activity - com.sbro.emucorex.MainActivity; ES-DE passes the disc as the intent data URI. + com.sbro.emucorex.MainActivity, and ES-DE passes the disc as the intent data URI. ref: app/build.gradle.kts:66-70, app/build.gradle.kts:97, app/src/main/AndroidManifest.xml:90-104, app/src/main/cpp/ARM_ANDROID/CMakeLists.txt:78-82, @@ -40,7 +40,7 @@ notes: | app/src/main/cpp/pcsx2/pcsx2/CMakeLists.txt:706, app/src/main/cpp/pcsx2/pcsx2/CMakeLists.txt:723-734 - Storage. The data root is the app files directory; the app creates cache, + Storage. The data root is the app files directory. The app creates cache, resources, inis, sstates and memcards under it, then copies the whole resources asset tree out of the package into resources. The core is handed AppRoot, DataRoot, Resources, Settings and Cache from that root, and the launcher sets @@ -149,7 +149,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and ROMVER is accepted, whatever its - name. The 2 to 8 MB range gates the folder scan; an image named in the + name. The 2 to 8 MB range gates the folder scan, but an image named in the configuration skips that range. Read into the 4 MB ROM region, which is zero-filled first, and truncated to it. Shorter than 2465792 bytes disables the OSDSys parameter HLE. @@ -170,7 +170,7 @@ files: extension, so the picker takes .7d alongside .bin and .rom, and the name hint r27v1602f carries it past the name test. Read into the 4 MB ROM window, whose upper half is cleared first. ROMVER marks it T with a fifth - character Z, which is what makes it COH-H and region 11; its description + character Z, which is what makes it COH-H and region 11. Its description comes from the EXTINFO serial. A System 246 arcade manifest selects this name from the BIOS folder. Byte-identical to the r27v1602f.7d member of the MAME sys246 set. @@ -554,7 +554,7 @@ files: Played from the resources directory whenever an achievement notification is raised and no custom sound is configured. Sound effects and the notification sound both default on. The vendored tree carries only the README for this - directory, so the file has to be supplied; the Android sound callback + directory, so the file has to be supplied. The Android sound callback returns without playing when the path is not a file. Upstream v2.8.0 ships it at 15696 bytes. source_ref: "app/src/main/cpp/ARM_ANDROID/src/integration/pcsx2_achievements_android.cpp:81, app/src/main/cpp/ARM_ANDROID/src/integration/pcsx2_achievements_android.cpp:1245-1250, app/src/main/cpp/pcsx2/pcsx2/Pcsx2Config.cpp:1963-1966, app/src/main/java/com/sbro/emucorex/core/NativeApp.kt:461-467" @@ -649,7 +649,7 @@ exclusion_note: > Left out are the parts of the bundled resource tree that this platform compiles out. ImGuiManager::Initialize returns false before the ImGui context exists, so LoadFontData never runs and fonts/RobotoMono-Medium.ttf, fonts/fa-solid-900.ttf - and fonts/promptfont.otf are never read; InitializeFullscreenUI returns false + and fonts/promptfont.otf are never read. InitializeFullscreenUI returns false unconditionally, so FullscreenUI::Initialize never runs and nothing under fullscreenui or icons is loaded, cover-placeholder.png included. The DX11 and DX12 renderers sit in the Windows branch of the core CMakeLists, so diff --git a/emulators/emucv.yml b/emulators/emucv.yml index 48125d60..070ef664 100644 --- a/emulators/emucv.yml +++ b/emulators/emucv.yml @@ -3,7 +3,7 @@ type: libretro core_classification: pure_libretro source: "https://gitlab.com/MaaaX-EPOCH84/libretro-emucv" profiled_date: "2026-09-17" -pin_frozen: "the shipping core is this revision. HEAD removed the prototype from the tree on 2026-09-11 (a188c0f) and archived its last description files on 2026-09-12 (06a066a); the new skeleton has not yet been copied from libretro-emuscv1 (ROADMAP step 4.3). Recaling would repoint these refs at a tree that currently holds nothing but a roadmap." +pin_frozen: "the shipping core is this revision. HEAD removed the prototype from the tree on 2026-09-11 (a188c0f) and archived its last description files on 2026-09-12 (06a066a). The new skeleton has not yet been copied from libretro-emuscv1 (ROADMAP step 4.3). Recaling would repoint these refs at a tree that currently holds nothing but a roadmap." source_commit: "6a6e1b15c5d5afefbc3fefdd8b52f3f2c8c0a0eb" core_version: "0.00" display_name: "EPOCH - Cassette Vision (EmuCV)" @@ -25,7 +25,7 @@ notes: | src/core.cpp:307) with a plain fopen (src/emu.cpp:138, src/fileio.cpp:84-93). The file must be exactly 4064 bytes, the 2032 valid program addresses as 16-bit words (src/emu.h:16, src/emu.h:223, - src/emu.cpp:143-153); any other size zeroes program memory and leaves + src/emu.cpp:143-153). Any other size zeroes program memory and leaves the cartridge not inserted. Each word is read as a big-endian 12-bit instruction (src/emu.cpp:159-164). The commented MD5 check at src/emu.cpp:313-320 is not compiled. diff --git a/emulators/emuscv.yml b/emulators/emuscv.yml index 804c31e5..5c0aabbe 100644 --- a/emulators/emuscv.yml +++ b/emulators/emuscv.yml @@ -20,7 +20,7 @@ notes: | BIOS loading in src/vm/scv/memory.cpp:initialize() (lines 74-243). Tries filenames in order: upd7801g.s01, upd7801g.bin, upd7801g.bios, bios.rom, bios.bin. First successful open wins. Upstream eSCV uses - only BIOS.ROM (uppercase); the libretro port renamed and added + only BIOS.ROM (uppercase), and the libretro port renamed and added fallback aliases. The BIOS is read as 0x1000 (4096) bytes into the bios[] array, mapped diff --git a/emulators/emux_gb.yml b/emulators/emux_gb.yml index de7063d6..174eebc2 100644 --- a/emulators/emux_gb.yml +++ b/emulators/emux_gb.yml @@ -18,7 +18,7 @@ notes: | dmg_boot.bin (libretro, controllers/mapper/gb_mapper.c:35) to match RetroArch conventions. Boot ROM loaded via file_map(PATH_SYSTEM, "dmg_boot.bin", 0, 256) in - gb_mapper_init (controllers/mapper/gb_mapper.c:225-228). Returns false on failure — no HLE + gb_mapper_init (controllers/mapper/gb_mapper.c:225-228). Returns false on failure, no HLE fallback. Mapped at 0x0000-0x00FF, overlays ROM0 until BOOT_LOCK (0xFF50) is written non-zero (lock_writeb, controllers/mapper/gb_mapper.c:97-106). diff --git a/emulators/emux_sms.yml b/emulators/emux_sms.yml index 0dd78013..109d9754 100644 --- a/emulators/emux_sms.yml +++ b/emulators/emux_sms.yml @@ -18,7 +18,7 @@ notes: | adds g_ram_data/g_ram_size exposure in mach/sms.c for RETRO_MEMORY_SYSTEM_RAM). BIOS loaded via file_map(PATH_SYSTEM, "bios.sms", 0, BIOS_SIZE) in - sms_mapper_init (controllers/mapper/sms_mapper.c:162-165). Returns false on failure — no HLE + sms_mapper_init (controllers/mapper/sms_mapper.c:162-165). Returns false on failure, no HLE fallback. Mapped at 0x0000, overlays cartridge ROM until bios_disable bit set in slot control register (controllers/mapper/sms_mapper.c:79-82). @@ -32,5 +32,5 @@ files: required: true size: 8192 validation: [size] - source_ref: "controllers/mapper/sms_mapper.c:12 (BIOS_SIZE=0x2000), :61 (bios_path), :162-170 (file_map + NULL check → return false)" + source_ref: "controllers/mapper/sms_mapper.c:12 (BIOS_SIZE=0x2000), :61 (bios_path), :162-170 (file_map, then false on a NULL map)" note: "Mapped at 0x0000, overlays cartridge ROM until bios_disable bit set. file_map rejects files < 8192 bytes (main/file.c:59)." diff --git a/emulators/ep128emu_core.yml b/emulators/ep128emu_core.yml index 014f7156..73f97864 100644 --- a/emulators/ep128emu_core.yml +++ b/emulators/ep128emu_core.yml @@ -22,7 +22,7 @@ systems: notes: >- Emulates Enterprise 64/128, Videoton TVC, Amstrad CPC 464/664/6128, and ZX Spectrum 16/48/128. All ROMs are embedded in the binary since - v1.1.0; external files override built-in data. Content type is + v1.1.0, and external files override built-in data. Content type is auto-detected and determines machine configuration and ROM selection. Custom ROM mappings are possible via .ep128cfg config files placed in ep128emu/config/ or next to content. The .info declares epd19hft.rom diff --git a/emulators/epsxe.yml b/emulators/epsxe.yml index b8eee2d7..0215de3b 100644 --- a/emulators/epsxe.yml +++ b/emulators/epsxe.yml @@ -26,7 +26,7 @@ notes: | functions in .dynsym although it reports as stripped, so it is cited by function name. The Android side is package com.epsxe.ePSXe, versionCode 139 versionName 2.0.15, apk md5 e18988b825f263bbc961bfbed1c4bc0b, with 2.0.6 - (fce9c60c5cbc4e075cf97a587e64eb78) read alongside it; both verify against the + (fce9c60c5cbc4e075cf97a587e64eb78) read alongside it. Both verify against the epsxe.com signing certificate (CN=epsxeteam, serial 0x4fdaca68), every entry digest matches and none is unsigned. Two copies of 2.0.16 circulating on archive.org are repackaged, signed CN=A1 and ModYolo, and are not read here. @@ -62,7 +62,7 @@ notes: | Both consumer families carry a table of the images they recognise, and the two tables are built differently and do not hold the same set. Android ships 21 - pairs of label and md5; findBios walks the tree to a depth of ten, skipping + pairs of label and md5. findBios walks the tree to a depth of ten, skipping DCIM, Camera, asec, secure, dev, obb, .lfs and anything under /Android/data, keeps files whose lowercased name ends in .bin and whose length is exactly 524288, md5s each one and on a hit writes biosPref to that path and turns @@ -71,7 +71,7 @@ notes: | own: over the 512 KB as big endian 16-bit words, the sum shifted left 16 bits or'd with the low 16 bits of the xor. That value is looked up only to name the image in the setup wizard. The Linux and macOS builds carry neither table. - Seventeen dumps are in both tables; four are known to Android alone; two are + Seventeen dumps are in both tables, four are known to Android alone, and two are known to Windows alone and both turn out to be dumps TOSEC marks [b]. ref: ScanBiosTask.java:28, ScanBiosTask.java:145-191, ePSXeNative.java:280, ePSXe 2.0.18 Windows 0x5c1090-0x5c1384, ePSXe 2.0.18 Windows 0x5c108c, @@ -90,7 +90,7 @@ notes: | Video, sound, cdrom and input go through the PSEmu Pro plugin interface. init_gpu builds plugins/<name> from the configured name, dlopens it and resolves GPUinit, GPUopen, GPUdmaChain and the rest of the entry points one by - one; init_spu_plugins and LoadPadPlugins do the same for their own. Windows + one, and init_spu_plugins and LoadPadPlugins do the same for their own. Windows enumerates gpu*.dll, spu*.dll and cdr*.dll in plugins\. GPUCORE, SPUCORE and INPUTCORE are the built-in defaults and are not files. Android has no PSEmu Pro loader: its two OpenGL renderers ship inside the package and are only replaced @@ -220,7 +220,7 @@ files: validation: [size, md5] md5: ca5cfc321f916756e3f0effbfaeba13b description: "DTL-H1100 (v2.2 03-06-96 D)" - note: "Known to the Android table alone; no Windows record carries its checksum." + note: "Known to the Android table alone. No Windows record carries its checksum." source_ref: "ScanBiosTask.java:28, ScanBiosTask.java:162-172" - name: scph1001_v21.bin @@ -234,7 +234,7 @@ files: validation: [size, md5] md5: da27e8b6dab242d8f91a9b25d80c63b8 description: "DTL-H1101 (v2.1 07-17-95 A)" - note: "Known to the Android table alone; no Windows record carries its checksum." + note: "Known to the Android table alone. No Windows record carries its checksum." source_ref: "ScanBiosTask.java:28, ScanBiosTask.java:162-172" - name: scph1002b.bin @@ -248,7 +248,7 @@ files: validation: [size, md5] md5: 417b34706319da7cf001e76e40136c23 description: "SCPH-1002, DTL-H1102 (v2.1 07-17-95 E)" - note: "Known to the Android table alone; no Windows record carries its checksum." + note: "Known to the Android table alone. No Windows record carries its checksum." source_ref: "ScanBiosTask.java:28, ScanBiosTask.java:162-172" - name: scph5000.bin @@ -430,7 +430,7 @@ files: validation: [size] md5: eb201d2d98251a598af467d4347bb62f description: "SCPH-5000, DTL-H1200, DTL-H3000 (v2.2 12-04-95 J), bad dump" - note: "Recognised by Windows alone, as scph5000 - JP with id 0xa63468aa. That record is pinned on a checksum, not on a hash the code spells out; the md5 here is the dump that reproduces the checksum. TOSEC tags the same dump [b]." + note: "Recognised by Windows alone, as scph5000 - JP with id 0xa63468aa. That record is pinned on a checksum, not on a hash the code spells out, and the md5 here is the dump that reproduces the checksum. TOSEC tags the same dump [b]." source_ref: "ePSXe 2.0.18 Windows 0x5c118c, ePSXe 2.0.18 Windows 0x42f525-0x42f568" - name: scph5502_b.bin @@ -632,7 +632,7 @@ files: category: game_data unsourceable: "guide text the user files under the disc serial" description: "in-app guide for one title" - note: "Android only. Named after the disc serial and loaded into the help viewer as a local page; the menu entry is offered only when the file is there." + note: "Android only. Named after the disc serial and loaded into the help viewer as a local page. The menu entry is offered only when the file is there." source_ref: "ePSXe.java:1047, ePSXe.java:1857, ePSXe.java:1896" - name: skin.png diff --git a/emulators/eternal.yml b/emulators/eternal.yml index 88977d50..5ed54916 100644 --- a/emulators/eternal.yml +++ b/emulators/eternal.yml @@ -17,17 +17,17 @@ notes: | Virtual machine for the Eternal Software Initiative architecture, a Subleq variant with indirect operands, a keyboard port, a console port, a wall clock at word 64 and a timer interrupt through word 0. Adrian Cable's - reference machines are vm/vm.c (SDL3 framebuffer) and vm/vm_console.c; - the libretro core by iyzsong carries the same loop in libretro.c:186-222. + reference machines are vm/vm.c (SDL3 framebuffer) and vm/vm_console.c, + and the libretro core by iyzsong carries the same loop in libretro.c:186-222. Machine memory is a static array of 3<<27 words, 1.5 GiB, cleared again - when the content is unloaded (libretro.c:360-364); the framebuffer is its + when the content is unloaded (libretro.c:360-364). The framebuffer is its last 800x512 words (libretro.c:9-13, 22-23), pushed to the frontend as XRGB8888 on every retro_run (libretro.c:330-334). The content is the whole machine image. retro_load_game copies the buffer the frontend hands over to word 0, refuses an image larger than memory and - starts the interpreter on a thread (libretro.c:302-314); need_fullpath is + starts the interpreter on a thread (libretro.c:302-314). need_fullpath is false and the accepted extensions are capsule and bootimage (libretro.c:275-282). The upstream machines fread the same file into mem (vm/vm.c:45-48, vm/vm_console.c:32). @@ -39,15 +39,15 @@ notes: | 39, followed by the flat binary (tools/make_boot_image.py:34-68). The upstream repository ships capsules/vmlinux.bootimage.xz, ESI Linux with busybox, Doom, nano, lynx and htop in its initramfs, 110 MiB once - decompressed; the frontend does not open xz, so the image is decompressed + decompressed. The frontend does not open xz, so the image is decompressed before loading. Nothing else is read. retro_set_environment registers the log interface and - the keyboard callback and nothing more (libretro.c:238-249); the core never + the keyboard callback and nothing more (libretro.c:238-249), and the core never asks for a system, save or content directory and opens no file itself. Keyboard events are translated to USB HID usage IDs and queued eight deep - (libretro.c:36-184); console output goes to the host stdout with write - (libretro.c:205-206); a fetched C of zero halts the machine and asks the + (libretro.c:36-184). Console output goes to the host stdout with write + (libretro.c:205-206). A fetched C of zero halts the machine and asks the frontend to shut down (libretro.c:196-199). No savestate (libretro.c:336-339), no memory map, no audio. diff --git a/emulators/etlegacy.yml b/emulators/etlegacy.yml index 89e19a03..619ab3b0 100644 --- a/emulators/etlegacy.yml +++ b/emulators/etlegacy.yml @@ -18,20 +18,20 @@ notes: | Wolfenstein: Enemy Territory installation to <path>". pak1.pk3 and pak2.pk3 are checked against the server's requested pak list in FS_ComparePaks (src/qcommon/files.c:4011-4018) but neither is a - startup gate; third-party mods pull them in as needed (see README.md + startup gate. Third-party mods pull them in as needed (see README.md "In addition, third party mods might also require pak1.pk3 and pak2.pk3"). mp_bin.pk3 ships in the retail release and holds the stock multiplayer binaries. NUM_ID_PAKS = 9 (src/qcommon/qcommon.h:815) counts the names recognised - by FS_idPak; retail Enemy Territory 2.60b publishes only pak0, pak1, + by FS_idPak. Retail Enemy Territory 2.60b publishes only pak0, pak1, pak2 and mp_bin, so the extra slots are reserved for forward compatible server lists, never filled by id. The ET Legacy project ships its own replacement etmain/ assets (configs, presets, locale files) directly in the source tree, plus a Legacy mod pk3 downloaded on first run. The user still has to supply the retail - pak0.pk3 from the free Enemy Territory 2.60b download; pak0.pk3 holds + pak0.pk3 from the free Enemy Territory 2.60b download. pak0.pk3 holds every id map, model, texture and sound. files: @@ -65,4 +65,4 @@ files: path: "etmain/mp_bin.pk3" required: false source_ref: "src/qcommon/files.c:4011-4018 (FS_idPak)" - note: "Retail multiplayer QVM binaries. ET Legacy ships its own cgame/ui binaries; retail pack is for pure clients joining stock servers." + note: "Retail multiplayer QVM binaries. ET Legacy ships its own cgame/ui binaries, and the retail pack is for pure clients joining stock servers." diff --git a/emulators/exel-hence.yml b/emulators/exel-hence.yml index 85b3e385..36a479ea 100644 --- a/emulators/exel-hence.yml +++ b/emulators/exel-hence.yml @@ -30,5 +30,5 @@ notes: | line to auto-start the program (ref: src/libretro.c:614-686). It belongs to the content. -exclusion_note: "BIOS, BASIC cartridges and ExelDisk DOS compiled into the core; the system directory is never read" +exclusion_note: "BIOS, BASIC cartridges and ExelDisk DOS compiled into the core, the system directory is never read" files: [] diff --git a/emulators/fallout1-ce.yml b/emulators/fallout1-ce.yml index 8199f920..ab7ad6c8 100644 --- a/emulators/fallout1-ce.yml +++ b/emulators/fallout1-ce.yml @@ -22,11 +22,11 @@ notes: | master_patches / critter_patches default to "master.dat", "critter.dat", "data" and "data" when the file is missing (gconfig.cc:58-61). On startup, game_init_databases() in src/game/game.cc:1223 opens both - DAT files with db_init(); either missing raises GNWSystemError + DAT files with db_init(). Either missing raises GNWSystemError "Could not find the master/critter datafile" (lines 1249, 1266) and the game exits. - The data/ directory is a user-writable patch overlay; it is empty on a + The data/ directory is a user-writable patch overlay. It is empty on a clean retail install, so retrobios does not ship an empty tree. Music (ACM files under data/sound/music/) and movies (sound/MOVIES/) are loaded on demand and the engine runs without them, so they are marked diff --git a/emulators/fallout2-ce.yml b/emulators/fallout2-ce.yml index d950e54e..ea3b9cfd 100644 --- a/emulators/fallout2-ce.yml +++ b/emulators/fallout2-ce.yml @@ -33,7 +33,7 @@ notes: | present (src/game.cc:1380-1382). Not required for the base game. Music (ACM), movies (MVE) and sound effects live in sound/, movies/, - and data/ overlays; the engine runs without them, so they are not + and data/ overlays. The engine runs without them, so they are not tracked here. exclusion_note: "data/, sound/ and movies/ load from the retail install folder, not from a shared BIOS tree" diff --git a/emulators/fba2x.yml b/emulators/fba2x.yml index 6e51b546..4f9f3e2c 100644 --- a/emulators/fba2x.yml +++ b/emulators/fba2x.yml @@ -50,7 +50,7 @@ notes: | the same base) because it does not share binaries or load behaviour. files: - # ─── Neo Geo system BIOS (archive: neogeo.zip) ─── + # Neo Geo system BIOS (archive: neogeo.zip) - name: "neogeo.zip" category: bios_zip system: snk-neogeo-mvs @@ -116,7 +116,7 @@ files: size: 524288 crc32: "148dd727" - # ─── PGM board BIOS (archive: pgm.zip) ─── + # PGM board BIOS (archive: pgm.zip) - name: "pgm.zip" category: bios_zip system: igs-pgm diff --git a/emulators/fbalpha2012_cps1.yml b/emulators/fbalpha2012_cps1.yml index c8319178..5f226557 100644 --- a/emulators/fbalpha2012_cps1.yml +++ b/emulators/fbalpha2012_cps1.yml @@ -22,13 +22,13 @@ notes: | their ROM set (cd-q1.1k through cd-q4.4k), not as a separate DSP BIOS. Board PLDs (buf1, ioa1, prg1, rom1, sou1) are listed in ROM definitions as - BRF_OPT (optional). These are GAL/PAL dumps for hardware preservation — + BRF_OPT (optional). These are GAL/PAL dumps for hardware preservation, never loaded by the emulator. ROM path: ROMs are loaded from the content directory (g_rom_dir). system_directory (libretro.cpp:2202) is used only for hiscore.dat. - The .info note "BIOS files must be inside the ROM directory" is misleading — + The .info note "BIOS files must be inside the ROM directory" is misleading: there are no BIOS files for CPS-1. This note is generic across all FBA cores. 244 ROM sets defined (488 STD_ROM_PICK/FN entries = 244 games). diff --git a/emulators/fbalpha2012_neogeo.yml b/emulators/fbalpha2012_neogeo.yml index 0a9bd750..1a8ab1ef 100644 --- a/emulators/fbalpha2012_neogeo.yml +++ b/emulators/fbalpha2012_neogeo.yml @@ -57,4 +57,4 @@ notes: | files: [] -exclusion_note: "Neo Geo BIOS is a parent ROM set (neogeo.zip) placed in the ROM directory alongside game ZIPs. Not a system directory file — follows arcade ROM set convention." +exclusion_note: "Neo Geo BIOS is a parent ROM set (neogeo.zip) placed in the ROM directory alongside game ZIPs. Not a system directory file, it follows the arcade ROM set convention." diff --git a/emulators/fbalpha2019.yml b/emulators/fbalpha2019.yml index 1621af2d..a902cad3 100644 --- a/emulators/fbalpha2019.yml +++ b/emulators/fbalpha2019.yml @@ -29,7 +29,7 @@ systems: notes: | Final Burn Alpha v0.2.97.44 as left in libretro/fbalpha, the repository the libretro project froze when development moved to FinalBurn Neo. The makefile - builds fbalpha_libretro.so; ROCKNIX installs it as fbalpha2019_libretro.so. + builds fbalpha_libretro.so, and ROCKNIX installs it as fbalpha2019_libretro.so. ref: src/burner/libretro/libretro.cpp:19 Each archive the driver names is looked for in three places, the first that @@ -76,7 +76,7 @@ files: system: snk-neogeo-mvs description: "Neo Geo system BIOS ROM set" required: true - note: "sm1.sm1, sfix.sfix and 000-lo.lo are required. sp-s3.sp1 is required unless one of the other 68K BIOS images is present; all other members are BRF_OPT." + note: "sm1.sm1, sfix.sfix and 000-lo.lo are required. sp-s3.sp1 is required unless one of the other 68K BIOS images is present. All other members are BRF_OPT." source_ref: "src/burn/drv/neogeo/d_neogeo.cpp:930-981, src/burn/drv/neogeo/d_neogeo.cpp:1207-1216, src/burner/libretro/libretro.cpp:733-748" contents: - name: "sp-s3.sp1" @@ -286,7 +286,7 @@ files: system: coleco-colecovision description: "ColecoVision system BIOS ROM set" required: true - note: "coleco.rom is required; colecoa.rom, svi603.rom and czz50.rom are BRF_OPT. Archive name from CVGetZipName, which drops the cv_ prefix of cv_coleco." + note: "coleco.rom is required, while colecoa.rom, svi603.rom and czz50.rom are BRF_OPT. Archive name from CVGetZipName, which drops the cv_ prefix of cv_coleco." source_ref: "src/burn/drv/coleco/d_coleco.cpp:638-670, src/burn/drv/coleco/d_coleco.cpp:675-680" contents: - name: "coleco.rom" @@ -307,7 +307,7 @@ files: system: msx description: "MSX1 system BIOS ROM set" required: true - note: "msx.rom is required; msxj.rom and kanji.rom are BRF_OPT. Archive name from MSXGetZipName, which drops the msx_ prefix of msx_msx." + note: "msx.rom is required, while msxj.rom and kanji.rom are BRF_OPT. Archive name from MSXGetZipName, which drops the msx_ prefix of msx_msx." source_ref: "src/burn/drv/msx/d_msx.cpp:1680-1712, src/burn/drv/msx/d_msx.cpp:1716-1720" contents: - name: "msx.rom" @@ -363,7 +363,7 @@ files: system: deco-cassette description: "DECO Cassette System BIOS ROM set" required: true - note: "The program ROMs and cassmcu.1c are required; the six PROMs (v2.3m, v4.10d, v3.3j, dsp-3_p3-.e5, rms-3_p4-.f6, dsp-3_p5-.m4) are BRF_OPT." + note: "The program ROMs and cassmcu.1c are required, while the six PROMs (v2.3m, v4.10d, v3.3j, dsp-3_p3-.e5, rms-3_p4-.f6, dsp-3_p5-.m4) are BRF_OPT." source_ref: "src/burn/drv/dataeast/d_decocass.cpp:3392-3446, src/burn/drv/dataeast/d_decocass.cpp:3456-3465" contents: - name: "v0a-.7e" @@ -425,7 +425,7 @@ files: system: taito-cchip description: "Taito C-Chip uPD78C11 internal ROM" required: true - note: "Named as board ROM set by Operation Wolf, Rainbow Islands, Volfied and others; there is no BurnDriver called cchip, the name comes from szBoardROM." + note: "Named as board ROM set by Operation Wolf, Rainbow Islands, Volfied and others. There is no BurnDriver called cchip, the name comes from szBoardROM." source_ref: "src/burn/drv/taito/d_taitomisc.cpp:1369-1373, src/burn/drv/taito/d_taitomisc.cpp:6250" contents: - name: "cchip_upd78c11.bin" diff --git a/emulators/fbneo_cps12.yml b/emulators/fbneo_cps12.yml index 208598e8..ca207bc5 100644 --- a/emulators/fbneo_cps12.yml +++ b/emulators/fbneo_cps12.yml @@ -23,7 +23,7 @@ notes: | Zero BRF_BIOS entries in d_cps1.cpp and d_cps2.cpp. QSound emulated in software (qs_c.cpp:QscInit, panning table). No DSP ROM needed. - Board PLDs (buf1, ioa1, prg1/prg2, rom1, sou1) are BRF_OPT — GAL/PAL + Board PLDs (buf1, ioa1, prg1/prg2, rom1, sou1) are BRF_OPT: GAL/PAL dumps for hardware preservation, never loaded by the emulator. hiscore.dat enables persistent high scores across all arcade games. diff --git a/emulators/fbneo_neogeo.yml b/emulators/fbneo_neogeo.yml index bece09e2..e883e36c 100644 --- a/emulators/fbneo_neogeo.yml +++ b/emulators/fbneo_neogeo.yml @@ -47,7 +47,7 @@ archive_prefix: fbneo files: # ------------------------------------------------------- - # Neo Geo MVS/AES (neogeo.zip) — 68K BIOS ROMs + # Neo Geo MVS/AES (neogeo.zip), 68K BIOS ROMs # ------------------------------------------------------- - name: "sp-s3.sp1" archive: neogeo.zip diff --git a/emulators/flycast-dojo.yml b/emulators/flycast-dojo.yml index f3ef4fb9..877abab2 100644 --- a/emulators/flycast-dojo.yml +++ b/emulators/flycast-dojo.yml @@ -46,7 +46,7 @@ notes: | Arcade BIOS archives are opened as <name>.zip, then <name>.7z (core/hw/naomi/naomi_cart.cpp:69-71). Each ROM inside is looked up by CRC - then by filename; the crc field of every BIOS blob is left at zero, so the + then by filename. The crc field of every BIOS blob is left at zero, so the filename decides. No hash is checked on an archive. NAOMI 2 is a platform of its own here: naomi_cart_GetPlatform returns diff --git a/emulators/flycast.yml b/emulators/flycast.yml index b139f262..097e4672 100644 --- a/emulators/flycast.yml +++ b/emulators/flycast.yml @@ -26,7 +26,7 @@ notes: | The libretro port (libretro/flycast, last updated 2025-12-12) is significantly behind upstream (flyinghead/flycast). Key divergences: - - NAOMI 2 has no separate BIOS entry or platform detection; NAOMI 2 games + - NAOMI 2 has no separate BIOS entry or platform detection: NAOMI 2 games run as NAOMI using naomi.zip. Upstream has naomi2.zip with dedicated ROMs. - System SP is not supported. Upstream has segasp.zip support. - The n2_ prefix for NAOMI 2 flat boot ROMs is dead code (DC_PLATFORM_NAOMI2 diff --git a/emulators/flycast2021.yml b/emulators/flycast2021.yml index 063af00f..429328c7 100644 --- a/emulators/flycast2021.yml +++ b/emulators/flycast2021.yml @@ -40,10 +40,10 @@ notes: | NAOMI and Atomiswave: a BIOS archive is opened as <system>/dc/<name> with .7z then .zip appended. Each member is looked for in the game archive, its parent, - then the BIOS archive, by CRC32 and then by name; the BIOS table carries no + then the BIOS archive, by CRC32 and then by name. The BIOS table carries no CRC32, so only the name matches. The member for the configured region is tried first, then the first member listed. A game whose table entry names a - BIOS refuses to start without it; the others default to naomi. Five archive + BIOS refuses to start without it, and the others default to naomi. Five archive names are reachable from the game table: naomi, awbios, f355bios, f355dlx, hod2bios. airlbios and naomigd have table entries but no game names them. ref: core/hw/naomi/naomi_cart.cpp:76-176, core/hw/naomi/naomi_cart.cpp:227-247, @@ -66,7 +66,7 @@ files: min_size: 2097152 validation: [size] description: "Dreamcast boot ROM" - note: "Read as 2 MB into the system ROM; a shorter file is rejected. Needed only to boot to the BIOS menu or when the HLE BIOS option is disabled." + note: "Read as 2 MB into the system ROM, and a shorter file is rejected. Needed only to boot to the BIOS menu or when the HLE BIOS option is disabled." source_ref: "core/hw/holly/sb_mem.cpp:50-65, core/hw/holly/sb_mem.cpp:215-229, core/hw/flashrom/flashrom.h:54-67, core/nullDC.cpp:420-431" - name: "dc_nvmem.bin" @@ -77,7 +77,7 @@ files: min_size: 131072 validation: [size] description: "Dreamcast flash ROM" - note: "Loaded with the boot ROM and by the HLE path; a missing file leaves the flash blank and the core runs. Written back as dc_nvmem.bin." + note: "Loaded with the boot ROM and by the HLE path. A missing file leaves the flash blank and the core runs. Written back as dc_nvmem.bin." source_ref: "core/hw/holly/sb_mem.cpp:196-213, core/hw/holly/sb_mem.cpp:231, core/hw/holly/sb_mem.cpp:236-243, core/hw/holly/sb_mem.cpp:271-278" - name: "font.bin" diff --git a/emulators/fmsx.yml b/emulators/fmsx.yml index 477031b6..d3439f5a 100644 --- a/emulators/fmsx.yml +++ b/emulators/fmsx.yml @@ -239,9 +239,9 @@ files: - name: CARTS.CRC required: false bundled: false - unsourceable: "no fMSX release examined ships one; the mapper database the author distributes is CARTS.SHA" + unsourceable: "no fMSX release examined ships one, and the mapper database the author distributes is CARTS.SHA" source_ref: "fMSX/MSX.c:2697-2713" - note: "Mapper database opened in the system directory before CARTS.SHA. Each line holds the sum of the ROM bytes as eight hexadecimal digits and a mapper number (%08X %d); a matching line sets the mapper and CARTS.SHA is not read." + note: "Mapper database opened in the system directory before CARTS.SHA. Each line holds the sum of the ROM bytes as eight hexadecimal digits and a mapper number (%08X %d). A matching line sets the mapper and CARTS.SHA is not read." - name: CARTS.SHA required: false diff --git a/emulators/fpse-ng.yml b/emulators/fpse-ng.yml index 92215e6e..420de9b8 100644 --- a/emulators/fpse-ng.yml +++ b/emulators/fpse-ng.yml @@ -27,12 +27,12 @@ notes: | signature block travels inside the copy read here: the repackager kept the original apk as assets/SignatureKiller/origin.apk, whose MANIFEST.MF carries the sha256 of all 1278 entries of the distributed build. 1274 match byte for - byte, among them every native library and every resource; AndroidManifest.xml, + byte, among them every native library and every resource. AndroidManifest.xml, classes.dex and resources.arsc differ, stamp-cert-sha256 is dropped and one class, bin/mt/signature/KillerApplication, is added. Native code and resources are therefore the distributed ones and the java below is the application's own, minus that injection. A second copy, apkvision 1.8, is signed with the Android - test key and ships three of the eight libraries its own core links against; it + test key and ships three of the eight libraries its own core links against. It is read only to confirm that the preference key, the two size tests and the checksum constant below are the application's and not the repackager's. ref: com.emulator.fpse64 1.13 assets/SignatureKiller/origin.apk @@ -40,7 +40,7 @@ notes: | Two roots hold everything. The private files directory of the package is the one the core is given, and bios, plugin, cfg and skin are created under it - right after the libraries load; the emulator resolves its own paths against it. + right after the libraries load, and the emulator resolves its own paths against it. The second is a directory named FPse64 at the root of shared storage, holding memcards, cheats, shaders, ogl, sbi, sstates, titles, icons, videos and filelist.txt. Paths below are relative to the first root unless they name the @@ -56,9 +56,9 @@ notes: | exists or is not exactly 524288 bytes clears the preference and the session runs on HLE. Slot 6 receives the empty string whenever the path is empty, the BIOS switch is off or the launching intent carried bios=0, which is the - documented way to ask for HLE; the shortcuts the application pins carry that + documented way to ask for HLE, and the shortcuts the application pins carry that same extra. On the core side the value is opened as given, then retried below - bios/ under the root, so a bare name resolves there; a hit is read as one block + bios/ under the root, so a bare name resolves there. A hit is read as one block of 0x80000 bytes after "Loading '%s'...", and a miss reports "Can't load biosfile '%s', switching to HLE", sets the HLE bit and writes "CEX-3000/1001/1002 by K.S.", "System ROM Version 2.2 12/04/95 A" and the Sony @@ -85,7 +85,7 @@ notes: | Emulation is split across libraries the core links against. libfpse.so lists libopengl, libsoft1, libspuplugin, libneon, libsdl and libnfsplugin in DT_NEEDED, and Main names uncompress, spuplugin, soft1, nfsplugin and opengl - before fpse; sdl and neon are named earlier from a static block that swallows + before fpse. sdl and neon are named earlier from a static block that swallows UnsatisfiedLinkError, the rest are not guarded. All eight ship in the package for arm64-v8a and no other ABI. Eighteen constants naming nine plugins296 archives on fpse.net and fpsece.net survive in the class and nothing reads @@ -117,7 +117,7 @@ notes: | notes from fpse.net/games64/, overlay pad skins from fpse.net/s/ as padtemp.zip extracted into skin/, and vrback.zip extracted at the root of shared storage. Files named after a game identifier and ending in .sbi are - downloaded into FPse64/sbi for the titles of one internal list; no library and + downloaded into FPse64/sbi for the titles of one internal list. No library and no java path reads them back, and the string ".sbi" appears in none of the eight libraries. ref: Main.java:10505-10507, Main.java:16605, Main.java:16644, @@ -214,7 +214,7 @@ files: # out of assets once storage access is granted, and a pair dropped in by # hand joins the list. Cartoon_A, Cartoon_B, FXAA, FXAA_natural_vision and # TV_HDR share one vertex shader, as do CRT-Hyllian, Grayscale and - # MangaToon; each pair is read by its own name. + # MangaToon. Each pair is read by its own name. - name: "4xhqglsl.vsh" path: "FPse64/shaders/4xhqglsl.vsh" required: false diff --git a/emulators/fpse.yml b/emulators/fpse.yml index 68c8223a..34b9b8ee 100644 --- a/emulators/fpse.yml +++ b/emulators/fpse.yml @@ -73,7 +73,7 @@ notes: | them. They are distributed both ways. 0.11.190 shipped none of them, tested for each file in the private directory, stopped on an error dialog before loading the core when one was absent, and fetched plugins267.zip and its per GPU and per - ABI variants from fpse.net; 12.1 carries them in the package and keeps an + ABI variants from fpse.net. 12.1 carries them in the package and keeps an updater that asks getfile.php for the list matching its own versionCode and ABI, alongside plugins605 constants nothing reads. Both generations of the pack still answer: plugins605v7.zip is 1359776 bytes and holds the armeabi-v7a build of @@ -213,7 +213,7 @@ exclusion_note: > so a replacement stays. It is not a dump of the font ROM inside the Japanese BIOS, and it shares its generic name with the unrelated kanji ROMs of the MSX and the PC-88. Only - the ARM builds name it; the x86 build of 0.11.190 carries neither it nor the + the ARM builds name it: the x86 build of 0.11.190 carries neither it nor the v2.2 identification strings. The disc images and their .cue sidecars are not emulator files. The HLE BIOS is not a file either: it is code, and the strings it answers a BIOS identification with sit in .rodata beside the rest of the core diff --git a/emulators/freej2me_plus.yml b/emulators/freej2me_plus.yml index 5bd4a580..593b80e3 100644 --- a/emulators/freej2me_plus.yml +++ b/emulators/freej2me_plus.yml @@ -20,7 +20,7 @@ notes: | directory, checks that freej2me_plus-lr.jar exists there and spawns java -jar with the file encoding and the screen size as arguments, then drives the Java process over pipes. Windows launches javaw through - CreateProcess with the system directory as starting directory; Linux and + CreateProcess with the system directory as starting directory, while Linux and macOS fork, chdir() into it and execvp() java. A Java runtime must be on the host PATH, and the start failure message asks for Java 6 or newer. The jar is built by ant from build.xml, which writes the libretro variant as @@ -35,7 +35,7 @@ notes: | Only existence is tested. When the jar is absent the core posts the SYSTEM_NOT_FOUND message and returns from retro_init before any process is created, so nothing loads. The message text still names freej2me-lr.jar, - the file the original core opens; this core opens freej2me_plus-lr.jar. + the file the original core opens. This core opens freej2me_plus-lr.jar. ref: src/libretro/freej2me_libretro.c:339-346, src/libretro/freej2me_libretro.c:866-872, src/libretro/freej2me_libretro.h:73-79 @@ -59,10 +59,10 @@ notes: | Two files are user supplied and optional. With the freej2me_midifont core option on, Manager.checkCustomMidi loads the first .sf2 or .gm listed in - freej2me_system/customMIDI/ as the MIDI soundbank; off, or with the + freej2me_system/customMIDI/ as the MIDI soundbank. Off, or with the directory empty, the JVM default soundbank is used. With freej2me_textfont on, PlatformFont loads the first .ttf, .otf or .ttc in - freej2me_system/customFont/; off, the AWT SansSerif, Monospaced and Dialog + freej2me_system/customFont/. Off, the AWT SansSerif, Monospaced and Dialog faces are used. Both directories are created with a placeholder file when missing, and neither file has a fixed name. ref: src/libretro/freej2me_libretro.c:464-469, @@ -82,7 +82,7 @@ files: required: true validation: [existence] description: "FreeJ2ME-Plus libretro Java application" - note: "Java program the native core launches with java -jar from the system directory root. Built by ant from build.xml at the pinned revision; the code reads no size and no hash." + note: "Java program the native core launches with java -jar from the system directory root. Built by ant from build.xml at the pinned revision. The code reads no size and no hash." source_ref: "src/libretro/freej2me_libretro.c:38-45 (freej2meapp), src/libretro/freej2me_libretro.c:859-875 (GET_SYSTEM_DIRECTORY, freej2me_present, SYSTEM_NOT_FOUND_MSG), src/libretro/freej2me_libretro.c:339-346 (access F_OK), src/libretro/freej2me_libretro.c:877-888 (java -jar argv), build.xml:86-99 (destfile)" - name: "<soundfont>.sf2" diff --git a/emulators/frotz.yml b/emulators/frotz.yml index 62623cad..fc5db1ab 100644 --- a/emulators/frotz.yml +++ b/emulators/frotz.yml @@ -29,5 +29,5 @@ notes: | resource files under the [Resources] Dir setting, "./" by default (ref: src/sdl/sf_resource.c:75, 415). Both belong to the game. -exclusion_note: "fonts compiled into the binary; external TrueType fonts only when the user config names them" +exclusion_note: "fonts compiled into the binary, external TrueType fonts only when the user config names them" files: [] diff --git a/emulators/fury.yml b/emulators/fury.yml index 0b8239b9..50ef0a29 100644 --- a/emulators/fury.yml +++ b/emulators/fury.yml @@ -30,7 +30,7 @@ notes: | No hash or filename is validated by the engine: Ion Fury ships one GRP (fury.grp) that holds every map, art bank, sound and DEF the game needs, plus a small number of top-level files the retail installers lay down - alongside it. Only the GRP is listed below; the other files + alongside it. Only the GRP is listed below. The other files (fury.cfg, settings.cfg, saves, screenshots) are user state. files: diff --git a/emulators/future-pinball-fploader.yml b/emulators/future-pinball-fploader.yml index 8681eccb..f05bffe6 100644 --- a/emulators/future-pinball-fploader.yml +++ b/emulators/future-pinball-fploader.yml @@ -20,7 +20,7 @@ notes: | with VirtualAllocEx and WriteProcessMemory, runs LoadLibraryA on it through CreateRemoteThread, waits for that thread and resumes the main one. Everything else lives in BAM.dll, which detours the running program. The loader is - published as source; the shipped FPLoader.exe carries the same .text and + published as source, and the shipped FPLoader.exe carries the same .text and .rdata as the build committed to that repository and differs only by an Authenticode blob, 9472 bytes against 5384. ref: BAM_FPloader FPLoader.cpp:259-305, FPLoader.exe .text sha1 @@ -30,11 +30,11 @@ notes: | C:\Games\Future Pinball\BAM\. Both missing puts up "Couldn't locate BAM.dll." and returns -1. Future Pinball.exe comes from /FPEXE if that switch names an existing file, otherwise from one level above the loader, then from the - loader's directory, then from C:\Games\Future Pinball\; the same failure path + loader's directory, then from C:\Games\Future Pinball\. The same failure path reports "Couldn't locate Future Pinball.exe.". Before the process is created the loader prepends its own directory to %PATH% so the system resolves renderingengine.dll from there while the working directory is the game - directory. /STAYINRAM keeps the loader alive until the game thread ends; the + directory. /STAYINRAM keeps the loader alive until the game thread ends. The rest of the command line is handed to Future Pinball untouched, which is how /Open, /Play, /Exit and /ArcadeRender reach it. ref: BAM_FPloader FPLoader.cpp:40-48, 87-111, 166-240, 249-257 @@ -51,7 +51,7 @@ notes: | glTexImage2D and wglChoosePixelFormatARB taken separately. That is how BAM sees the program's own resource and file traffic and can answer it. Newton is reached through GetModuleHandleA on the copy Future Pinball already imported - followed by GetProcAddress on 83 entry points; no second copy is loaded. + followed by GetProcAddress on 83 entry points. No second copy is loaded. ref: BAM.dll 1.5-408 .text:0x10082a75-0x10082f3d, 0x100831b3-0x100831d9, 0x1002ab92-0x1002abeb, .rsrc version, debug tags Routed_glTexImage2D and Routed_wglChoosePixelFormatARB @@ -78,7 +78,7 @@ notes: | Future Pinball itself uses: the program carries 29 resources of type BMP and every id the shipped packs contain is one of them, 452 being the ball. balls\*.zip is walked with FindFirstFileA and each hit becomes a choice in the - menu; default.zip in the BAM directory is applied without being chosen. The + menu, while default.zip in the BAM directory is applied without being chosen. The routed FindResourceA answers the nine SHADERS resources the same way, while the single XML resource, id 464, is read straight from the program by the save path and is what the presets under XML\ are edited copies of. The 83 GLSL @@ -711,7 +711,7 @@ files: size: 45056 description: "Score database the plugin opens by name" source_ref: "PinballHighScore.dll .rdata" - note: "Only BAM-OpenVR.zip carries a copy; the plugin creates one otherwise." + note: "Only BAM-OpenVR.zip carries a copy. The plugin creates one otherwise." - name: PuPPlugin.dll system: fpinball @@ -848,7 +848,7 @@ analysis: source_ref: "BAM.dll 1.5-408 .text:0x1007a45b, 0x1007ae0a, 0x100d4318-0x100d4391" note: >- The crash log is written from the fault handler installed at load - time; the other two only when the matching switch is on the command + time, the other two only when the matching switch is on the command line. shipped_but_not_loaded: @@ -858,7 +858,7 @@ analysis: source_ref: "BAM.dll, renderingengine.dll and every plugin import directory" note: >- No shipped binary imports it and neither BAM.dll nor - renderingengine.dll names it in any string; both carry their own zlib. + renderingengine.dll names it in any string. Both carry their own zlib. - what: "License.txt, 3741 bytes" source_ref: "bam-setup.exe payload" note: "The zlib licence the loader source carries, copied into the install." diff --git a/emulators/future-pinball.yml b/emulators/future-pinball.yml index 9eb9d000..8820c28d 100644 --- a/emulators/future-pinball.yml +++ b/emulators/future-pinball.yml @@ -17,7 +17,7 @@ notes: | Closed-source Windows pinball simulator and table editor written by Chris Leathley for BSP Software Design Solutions. Development stopped with v1.9.1.20101231, still served from futurepinball.com. Rendering is OpenGL - (88 imports from opengl32 and 4 from glu32); ddraw is loaded by name only to + (88 imports from opengl32 and 4 from glu32). ddraw is loaded by name only to call DirectDrawCreateEx while enumerating display modes. Physics come from Newton Game Dynamics, audio from FMOD 3, image decoding from DevIL and the script editor from Scintilla. The binary registers its own type library at @@ -48,7 +48,7 @@ notes: | are .fpl files, also OLE compound documents, holding models, textures, sounds, DMD fonts and scripts under one storage per item. The Texture, Sound, Model and DMD Font managers each offer Import, which copies the item into the table, - and Link, which records the library name and the item name instead; the manual + and Link, which records the library name and the item name instead. The manual recommends always linking to the shipped model library. A linked library is opened by StgOpenStorage on the name as written, which resolves against the table's own folder, and on failure against the install directory plus @@ -70,7 +70,7 @@ notes: | 0x00478d20, Future Pinball Manual.chm GlobalScript.html Settings live in the registry under HKCU\Software\Future Pinball, split into - GamePlayer, GamePlayer\Joypads and Editor keys; there is no ini file. + GamePlayer, GamePlayer\Joypads and Editor keys. There is no ini file. RetroBat writes resolution, aspect ratio, camera, render preset and the whole joypad map there before launching. Per table state is written to fpRAM\<table>.fpRAM beside the program. Nothing in the program verifies a size @@ -82,7 +82,7 @@ notes: | Front ends drive it with the documented switches /Open "<table>", /Play, /Exit and /ArcadeRender. ES-DE declares it for Windows only, as FUTURE-PINBALL finding "Future Pinball.exe" and as FUTURE-PINBALL-FPLOADER finding - "BAM\FPLoader.exe", both invoked with /Exit /Play /Open; the fpinball system + "BAM\FPLoader.exe", both invoked with /Exit /Play /Open. The fpinball system is a placeholder on its six other platforms. RetroBat maps the emulator keys fpinball and bam to one generator, one install folder and the same "Future Pinball.exe" presence check, swapping only the launched binary, and @@ -361,8 +361,8 @@ files: source_ref: "Future Pinball.exe 1.9.1.20101231 .text:0x0045f1b8-0x0045f1f8" note: >- The directory is read from HKCU\Software\NaturalPoint\NATURALPOINT\NPClient - Location, this name appended and the result given to LoadLibraryA; - NP_GetSignature and the rest are then bound with GetProcAddress. A null + Location, this name appended and the result given to LoadLibraryA, + then NP_GetSignature and the rest are bound with GetProcAddress. A null handle jumps past all tracking setup. It comes from a TrackIR install, not from any Future Pinball distribution, which is why no path is given here. diff --git a/emulators/gambatte.yml b/emulators/gambatte.yml index cbfdd09a..cd9c5d96 100644 --- a/emulators/gambatte.yml +++ b/emulators/gambatte.yml @@ -12,8 +12,8 @@ cores: systems: [nintendo-gb, nintendo-gbc] notes: | - Accuracy-focused GB/GBC emulator. No BIOS required for normal operation; - built-in HLE boot sequence skips the Nintendo logo animation. + Accuracy-focused GB/GBC emulator. No BIOS required for normal operation: + the built-in HLE boot sequence skips the Nintendo logo animation. Core option gambatte_gb_bootloader (default: enabled) enables loading official boot ROMs from the system directory for the real startup animation. @@ -27,7 +27,7 @@ notes: | detection (ld b,0x01), enabling GBA-enhanced features in compatible GBC games. - The upstream standalone supports SGB boot ROM loading; the libretro + The upstream standalone supports SGB boot ROM loading, but the libretro port does not implement this. Custom palette files (palettes/*.pal) are user-created colorization diff --git a/emulators/gargoyle.yml b/emulators/gargoyle.yml index 1e29a67e..45ca0e83 100644 --- a/emulators/gargoyle.yml +++ b/emulators/gargoyle.yml @@ -34,7 +34,7 @@ notes: | ref: garglk/launcher.cpp:114-189 (probe, extensions, interpreters), 379-419 (rungame) Formats and the interpreter each one runs: Adrift 4 and Adrift 5 both - default to scarier, which handles the two; scare takes Adrift 4 and + default to scarier, which handles the two. Scare takes Adrift 4 and FrankenDrift takes Adrift 5 only where the build asked for them, since each covers a single format. Then AdvSys (advsys), AGT (agility), Alan 2 (alan2), Alan 3 (alan3), Glulx (git), Hugo (hugo), JACL (jacl), Level 9 (level9), Magnetic @@ -51,7 +51,7 @@ notes: | Every glyph is drawn through FreeType rather than by the operating system, so a font file has to be reachable. The default config asks for the families - "Gargoyle Mono" and "Gargoyle Serif"; if fontconfig cannot resolve them, the + "Gargoyle Mono" and "Gargoyle Serif". If fontconfig cannot resolve them, the interpreter loads the shipped TTF files by name from the data directory, then the executable directory, then the working directory, and calls winabort() when all three miss. @@ -69,7 +69,7 @@ notes: | <binary>/../share/gargoyle for the AppImage, the install directory on Windows, and the bundle Resources directory on macOS. Fonts sit at its root and themes in its themes subdirectory. macOS keeps the eight Gargoyle faces - in Resources/Fonts and Unifont in Resources; the Windows installer also + in Resources/Fonts and Unifont in Resources, and the Windows installer also registers the eight faces as system fonts. ref: garglk/sysqt.cpp:960-1004, garglk/sysmac.mm:1013-1030, garglk/CMakeLists.txt:137,145, 510-534, gargoyle_osx.sh:124-125,211-213, installer.nsi:89-90,208-215 @@ -107,7 +107,7 @@ exclusion_note: > TADS character mapping files are not loaded by this build. The Glk port reports utf-8 and asc7dflt as the local character sets, both built-in tables, and its os_gen_charmap_filename() returns an empty name, so the - automatic .tcp lookup never runs; cmap_load() only fires for a path given + automatic .tcp lookup never runs. cmap_load() only fires for a path given with -ctab. The agil.cfg read by AGiliTy lives in os_dos.c and os_dos16.c, while the build compiles os_glk.c. ref: terps/tads/glk/osmisc.c:69-72,316-334, terps/tads/tads2/cmap.c:290-315, @@ -158,7 +158,7 @@ files: source_ref: "garglk/draw.cpp:664 (make_entry propz), garglk/draw.cpp:421-471 (make_font, winabort)" # -- Glyph substitution fonts, data directory root -- - # Tried for every face after the main fonts; a load failure is skipped. + # Tried for every face after the main fonts, and a load failure is skipped. - name: "unifont.otf" description: "GNU Unifont, Basic Multilingual Plane glyph fallback" required: false diff --git a/emulators/gba-emu.yml b/emulators/gba-emu.yml index ec771930..6f41a218 100644 --- a/emulators/gba-emu.yml +++ b/emulators/gba-emu.yml @@ -36,12 +36,12 @@ notes: | the length CPUInit tests again before copying it and setting useBios (GBA.emu/src/core/gba/gba.cpp:3758-3778). Nothing else about the file is examined: CPUIsGBABios, the extension test upstream passes to utilLoad, has no - caller here (GBA.emu/src/core/gba/gba.cpp:1655-1675; upstream + caller here (GBA.emu/src/core/gba/gba.cpp:1655-1675, upstream src/core/gba/gba.cpp:4975-4986). Without a file the app runs on the built-in myROM stub copied into the BIOS area (GBA.emu/src/core/gba/gba.cpp:131-305,3776-3778) and on the service call - implementations of gbaBios.cpp; useBios decides only whether an SWI enters + implementations of gbaBios.cpp. useBios decides only whether an SWI enters BIOS code or the HLE routine, and which register reset a boot performs (GBA.emu/src/core/gba/gba.cpp:2525-2545,4104-4112). Two settings gate the read: the per-content Use BIOS tristate defaults to Auto, which follows the @@ -70,9 +70,9 @@ notes: | VBA-M's own file entry points reach nothing in this build. CPULoadRom, the battery, state, GSA snapshot and eeprom import functions and the EmulatedSystem table sit inside #if 0 blocks (GBA.emu/src/core/gba/gba.cpp:1301-1614, - 1885-2134,4803-4869); CPUExportEepromFile and cheatsImportGSACodeFile keep no + 1885-2134,4803-4869), CPUExportEepromFile and cheatsImportGSACodeFile keep no caller (GBA.emu/src/core/gba/gba.cpp:1276, - GBA.emu/src/core/gba/gbaCheats.cpp:2081); and utilOpenFile, the call all of + GBA.emu/src/core/gba/gbaCheats.cpp:2081), and utilOpenFile, the call all of them open files with, is implemented by no source in the build (GBA.emu/src/CMakeLists.txt:6-36, GBA.emu/src/main/VbamApi.cc:279-321). The e-Reader reads no dotcode either, the tree carrying its header alone and the diff --git a/emulators/gbc-emu.yml b/emulators/gbc-emu.yml index d962a1af..55833963 100644 --- a/emulators/gbc-emu.yml +++ b/emulators/gbc-emu.yml @@ -26,7 +26,7 @@ notes: | GBC.emu/src/main/AppMeta.cc:26) and driven by the app's own video, audio, input and save layers, with the OSD compiled out (GBC.emu/CMakeLists.txt:14-19). Content is read from .gb, .gbc and .dmg files - (GBC.emu/metadata/conf.mk:5, GBC.emu/src/main/AppMeta.cc:30); an archive is + (GBC.emu/metadata/conf.mk:5, GBC.emu/src/main/AppMeta.cc:30). An archive is opened by the framework, which keeps the first entry passing that same filter (EmuFramework/src/EmuSystem.cc:392-419). diff --git a/emulators/gearcoleco.yml b/emulators/gearcoleco.yml index 7bd6fa6b..019a9e39 100644 --- a/emulators/gearcoleco.yml +++ b/emulators/gearcoleco.yml @@ -14,7 +14,7 @@ systems: - coleco-adam notes: | - ColecoVision and Coleco ADAM emulator by Ignacio Sanchez (drhelius); the + ColecoVision and Coleco ADAM emulator by Ignacio Sanchez (drhelius). The libretro port lives in the same repository. Three firmware roles are declared in kAdamFirmwareMetadata (src/Adam.cpp:26-42): OS-7, EOS and SmartWriter, each with a size, a CRC32 and its accepted file names. @@ -31,7 +31,7 @@ notes: | The machine is chosen per load (platforms/libretro/libretro.cpp:2386-2388): .ddp, .dsk, a ZIP holding an ADAM image, an .m3u playlist, no content at all, or a cartridge with the core option gearcoleco_cartridge_hardware set to ADAM start the - ADAM; any other cartridge starts the ColecoVision. The "adam" subsystem + ADAM, and any other cartridge starts the ColecoVision. The "adam" subsystem (platforms/libretro/libretro.cpp:528-536) takes a cartridge, two disks and two data packs. ColecoVision: load_colecovision_firmware() (platforms/libretro/libretro.cpp:851-878) needs OS-7 @@ -39,7 +39,7 @@ notes: | It runs again on retro_reset() (platforms/libretro/libretro.cpp:2203-2204). The image goes through Memory::LoadBiosFromBuffer() (src/Memory.cpp:310-319) and byte 0x69 is patched on reset, 0x32 when the cartridge is PAL and 0x3C otherwise - (src/Memory.cpp:246-249); the ADAM always gets 0x3C (src/Memory.cpp:221). + (src/Memory.cpp:246-249). The ADAM always gets 0x3C (src/Memory.cpp:221). ADAM: load_adam_firmware() (platforms/libretro/libretro.cpp:880-941) needs all three roles and every ADAM entry point returns false when one is missing (libretro.cpp: @@ -51,7 +51,7 @@ notes: | 8 KiB in cartridge mode (src/Adam.cpp:531-555). Save RAM, save states and IPS patches are read next to the content or in - the frontend save directory; they are state the core writes, not files a + the frontend save directory. They are state the core writes, not files a user obtains. files: @@ -66,7 +66,7 @@ files: validation: [size, crc32] source_ref: "platforms/libretro/libretro.cpp:772-833 (find_firmware), platforms/libretro/libretro.cpp:851-878 (load_colecovision_firmware), platforms/libretro/libretro.cpp:2398-2402, platforms/libretro/libretro.cpp:2203-2204, src/Adam.cpp:28-32, src/Adam.h:53, src/Memory.cpp:310-319, src/Memory.cpp:246-249" note: > - Loaded for both machines. Any 8192-byte image is accepted; a CRC32 + Loaded for both machines. Any 8192-byte image is accepted, and a CRC32 other than 3aa93ef3 logs "Unknown OS-7 revision" and runs. PAL timing comes from the byte patched at 0x69, not from a PAL dump. @@ -79,7 +79,7 @@ files: validation: [size, crc32] source_ref: "platforms/libretro/libretro.cpp:880-941 (load_adam_firmware), platforms/libretro/libretro.cpp:2371-2372, platforms/libretro/libretro.cpp:2428-2432, platforms/libretro/libretro.cpp:2445-2446, platforms/libretro/libretro.cpp:2529-2533, src/Adam.cpp:33-36, src/Adam.h:54, src/Adam.cpp:139-148, src/Adam.cpp:168-190, src/GearcolecoCore.cpp:410-415, src/Adam.cpp:537-540" note: > - The 8 KiB EOS bank, the first half of the 16 KiB u22 chip; a CRC32 + The 8 KiB EOS bank, the first half of the 16 KiB u22 chip. A CRC32 other than 05a37a34 logs "Unknown EOS revision" and runs. Only the ADAM needs it: ColecoVision cartridges load without it. diff --git a/emulators/geargrafx.yml b/emulators/geargrafx.yml index a45cd1b5..67b63191 100644 --- a/emulators/geargrafx.yml +++ b/emulators/geargrafx.yml @@ -24,7 +24,7 @@ notes: | picks the file name from the core option geargrafx_cdrom_bios (platforms/libretro/libretro.cpp:1568-1591): System Card 1 loads syscard1.pce, System Card 2 loads syscard2.pce, System Card 3 (the default) - and Force Game Express load syscard3.pce; the older values Auto and Game + and Force Game Express load syscard3.pce. The older values Auto and Game Express are still accepted and map to the same. The path is "{system_directory}/{name}" (platforms/libretro/libretro.cpp:736). When the card is missing the core posts "CD-ROM BIOS not found" and continues @@ -43,7 +43,7 @@ notes: | (src/defines.h:53-54). CRC32 is computed over the accepted image. GatherBIOSInfoFromDB() (src/media.cpp:1027-1061) looks the CRC up in k_game_database entries flagged GG_GAMEDB_BIOS_SYSCARD or - GG_GAMEDB_BIOS_GAME_EXPRESS (src/game_db.h:48-56); an unknown CRC marks the + GG_GAMEDB_BIOS_GAME_EXPRESS (src/game_db.h:48-56). An unknown CRC marks the image "Unknown" and invalid but it is still used. For CD content the ROM banks map onto the System Card buffer, or onto the @@ -64,11 +64,11 @@ notes: | (platforms/libretro/libretro.cpp:775-797). Media::LoadPacBiosData() (src/media.cpp:570-632) accepts 0x80000 bytes (GG_BIOS_LASERACTIVE_SIZE, src/defines.h:55), with or without a 512-byte header, and compares the - CRC32 with the values hardcoded for the region; an unknown CRC is logged + CRC32 with the values hardcoded for the region. An unknown CRC is logged and the image is still used. SelectPacBios() (src/media.cpp:634-660) follows the option, then the regionCode of the MMI image, then whichever region is loaded. An MMI image that names no card maps the PAC firmware - (src/media.cpp:1094-1103); one that names a card uses the System Card or + (src/media.cpp:1094-1103), and one that names a card uses the System Card or Game Express buffer. retro_load_game() fails when the firmware the MMI image needs is not loaded (platforms/libretro/libretro.cpp:534-549). diff --git a/emulators/geartowns.yml b/emulators/geartowns.yml index 5589ade3..b54b12c9 100644 --- a/emulators/geartowns.yml +++ b/emulators/geartowns.yml @@ -25,7 +25,7 @@ notes: | accepting first only a set made for the selected model and then any set (platforms/libretro/libretro.cpp:798-825). Firmware::FindSources() takes as candidates the folder itself, every direct subfolder and every .zip in - it (src/media/firmware.cpp:286-346); folder and zip names are free. A + it (src/media/firmware.cpp:286-346). Folder and zip names are free. A candidate counts only when the System, OS, Font and Dictionary ROMs are all present at the right size, and the CRC32 of its System ROM names the set (src/media/firmware.cpp:375-414, src/media/firmware.h:114-123). @@ -41,31 +41,31 @@ notes: | (platforms/libretro/libretro.cpp:827-860). File names are matched without case, inside a zip only at the archive root - (src/media/firmware.cpp:614-663). Accepted names per component are - FMT_SYS.ROM, FMT_SYS_A.ROM, FMTHR_SYS.ROM; FMT_DOS.ROM, FMT_DOS_A.ROM; - FMT_FNT.ROM; FMT_DIC.ROM; FMT_F20.ROM, FMT_F20_A.ROM; MYTOWNS.ROM, - MYTOWNSUX.ROM, MYTOWNSM2.ROM, MYTOWNSFTV.ROM, MYTOWNSHR.ROM; MAR_EX0.ROM to - MAR_EX3.ROM (src/media/firmware.cpp:28-42). Without separate files the + (src/media/firmware.cpp:614-663). Accepted names, one group per component, + are (FMT_SYS.ROM, FMT_SYS_A.ROM, FMTHR_SYS.ROM), (FMT_DOS.ROM, FMT_DOS_A.ROM), + (FMT_FNT.ROM), (FMT_DIC.ROM), (FMT_F20.ROM, FMT_F20_A.ROM), (MYTOWNS.ROM, + MYTOWNSUX.ROM, MYTOWNSM2.ROM, MYTOWNSFTV.ROM, MYTOWNSHR.ROM) and (MAR_EX0.ROM + to MAR_EX3.ROM) (src/media/firmware.cpp:28-42). Without separate files the Marty components are cut from MROM.M36 and MROM.M37, 2 MiB each (src/media/firmware.cpp:497-508): OS at 0 and the first three extension - parts in M36; the fourth extension part, 20-dot font at 0x80000, + parts in M36, and the fourth extension part, 20-dot font at 0x80000, dictionary at 0x100000, font at 0x180000 and System ROM at 0x1C0000 in M37. Each component must have its exact size or it is rejected (src/media/firmware.cpp:530-612, src/common/defines.h:47-54): System 256 KiB, OS 512 KiB, Font 256 KiB, Dictionary 512 KiB, 20-dot Font 512 KiB, Serial 32 bytes, Extension 2 MiB (four 512 KiB parts). System, OS, Font and - Dictionary are required; a missing 20-dot Font or Extension is replaced by + Dictionary are required. A missing 20-dot Font or Extension is replaced by 0xFF, a missing Serial ROM is generated (src/media/firmware.cpp:73-163, src/media/firmware.cpp:258-261). The CRC32 of every component is looked up - in game_db.h (src/media/firmware.cpp:165-182, src/media/game_db.h:303-335); - an unknown CRC only produces a warning. The Free FM Towns set is known by + in game_db.h (src/media/firmware.cpp:165-182, src/media/game_db.h:303-335), + and an unknown CRC only produces a warning. The Free FM Towns set is known by System 65DC3B1F, OS 43C18E92, Font 736D9CB1 and a blank Dictionary 504BF849. The Marty slices are known by System 937311F6, OS 2BC2AF96, Extension E1A9FA72 and 20-dot Font 75660AAC. The CMOS is written by the core next to the saves - (platforms/libretro/libretro.cpp:2753-2767); it is state, not a file to + (platforms/libretro/libretro.cpp:2753-2767). It is state, not a file to obtain. files: @@ -85,7 +85,7 @@ files: Set for the Model 1/2, the machine Auto falls back to. The same four files load from any subfolder of system/geartowns or from system/geartowns itself. The core has no CRC for a Model 1/2 20-dot - Font; fmt_f20.rom is read when present. + Font, and fmt_f20.rom is read when present. - name: "fmtownsux.zip" description: "FM Towns II UX firmware set" @@ -131,7 +131,7 @@ files: - { name: "fmt_dic.rom", size: 524288 } - { name: "mytownshr.rom", size: 32, crc32: "c52f0e89" } source_ref: "src/media/firmware.h:121, src/media/firmware.cpp:28-34, src/media/game_db.h:322-324" - note: "First choice for the HG; the HR itself is not emulated." + note: "First choice for the HG. The HR itself is not emulated." - name: "fmtownsftv.zip" description: "FM Towns II Fresh TV firmware set" @@ -147,4 +147,4 @@ files: - { name: "fmt_f20.rom", size: 524288, crc32: "9f55a20c" } - { name: "mytownsftv.rom", size: 32, crc32: "a961aae7" } source_ref: "src/media/firmware.h:122, src/media/firmware.cpp:28-34, src/media/game_db.h:326-329" - note: "Second choice for the HG; the MF/Fresh itself is not emulated." + note: "Second choice for the HG. The MF/Fresh itself is not emulated." diff --git a/emulators/geolith.yml b/emulators/geolith.yml index c4ece556..014bad33 100644 --- a/emulators/geolith.yml +++ b/emulators/geolith.yml @@ -17,16 +17,16 @@ systems: notes: | Geolith emulates the Neo Geo AES, MVS, CD, and CDZ. Cartridge systems use - .NEO format ROMs; CD systems use .cue or .chd disc images. System ROMs come + .NEO format ROMs, CD systems use .cue or .chd disc images. System ROMs come from MAME-format ZIP archives in the system directory. Cartridge content opens aes.zip (System Type = AES, default) or neogeo.zip (MVS and Universe BIOS) (libretro/libretro.c:1222-1225). CD content opens neocd.zip (Front/Top Loader) or neocdz.zip (CDZ, default, and CD Universe - BIOS) (libretro/libretro.c:1213-1221); Front/Top Loader additionally reads + BIOS) (libretro/libretro.c:1213-1221). Front/Top Loader additionally reads 000-lo.lo from neocdz.zip, so neocdz.zip is needed in every CD mode (libretro/libretro.c:1232-1239). The Irritating Maze in MVS mode loads - 236-bios.sp1 from irrmaze.zip for trackball support; without it the game + 236-bios.sp1 from irrmaze.zip for trackball support. Without it the game runs but the trackball does not work (libretro/libretro.c:1281-1292). Inside the opened archive, members are extracted by exact filename @@ -43,7 +43,7 @@ notes: | - CD Top Loader: top-sp1.bin - CDZ: neocd.bin - CD Universe BIOS: uni-bioscd33.rom - 000-lo.lo is required in every mode; only the Front/Top Loader tolerates + 000-lo.lo is required in every mode. Only the Front/Top Loader tolerates its absence from neocd.zip because it comes from neocdz.zip instead (src/geo.c:234-243, 273-285). sfix.sfix and sm1.sm1 are required for MVS and Universe BIOS modes only (src/geo.c:245-267). @@ -52,7 +52,7 @@ notes: | detection and the optional CD speed hack patches use byte patterns and apply only when the 68K BIOS is at least 512 KiB (src/geo_cd.c:1888-1910, 1904-1924). Upstream declares the expected archive MD5s through the Jolly - Good API BIOS list (jg.c:220-231); the md5 fields on the archives below + Good API BIOS list (jg.c:220-231), and the md5 fields on the archives below are copied from it. files: @@ -84,14 +84,14 @@ files: system: snk-neogeo-cd required: true md5: "b31a246b69493c35194fe0bac120dc37" - note: "Neo Geo CDZ System ROMs. Opened for CDZ (default) and CD Universe BIOS; also supplies 000-lo.lo to Front/Top Loader mode." + note: "Neo Geo CDZ System ROMs. Opened for CDZ (default) and CD Universe BIOS, and also supplies 000-lo.lo to Front/Top Loader mode." source_ref: "libretro/libretro.c:1213-1239, jg.c:227-228" - name: "irrmaze.zip" system: snk-neogeo-mvs required: false md5: "0e369df30a70e45547cef9e4078dc511" - note: "The Irritating Maze auxiliary BIOS. Loaded in MVS mode for trackball support; on failure the game runs without trackball." + note: "The Irritating Maze auxiliary BIOS. Loaded in MVS mode for trackball support. On failure the game runs without trackball." source_ref: "libretro/libretro.c:1281-1292, jg.c:229-230" # ----------------------------------------------------------- @@ -222,7 +222,7 @@ files: required: false size: 131072 crc32: "5a86cff2" - note: "Zoom lookup table. Extraction is attempted but absence is tolerated in Front/Top Loader mode; the copy in neocdz.zip is used instead." + note: "Zoom lookup table. Extraction is attempted but absence is tolerated in Front/Top Loader mode, where the copy in neocdz.zip is used instead." source_ref: "src/geo.c:234-243" # ----------------------------------------------------------- diff --git a/emulators/gopher2600.yml b/emulators/gopher2600.yml index fff9015d..35c1af90 100644 --- a/emulators/gopher2600.yml +++ b/emulators/gopher2600.yml @@ -31,13 +31,13 @@ notes: | tape or BIN, then the configuration directory (hardware/memory/cartridge/supercharger/bios.go:53-116). Each candidate name is tried in turn and the content is gated on MD5 before the caller checks the 2048 byte length, so a file under the right name with the wrong content is - refused. ReqSpec selects the PAL table and the PAL hash (hardware/memory/cartridge/supercharger/bios.go:56-59); + refused. ReqSpec selects the PAL table and the PAL hash (hardware/memory/cartridge/supercharger/bios.go:56-59). ReqSpec comes from the television specification, the stella.pro entry or the filename (cartridgeloader/loader.go:194-201). The demo unit is recognised by MD5 of the 256 bytes at 0x300 of the loaded image (hardware/memory/cartridge/supercharger/demounit.go:58,78). When that image carries more than 2048 bytes it - holds the Schweber chip and the carousel together; otherwise the eight ROMs + holds the Schweber chip and the carousel together, otherwise the eight ROMs are read from the directory of the loaded file (demounit_controller.go: 178-200). A read error or a length other than 8192 logs and returns nil, and the peripheral is left unplugged. @@ -46,7 +46,7 @@ notes: | configuration directory (properties/properties.go:28,48-58). It is loaded by NewDebugger (debugger/debugger.go:357), which drives play as well as debug (gopher2600.go:261,307,326), so it applies to the plain `gopher2600 <rom>` - invocation. A missing file is logged and start-up continues; the ROM selector + invocation. A missing file is logged and start-up continues. The ROM selector then falls back to the filename and no television specification is inferred from the cartridge name. diff --git a/emulators/gopher64.yml b/emulators/gopher64.yml index 8d845c8f..a8873795 100644 --- a/emulators/gopher64.yml +++ b/emulators/gopher64.yml @@ -20,7 +20,7 @@ notes: | the release binary, RetroBat in portable mode. The boot chain reads no file. Both PIF ROMs are compiled in as 1984 byte - arrays, the size of the PIF ROM window (src/device/pif/rom.rs:1,90; + arrays, the size of the PIF ROM window (src/device/pif/rom.rs:1,90 and src/device/pif.rs:7). reset_pif installs the PAL image when the cartridge country code is one of DFIPSUXY and the NTSC image otherwise (src/device/pif.rs:252-257, src/device/cart/rom.rs:137-143), and the VR4300 @@ -47,13 +47,13 @@ notes: | Everything else under the configuration, data and cache directories is written by the emulator: config.json and cheats.json (src/ui/config.rs:99-111,134-146), - retroachievements.json (src/lib.rs:209; src/retroachievements.rs:37,61), + retroachievements.json (src/lib.rs:209, src/retroachievements.rs:37,61), ice_config.json from the netplay server response (src/ui/netplay.rs:715-718, src/netplay.rs:419), the eeprom, sram, flash, mempak, sdcard and romsave saves - and the savestates (src/ui/storage.rs:212-232; src/savestates.rs:179,236). For + and the savestates (src/ui/storage.rs:212-232, src/savestates.rs:179,236). For a netplay launch the GUI serialises the cheats to the cache directory, passes them to a re-exec of itself through the hidden --cheats flag and deletes the - file afterwards (src/ui/gui.rs:585-595,602-617,632; src/lib.rs:141-147). + file afterwards (src/ui/gui.rs:585-595,602-617,632, src/lib.rs:141-147). portable.txt is tested for existence only, to move those three directories beside the executable (src/ui.rs:186-200). diff --git a/emulators/gzdoom.yml b/emulators/gzdoom.yml index b0232cd1..2a8e15c8 100644 --- a/emulators/gzdoom.yml +++ b/emulators/gzdoom.yml @@ -29,7 +29,7 @@ notes: | Game data is a user-supplied IWAD. iwadinfo.txt declares each known IWAD with its IWADName, MustContain lumps and support files. The search directories are scanned for the file names of its Names block - and for any .iwad, .ipk3 or .ipk7 file; each candidate is then + and for any .iwad, .ipk3 or .ipk7 file. Each candidate is then identified by its lumps, not by its name. The Names block also lists doomu.wad, doom1.wad, bfgdoom.wad, bfgdoom2.wad, freedoomu.wad, freedoom.wad, hereticsr.wad, heretic1.wad, hexendemo.wad, hexdemo.wad, @@ -78,14 +78,14 @@ files: path: "soundfonts/gzdoom.sf2" required: false source_ref: "src/common/audio/music/i_soundfont.cpp:334-352, 427-430, 439-459, src/CMakeLists.txt:1429" - note: "Default soundfont, used when the soundfont directories hold none. Every file of those directories is taken by its content; when no soundfont is named gzdoom the first SF2 found is used." + note: "Default soundfont, used when the soundfont directories hold none. Every file of those directories is taken by its content. When no soundfont is named gzdoom the first SF2 found is used." - name: "GENMIDI.GS.wopl" category: game_data path: "fm_banks/GENMIDI.GS.wopl" required: false source_ref: "src/CMakeLists.txt:1431, src/gameconfigfile.cpp:165-195, src/common/audio/music/i_soundfont.cpp:355-359" - note: "OPL3 bank copied next to the executable; fm_banks is one of the scanned soundfont directories." + note: "OPL3 bank copied next to the executable. fm_banks is one of the scanned soundfont directories." - name: "gs-by-papiezak-and-sneakernets.wopn" category: game_data @@ -106,7 +106,7 @@ files: system: doom required: false source_ref: "wadsrc_extra/static/iwadinfo.txt:420, 437, 659" - note: "The Ultimate DOOM and DOOM Registered both use this name; told apart by their lumps." + note: "The Ultimate DOOM and DOOM Registered both use this name and are told apart by their lumps." - name: "doom2.wad" category: game_data @@ -272,7 +272,7 @@ files: system: heretic 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; told apart by the EXTENDED lump." + note: "Both Heretic and Shadow of the Serpent Riders use this name and are told apart by the EXTENDED lump." - name: "blasphem.wad" aliases: ["blasphemer.wad"] diff --git a/emulators/hakux.yml b/emulators/hakux.yml index 7b8bc3cf..a12f5276 100644 --- a/emulators/hakux.yml +++ b/emulators/hakux.yml @@ -51,7 +51,7 @@ notes: | non-zero multiple of 64 KB, otherwise 256 KB of 0xFF is mapped in its place. The MCPX image must be exactly 512 bytes, another size clears the path with an error, and the machine property is checked a second time and ends the process - when it disagrees; the bytes are overlaid on the last 512 of the mirrored flash + when it disagrees. The bytes are overlaid on the last 512 of the mirrored flash region. The EEPROM must be 256 bytes and is generated as XBOX_EEPROM_VERSION_R1 when the path does not exist. An empty disk path attaches no drive at index 0 at all, while the disc drive at index 1 is always @@ -107,7 +107,7 @@ files: Copied under the fixed name mcpx.bin from whatever .bin, .rom or .img file the wizard is pointed at, and named by bootrom_path in the config. A size other than 512 bytes empties the setting and the machine property is left - off; when the property is set the loader checks the size again and ends the + off. When the property is set the loader checks the size again and ends the process rather than continue. The bytes are read over the last 512 of the flash image and the region stays writable so early retail kernels keep their cache quirk. @@ -118,14 +118,14 @@ files: path: "x1box/flash.bin" config_key: "sys.files.flashrom_path" min_size: 65536 - size_note: "Any non-zero multiple of 65536; 256 KB is assumed when the image cannot be read." + size_note: "Any non-zero multiple of 65536, and 256 KB is assumed when the image cannot be read." validation: [size] description: "Xbox flash ROM" note: >- Copied under the fixed name flash.bin and passed as -bios. A path that cannot be opened queues an error and clears autostart, so nothing runs without it. The image is mapped at 0xFF000000 and mirrored to the top of - the address space; a size that is zero or not a multiple of 64 KB, or a + the address space. A size that is zero or not a multiple of 64 KB, or a short read, falls back to 256 KB filled with 0xFF. A retail image cannot launch unsigned code, so a debug or modified image is what boots a title. source_ref: "system/vl.c:3057-3072, hw/xbox/xbox.c:65-124, android/app/src/main/java/com/rfandango/haku_x/SetupWizardActivity.kt:76-97, android/app/src/main/cpp/xemu_android.cpp:670, 761-773" @@ -141,7 +141,7 @@ files: drive at all and an unopenable one only queues a message, but the launcher refuses to leave the wizard until the file resolves. The formatter builds FATX partitions inside an image that already exists and needs at least - 0x1DD156000 bytes for the retail layout; it never creates the image. A + 0x1DD156000 bytes for the retail layout, but it never creates the image. A qcow2 with a backing file is reported at load because the sectors it did not modify are read from that other file. source_ref: "system/vl.c:3078-3092, android/app/src/main/java/com/rfandango/haku_x/SetupWizardActivity.kt:99-120, android/app/src/main/java/com/rfandango/haku_x/XboxHddFormatter.kt:7-29, 47-79, android/app/src/main/cpp/xemu_android.cpp:176-184, 671-672, 774-795" @@ -157,7 +157,7 @@ files: Always pointed at x1box/eeprom.bin, a path the wizard never asks for. Generated as XBOX_EEPROM_VERSION_R1 when it does not exist, so a dump is needed only to carry over a console serial, region or HDD key. It is - attached through the smbus-storage device; a size other than 256 bytes, or + attached through the smbus-storage device. A size other than 256 bytes, or a generation that fails, clears autostart. Preparing Insignia and the EEPROM editor write to it in place. source_ref: "system/vl.c:2921-2964, 3045-3055, android/app/src/main/cpp/xemu_android.cpp:671, 711, android/app/src/main/java/com/rfandango/haku_x/SettingsActivity.kt:1264-1267" @@ -220,8 +220,8 @@ files: texture_replace in internal storage, and read back by the Vulkan renderer from the subdirectory named after the title id of the running XBE in eight hexadecimal digits. A name is kept only when the stem is sixteen - hexadecimal digits, which is the content hash of the texture it replaces; - each PNG is decoded to a .raw sidecar carrying width and height and mapped + hexadecimal digits, which is the content hash of the texture it replaces. + Each PNG is decoded to a .raw sidecar carrying width and height and mapped from there. Off unless the setting is on and the folder is set. source_ref: "hw/xbox/nv2a/pgraph/vk/texture_replace.c:227-320, 331-377, 388-435, android/app/src/main/java/com/rfandango/haku_x/GameLibraryActivity.kt:904-990, android/app/src/main/java/com/rfandango/haku_x/MainActivity.kt:105-113" @@ -235,7 +235,7 @@ files: Read from the assets of the package at startup and handed to SDL as a memory stream. The asset manager reads inside the archive and the path is a constant, so there is no search order and nothing outside the package - replaces this copy; an added pad mapping goes in through + replaces this copy. An added pad mapping goes in through controller_map.txt instead. The revision shipped here is 589031 bytes and is not the one other releases carry under this name. source_ref: "android/app/src/main/cpp/xemu_android.cpp:193-268" diff --git a/emulators/hatari.yml b/emulators/hatari.yml index 4b37ac4a..3fe4b9a0 100644 --- a/emulators/hatari.yml +++ b/emulators/hatari.yml @@ -26,19 +26,19 @@ notes: | src/CMakeLists.txt:371-404), reports library_name hatari and the HATARI_VERSION string 2.6.1-devel (src/retro/main_retro.c:218-219, src/includes/version.h:8). The .info shipped in the tree declares no - firmware (share/libretro/info/libretro-hatari.info); the + firmware (share/libretro/info/libretro-hatari.info). The hatari_libretro.info in libretro-core-info took that file's metadata on 2026-09-16 and keeps a tos.img firmware entry with the TOS 1.02 US MD5, which this code never checks. retro_init builds <system>/tos.img, records whether it exists and passes - it as --tos (src/retro/main_retro.c:157-207); when it is absent a + it as --tos (src/retro/main_retro.c:157-207). When it is absent a frontend message is shown and retro_run only refreshes the framebuffer (src/retro/main_retro.c:186-189, src/retro/main_retro.c:250-261). The name is fixed by that check: the .rom and .tos fallbacks of File_Read (src/tos.c:60-66, src/file.c:312-353, src/file.c:544-583) are never reached under a frontend. A missing --tos file fails option parsing - (src/options.c:1026-1079, src/options.c:1937-1945); Main_ErrorExit only + (src/options.c:1026-1079, src/options.c:1937-1945), but Main_ErrorExit only raises the quit flag in this build (src/retro/main_retro.c:478-490), so Main_Init carries on with bUseTos cleared and TOS_InitImage installs the built-in test stub of faketosData.c instead of reading a ROM @@ -79,7 +79,7 @@ notes: | enabled (src/midi.c:342-367, src/printer.c:42-65, src/printer.c:89-106, src/rs232.c:175-246, src/scc.c:439-500). szMappingFileName is parsed (src/configuration.c:256) but the port's Keymap_LoadRemapFile is empty - (src/retro/keymap.c:222-224); only the SDL build reads a keymap file + (src/retro/keymap.c:222-224). Only the SDL build reads a keymap file (src/sdl/keymap.c:701). The autosave snapshot is restored by M68000_Start (src/m68000.c:332-348), which the port never calls. TT and Falcon NVRAM is hatari.nvram in the home directory, read at NvRam_Init @@ -98,7 +98,7 @@ notes: | hatari_savestate.tmp in the system directory (src/retro/main_retro.c:41, src/retro/main_retro.c:292-359). IPF support is compiled in from rsn8887/capsimg when ENABLE_STATIC_CAPSIMAGE is on - (cmake/BuildDependencies.cmake:93-126); the Windows jobs build with it + (cmake/BuildDependencies.cmake:93-126). The Windows jobs build with it since September 2026 (.gitlab-ci-libretro.yml:101, .gitlab-ci-libretro.yml:109) and the static Vita, Wii, Wii U and Switch jobs turn it off (.gitlab-ci-libretro.yml:193, .gitlab-ci-libretro.yml:202, @@ -133,7 +133,7 @@ files: replaced by sym, and the image path is always tos.img here: retro_init passes <system>/tos.img as --tos and no other image name reaches the loader, so a table named after another image, emutos.sym beside - emutos.img, is never opened. nSymbolsAutoLoad gates the read; its + emutos.img, is never opened. nSymbolsAutoLoad gates the read. Its default is not off and no core option changes it, so the table is read at every TOS load when present. The symbols serve the built-in debugger. @@ -149,8 +149,8 @@ files: source_ref: "src/cart.c:41-47, src/cart.c:53-88, src/cart.c:97-104, src/cart.c:114-142, src/configuration.c:487-493, src/configuration.c:814" note: > Set through hatari.cfg. Raw images up to 0x20000 bytes or .stc - images of exactly 0x20004 bytes whose 4-byte header is skipped; - extensions .img, .rom and .stc are tried when the configured path is + images of exactly 0x20004 bytes whose 4-byte header is skipped. + Extensions .img, .rom and .stc are tried when the configured path is missing. Replaced by the built-in GEMDOS trampoline whenever GEMDOS hard disk emulation, extended VDI, program autostart or OS tracing is on. @@ -167,7 +167,7 @@ files: description: "Hatari configuration file" required: false storage: user_provided - unsourceable: "user settings in Hatari's INI format; no canonical contents" + unsourceable: "user settings in Hatari's INI format, with no canonical contents" source_ref: "src/main.c:260-282, src/main.c:319-322, src/main.c:328-330, src/configuration.c:862-867, src/configuration.c:1061-1071, src/paths.c:236-250, CMakeLists.txt:444-461" note: > Read from <CONFDIR>/hatari.cfg and then from hatari.cfg in the @@ -182,8 +182,8 @@ files: min_size: 50 validation: [size] storage: user_provided - unsourceable: "machine state the emulator writes itself at exit; no canonical contents" + unsourceable: "machine state the emulator writes itself at exit, with no canonical contents" source_ref: "src/falcon/nvram.c:96-97, src/falcon/nvram.c:116-141, src/falcon/nvram.c:148-171, src/falcon/nvram.c:282-294, src/falcon/nvram.c:334-337, src/paths.c:236-250, src/main.c:208" note: > - Read from the RetroArch save directory at NvRam_Init; a short read + Read from the RetroArch save directory at NvRam_Init. A short read keeps the built-in defaults. Saved back on exit. diff --git a/emulators/hatari2014.yml b/emulators/hatari2014.yml index 9e19f6b4..e6af122c 100644 --- a/emulators/hatari2014.yml +++ b/emulators/hatari2014.yml @@ -22,13 +22,13 @@ notes: | the July 2014 release, kept on the hitari2014-mercurial branch of libretro/hatari after the main branch moved to a new port. The branch carries the Mercurial history up to the 1.8.0 release commit plus the - port commits started in November 2014; it builds as hatari2014 + port commits started in November 2014. It builds as hatari2014 (Makefile.libretro:22, .gitlab-ci-libretro.yml:12) and reports library_name Hatari2014, version 1.8 (libretro/libretro.c:1466-1468). No hatari2014 .info exists in libretro-core-info yet. Directory layout under the libretro system directory: the Hatari working - and data directories are <system>/hatari (src/paths.c:323-324; the + and data directories are <system>/hatari (src/paths.c:323-324, or the system directory itself on Vita and PS3, src/paths.c:313-319), the default TOS is <system>/tos.img, extra TOS images go in <system>/hatari/tos, BOOT.ST in <system>/hatari, floppy.raw and the @@ -40,7 +40,7 @@ notes: | (src/paths.c:237-239). TOS selection: retro_set_environment lists <system>/tos.img and every - entry of <system>/hatari/tos (libretro/libretro.c:393-411); the + entry of <system>/hatari/tos (libretro/libretro.c:393-411). The hatari_tosimage option offers those ending in img (libretro/libretro.c:270-299) and the choice becomes RETRO_TOS (libretro/libretro.c:640-649). retro_load_game refuses content when that @@ -50,7 +50,7 @@ notes: | whole, strips the 256-byte (or 34-byte for 4.92) loader of a RAM TOS, detects EmuTOS by ETOS at offset 0x2c, and rejects an image whose version word is outside 0x100-0x4FF, whose load address is neither 0xE00000 nor - 0xFC0000, or which exceeds 1 MB; a 16 KB image with version 0 is the TOS + 0xFC0000, or which exceeds 1 MB. A 16 KB image with version 0 is the TOS 0.00 boot loader (src/tos.c:575-651). Machine type and CPU are coerced to the TOS version unless the image is EmuTOS (src/tos.c:459-566), and ROM patches are applied for TOS 1.00, 1.02, 1.04, 1.06, 1.62, 2.05, 2.06, @@ -69,7 +69,7 @@ notes: | Floppy, ACSI, IDE and GEMDOS images are content. When a .gem folder is loaded, <system>/hatari/BOOT.ST is inserted into drive A so TOS boots with the GEMDOS drive (libretro/libretro.c:1663-1671). Memory snapshots - for retro_serialize stay in memory (libretro/libretro.c:1768-1793); + for retro_serialize stay in memory (libretro/libretro.c:1768-1793), and hatari.sav, auto.sav, hatari.prn, hatari.wav and hatari.avi are output names under <system>/hatari. DESKTOP.INF and NEWDESK.INF are created or rewritten inside the emulated C: directory when extended VDI is on @@ -86,7 +86,7 @@ files: note: > Any TOS 1.00 to 4.04, TOS 0.00, a RAM TOS or EmuTOS. Additional images are read from <system>/hatari/tos and selected with the hatari_tosimage - option; only names ending in img are offered. + option. Only names ending in img are offered. - name: "cartridge ROM" path: null @@ -99,7 +99,7 @@ files: source_ref: "src/cart.c:40-46, src/cart.c:53-88, src/cart.c:121-133, src/configuration.c:336, src/configuration.c:592, libretro/gui-retro/dlgRom.c:82-89" note: > Raw images up to 0x20000 bytes or .stc images of exactly 0x20004 bytes - whose 4-byte header is skipped; any other size is refused. Extensions + whose 4-byte header is skipped. Any other size is refused. Extensions .img, .rom and .stc are tried when the configured path is missing. - name: "BOOT.ST" @@ -115,10 +115,10 @@ files: required: false has_builtin: true storage: user_provided - unsourceable: "any headerless s16le stereo 44100 Hz sample the user records; no name or version the code expects beyond the filename" + unsourceable: "any headerless s16le stereo 44100 Hz sample the user records, with no name or version the code expects beyond the filename" source_ref: "libretro/floppy_sound.c:118-170, libretro/libretro.c:844-852, libretro/libretro.c:1379" note: > - Read whole at retro_init; an empty or short read falls back to the + Read whole at retro_init. An empty or short read falls back to the synthesised click (libretro/floppy_sound.c:31-95). Played on each drive LED rising edge when hatari_floppy_sound is on. @@ -127,7 +127,7 @@ files: description: "Hatari configuration file" required: false storage: user_provided - unsourceable: "user settings in Hatari's INI format; no canonical contents" + unsourceable: "user settings in Hatari's INI format, with no canonical contents" source_ref: "libretro/libretro.c:945-951, src/main.c:805-831, src/main.c:892-894, src/configuration.c:630-633, src/configuration.c:768-777, src/paths.c:283-284" note: > Read only when the hatari_autoload_config option is on (off by default): @@ -140,9 +140,9 @@ files: description: "Keyboard remap table, one PC key code and ST scan code pair per line" required: false storage: user_provided - unsourceable: "user-written mapping in the doc/keymap-sample.txt format; no canonical contents" + unsourceable: "user-written mapping in the doc/keymap-sample.txt format, with no canonical contents" source_ref: "src/keymap.c:53-59, src/keymap.c:605-658, src/change.c:359, src/configuration.c:188, src/configuration.c:504" - note: "Empty by default; loaded at Keymap_Init and on configuration change when the path is set." + note: "Empty by default. Loaded at Keymap_Init and on configuration change when the path is set." - name: "hatari.nvram" path: null @@ -151,8 +151,8 @@ files: has_builtin: true min_size: 50 validation: [size] - unsourceable: "machine state the emulator writes itself at exit; no canonical contents" + unsourceable: "machine state the emulator writes itself at exit, with no canonical contents" source_ref: "src/falcon/nvram.c:63-85, src/falcon/nvram.c:186-216, src/falcon/nvram.c:223-226, src/main.c:752, src/paths.c:283-284" note: > - Read from the Hatari home directory at NvRam_Init; a short read keeps + Read from the Hatari home directory at NvRam_Init. A short read keeps the built-in defaults adjusted to the monitor type. Saved back on exit. diff --git a/emulators/hatarib.yml b/emulators/hatarib.yml index 6f5c56fd..4cf1437d 100644 --- a/emulators/hatarib.yml +++ b/emulators/hatarib.yml @@ -20,7 +20,7 @@ notes: | hatariB carries Hatari 2.6.1 in its hatari/ directory, every change fenced by __LIBRETRO__ (DEVELOP.md:7-14, DEVELOP.md:44-48), and builds as hatarib (makefile.libretro:1, makefile.libretro:3, - core/core.c:1134); the upstream_commit is the v2.6.1 tag the tree was + core/core.c:1134). The upstream_commit is the v2.6.1 tag the tree was taken from. The core reads and writes through core_file.c, using the libretro VFS when the frontend offers version 3 (core/core_file.c:747-790). Hatari's own @@ -44,12 +44,12 @@ notes: | .rom, .bin or .cart, hard disks are any file or subdirectory (core/core_config.c:11, core/core_config.c:1318-1385). The TOS option defaults to <tos.img> when the file exists and to EmuTOS 192uk otherwise - (core/core_config.c:68-92, core/core_config.c:1325-1340); the four + (core/core_config.c:68-92, core/core_config.c:1325-1340). The four special values select tos.img or one of the built-in images, any other value is a path under the system directory (core/core_config.c:1112-1135). TOS_LoadImage copies the built-in image or reads the file with core_read_file_system and caches it - (hatari/src/tos.c:45-63, hatari/src/tos.c:1028-1078); a failed load + (hatari/src/tos.c:45-63, hatari/src/tos.c:1028-1078). A failed load raises a notification and halts the CPU instead of leaving (hatari/src/tos.c:1080-1086, hatari/src/tos.c:1250-1262, core/core.c:419-433, hatari/src/main.c:906-925). Validation is @@ -72,7 +72,7 @@ notes: | (hatari/src/cart.c:108-147). A permanent hard disk comes from system/hatarib through hatarib_hardimg and hatarib_hardtype, GEMDOS folder, ACSI, SCSI or IDE (core/core_config.c:186-233, - core/core_config.c:1018-1075, core/core_config.c:1169-1180); temporary + core/core_config.c:1018-1075, core/core_config.c:1169-1180). Temporary ones are content with an .acsi, .ahd, .vhd, .scsi, .shd, .ide or .gem extension or lines of an M3U (core/core_disk.c:16-23, core/core_disk.c:676-713, core/core_disk.c:782-785, @@ -80,21 +80,21 @@ notes: | (hatari/src/hdc.c:903, hatari/src/hdc.c:961-963, hatari/src/ide.c:663-666) and GEMDOS folders through core_scandir_hard (hatari/src/gemdos.c:672, hatari/src/gemdos.c:770, - hatari/src/gemdos.c:1330); hard disks are write protected by default + hatari/src/gemdos.c:1330). Hard disks are write protected by default (hatari/src/configuration.c:918). Floppy content is ST, MSA, DIM, STX, IPF or CTR, also inside a ZIP, ZST or GZ, or an M3U or M3U8 list with #BOOTA, #BOOTB, #AUTO and #RES directives (core/core_disk.c:14-24, core/core_disk.c:202-384, core/core_disk.c:444-559, core/core_disk.c:621-670). Before the original image the core takes a same-named copy from the save directory and, for STX, a .wd1772 overlay - there (core/core_disk.c:787-814); modified disks are written back to + there (core/core_disk.c:787-814), and modified disks are written back to the save directory (core/core_disk.c:1154-1226, hatari/src/st.c:93, hatari/src/msa.c:417, hatari/src/floppy_stx.c:451). #AUTO and #RES write a virtual INF file to system/hatarib.tmp (hatari/src/inffile.c:761) and, when booting from a GEMDOS C: folder, read the DESKTOP.INF, NEWDESK.INF or EMUDESK.INF found there (hatari/src/inffile.c:598-667). MIDI goes through the libretro MIDI - interface (core/core.c:485-545, hatari/src/midi.c:593-700); Midi_Host_Open + interface (core/core.c:485-545, hatari/src/midi.c:593-700), and Midi_Host_Open no longer opens files (hatari/src/midi.c:346-424). files: @@ -110,7 +110,7 @@ files: note: > Any TOS 1.00 to 4.04, TOS 0.00, a RAM TOS or EmuTOS. Further images go in system/hatarib/ with an .img, .rom, .bin or .tos extension and - are selected with the hatarib_tos option; without tos.img the + are selected with the hatarib_tos option. Without tos.img the built-in EmuTOS 192uk is the default. - name: "etos1024k.img" @@ -126,7 +126,7 @@ files: note: > Compiled into the core from emutos/etos1024k.img and never opened at run time. Built from the hatarib-custom-140 branch of - bbbradsmith/emutos; hashes are of the file in the repository. + bbbradsmith/emutos. Hashes are of the file in the repository. - name: "etos192uk.img" description: "EmuTOS 1.4 192 KB UK image, 50 Hz, default TOS" @@ -142,7 +142,7 @@ files: Compiled into the core from emutos/etos192uk.img and never opened at run time. Selected when no tos.img exists and no other image is chosen. Built from the hatarib-custom-140 branch of - bbbradsmith/emutos; hashes are of the file in the repository. + bbbradsmith/emutos. Hashes are of the file in the repository. - name: "etos192us.img" description: "EmuTOS 1.4 192 KB US image, 60 Hz" @@ -157,7 +157,7 @@ files: note: > Compiled into the core from emutos/etos192us.img and never opened at run time. Built from the hatarib-custom-140 branch of - bbbradsmith/emutos; hashes are of the file in the repository. + bbbradsmith/emutos. Hashes are of the file in the repository. - name: "cartridge ROM" path: null @@ -183,11 +183,11 @@ files: min_size: 50 validation: [size] storage: user_provided - unsourceable: "machine state the emulator writes itself when the content closes; no canonical contents" + unsourceable: "machine state the emulator writes itself when the content closes, with no canonical contents" source_ref: "hatari/src/falcon/nvram.c:97, hatari/src/falcon/nvram.c:111-117, hatari/src/falcon/nvram.c:127-170, hatari/src/falcon/nvram.c:178-205, hatari/src/falcon/nvram.c:317-330, hatari/src/falcon/nvram.c:371-374, hatari/src/falcon/nvram.h:54-58, core/core_file.c:273-277, core/core_file.c:319-322" note: > Read from the system directory at NvRam_Init for the TT and Falcon - machines only; a read shorter than 50 bytes keeps the built-in + machines only. A read shorter than 50 bytes keeps the built-in defaults. Written back when the core shuts down. - name: "capsimg.so" @@ -198,7 +198,7 @@ files: note: > Opened with dlopen on the first IPF or CTR read, from the dlopen search path or next to the core, and required to export the CAPS - functions the core imports; without it those images are refused + functions the core imports. Without it those images are refused with a notification and every other format still works. rsn8887/capsimg publishes one build per platform under this name. @@ -209,6 +209,6 @@ files: source_ref: "hatari/src/floppy_ipf.c:320-331, hatari/src/floppy_ipf.c:637-645, hatari/src/floppy_ipf.c:733-783, hatari/src/floppy_ipf.c:791-803, DEVELOP.md:56" note: > Opened with LoadLibrary on the first IPF or CTR read, from the - RetroArch directory or the library search path; without it those + RetroArch directory or the library search path. Without it those images are refused with a notification and every other format still works. diff --git a/emulators/higan_sfc.yml b/emulators/higan_sfc.yml index e7acb616..49eb06e1 100644 --- a/emulators/higan_sfc.yml +++ b/emulators/higan_sfc.yml @@ -38,7 +38,7 @@ notes: | (icarus/heuristics/super-famicom.cpp:707-759) and write a manifest naming each firmware file with its size (icarus/heuristics/super-famicom.cpp:482-545). DSP1 games are given the - DSP1B names; dsp1.program.rom and dsp1.data.rom are named for the Campus + DSP1B names, while dsp1.program.rom and dsp1.data.rom are named for the Campus Challenge '92 and Powerfest '94 cartridges (icarus/heuristics/super-famicom.cpp:623-640, icarus/heuristics/super-famicom.cpp:416-417, @@ -49,7 +49,7 @@ notes: | and imports again (higan/target-libretro/libretro.cpp:105-141). locate_libretro tries the system directory, then higan/ under the user's config and data directories (higan/target-libretro/libretro.cpp:15-35). No - hash is checked; the sizes below are those the manifest declares, and a + hash is checked. The sizes below are those the manifest declares, and a shorter file leaves the second import short and the load fails. The icarus database is read from Database/ next to the frontend @@ -88,14 +88,14 @@ files: system: nintendo-snes size: 6144 required: false - note: "Named for the Campus Challenge '92 and Powerfest '94 cartridges and by the icarus database; other DSP1 games use dsp1b.program.rom." + note: "Named for the Campus Challenge '92 and Powerfest '94 cartridges and by the icarus database. Other DSP1 games use dsp1b.program.rom." source_ref: "higan/sfc/cartridge/load.cpp:227-257, icarus/heuristics/super-famicom.cpp:416, icarus/heuristics/super-famicom.cpp:437" - name: "dsp1.data.rom" system: nintendo-snes size: 2048 required: false - note: "Named for the Campus Challenge '92 and Powerfest '94 cartridges and by the icarus database; other DSP1 games use dsp1b.data.rom." + note: "Named for the Campus Challenge '92 and Powerfest '94 cartridges and by the icarus database. Other DSP1 games use dsp1b.data.rom." source_ref: "higan/sfc/cartridge/load.cpp:227-257, icarus/heuristics/super-famicom.cpp:417, icarus/heuristics/super-famicom.cpp:438" - name: "dsp1b.program.rom" diff --git a/emulators/higan_sfc_balanced.yml b/emulators/higan_sfc_balanced.yml index a34da810..f4f461cc 100644 --- a/emulators/higan_sfc_balanced.yml +++ b/emulators/higan_sfc_balanced.yml @@ -32,7 +32,7 @@ notes: | and retro_get_system_info announces it as library_version under the name "higan (Super Famicom Balanced)" (nSide/target-libretro/libretro.cpp:87-93, nSide/target-libretro/libretro-sfc.cpp:486). The balanced profile keeps a - scanline-based PPU; the accuracy profile is refused at build time + scanline-based PPU, and the accuracy profile is refused at build time (nSide/target-libretro/GNUmakefile:1-2, nSide/target-libretro/libretro.cpp:38-39). The library is named nside_$(corename)_libretro with corename sfc_balanced (nSide/target-libretro/GNUmakefile:4-13, nSide/target-libretro/GNUmakefile:18-23), @@ -56,9 +56,9 @@ notes: | directories (nSide/target-libretro/libretro.cpp:3-31). Identifiers come from the cartridge label: DSP1 for PILOTWINGS, DSP2 for DUNGEON MASTER, DSP3 for SD Gundam GX, DSP4 for TOP GEAR 3000 and PLANETS CHAMP TG3000, DSP1B - otherwise; ST011 for 2DAN MORITA SHOUGI, ST010 otherwise; ST018 and Cx4 have - a single revision (icarus/heuristics/super-famicom.cpp:512-541). No hash is - checked; a file shorter than the size the manifest declares leaves the + otherwise. ST011 is used for 2DAN MORITA SHOUGI, ST010 otherwise, and ST018 + and Cx4 have a single revision (icarus/heuristics/super-famicom.cpp:512-541). + No hash is checked, and a file shorter than the size the manifest declares leaves the second import short and the load fails. The sizes below are those declared by the heuristics. diff --git a/emulators/holani.yml b/emulators/holani.yml index fa9387ac..1aeb5b4a 100644 --- a/emulators/holani.yml +++ b/emulators/holani.yml @@ -23,7 +23,7 @@ notes: | libretro wrapper attempts to load the real lynxboot.img, but if the file is missing or the system directory is invalid, Lynx::new() already has the free boot ROM initialized. No hash validation on the external - file; Rom::from_slice() only checks length == 512. + file: Rom::from_slice() only checks length == 512. files: - name: "lynxboot.img" diff --git a/emulators/hurrican.yml b/emulators/hurrican.yml index 96dcf521..4950e6df 100644 --- a/emulators/hurrican.yml +++ b/emulators/hurrican.yml @@ -84,7 +84,7 @@ files: bundled: true source_ref: "Hurrican/src/DX8Graphics.cpp:393-428" note: > - Loaded by the GL2 and GL3 renderers (GL2 is the build default); a GL1 + Loaded by the GL2 and GL3 renderers (GL2 is the build default). A GL1 build compiles this block out. - name: "music/" @@ -112,4 +112,4 @@ files: required: false bundled: true source_ref: "Hurrican/src/DX8Input.cpp:97-102" - note: "Passed to SDL_GameControllerAddMappingsFromFile; the result is only logged." + note: "Passed to SDL_GameControllerAddMappingsFromFile, and the result is only logged." diff --git a/emulators/hypseus-singe.yml b/emulators/hypseus-singe.yml index 0b40c89d..b472fe75 100644 --- a/emulators/hypseus-singe.yml +++ b/emulators/hypseus-singe.yml @@ -23,7 +23,7 @@ notes: | Each Daphne game loads its own arcade ROM set. game::load_roms() walks the driver rom_def table and opens roms/<set>.zip, locating each member by name - case-insensitively; a member missing from the archive falls back to a loose + case-insensitively. A member missing from the archive falls back to a loose file at roms/<set>/<member> (game.cpp:636-768). The set name is the rom_def dir field when set, otherwise the driver shortgamename, so a variant can pull members out of another game's archive. roms/ resolves under -romdir when @@ -39,13 +39,13 @@ notes: | Hashing is per member, never over the archive. The Dragon's Lair Enhancement and Space Ace Enhancement sets carry an extra - readme member checked by exact CRC32 through verify_required_file(); a + readme member checked by exact CRC32 through verify_required_file(). A missing or altered readme calls set_quitflag() and the game does not run (game.cpp:773-837, lair.cpp:197-205, 261-275, 373-380). Singe games are not covered by rom_def. The Lua script, framefile and video arrive with the content and are passed on the command line (-script, -zlua, - -framefile); singe_utils.cpp:35-42 only exposes the roms path to scripts. + -framefile). singe_utils.cpp:35-42 only exposes the roms path to scripts. The emulator asset tree ships in the source distribution and packagers install it beside the binary (Batocera copies pics, fonts, sound and the @@ -61,7 +61,7 @@ notes: | the Thayer's Quest key overlay (video.cpp:632-635). A bezel directory, default bezels/, takes precedence for the bmp and png entries. fonts/ - default.ttf plus daphne.ttf for legacy overlay and Singe games or - digital.ttf otherwise; a font that fails to open calls set_quitflag() + digital.ttf otherwise. A font that fails to open calls set_quitflag() (video.cpp:271-293, splash.cpp:45). sound/ - the per-game wav samples named by each driver, plus grumble.wav loaded for every game. load_waves() failure fails sound::init() and diff --git a/emulators/idtech4a++.yml b/emulators/idtech4a++.yml index 3ffd7959..d064de75 100644 --- a/emulators/idtech4a++.yml +++ b/emulators/idtech4a++.yml @@ -56,7 +56,7 @@ notes: | Game data lives under a working directory, `/sdcard/diii4a` unless the preference names another, and each game reads a base folder inside it. With the standalone-directory preference on, which is the default, the base folder sits - under a per-game subdirectory; with it off, games that are not marked always + under a per-game subdirectory. With it off, games that are not marked always standalone read the base folder directly under the working directory. The Dark Mod, UZDOOM, FTEQW, ECWolf, Xash3D, Source and both Serious Sam entries are always standalone and keep their subdirectory either way. @@ -79,7 +79,7 @@ notes: | quake1/darkplaces/id1), UZDOOM 4.14.3 (uzdoom), Wolfenstein 3D (ECWolf 1.4.2, ecwolf), FTEQW 1.05 (fteqw), Xash3D 0.21 (xash/valve), Source Engine 1.16 (srceng/hl2), Serious Sam TFE 1.10.7 (serioussamtfe) and Serious Sam TSE 1.10.7 - (serioussamtse). Every one is built in this configuration; the F-Droid flavour + (serioussamtse). Every one is built in this configuration. The F-Droid flavour leaves out Xash3D and Source, and the idtech flavour leaves out those two and Serious Sam. DOOM 3 BFG carries a second library for its Vulkan renderer. ref: Q3E/src/main/java/com/n0n3m4/q3e/Q3EGame.java:17-291, @@ -133,7 +133,7 @@ notes: | `idtech4amm.version` is written beside them and compared on the next run, so an engine update replaces the copy and a user edit survives otherwise. The Dark Mod, DOOM 3 BFG, UZDOOM, Xash3D, Source, Enemy Territory, ECWolf, Skin Deep and - ETQW are covered by this path; the bot, Rivensin and translation archives are + ETQW are covered by this path, while the bot, Rivensin and translation archives are extracted on request from the launcher instead. ref: Q3E/src/main/java/com/n0n3m4/q3e/Q3EMain.java:167, Q3E/src/main/java/com/n0n3m4/q3e/Q3EGameHelper.java:667-746, 964-984, @@ -163,7 +163,7 @@ files: sha1: dd2364da2cc8b49e32330ba9abff80727b4ea0a0 description: "UZDOOM engine resource archive" note: >- - Named by BASEWAD and searched before anything else; a miss ends the process + Named by BASEWAD and searched before anything else. A miss ends the process with "Cannot find uzdoom.pk3". Carries the hex font, the widget resources and the script definitions the engine needs before a game is chosen. Copied out of the apk with the rest of the UZDOOM resource directory. @@ -238,8 +238,8 @@ files: description: "SoundFont for the MIDI devices" note: >- Collected by scanning a `soundfonts` directory added to the search paths of - the config file (Q3E/src/main/jni/zdoom/src/gameconfigfile.cpp:220, 258); - every .sf2 and zipped GUS patch set found there becomes a menu entry. + the config file (Q3E/src/main/jni/zdoom/src/gameconfigfile.cpp:220, 258). + Every .sf2 and zipped GUS patch set found there becomes a menu entry. fluid_patchset defaults to GAMENAMELOWERCASE, "uzdoom", which FindSoundFont matches against the file base name. source_ref: "Q3E/src/main/jni/zdoom/src/version.h:110, Q3E/src/main/jni/zdoom/src/common/audio/music/music_config.cpp:119, Q3E/src/main/jni/zdoom/src/common/audio/music/i_soundfont.cpp:335-370, 458-468" @@ -282,7 +282,7 @@ files: description: "ECWolf engine resource archive" note: >- Named by MAIN_PK3 and passed to the game selector with the program - directory (Q3E/src/main/jni/ecwolf/src/wl_main.cpp:1294-1307); failing + directory (Q3E/src/main/jni/ecwolf/src/wl_main.cpp:1294-1307). Failing to open it ends the process with "Could not open ecwolf.pk3!". It holds the IWADINFO rules that identify which Wolfenstein data set is present, the palettes and the actor definitions. This build reads it from disk after extraction, unlike the libretro core which @@ -343,7 +343,7 @@ files: note: >- Unpacked into the ETQW base folder. The name sorts last so the entries override the ones the retail archives carry. ETQW_GLSL_SHADER_VERSION - names the set the build expects and reads .6 here; the .3 pack it + names the set the build expects and reads .6 here. The .3 pack it replaced is kept as a variant for older builds. source_ref: "Q3E/src/main/java/com/n0n3m4/q3e/Q3EPatchResourceManager.java:208-217, Q3E/src/main/java/com/n0n3m4/q3e/Q3EGameHelper.java:790-809, Q3E/src/main/java/com/n0n3m4/q3e/Q3EGameConstants.java:400" @@ -357,7 +357,7 @@ files: sha1: f156945f70545e37fb5ee33a95ee97204a7f60b7 description: "ET: Legacy mod archive matching the built engine" note: >- - Copied into the `legacy` folder, the mod the engine runs by default; the + Copied into the `legacy` folder, the mod the engine runs by default. The retail Enemy Territory data in `etmain` stays the user's to supply. The file name is built from the engine version, so a Legacy update lands under a new name. @@ -475,8 +475,8 @@ files: note: >- Read in place from the assets, never extracted. Archives with this suffix are folded into the search path wherever they are found, and the - `controls_theme/` folders inside become named entries in the theme chooser; - this one carries the cs16-client and source-engine sets. + `controls_theme/` folders inside become named entries in the theme chooser. + This one carries the cs16-client and source-engine sets. source_ref: "Q3E/src/main/java/com/n0n3m4/q3e/Q3EGlobals.java:230, Q3E/src/main/java/com/n0n3m4/q3e/karin/KFDManager.java:44, 102, 113-129, Q3E/src/main/java/com/n0n3m4/q3e/karin/KFileDescriptor.java:56, 102" - name: btn_jump.png @@ -513,7 +513,7 @@ files: writes for itself, DoomConfig.cfg, Quake4Config.cfg, preyconfig.cfg, q3config.cfg, wolfconfig.cfg, Darkmod.cfg, uzdoom.ini and the rest, and opens any of them in its editor. The config files are written by the - engines; this one only ever comes from the user. + engines, but this one only ever comes from the user. source_ref: "Q3E/src/main/java/com/n0n3m4/q3e/Q3EInterface.java:722-836, Q3E/src/main/java/com/n0n3m4/q3e/Q3EGameConstants.java:63-88, idTech4Amm/src/main/java/com/karin/idTech4Amm/ConfigEditorActivity.java:103" - name: description.txt @@ -536,7 +536,7 @@ files: while the game controller subsystem starts, after the compiled-in mappings and before the ones the environment carries. It reaches the six games the app runs on SDL, Xash3D, Source, ECWolf, Skin Deep, Quadrilateral Cowboy - and Icarus; the other engines take input from the Q3E frontend instead. The + and Icarus. The other engines take input from the Q3E frontend instead. The SDL2 tree under deplibs is what the build compiles, version 2.32.5. source_ref: "Q3E/src/main/jni/deplibs/SDL2/src/joystick/SDL_gamecontroller.c:1873-1884, 1890-1916, Q3E/src/main/jni/deplibs/SDL2/include/SDL_version.h:59-61, Q3E/src/main/jni/CMakeLists.txt:90-102, Q3E/src/main/java/com/n0n3m4/q3e/Q3EGameConstants.java:430, 454-461" @@ -649,7 +649,7 @@ exclusion_note: > the DOOM engine accepts as an IWAD, read from `iwadinfo.txt` in `game_support.pk3`, the four the launcher offers as selectable UZDOOM data files, and the five extensions ECWolf reports when no Wolfenstein data is - found; all of them are game content, held here the same way the PrBoom and + found. All of them are game content, held here the same way the PrBoom and boom3 profiles hold theirs, in the notes. `stdout.txt` and `stderr.txt` are opened for writing by the engine and read back only to show the last run log, and an `idtech4amm.version` stamp is written beside each extracted resource. diff --git a/emulators/ikemen.yml b/emulators/ikemen.yml index beaf21d2..2eb814ce 100644 --- a/emulators/ikemen.yml +++ b/emulators/ikemen.yml @@ -16,7 +16,7 @@ notes: | .def, .air, .cmd, .cns, .sff and .snd files of M.U.G.E.N. content, plus its own .zss state files. - Every file is read relative to the working directory; paths below are + Every file is read relative to the working directory. Paths below are written under ikemen/, which stands for it. The file names come from the embedded default configuration, src/resources/defaultConfig.ini, which save/config.ini overrides (src/main.go:189-195). @@ -216,7 +216,7 @@ files: source_ref: "font/debug.def:19, src/util_desktop.go:29-40" note: > When the file is not found, the same name is searched in the system - font directories; the engine panics when that fails too. + font directories, and the engine panics when that fails too. - name: "default-3x5.def" path: "ikemen/font/default-3x5.def" @@ -306,7 +306,7 @@ files: required: true bundled: true source_ref: "src/fightscreen.go:4916-4926" - note: "Named by the sff key of fight.def; a load failure fails loadFightScreen." + note: "Named by the sff key of fight.def. A load failure fails loadFightScreen." - name: "fight.snd" path: "ikemen/data/fight.snd" @@ -315,7 +315,7 @@ files: required: true bundled: true source_ref: "src/fightscreen.go:4927-4937" - note: "Named by the snd key of fight.def; a load failure fails loadFightScreen." + note: "Named by the snd key of fight.def. A load failure fails loadFightScreen." - name: "fightfx.sff" path: "ikemen/data/fightfx.sff" @@ -324,7 +324,7 @@ files: required: true bundled: true source_ref: "src/fightscreen.go:4938-4948" - note: "Named by the fightfx.sff key of fight.def; a load failure fails loadFightScreen." + note: "Named by the fightfx.sff key of fight.def. A load failure fails loadFightScreen." - name: "fightfx.air" path: "ikemen/data/fightfx.air" @@ -333,7 +333,7 @@ files: required: true bundled: true source_ref: "src/fightscreen.go:4949-4959" - note: "Named by the fightfx.air key of fight.def; a load failure fails loadFightScreen." + note: "Named by the fightfx.air key of fight.def. A load failure fails loadFightScreen." - name: "common.snd" path: "ikemen/data/common.snd" @@ -342,7 +342,7 @@ files: required: true bundled: true source_ref: "src/fightscreen.go:4960-4966" - note: "Named by the common.snd key of fight.def; a load failure fails loadFightScreen." + note: "Named by the common.snd key of fight.def. A load failure fails loadFightScreen." - name: "system.snd" path: "ikemen/data/system.snd" @@ -381,7 +381,7 @@ files: bundled: true source_ref: "src/stage.go:204-212" note: > - A background element of type video names its file in path; video/ is + A background element of type video names its file in path, and video/ is the default directory of the lookup. - name: "gamecontrollerdb.txt" diff --git a/emulators/ines.yml b/emulators/ines.yml index 5b87518f..c1ae2688 100644 --- a/emulators/ines.yml +++ b/emulators/ines.yml @@ -20,12 +20,12 @@ notes: | author publishes himself, package com.fms.ines versionName 6.1.4 versionCode 6104, apk md5 d0e1b93b09d4b58294efd4e1509e25ca, signed CN=Marat Fayzullin O=Garage Research issued 2011, sha256 - d09469e9b550cbc9005d3bd089f3df5f0ba89cba71cdd3b33736a0382d6f9848; the two + d09469e9b550cbc9005d3bd089f3df5f0ba89cba71cdd3b33736a0382d6f9848. The two download paths on that site serve the same bytes. Google Play carries the emulator as com.fms.ines.free, the package ES-DE launches, and inside VGBAnext as com.fms.ng, the author recording that Play removed the original com.fms.ines listing over its built-in cheats. The native libraries keep their symbol - tables, so the readings below cite libmain.so offsets in the x86_64 slice; the + tables, so the readings below cite libmain.so offsets in the x86_64 slice, and the arm64-v8a, armeabi-v7a, armeabi and x86 slices carry the same filename set. The free iNES 6.1 builds for Windows and Ubuntu were read beside it and open the same files under the same names. No source has ever been published: the author @@ -90,7 +90,7 @@ files: min_size: 8192 validation: [size] description: "Famicom Disk System BIOS" - note: "Opened by bare name, so it resolves against the working directory and then against the home directory. Read as 0x2000 bytes into RAM at 0xE000; a missing file reports NOT FOUND and a short read FAILED, and either aborts the disk load. Only the length of that read is checked, so a longer file passes on its first 8192 bytes and no hash is compared. The open is gzip transparent, so a compressed copy answers too." + note: "Opened by bare name, so it resolves against the working directory and then against the home directory. Read as 0x2000 bytes into RAM at 0xE000. A missing file reports NOT FOUND and a short read FAILED, and either aborts the disk load. Only the length of that read is checked, so a longer file passes on its first 8192 bytes and no hash is compared. The open is gzip transparent, so a compressed copy answers too." source_ref: "libmain.so LoadFDS 0x3bdd0-0x3c245 (open 0x3bf97, read 0x3bfc5-0x3bff7), iNES61-Ubuntu-x86-bin ines 0x38165-0x381a9" - name: iNES.pal @@ -129,7 +129,7 @@ files: category: game_data size: 27447 description: "cheat database read by the Cheatopedia browser" - note: "Looked up in the package assets first, then through the home directory, its subdirectories and Downloads, with <HomeDir>/Cheats as the default cheat directory. Include lines pull further sets through the same lookup; the package carries seven of them, battle-toads, dragon-warrior, dragon-warrior-2, fceu, final-fantasy-2, final-fantasy-3 and super-mario-brothers." + note: "Looked up in the package assets first, then through the home directory, its subdirectories and Downloads, with <HomeDir>/Cheats as the default cheat directory. Include lines pull further sets through the same lookup. The package carries seven of them: battle-toads, dragon-warrior, dragon-warrior-2, fceu, final-fantasy-2, final-fantasy-3 and super-mario-brothers." source_ref: "Cheatopedia.java:339, 448, 505-520, CheatHelper.java:14-24" - name: "<game>.ips" @@ -165,7 +165,7 @@ exclusion_note: > system provides, dlopen'd by name from InitAudio and the only other literal filename in the binary. The twenty palettes under Palettes/ in the Windows and Ubuntu distributions are left out as the shipped candidates for iNES.pal, which - the emulator never opens under those names; four of them are the VS System + the emulator never opens under those names. Four of them are the VS System chip palettes, RP2C04-001, RP2C04-002, RP2C04-003 and RP2C05-004, and they reach the emulator through the palette entries above rather than a path of their own. Neither the VS System nor the FamilyBASIC keyboards need a file: diff --git a/emulators/infinity.yml b/emulators/infinity.yml index 7dce5829..5f66d096 100644 --- a/emulators/infinity.yml +++ b/emulators/infinity.yml @@ -60,7 +60,7 @@ notes: | reads SPIR-V modules from the application assets instead, one vertex module plus one fragment module chosen by the display filter. Version 501 ships no shader asset at all, version 404 ships the four listed below, and both libraries name - them; the loader takes no null check between AAssetManager_open and + them, and the loader takes no null check between AAssetManager_open and AAsset_getLength. The manifest requires only abi and density splits, so no asset pack can deliver them separately. ref: vh.java:381 graphics_backend default 0, vh.java:297 display_filter default 0, diff --git a/emulators/ioquake3.yml b/emulators/ioquake3.yml index fe248277..429997b7 100644 --- a/emulators/ioquake3.yml +++ b/emulators/ioquake3.yml @@ -20,7 +20,7 @@ notes: | Loaded paks are matched against hardcoded unsigned 32-bit checksums (code/qcommon/files.c:178-198: pak_checksums[], missionpak_checksums[]). - These are NOT MD5 / SHA1 / CRC32 of the file; they are id's own custom + These are NOT MD5 / SHA1 / CRC32 of the file. They are id's own custom pak checksum (sum of each lump CRC, see FS_LoadZipFile). A mismatch prints "WARNING: baseq3/pak0.pk3 is present but its checksum (%u) is not correct" (code/qcommon/files.c:3574) and keeps running: the loader @@ -53,7 +53,7 @@ files: required: true source_ref: "code/qcommon/files.c:180 (pak_checksums[0]=1566731103u), 3568 (per-index checksum compare), 3697 (fatal when a baseq3 pak is absent)" note: "Retail Quake III Arena base pak. Engine prints a warning on checksum mismatch, does not refuse the file." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak1.pk3" category: game_data @@ -122,7 +122,7 @@ files: path: "demoq3/pak0.pk3" required: false source_ref: "code/qcommon/files.c:178 (DEMO_PAK0_CHECKSUM=2985612116u), 3557-3562 (demoq3 pak0 checksum compare), 3661-3674 (accepted in place of baseq3/pak0.pk3)" - note: "Demo pak. Recognised only under demoq3/ and only with this checksum; the engine then prints a warning and counts baseq3/pak0.pk3 as found." + note: "Demo pak. Recognised only under demoq3/ and only with this checksum. The engine then prints a warning and counts baseq3/pak0.pk3 as found." # ================================================================ # Team Arena (missionpack/, 4 numbered paks) @@ -137,7 +137,7 @@ files: required: false source_ref: "code/qcommon/files.c:193 (missionpak_checksums[0]=2430342401u)" note: "Team Arena base pak. Required only when launching +set fs_game missionpack." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak1.pk3" category: game_data diff --git a/emulators/iortcw.yml b/emulators/iortcw.yml index 52fd76b1..e8e8cf00 100644 --- a/emulators/iortcw.yml +++ b/emulators/iortcw.yml @@ -25,7 +25,7 @@ notes: | ref: SP/code/qcommon/files.c:3842-3972, MP/code/qcommon/files.c:3836-3966 Single-player (SP/code/qcommon/files.c) then requires the four - point-release paks; a missing one is fatal, a wrong checksum only + point-release paks. A missing one is fatal, a wrong checksum only prints a warning: main/sp_pak1.pk3 five localized checksums (en/fr/gm/it/sp) main/sp_pak2.pk3 3033901371, or 285968110 for the German release @@ -58,8 +58,8 @@ files: path: "main/pak0.pk3" required: true source_ref: "SP/code/qcommon/files.c:183-185, 3865-3882, 3950-3967, MP/code/qcommon/files.c:194-196, 3859-3876, 3944-3961" - note: "RTCW retail base. Checksum 1886207346 in both builds; fatal when missing or when the checksum differs." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + note: "RTCW retail base. Checksum 1886207346 in both builds, fatal when missing or when the checksum differs." + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # main/ - single-player point-release paks @@ -71,7 +71,7 @@ files: path: "main/sp_pak1.pk3" required: true source_ref: "SP/code/qcommon/files.c:188, 196, 204, 212, 220, 3735-3767, 3806-3826" - note: "Single-player build: fatal when missing. One checksum per language (en/fr/gm/it/sp); a mismatch prints a warning." + note: "Single-player build: fatal when missing. One checksum per language (en/fr/gm/it/sp), and a mismatch prints a warning." - name: "sp_pak2.pk3" category: game_data diff --git a/emulators/iratajaguar.yml b/emulators/iratajaguar.yml index 347613af..0a5e3366 100644 --- a/emulators/iratajaguar.yml +++ b/emulators/iratajaguar.yml @@ -16,7 +16,7 @@ mode: standalone notes: | Atari Jaguar emulator for Android, the Android build of Maxim Grishin's Phoenix Emu Project. The native library is libphoenixcore.so and reports - PhoenixEmuProject core 2.8.21; the same core carries the author's desktop builds + PhoenixEmuProject core 2.8.21. The same core carries the author's desktop builds and his three other Android emulators, Real3DOPlayer, NumPadPlayer and GearMasterPlayer. The build read here is the free package the author publishes himself, IrataJaguar_free_1.0.7.zip holding app-release.apk md5 @@ -26,7 +26,7 @@ notes: | f268dda6844e4f6013731f7ec7adbbb89a22cf06c9753e85c184b889dc81a758. No source has been published. The Android slices are stripped, so the readings below were taken against the desktop 2.8.JAG build from the same site, which keeps its - symbol table, and each was confirmed against the Android x86_64 slice; the + symbol table, and each was confirmed against the Android x86_64 slice. The arm64-v8a, armeabi-v7a and x86 slices carry the same signature bytes at 0x9f7e8, 0x83988 and 0xba848. ref: app-release.apk META-INF/CERT.RSA, AndroidManifest.xml, @@ -39,7 +39,7 @@ notes: | rom, jag, cof and j64 and hands every candidate to the library, which caches what it found in configs.xml under the private storage path as Library/CARTRIDGE and Library/BIOS entries carrying path, size, fast-md5, md5 and sh1. Those hashes are - the cache key; nothing compares them against a known value. nameOfBios returns + the cache key, and nothing compares them against a known value. nameOfBios returns the single BIOS the library holds and the game list shows it as its first row, shifting the game indices by one. ref: MainActivity.java:257-273, 382-392, 447, 517, 99-100, 557-561, @@ -94,7 +94,7 @@ files: required: true validation: [signature] description: "Atari Jaguar boot ROM" - note: "The emulator spells no filename for it. Any file the directory scan reaches whose first twelve bytes are 00 00 00 00 00 E0 00 08 41 F9 00 F0 is taken as the BIOS, so more than one boot ROM revision answers; the name carried here is the catalogue name of the retail dump, crc32 FB731AAA, under the extension the BIOS data element declares. Read into a 1 MB window at 0xE00000 and byte swapped, and its first eight bytes are copied over DRAM 0 to give the 68000 its reset vector. A longer file is read up to that bound rather than rejected." + note: "The emulator spells no filename for it. Any file the directory scan reaches whose first twelve bytes are 00 00 00 00 00 E0 00 08 41 F9 00 F0 is taken as the BIOS, so more than one boot ROM revision answers. The name carried here is the catalogue name of the retail dump, crc32 FB731AAA, under the extension the BIOS data element declares. Read into a 1 MB window at 0xE00000 and byte swapped, and its first eight bytes are copied over DRAM 0 to give the 68000 its reset vector. A longer file is read up to that bound rather than rejected." source_ref: "dumpAdapterJaguarROM::dumpAdapterJaguarROM 0x8d3c20 (memcmp 0x8d4259-0x8d426f), bios_sign 0x99d7a0, platformJaguar::getConfig 0x8ce197-0x8ce209, platformJaguar::platformJaguar 0x8d0bc7-0x8d0c2e" exclusion_note: > diff --git a/emulators/irogb.yml b/emulators/irogb.yml index b8981878..96bc9d65 100644 --- a/emulators/irogb.yml +++ b/emulators/irogb.yml @@ -26,14 +26,14 @@ notes: | auto (the default) tries cgb_boot.bin then dmg_boot.bin, none opens nothing (src/frontend/libretro/libretro_host.cpp:86-113). Under auto a DMG cartridge boots through the CGB boot ROM whenever cgb_boot.bin is - present and gets the CGB colouring of monochrome games; the + present and gets the CGB colouring of monochrome games. The irogb_monochrome_dmg option turns that off. BootROM accepts a file of exactly 256 or 2304 bytes and rejects any other size (src/memory/boot.cpp:10-24). The size also picks the machine: a 2304-byte image starts in CGB mode (src/gbc.cpp:330-340). 256 bytes covers DMG, DMG0, MGB and SGB dumps, 2304 bytes CGB, CGB0, AGB0 and AGB - dumps (includes/memory/boot.hpp:9-30); only the two names above are + dumps (includes/memory/boot.hpp:9-30). Only the two names above are ever opened. No hash is checked. Without a boot ROM, or when the file fails to open or has another size, @@ -41,7 +41,7 @@ notes: | values, unmaps the boot ROM and sets CGB mode from the cartridge header (src/gbc.cpp:342-349, src/gbc.cpp:387-405, src/gbc.cpp:489-490). - The .info declares cgb_bios.bin; the code opens cgb_boot.bin. + The .info declares cgb_bios.bin, but the code opens cgb_boot.bin. files: - name: "dmg_boot.bin" diff --git a/emulators/jazz2-native.yml b/emulators/jazz2-native.yml index 63cbeb18..66eceeaa 100644 --- a/emulators/jazz2-native.yml +++ b/emulators/jazz2-native.yml @@ -368,7 +368,7 @@ files: standalone_path: "Source/boss2.j2b" required: false source_ref: "Sources/Jazz2/Compatibility/EventConverter.cpp:360-370, Sources/Jazz2/Compatibility/AssetConverter.cpp:505-508, Sources/Jazz2/LevelHandler.cpp:1397-1400, Sources/Jazz2/ContentResolver.cpp:2784-2788" - note: "Boss music. The boss activation event carries a music index that is converted to boss1.j2b or boss2.j2b and recorded as music the level uses; share3.j2l carries index 1." + note: "Boss music. The boss activation event carries a music index that is converted to boss1.j2b or boss2.j2b and recorded as music the level uses. share3.j2l carries index 1." # Cinematics, read from Content/Cinematics/ then from Source/ diff --git a/emulators/jl-mod.yml b/emulators/jl-mod.yml index 960761c8..62a60b87 100644 --- a/emulators/jl-mod.yml +++ b/emulators/jl-mod.yml @@ -254,7 +254,7 @@ files: unsourceable: "user supplied, no canonical file" category: game_data description: "DLS sound bank for MIDI playback" - note: "The config screen lists every regular file in the sound banks directory with no extension filter, and the selected name is kept as a path when the file exists. EAS_LoadDLSCollection reads it with the header search flag off; a rejected file throws and the plugin is skipped." + note: "The config screen lists every regular file in the sound banks directory with no extension filter, and the selected name is kept as a path when the file exists. EAS_LoadDLSCollection reads it with the header search flag off. A rejected file throws and the plugin is skipped." source_ref: "app/src/main/java/ru/playsoftware/j2meloader/config/ConfigActivity.java:318-337, app/src/main/java/javax/microedition/shell/MicroLoader.java:272-274, app/src/main/cpp/mmapi_eas/eas_player.cpp:112-126" - name: "<soundbank>.sf2" diff --git a/emulators/jollycv.yml b/emulators/jollycv.yml index ef970f75..c03afcaa 100644 --- a/emulators/jollycv.yml +++ b/emulators/jollycv.yml @@ -18,7 +18,7 @@ systems: notes: | JollyCV emulates the ColecoVision (with Super Game Module), the VTech CreatiVision and the Nichibutsu My Vision. The libretro port and the - Jolly Good build share the same src/ tree; only the front end differs. + Jolly Good build share the same src/ tree, and only the front end differs. The libretro port picks the system from the file name (libretro/libretro.c:670-679): ".myv" is My Vision, ".rom" and ".bin" @@ -35,14 +35,14 @@ notes: | jcv_coleco_bios_load or jcv_crvision_bios_load, which keep it only when the size is exactly SIZE_CVBIOS (8192) or SIZE_CRVBIOS (2048). The return value of that size check is dropped at src/jollycv.c:427, so a file of the - wrong size passes the loader while the BIOS pointer stays NULL; the first + wrong size passes the loader while the BIOS pointer stays NULL, and the first BIOS read (src/jcv_coleco.c:281-282, src/jcv_crvision.c:443-444) then dereferences it. A missing file fails retro_load_game. My Vision loads no BIOS (libretro/libretro.c:717-719). The Jolly Good build reads the same two names from the front end's BIOS path (jg.c:463-481) and declares them through jg_get_bioslist with an - MD5 each (jg.c:151-156). The core never compares those MD5; the reference + MD5 each (jg.c:151-156). The core never compares those MD5. The reference front end hashes the file against them for a debug log only (jgrf src/jgrf.c:441-458). The md5: fields below carry these values. @@ -60,7 +60,7 @@ files: md5: "2c66f5911e5b42b8ebe113403548eee7" validation: [size] source_ref: "libretro/libretro.c:697-703, src/jollycv.c:406-432, src/jcv_coleco.c:402-410, jg.c:151-153" - note: "Mapped at 0x0000-0x1FFF, replaced by the lower 8K of SGM RAM when the Super Game Module enables it. The MD5 is the value the JG bioslist declares; the core compares the size only." + note: "Mapped at 0x0000-0x1FFF, replaced by the lower 8K of SGM RAM when the Super Game Module enables it. The MD5 is the value the JG bioslist declares, and the core compares the size only." - name: "bioscv.rom" system: creativision @@ -70,7 +70,7 @@ files: md5: "3b1ef759d8e3fb4071582efd33dd05f9" validation: [size] source_ref: "libretro/libretro.c:707-713, src/jollycv.c:406-432, src/jcv_crvision.c:316-324, jg.c:154-155" - note: "Mapped at 0xF800-0xFFFF. The MD5 is the value the JG bioslist declares; the core compares the size only." + note: "Mapped at 0xF800-0xFFFF. The MD5 is the value the JG bioslist declares, and the core compares the size only." platform_details: colecovision: diff --git a/emulators/julius.yml b/emulators/julius.yml index 5fdb2c20..c978fa6b 100644 --- a/emulators/julius.yml +++ b/emulators/julius.yml @@ -15,10 +15,10 @@ systems: notes: | Open-source reimplementation of Impressions Games' Caesar III engine. It reads every graphic, text, sound and scenario from an installed copy - of the game; nothing is bundled. + of the game. Nothing is bundled. The data directory is the command-line argument. pre_init() makes it - the base path and runs game_pre_init(); a missing directory shows + the base path and runs game_pre_init(). A missing directory shows "Julius requires the original files from Caesar 3" and exits (ref: src/platform/julius.c:488-501, 580-586). File lookups are case-corrected inside that directory. @@ -29,7 +29,7 @@ notes: | climate graphics c3.sg2 and c3.555, the barbarian enemy graphics goths.sg2 and goths.555, and c3_model.txt (ref: src/game/game.c:79-104). Any of them missing aborts init. The_empire.555 is loaded with the - climate graphics; a wrong size is logged and the game continues + climate graphics. A wrong size is logged and the game continues (ref: src/core/image.c:283-293, 323). The other climates, enemies, sounds, videos and scenario maps are opened from the same directory on demand. @@ -46,7 +46,7 @@ files: required: true description: "Caesar III install directory" source_ref: "src/platform/julius.c:488-501" - note: "Given on the command line; every game file is opened by name inside it." + note: "Given on the command line. Every game file is opened by name inside it." - name: "c3.eng" path: "caesar3/c3.eng" system: "caesar3" @@ -62,7 +62,7 @@ files: required: true description: "Caesar III message text" source_ref: "src/core/lang.c:24, 129-150, 160-165" - note: "Loaded as a pair with c3.eng; c3_mm.rus replaces it on a Russian install." + note: "Loaded as a pair with c3.eng, and c3_mm.rus replaces it on a Russian install." - name: "c3.sg2" path: "caesar3/c3.sg2" system: "caesar3" diff --git a/emulators/kegs.yml b/emulators/kegs.yml index f16b82b8..1f0731af 100644 --- a/emulators/kegs.yml +++ b/emulators/kegs.yml @@ -31,7 +31,7 @@ notes: | g_rom_c700[] (config.c:463,1165-1169). Slot 6 gets a Disk II PROM rebuilt at load time, XORed out of the IIGS ROM through g_rom_c600_rom01_diffs[] (config.c:428,1177-1183) or copied from offset 0x600 of a //e ROM - (config.c:1172-1176); the IIGS control panel reaches it by setting slot 6 + (config.c:1172-1176). The IIGS control panel reaches it by setting slot 6 to "Your Card". Text uses g_font_array[] from kegsfont.h (video.c:272-273, prepared at sim65816.c:667). @@ -77,6 +77,6 @@ files: source_ref: "config.c:136-137,259-276,1070-1093" note: > Picked through the F4 config panel, which stores the path in - g_cfg_charrom_path; there is no default name. KEGS reads 4096 bytes at + g_cfg_charrom_path, and there is no default name. KEGS reads 4096 bytes at 0x1000 times the selected font number and replaces the built-in text font with them. The 32 fonts it lists span a 131072-byte image. diff --git a/emulators/kemulator.yml b/emulators/kemulator.yml index c7cdf47d..a17a1617 100644 --- a/emulators/kemulator.yml +++ b/emulators/kemulator.yml @@ -41,7 +41,7 @@ notes: | x64/src/main/emulator/EmulatorPlatform.java:9-11 Every caller degrades when the probe fails. PlayerImpl.midi() breaks out of the - ma block and falls back to MidiSystem; PlayerImpl.mmf(), SmafPlayer, AudioClip + ma block and falls back to MidiSystem. PlayerImpl.mmf(), SmafPlayer, AudioClip and PhrasePlayerImpl each throw and lose SMAF audio alone. Only the file's existence is tested, then the path goes to Native.load, so the code reads no size and no hash. @@ -77,7 +77,7 @@ files: required: false validation: [existence] description: "Yamaha MA-7 SMAF hardware layer" - note: "Tested for existence next to M7_EmuSmw7.dll; the MA-7 branch is skipped unless both are present. Loaded by the Windows loader as a dependency of the sequencer library, which is the path handed to Native.load." + note: "Tested for existence next to M7_EmuSmw7.dll, and the MA-7 branch is skipped unless both are present. Loaded by the Windows loader as a dependency of the sequencer library, which is the path handed to Native.load." source_ref: "src/media/emulator/media/mmf/MMFPlayer.java:21" - name: M5_EmuSmw5.dll @@ -93,7 +93,7 @@ files: required: false validation: [existence] description: "Yamaha MA-5 SMAF hardware layer" - note: "Tested for existence next to M5_EmuSmw5.dll; the MA-5 branch is skipped unless both are present." + note: "Tested for existence next to M5_EmuSmw5.dll, and the MA-5 branch is skipped unless both are present." source_ref: "src/media/emulator/media/mmf/MMFPlayer.java:25" - name: ma3smwemu.dll @@ -141,7 +141,7 @@ files: sha1: f59e0d445aafe2503c6e5249ca07df4b89626f8f validation: [existence] description: "Mascot Capsule V3 renderer" - note: "Pulled in by the Windows loader when java_micro3d_v3_32.dll loads; no Java code names it." + note: "Pulled in by the Windows loader when java_micro3d_v3_32.dll loads. No Java code names it." source_ref: "micro3d_dll/src/com/mascotcapsule/micro3d/v3/Figure.java:163" - name: s60snr.ttf @@ -181,5 +181,5 @@ files: category: game_data validation: [existence] description: "UI strings, English" - note: "Read from the lang directory next to the executable at startup and kept as the fallback bundle; the language setting names a sibling in the same directory. Every lookup that misses both bundles falls back to the string built into the call site." + note: "Read from the lang directory next to the executable at startup and kept as the fallback bundle, and the language setting names a sibling in the same directory. Every lookup that misses both bundles falls back to the string built into the call site." source_ref: "src/main/emulator/UILocale.java:11-48" diff --git a/emulators/kenji-nx.yml b/emulators/kenji-nx.yml index d60fd020..efb8975f 100644 --- a/emulators/kenji-nx.yml +++ b/emulators/kenji-nx.yml @@ -52,7 +52,7 @@ notes: | Two read paths belong to the desktop build alone, because the Android build drops LibKenjinx.Native.cs and wires those subsystems differently. SDL_GameControllerDB.txt is read by SDL3Driver, whose only callers are the - SDL3 audio, gamepad and keyboard drivers; on Android JnaDeviceInitialize + SDL3 audio, gamepad and keyboard drivers. On Android JnaDeviceInitialize builds an OpenALHardwareDeviceDriver and InitializeInput builds a VirtualGamepadDriver, so SDL3 never initialises. Amiibo diverge the same way: the desktop scan decrypts a dump through AmiiboBinReader and therefore needs @@ -93,7 +93,7 @@ files: reader, but an empty header key stops NCA header decryption outright and no encrypted content loads. The desktop importer accepts a .keys file or a zip of them and rejects any line that is not "name = value" in lowercase - hexadecimal; the Android importer accepts the name prod.keys only and + hexadecimal. The Android importer accepts the name prod.keys only and copies it straight into the system directory. source_ref: "src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs:231-266, src/Ryujinx.HLE/FileSystem/ContentManager.cs:500-537,681-684,1082-1118, src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/viewmodels/SettingsViewModel.kt:254-301" @@ -135,7 +135,7 @@ files: note: >- Chosen through a file picker and read whole at install time, by path on desktop and by file descriptor on Android. A zip is walked entry by entry - and an xci is opened at its update partition; a directory of NCAs is also + and an xci is opened at its update partition. A directory of NCAs is also accepted on desktop. Each NCA is decrypted with the key set to read its title id and content type, the package is rejected when it carries archives that belong to no system title, and the version string comes out @@ -156,7 +156,7 @@ files: HMAC key, a 14-byte type string, a reserved byte, a magic size byte, 16 magic bytes and a 32-byte XOR pad. Any total other than 160 bytes throws and the scan fails. The desktop window hides its amiibo-from-dump entry - when the file is absent. Only the desktop scan path decrypts a dump; the + when the file is absent. Only the desktop scan path decrypts a dump. The Android slots hand the raw bytes to the tag buffer instead. source_ref: "src/Ryujinx.HLE/HOS/Services/Nfc/AmiiboDecryption/AmiiboBinReader.cs:22-44,331-336, src/Ryujinx.HLE/HOS/Services/Nfc/AmiiboDecryption/AmiiboDecryptor.cs:10-16, src/Ryujinx.HLE/HOS/Services/Nfc/AmiiboDecryption/AmiiboMasterKey.cs:15-39, src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs:385,2243" @@ -206,7 +206,7 @@ files: Imported through a picker filtered on application/zip and unpacked into a folder named after the archive under drivers in the data root. A folder is offered only when it holds a meta.json naming a libraryName that resolves - to a file present beside it; the chosen path is remembered in a file named + to a file present beside it, and the chosen path is remembered in a file named selected. At renderer start the folder is copied into internal storage, because the external filesystem cannot carry an executable mapping, loaded through the rootless Adreno driver loader, and the resulting handle is diff --git a/emulators/kronos.yml b/emulators/kronos.yml index b07e2509..69497107 100644 --- a/emulators/kronos.yml +++ b/emulators/kronos.yml @@ -37,7 +37,7 @@ notes: | STV blob table: BiosList at yabause/src/ctrl/src/stv.c:112-136. ROM cartridge DB: yabause/src/utils/src/db.c:43-45. - Standalone supports MPEG card ROM loading (Video CD card); disabled in + Standalone supports MPEG card ROM loading (Video CD card). Disabled in libretro port (mpegpath = NULL in yabause/src/libretro/libretro.c:1578). archive_prefix: kronos @@ -160,7 +160,7 @@ files: system: sega-stv region: [europe] required: false - note: "Loaded only when the set allows STV_REGION_EU; among allowed regions the kronos_stv_favorite_region option, Europe by default, picks (yabause/src/ctrl/src/stv.c:2435, 2562-2564)." + note: "Loaded only when the set allows STV_REGION_EU. Among allowed regions the kronos_stv_favorite_region option, Europe by default, picks (yabause/src/ctrl/src/stv.c:2435, 2562-2564)." size: 524288 crc32: "f7722da3" validation: [crc32] diff --git a/emulators/lime3ds.yml b/emulators/lime3ds.yml index 65bb6fcf..7cfe2e44 100644 --- a/emulators/lime3ds.yml +++ b/emulators/lime3ds.yml @@ -75,14 +75,14 @@ files: system: nintendo-3ds required: false hle_fallback: true - note: "legacy path, tried after the shared font system archive; decompressed BCFNT with the 0x80 byte APT header" + note: "legacy path, tried after the shared font system archive. It is a decompressed BCFNT with the 0x80 byte APT header" source_ref: "src/core/hle/service/apt/apt.cpp:254-270, src/core/hle/service/apt/apt.cpp:276-291" - name: seeddb.bin path: sysdata/seeddb.bin system: nintendo-3ds required: false - note: "game seed database for 9.6+ titles; an empty database is written when the file is absent" + note: "game seed database for 9.6+ titles. An empty database is written when the file is absent" source_ref: "src/core/file_sys/seed_db.cpp:12-58" - name: CTCert.bin @@ -91,7 +91,7 @@ files: required: false size: 384 validation: [size] - note: "console client certificate; signature type must be 0x010005 and the issuer one of the two Nintendo CA G3 strings. The certificate here is assembled from a console OTP: signature and expiry read at 0x44 and 0x20, public key derived from the private key at 0x24 over sect233r1, and the whole body checked against Nintendo's root public key" + note: "console client certificate. Signature type must be 0x010005 and the issuer one of the two Nintendo CA G3 strings. The certificate here is assembled from a console OTP: signature and expiry read at 0x44 and 0x20, public key derived from the private key at 0x24 over sect233r1, and the whole body checked against Nintendo's root public key" source_ref: "src/core/hle/service/am/am.cpp:2427-2454, src/core/hle/service/am/am.cpp:83-93, src/core/hle/service/am/am.h:95" - name: SecureInfo_A @@ -100,7 +100,7 @@ files: required: false size: 273 validation: [size] - note: "console region and serial number; loaded on a size check alone" + note: "console region and serial number, loaded on a size check alone" source_ref: "src/core/hle/service/cfg/cfg.cpp:608-610, 689-709, src/core/hle/service/cfg/cfg.h:180-186" - name: LocalFriendCodeSeed_B @@ -109,5 +109,5 @@ files: required: false size: 272 validation: [size] - note: "friend code generation seed; loaded on a size check alone" + note: "friend code generation seed, loaded on a size check alone" source_ref: "src/core/hle/service/cfg/cfg.cpp:604-606, 711-732, src/core/hle/service/cfg/cfg.h:188-193" diff --git a/emulators/linapple.yml b/emulators/linapple.yml index ab181426..f3030ba2 100644 --- a/emulators/linapple.yml +++ b/emulators/linapple.yml @@ -49,7 +49,7 @@ notes: | (src/frontends/common/AppController.cpp:127-171,251-253). mem_initialize accepts the buffer at exactly 16384 or 12288 bytes, or larger, taking the trailing 16384 for the //e-class types and the trailing 12288 otherwise - (src/apple2/Memory.cpp:1038-1059). No hash or name is checked; the file is + (src/apple2/Memory.cpp:1038-1059). No hash or name is checked: the file is whatever the user points at. Character generators are res/charset40*.png, converted to XPM by CMake @@ -74,7 +74,7 @@ notes: | assigned, so the names resolve against the working directory. g_file_name_symbols lists nine tables (src/Debugger/Debugger_Symbols.cpp:37-48). CmdSymbolsLoad reads a table's default file when it receives no argument - (src/Debugger/Debugger_Symbols.cpp:636-652); its only caller is the LOAD + (src/Debugger/Debugger_Symbols.cpp:636-652). Its only caller is the LOAD parameter of the SYM commands (src/Debugger/Debugger_Symbols.cpp:817-819), and debug_initialize loads no table (src/Debugger/Debug.cpp:29-37). ParseSymbolTable opens the file with fopen and a missing one leaves the @@ -141,7 +141,7 @@ files: # ENABLE_ROM_CLONE_PRAVETS and ENABLE_ROM_CLONE_TK3000E are OFF in # CMakeLists.txt:95-97, so these machine types refuse to start unless the # user passes the image with --rom. The names are the ones upstream gives - # the images in res/roms; the option takes a path and checks no name. + # the images in res/roms. The option takes a path and checks no name. - name: Base64A.rom required: false description: "Copam Base 64A clone system ROM, supplied with --rom" @@ -316,7 +316,7 @@ analysis: video_roms: note: > Compiled in under the macro of their machine. No source file reads - the symbols; the display uses the character_generators below. + the symbols. The display uses the character_generators below. images: - symbol: g_rom_apple2_video image: res/roms/Apple2_Video.rom @@ -387,7 +387,7 @@ analysis: size: 256 md5: 4f80448507cf43ab40c17ac08d89e278 sha1: afd060e6f35faf3bb0146fa889fc787adf56330a - note: "Compiled in; no source file reads the symbol" + note: "Compiled in. No source file reads the symbol" - device: "Super Serial Card" slot: 2 @@ -401,7 +401,7 @@ analysis: Not generated and behind no cmake option: the card carries the 2048 bytes as an array in SuperSerialRom.h, the last page mapped at $Cn00 and the whole image at $C800. The generator does not read - res/roms/SSC.rom; a build test pins its SHA-1 as the reference of + res/roms/SSC.rom. A build test pins its SHA-1 as the reference of that transcription. - device: "Mouse interface card" @@ -426,7 +426,7 @@ analysis: note: > Not generated and behind no cmake option: the card carries the 256 bytes as an array in Printer.cpp. The generator does not read - res/roms/Parallel.rom; a build test pins its SHA-1 as the reference + res/roms/Parallel.rom. A build test pins its SHA-1 as the reference of that transcription. - device: "Clock card" @@ -482,7 +482,7 @@ analysis: - A2_DOS33.SYM - A2_PRODOS.SYM note: > - Each table is read by the LOAD parameter of its SYM command; no table is + Each table is read by the LOAD parameter of its SYM command, and no table is loaded when the debugger starts. Only APPLE2E.SYM and A2_BASIC.SYM are distributed with the emulator, in res/. The user slots and the remaining tables have no shipped counterpart. diff --git a/emulators/lindbergh-loader.yml b/emulators/lindbergh-loader.yml index ca6beae0..9b764c91 100644 --- a/emulators/lindbergh-loader.yml +++ b/emulators/lindbergh-loader.yml @@ -33,7 +33,7 @@ notes: | from constants and recomputes the CRCs (eeprom.c:33-48, baseBoard.c:60-74, eepromSettings.c:24-120). Card_01.crd and Card_02.crd are written from a 56-byte header held in the binary (cardReader.c:227-247). lindbergh.ini and - controls.ini are optional; both fall back to compiled-in defaults and can be + controls.ini are optional: both fall back to compiled-in defaults and can be emitted with --create (config.c:510-516, src/lindbergh/sdlInput.c:790-795). The one hard external dependency is the NVIDIA Cg runtime. findLibCg() checks @@ -74,8 +74,8 @@ files: note: >- Searched at LIBCG_PATH, /app/lib32/libCg2.so, $APP_IMG_ROOT/usr/lib32/ libCg2.so, then ./libCg.so and $LINDBERGH_LOADER_CURRENT_DIR/libCg.so. The - loader reads 8 bytes at offset 0x226d84 and requires exactly "2.0.0.12"; - a missing file, a different version string or a failed dlopen of + loader reads 8 bytes at offset 0x226d84 and requires exactly "2.0.0.12". + A missing file, a different version string or a failed dlopen of cgCreateContext, cgCreateProgram, cgGetProgramString, cgDestroyContext or cgDestroyProgram each call exit(EXIT_FAILURE). Upstream vendors the build as libs/libCg.so and both installers rename it to libCg2.so so it can sit @@ -199,7 +199,7 @@ files: The .abc is the metrics sidecar of the .tga atlas, named for the GDI ABC width triple. Header of 28 bytes: renderOffset, renderHeight, atlas width, atlas height, lineHeight, then firstSymbol and lastSymbol - as uint16 and a uint32 symbol count; then one 24-byte record per glyph, + as uint16 and a uint32 symbol count, then one 24-byte record per glyph: four float32 giving the normalised UV rectangle followed by leftMargin, width, rightMargin and a pad as uint16. Field names come from JayFoxRox/lindbergh-tools Utilities/src/font.c, written against a real @@ -225,7 +225,7 @@ files: The .abc is the metrics sidecar of the .tga atlas, named for the GDI ABC width triple. Header of 28 bytes: renderOffset, renderHeight, atlas width, atlas height, lineHeight, then firstSymbol and lastSymbol - as uint16 and a uint32 symbol count; then one 24-byte record per glyph, + as uint16 and a uint32 symbol count, then one 24-byte record per glyph: four float32 giving the normalised UV rectangle followed by leftMargin, width, rightMargin and a pad as uint16. Field names come from JayFoxRox/lindbergh-tools Utilities/src/font.c, written against a real @@ -252,7 +252,7 @@ files: The .abc is the metrics sidecar of the .tga atlas, named for the GDI ABC width triple. Header of 28 bytes: renderOffset, renderHeight, atlas width, atlas height, lineHeight, then firstSymbol and lastSymbol - as uint16 and a uint32 symbol count; then one 24-byte record per glyph, + as uint16 and a uint32 symbol count, then one 24-byte record per glyph: four float32 giving the normalised UV rectangle followed by leftMargin, width, rightMargin and a pad as uint16. Field names come from JayFoxRox/lindbergh-tools Utilities/src/font.c, written against a real @@ -280,7 +280,7 @@ files: The .abc is the metrics sidecar of the .tga atlas, named for the GDI ABC width triple. Header of 28 bytes: renderOffset, renderHeight, atlas width, atlas height, lineHeight, then firstSymbol and lastSymbol - as uint16 and a uint32 symbol count; then one 24-byte record per glyph, + as uint16 and a uint32 symbol count, then one 24-byte record per glyph: four float32 giving the normalised UV rectangle followed by leftMargin, width, rightMargin and a pad as uint16. Field names come from JayFoxRox/lindbergh-tools Utilities/src/font.c, written against a real @@ -307,7 +307,7 @@ files: was pushed from a developer host onto development units, and a stock production machine ships none. note: >- - An INI file read by Sega's boot programs, not by the games; the + An INI file read by Sega's boot programs, not by the games. The per-title <id>rc files that do ship in game dumps are xinit client scripts, a different thing. lxmaster (Sep 2005 and Jan 2008 builds) reads [develop], [terminal] and [segaboot], and from the 2008 build diff --git a/emulators/linkboy.yml b/emulators/linkboy.yml index 740e1a65..741647db 100644 --- a/emulators/linkboy.yml +++ b/emulators/linkboy.yml @@ -25,8 +25,8 @@ notes: | 83b92276d28d71e491ebcbec3fa85cef42ef49d8ee0c6fd1bbe0045bc118f866) and 1.4.2 (versionCode 12), both carrying the app signing certificate sha256 feb643cfdd9c49f58eb325fde3d869cefcf59e45dfadb8e540beca35a7b1c28e and the Play - distribution source stamp. Emulation lives in liblinkboy.so behind a JNI bridge; - addresses below are armeabi-v7a of 3.11.0 and class names are those of its + distribution source stamp. Emulation lives in liblinkboy.so behind a JNI bridge. + Addresses below are armeabi-v7a of 3.11.0 and class names are those of its obfuscated dex. Four subsystems are declared: GBA, GBC, GB and SGB (ve0.java:16-21). An SGB @@ -44,7 +44,7 @@ notes: | firmware/ and the name to the directory handed to setDataDir, the app's external files directory (c51.java:69, hg3.java:32-38), and opens the result with fopen "rb". A file whose length is not exactly the expected size is closed and treated as - absent, as is a short read; on success the loader returns the crc32 of the bytes + absent, as is a short read. On success the loader returns the crc32 of the bytes (liblinkboy.so 0x1c870-0x1ca10, crc32 at 0x1c4cc). A missing image stops nothing. The GBA path copies a replacement bios compiled into diff --git a/emulators/lrps2.yml b/emulators/lrps2.yml index baee9ab5..5154beed 100644 --- a/emulators/lrps2.yml +++ b/emulators/lrps2.yml @@ -21,7 +21,7 @@ resources_directory: "pcsx2/resources/" notes: | pcsx2/resources/GameIndex.yaml, the per-game patch, settings override and compatibility database, is the one the buildbot publishes in LRPS2.zip (the - lrps2 data directory). An OSD warning is shown if it is missing; some games + lrps2 data directory). An OSD warning is shown if it is missing, and some games do not boot without it. Hard fork of PCSX2 (pre-Qt, 1.7-dev era) ported to libretro. x86_64 only. BIOS detection is filename-agnostic: scans pcsx2/bios/ for any file between 4-8 MB diff --git a/emulators/lynx-emu.yml b/emulators/lynx-emu.yml index 3963ab89..eefcc55a 100644 --- a/emulators/lynx-emu.yml +++ b/emulators/lynx-emu.yml @@ -25,12 +25,12 @@ notes: | (Lynx.emu/metadata/conf.mk:8, Lynx.emu/src/main/AppMeta.cc:26) and driven by the app's own video, audio and input layers. The vendored copy declares Mednafen 1.32.0-UNSTABLE - (EmuFramework/include/shared/mednafen/mednafen-config.h:167); the upstream + (EmuFramework/include/shared/mednafen/mednafen-config.h:167). The upstream comparisons below are against the 1.32.1 release. Content is read from .lnx, .lyx and .o files (Lynx.emu/metadata/conf.mk:5, Lynx.emu/src/main/AppMeta.cc:30), and the module also takes a headerless image of 128, 256 or 512 KB, a filetype upstream rejects - (Lynx.emu/src/lynx/system.cpp:90-91,112; mednafen src/lynx/system.cpp:86-93). + (Lynx.emu/src/lynx/system.cpp:90-91,112, mednafen src/lynx/system.cpp:86-93). The boot ROM is the one file the user supplies and it carries no name of its own. The picker takes any name ending in .img and stores the chosen URI in @@ -39,7 +39,7 @@ notes: | MDFN_MakeFName returns that URI for MDFNMKF_FIRMWARE and drops the lynxboot.img name the module hands it, the name upstream resolves in its firmware directory (Lynx.emu/src/main/options.cc:150-154, - Lynx.emu/src/lynx/system.cpp:103; mednafen src/lynx/system.cpp:101). CRom + Lynx.emu/src/lynx/system.cpp:103, mednafen src/lynx/system.cpp:101). CRom opens the file only when the path is not empty and throws unless it is exactly 512 bytes (Lynx.emu/src/lynx/rom.cpp:75-95). Upstream has neither test: it opens whatever the firmware directory yields and takes 512 bytes or more @@ -65,7 +65,7 @@ notes: | 245-264, Lynx.emu/src/lynx/system.cpp:313,319). The custom palette entry survives in the module table and reaches nothing: Lynx_SetPixelFormat passes an empty span where upstream Emulate passes espec->CustomPalette - (Lynx.emu/src/lynx/system.cpp:352,555,583; mednafen src/lynx/system.cpp: + (Lynx.emu/src/lynx/system.cpp:352,555,583, mednafen src/lynx/system.cpp: 267,298), the app calls MDFNGI::Load directly instead of going through the Mednafen frontend that reads .pal files (EmuFramework/src/shared/mednafen-emuex/MDFNUtils.hh:133-145, diff --git a/emulators/m64plus-fz.yml b/emulators/m64plus-fz.yml index 9ebf2a2c..5801acfe 100644 --- a/emulators/m64plus-fz.yml +++ b/emulators/m64plus-fz.yml @@ -27,7 +27,7 @@ notes: | (AppData.java:334-337, DataPrefsActivity.java:173-182, GamePrefsActivity.java:288-296), so the three packages want the same files. The repository default branch is a 2017 snapshot - of the parent project; the application is built from fz-master, which carries + of the parent project, while the application is built from fz-master, which carries mupen64plus-core, the hle, cxd4 and parallel RSP plugins, the GLideN64, glide64mk2, gln64, rice, angrylion-plus and parallel video plugins, its own audio, touchscreen and raphnet input plugins, and a miniupnp bridge for @@ -53,7 +53,7 @@ notes: | image sits in the slot is the one loaded. A disk is recognised only when its system data header matches and carries one of three region words, 0xe848d316 for Japan, 0x2263ee56 for the United States and 0x00000000 for development - (RomHeader.java:180-212); the word sets a country code used for the ROM + (RomHeader.java:180-212). The word sets a country code used for the ROM database and cheat lookup, never for picking the IPL. Launching a bare disk with the global slot empty stops before the core starts (CoreService.java:621-623), and since disk only games still need a cartridge @@ -76,10 +76,10 @@ notes: | the gallery (SplashActivity.java:447, ScanRomsFragment.java:195, GamePrefsActivity.java:244). mupencheat.default is copied over Profiles/customCheats.txt into mupencheat.txt and parsed in Java - (SplashActivity.java:443, CheatUtils.java:88-93, GamePrefsActivity.java:618); - the core's own cheat.c opens no file. font.ttf is reached by GLideN64 only + (SplashActivity.java:443, CheatUtils.java:88-93, GamePrefsActivity.java:618), + while the core's own cheat.c opens no file. font.ttf is reached by GLideN64 only after /system/fonts/DroidSans.ttf fails, which it does on current Android - (TextDrawer.cpp:201-233,235-241, NativeConfigFiles.java:292); the core's OSD, + (TextDrawer.cpp:201-233,235-241, NativeConfigFiles.java:292). The core's OSD, the other upstream reader of that name, is absent from the Android source list (mupen64plus-core.mk:24-101). RiceVideoLinux.ini holds rice's per ROM settings (rice Config.cpp:38,933-951), Glide64mk2.ini glide64mk2's @@ -115,7 +115,7 @@ notes: | NativeConfigFiles.java:109-112,276,289). One file in the tree this build never reads: cxd4's rsp_conf.bin. Its reader - is the zilmar variant of update_conf behind #if !defined(M64P_PLUGIN_API); the + is the zilmar variant of update_conf behind #if !defined(M64P_PLUGIN_API). The build defines that macro (mupen64plus-rsp-cxd4.mk:8), so the variant compiled takes its settings from the core config API and ignores the filename it is handed (mupen64plus-rsp-cxd4 module.c:83-93,239,637-659). @@ -133,7 +133,7 @@ files: document picker with no extension filter and the file is copied to dd_rom.n64 before the core sees it. The core reads it whole, then byteswaps after identifying the first word as one of 0x80270740 (z64), - 0x40072780 (n64) or 0x27804007 (v64); any other value logs an invalid IPL + 0x40072780 (n64) or 0x27804007 (v64). Any other value logs an invalid IPL and disables 64DD. Size is not checked and no hash is computed. source_ref: "app/src/main/java/paulscode/android/mupen64plusae/jni/CoreService.java:599-612,621-623, app/src/main/java/paulscode/android/mupen64plusae/jni/CoreInterface.java:455-484, app/src/main/java/paulscode/android/mupen64plusae/persistent/GlobalPrefs.java:417,715, mupen64plus-core/upstream/src/main/main.c:1080-1145" diff --git a/emulators/mame.yml b/emulators/mame.yml index eba742f6..f26bce6c 100644 --- a/emulators/mame.yml +++ b/emulators/mame.yml @@ -86,24 +86,24 @@ notes: | system_dir/mame/roms. Cheats via per-game XML files. BIOS root set names follow current MAME conventions. ZN-based boards - renamed from legacy names (cpzn1 → coh1000c, atpsx → coh1000a, etc.). + renamed from legacy names (cpzn1 to coh1000c, atpsx to coh1000a, etc.). File structure uses vendor-based paths (src/mame/{vendor}/). - TI-99/4A: 6 machines in ti99_4x.cpp — ti99_4 parent (TI-99/4 1979), + TI-99/4A: 6 machines in ti99_4x.cpp: ti99_4 parent (TI-99/4 1979), ti99_4e clone (Europe), ti99_4a parent (TI-99/4A 1981), ti99_4ae clone (Europe), ti99_4qi clone (QI version 1983), ti99_4ev clone (with EVPC 1994). 5 ROMs per parent set: 3 GROMs (u500-u502) + 2 CPU ROMs (u610-u611, 16-bit interleaved). Speech Synthesizer sidecar device (speechsyn.cpp) with 2 TMS6100 vocabulary ROMs. Software list "ti99_cart". Peripheral Expansion Box with optional device ROMs (FDC, - RS232, HFDC, P-Code, EVPC, etc.) — all PEB devices require user + RS232, HFDC, P-Code, EVPC, etc.). All PEB devices require user configuration, none loaded by default. VGMPlay: virtual driver (src/mame/virtual/vgmplay.cpp) for playing VGM - music files. Standalone MAME only — not included in libretro/mame build. + music files. Standalone MAME only, not included in libretro/mame build. Uses MAME sound chip devices (QSound, YM2413/OPLL, YM2608/OPNA, etc.). - V.Smile: 2 machines in vsmile.cpp — vsmile parent (V.Smile 2005), + V.Smile: 2 machines in vsmile.cpp: vsmile parent (V.Smile 2005), vsmilem clone (V.Smile Motion 2008). SunPlus SPG24x CPU, 3 BIOS alternatives (v100, v102, v103). Clone vsmilem has 2 alternate BIOSes. Software lists "vsmile_cart", "vsmilem_cart". vsmileb.cpp @@ -3987,7 +3987,7 @@ files: # Model I (trs80.cpp): trs80 (Level I, parent, WORKING), trs80l2 (Level II, parent), # eg3003 (EACA Video Genie, parent), sys80/sys80p (clones), ht1080z/ht1080z2/ht108064 (clones). # Model III/4/4P (trs80m3.cpp): trs80m3 (parent), trs80m4/trs80m4p/cp500 (clones). - # Z80-based home computers (1977-1983). Only trs80 (Level I) is MACHINE_SUPPORTS_SAVE; + # Z80-based home computers (1977-1983). Only trs80 (Level I) is MACHINE_SUPPORTS_SAVE, # all others MACHINE_NOT_WORKING. Software lists: trs80_cass, trs80_flop, trs80_quik. - name: trs80.zip required: true @@ -4206,7 +4206,7 @@ files: system: trs80 source_ref: "src/mame/trs/trs80m3.cpp:530-539" note: | - TRS-80 Model 4P (1983). Clone of trs80m3. Completely different memory map; + TRS-80 Model 4P (1983). Clone of trs80m3. Completely different memory map: Model III ROMs loaded from boot disk, only a bootloader ROM on board. 2 BIOS variants: gate array (default) and disk loader hack. MACHINE_NOT_WORKING. @@ -4331,7 +4331,7 @@ files: size: 8192 crc32: "b2f49eb3" - # Device ROMs — sound chip ROM data + # Device ROMs: sound chip ROM data - name: qsound.zip required: false category: bios_zip diff --git a/emulators/mame2000.yml b/emulators/mame2000.yml index 1dc2d170..e743efa0 100644 --- a/emulators/mame2000.yml +++ b/emulators/mame2000.yml @@ -40,7 +40,7 @@ files: source_ref: "src/hiscore.c:18,132-146,252-254" note: >- high score definitions, loaded from ROM directory. metadata/hiscore.dat - of the core repository; is_mem_range reads only "cpu:addr:len:start:end" + of the core repository. is_mem_range reads only "cpu:addr:len:start:end" lines under a "gamename:" header. - name: cheat.dat diff --git a/emulators/mame2003_midway.yml b/emulators/mame2003_midway.yml index e8d31abe..a8adc621 100644 --- a/emulators/mame2003_midway.yml +++ b/emulators/mame2003_midway.yml @@ -19,7 +19,7 @@ notes: | devices that cannot load the full mame2003 core. Supports ~50 games (Mortal Kombat series, NBA Jam, Smash TV, Total Carnage, etc.). - No shared BIOS ZIPs needed — all Midway games are self-contained ROM sets. + No shared BIOS ZIPs needed: all Midway games are self-contained ROM sets. Uses system_dir/mame2003/ for data files (shared path with mame2003). Data files are not bundled in this repo. diff --git a/emulators/mame2003_plus.yml b/emulators/mame2003_plus.yml index 5dc41f2c..cb516261 100644 --- a/emulators/mame2003_plus.yml +++ b/emulators/mame2003_plus.yml @@ -72,7 +72,7 @@ files: source_ref: "src/hiscore.c:15,102-116,248" note: >- high score definitions, compiled into binary and spawned on first run. - metadata/hiscore.dat of the core repository; the compiled copy + metadata/hiscore.dat of the core repository. The compiled copy (precompile/hiscore_dat.h) predates its last edits. is_mem_range reads only "cpu:addr:len:start:end" lines under a "gamename:" header. diff --git a/emulators/mame2015.yml b/emulators/mame2015.yml index 836b6252..c92a3bc4 100644 --- a/emulators/mame2015.yml +++ b/emulators/mame2015.yml @@ -67,7 +67,7 @@ files: size: 216250 source_ref: "src/emu/hiscore.c:122-138,335-337" note: >- - high score definitions, external file, not embedded. metadata/hiscore.dat of the core repository; is_mem_range reads + high score definitions, external file, not embedded. metadata/hiscore.dat of the core repository. is_mem_range reads only "cpu:addr:len:start:end" lines under a "gamename:" header. # SNK Neo Geo MVS/AES diff --git a/emulators/mame4droid-2024.yml b/emulators/mame4droid-2024.yml index 7e3c077d..b81d6657 100644 --- a/emulators/mame4droid-2024.yml +++ b/emulators/mame4droid-2024.yml @@ -97,10 +97,10 @@ notes: | Android port of MAME 0.289 by David Valdeita (Seleuco), package com.seleuco.mame4d2024, app version 1.38.1. The repository carries the Android app, the myosd OSD MAME is built against and 16 patches over stock - sources; none of them changes which external files a user has to supply. + sources, and none of them changes which external files a user has to supply. res/values/strings.xml reads 0.289 and the whatsnew.txt in the asset bundle is MAME's own for 0.289, dated 2026-07-31. The README titles the - project MAME4droid (Current); the package id and the ES-DE find rules keep + project MAME4droid (Current), while the package id and the ES-DE find rules keep the 2024 name. MAME4droid.java hands the installation directory to Emulator.emulate, and @@ -111,7 +111,7 @@ notes: | the app's external media folder, picked in the settings. When a Storage Access Framework folder is chosen for ROMs the app prepends it to rompath, artpath, samplepath and swpath and keeps the installation directory as the - second entry; with the mame.ini setting on it passes no path at all and + second entry. With the mame.ini setting on it passes no path at all and leaves them to the ini chain. MainHelper.copyFiles unpacks res/raw/files.zip into that directory on first @@ -130,7 +130,7 @@ notes: | -ctrlr, language/<name>/strings.mo from -language, artwork/<name>.png from -effect, cheat members from the running machine, and folders/*.ini from a directory scan. Of the shipped presets the ini chain reaches raster.ini, - vector.ini, lcd.ini, gameboy.ini and gba.ini; the rest of ini/presets and + vector.ini, lcd.ini, gameboy.ini and gba.ini. The rest of ini/presets and all of ini/examples are templates no chain step names. The floppy sound set is named in floppy.cpp, which lists 19 of the 20 samples shipped: 525_seek_2ms.wav appears in no sample list in 0.289. @@ -158,7 +158,7 @@ files: sha1: "d16938569bb1b572f1e3f55bd17381dc28235d62" category: game_data description: "GNU Unifont, the UI font used for CJK and for the low-resolution OSD" - note: "Passed as -uifont when the language is Chinese, Japanese or Korean on the low-resolution OSD, or when the unifont setting is on. render_font opens it from fontpath, which defaults to the installation root; a miss falls back to the font compiled into the binary. Seeded from the package assets on first run; the hash identifies that drop, the loader checks nothing." + note: "Passed as -uifont when the language is Chinese, Japanese or Korean on the low-resolution OSD, or when the unifont setting is on. render_font opens it from fontpath, which defaults to the installation root, and a miss falls back to the font compiled into the binary. Seeded from the package assets on first run. The hash identifies that drop, the loader checks nothing." source_ref: "src/osd/myosd/droid/myosd_droid.cpp:1620-1624, src/emu/rendfont.cpp:526-534,853-863" - name: unifont.bdc @@ -169,7 +169,7 @@ files: sha1: "ce173b7341bb271da5bf47761f4bf3b4de8e9deb" category: game_data description: "compiled glyph cache for unifont.bdf" - note: "load_cached_bdf derives the name by swapping the BDF extension and opens it before parsing the 9 MB source font, accepting it only when its stored size and hash match unifont.bdf. Shipped prebuilt; MAME writes it itself when it is absent." + note: "load_cached_bdf derives the name by swapping the BDF extension and opens it before parsing the 9 MB source font, accepting it only when its stored size and hash match unifont.bdf. Shipped prebuilt, though MAME writes it itself when it is absent." source_ref: "src/emu/rendfont.cpp:888-905,1303-1325" - name: uismall.bdf @@ -213,7 +213,7 @@ files: sha1: "8d5a5e5b6b179f5c27f0d9379aea1c4fd36b51f9" category: game_data description: "per-game XML cheat files" - note: "cheat_manager::load_cheats opens <basename>.xml over cheatpath, which defaults to cheat, and emu_file's archive fallback rewrites the directory component to cheat.7z or cheat.zip before looking inside. It runs when -cheat is on, which the app passes from its cheats setting; the Lua cheat plugin reads the same collection when it is enabled. The collection distributed with it dates itself 03 April 2024, base release for MAME 0.264." + note: "cheat_manager::load_cheats opens <basename>.xml over cheatpath, which defaults to cheat, and emu_file's archive fallback rewrites the directory component to cheat.7z or cheat.zip before looking inside. It runs when -cheat is on, which the app passes from its cheats setting, and the Lua cheat plugin reads the same collection when it is enabled. The collection distributed with it dates itself 03 April 2024, base release for MAME 0.264." source_ref: "src/frontend/mame/cheat.cpp:1143-1190,1400-1412, plugins/cheat/init.lua:96-122, src/emu/fileio.cpp:713-716, src/emu/emuopts.cpp:51, src/osd/myosd/droid/myosd_droid.cpp:1536-1538" - name: boot.lua @@ -224,7 +224,7 @@ files: sha1: "3732f1aeea740c2e5df51b0b51c6665028314ae6" category: game_data description: "bootstrap script that starts the enabled Lua plugins" - note: "Opened by name from pluginspath after the plugin directories are scanned. Without it no plugin runs, so hiscore, autofire, inputmacro and data stay silent; the emulator itself is unaffected. A script that is present but fails to load is fatal." + note: "Opened by name from pluginspath after the plugin directories are scanned. Without it no plugin runs, so hiscore, autofire, inputmacro and data stay silent, but the emulator itself is unaffected. A script that is present but fails to load is fatal." source_ref: "src/frontend/mame/mame.cpp:139-221" - name: shaders.cfg @@ -235,7 +235,7 @@ files: sha1: "f58525f9a3dfc2c09957f0e5ec070474694dfa41" category: game_data description: "index of the GLES effect shaders, one per line as file, name, filtering and format version" - note: "load_filters reads it from the installation root and opens each shader it lists under shaders/. A missing file means no effect shaders; a listed shader that cannot be opened raises. 53 of the 65 shipped shaders are loaded: ten more are commented out, and stock.glsl and vector_halo-fringe - copia.glsl are named nowhere." + note: "load_filters reads it from the installation root and opens each shader it lists under shaders/. A missing file means no effect shaders, while a listed shader that cannot be opened raises. 53 of the 65 shipped shaders are loaded: ten more are commented out, and stock.glsl and vector_halo-fringe - copia.glsl are named nowhere." source_ref: "src/osd/myosd/renderer/filter_shader.cpp:106-183" - name: cross1.png diff --git a/emulators/mame4droid.yml b/emulators/mame4droid.yml index ddeb942a..3f6c7392 100644 --- a/emulators/mame4droid.yml +++ b/emulators/mame4droid.yml @@ -68,12 +68,12 @@ notes: | Android port of MAME 0.139u1 by David Valdeita (Seleuco), package com.seleuco.mame4droid. The Java app (seleuco/MAME4droid-0.139u1-, version 1.16.9) loads a prebuilt libMAME4droid.so built from the native - tree profiled here. src/version.c reads 0.139u1; the 0139u2 and 0139u3 + tree profiled here. src/version.c reads 0.139u1, and the 0139u2 and 0139u3 diffs ship in the repository unapplied. Romset is 0.139 only. 8846 drivers in mamedriv.c, 51 BIOS root sets. ZN-based boards keep their 0.139 set names (cpzn1, cpzn2, acpsx, atpsx, atluspsx, vspsx, psarc95, - tps, taitofx1); later MAME renamed them to coh####. + tps, taitofx1). Later MAME renamed them to coh####. setGlobalPath chdirs into the installation directory, /sdcard/MAME4droid or /sdcard/Android/data/com.seleuco.mame4droid/files, so every relative @@ -111,7 +111,7 @@ files: sha1: "c686635c5470e4711dbf817e8196dcb169fdc68d" category: game_data description: "high score memory ranges per game" - note: "Opened from the installation root with an empty search path, once per session, when the hiscore setting is on. That setting is off by default on Android. Seeded from the package assets on first run; the hash identifies that drop, the engine reads the file without checking it. Definitions are keyed to the 0.139 driver names, so another MAME generation's file is a different one." + note: "Opened from the installation root with an empty search path, once per session, when the hiscore setting is on. That setting is off by default on Android. Seeded from the package assets on first run. The hash identifies that drop, the engine reads the file without checking it. Definitions are keyed to the 0.139 driver names, so another MAME generation's file is a different one." source_ref: "src/emu/hiscore.c:29,365, src/emu/machine.c:379-382, src/osd/droid-ios/osd-droid.c:89,345" - name: cheat.zip @@ -122,7 +122,7 @@ files: sha1: "a737e925e3b86374da57496e3261d0303889977f" category: game_data description: "per-game XML cheat files" - note: "cheat_list_load opens cheat/<gamename>.xml and fopen_attempt_zipped rewrites the directory component to cheat.zip. Loaded when the cheat setting is on. Seeded from the package assets on first run; the hash identifies that drop, the engine reads members without checking the container." + note: "cheat_list_load opens cheat/<gamename>.xml and fopen_attempt_zipped rewrites the directory component to cheat.zip. Loaded when the cheat setting is on. Seeded from the package assets on first run. The hash identifies that drop, the engine reads members without checking the container." source_ref: "src/emu/cheat.c:428,1026-1027, src/emu/fileio.c:276-352, src/emu/emuopts.c:48, src/osd/droid-ios/osdmain.c:317" - name: Category.ini @@ -133,7 +133,7 @@ files: sha1: "75d31d949614b7d4e79de676c8a4b1c68b571f0a" category: game_data description: "game name to category map for the ROM list filter" - note: "Read from the installation root with a plain fopen the first time the category filter is used, then sorted for binary search. Seeded from the package assets on first run; the hash identifies that drop, the reader checks nothing." + note: "Read from the installation root with a plain fopen the first time the category filter is used, then sorted for binary search. Seeded from the package assets on first run. The hash identifies that drop, the reader checks nothing." source_ref: "src/emu/uimenu.c:4600-4648" - name: ui.bdf @@ -199,7 +199,7 @@ files: required: false category: game_data description: "crosshair bitmap for player 8" - note: "MAX_PLAYERS is 8 in src/emu/inptport.h:29. crosshair_colors has seven entries, so player 8 reads past the table; the file follows the white that 0.289 assigns beyond the table." + note: "MAX_PLAYERS is 8 in src/emu/inptport.h:29. crosshair_colors has seven entries, so player 8 reads past the table, and the file follows the white that 0.289 assigns beyond the table." source_ref: "src/emu/crsshair.c:169-174, src/emu/inptport.h:29" aliases: ["cross7.png"] diff --git a/emulators/mamemess.yml b/emulators/mamemess.yml index 0daad3bf..7cdcd5a5 100644 --- a/emulators/mamemess.yml +++ b/emulators/mamemess.yml @@ -150,7 +150,7 @@ notes: | "gmaster" (18 games). Driver in handheld/gmaster.cpp, in mess.flt. Fujitsu FM-7: 5 machines (fm7 parent, fmnew7 FM-NEW7, fm77av FM-77AV - IMPERFECT_GRAPHICS, fm7740sx FM-77AV40SX NOT_WORKING; fm8 FM-8 + IMPERFECT_GRAPHICS, fm7740sx FM-77AV40SX NOT_WORKING, fm8 FM-8 separate parent). M6809-based home computer family (1982-1988). fm7 parent set has F-BASIC 3.00, sub-CPU ROM, boot ROMs and optional Kanji ROM. fm77av adds initiate ROM, subsys A/B/CG ROMs and requires Kanji. @@ -185,7 +185,7 @@ notes: | MACHINE_IMPERFECT_GRAPHICS. mz2500 parent set has 6 ROMs: IPL, character generator ("hand made?" comment), kanji level 1, kanji level 2, dictionary, phone. mz2520 clone shares all ROMs except IPL (ipl2520.rom). cgrom region - declared but not dereferenced in driver code; loaded by MAME ROM system. + declared but not dereferenced in driver code, but loaded by MAME ROM system. Software lists: mz2500_flop, compatible with mz2000_flop. Driver in sharp/mz2500.cpp, in mess.flt. @@ -193,7 +193,7 @@ notes: | of mz700, mz800 separate parent MZ-800 MACHINE_NOT_WORKING, mz1500 separate parent MZ-1500 MACHINE_NOT_WORKING). Z80-based home computer family (1982-1984). mz700 parent set has monitor ROM and character generator ROM. mz800 parent set - has monitor ROM with 4 BIOS alternatives (official 9Z-504M + 3 Willy's variants); + has monitor ROM with 4 BIOS alternatives (official 9Z-504M + 3 Willy's variants), no cgrom (uses CGRAM). mz1500 is the Japanese MZ-800 with its own monitor ROM and shares cgrom format from mz700. Software lists: mz700_cass (mz700), mz800_cass (mz800/mz1500). Driver in sharp/mz700.cpp, in mess.flt. @@ -1789,7 +1789,7 @@ files: # Model I (trs80.cpp): trs80 (Level I, parent, WORKING), trs80l2 (Level II, parent), # eg3003 (EACA Video Genie, parent), sys80/sys80p (clones), ht1080z/ht1080z2/ht108064 (clones). # Model III/4/4P (trs80m3.cpp): trs80m3 (parent), trs80m4/trs80m4p/cp500 (clones). - # Z80-based home computers (1977-1983). Only trs80 (Level I) is MACHINE_SUPPORTS_SAVE; + # Z80-based home computers (1977-1983). Only trs80 (Level I) is MACHINE_SUPPORTS_SAVE, # all others MACHINE_NOT_WORKING. Software lists: trs80_cass, trs80_flop, trs80_quik. - name: trs80.zip required: true @@ -2008,7 +2008,7 @@ files: system: trs80 source_ref: "src/mame/trs/trs80m3.cpp:530-539" note: | - TRS-80 Model 4P (1983). Clone of trs80m3. Completely different memory map; + TRS-80 Model 4P (1983). Clone of trs80m3. Completely different memory map: Model III ROMs loaded from boot disk, only a bootloader ROM on board. 2 BIOS variants: gate array (default) and disk loader hack. MACHINE_NOT_WORKING. diff --git a/emulators/mandarine.yml b/emulators/mandarine.yml index e29ddb34..3a68a9a7 100644 --- a/emulators/mandarine.yml +++ b/emulators/mandarine.yml @@ -22,7 +22,7 @@ notes: | ref: src/common/common_paths.h:16-70, src/common/file_util.cpp:770-839 InitKeys reads boot9.bin then aes_keys.txt. Encrypted content needs one of the - two; a ROM without crypto reads neither. + two, while a ROM without crypto reads neither. ref: src/core/hw/aes/key.cpp:315-324, src/core/file_sys/ncch_container.cpp:200-210 Failure to derive a key or to find a seed marks the content undecryptable and @@ -84,7 +84,7 @@ files: path: sysdata/seeddb.bin system: nintendo-3ds required: false - note: "game seed database for 9.6+ titles; an empty database is written when the file is absent" + note: "game seed database for 9.6+ titles. An empty database is written when the file is absent" source_ref: "src/core/file_sys/seed_db.cpp:12-58" - name: shared_font.bin @@ -92,7 +92,7 @@ files: system: nintendo-3ds required: false hle_fallback: true - note: "legacy path, tried after the shared font system archive; decompressed BCFNT with the 0x80 byte APT header" + note: "legacy path, tried after the shared font system archive. It is a decompressed BCFNT with the 0x80 byte APT header" source_ref: "src/core/hle/service/apt/apt.cpp:254-270, src/common/common_paths.h:67" - name: CTCert.bin @@ -101,7 +101,7 @@ files: required: false size: 384 validation: [size] - note: "console client certificate; signature type must be 0x010005 and the issuer one of the two Nintendo CA G3 strings. The certificate here is assembled from a console OTP: signature and expiry read at 0x44 and 0x20, public key derived from the private key at 0x24 over sect233r1, and the whole body checked against Nintendo's root public key" + note: "console client certificate. Signature type must be 0x010005 and the issuer one of the two Nintendo CA G3 strings. The certificate here is assembled from a console OTP: signature and expiry read at 0x44 and 0x20, public key derived from the private key at 0x24 over sect233r1, and the whole body checked against Nintendo's root public key" source_ref: "src/core/hle/service/am/am.cpp:2427-2454, src/core/hle/service/am/am.cpp:83-93, src/core/hle/service/am/am.h:95" - name: SecureInfo_A @@ -110,7 +110,7 @@ files: required: false size: 273 validation: [size] - note: "console region and serial number; loaded on a size check alone, and paired with LocalFriendCodeSeed_B" + note: "console region and serial number, loaded on a size check alone, and paired with LocalFriendCodeSeed_B" source_ref: "src/core/hle/service/cfg/cfg.cpp:608-610, 689-709, src/core/hle/service/cfg/cfg.h:180-186" - name: LocalFriendCodeSeed_B @@ -119,5 +119,5 @@ files: required: false size: 272 validation: [size] - note: "friend code generation seed; loaded on a size check alone, and paired with SecureInfo_A" + note: "friend code generation seed, loaded on a size check alone, and paired with SecureInfo_A" source_ref: "src/core/hle/service/cfg/cfg.cpp:604-606, 711-732, src/core/hle/service/cfg/cfg.h:188-193" diff --git a/emulators/mariani.yml b/emulators/mariani.yml index 1e75698f..7d1db519 100644 --- a/emulators/mariani.yml +++ b/emulators/mariani.yml @@ -34,7 +34,7 @@ notes: | (source/frontends/mariani/preferences/PreferencesViewController.mm:191-193, 741-751). MemInitializeROM picks the system ROM from that setting (source/Memory.cpp:2052-2069). Default slots are the printer card in 1, Super Serial Card in 2, Mockingboard in 4 and Disk II in 6 - (source/CardManager.cpp:325-334); the hard disk and mouse cards are chosen by the + (source/CardManager.cpp:325-334), while the hard disk and mouse cards are chosen by the user. Two names in the resource map have no file in the bundle: the Resources build @@ -505,10 +505,10 @@ analysis: unreachable_resources: - filename: Mockingboard-D.rom - reason: "IDR_MOCKINGBOARD_D_FW appears only in the resource header and in the frontend's name table; nothing requests it" + reason: "IDR_MOCKINGBOARD_D_FW appears only in the resource header and in the frontend's name table, and nothing requests it" source_ref: "resource/resource.h:38, source/frontends/mariani/MarianiFrame.cpp:172" - filename: TKClock.rom - reason: "IDR_TKCLOCK_FW appears only in the resource header and in the frontend's name table; nothing requests it" + reason: "IDR_TKCLOCK_FW appears only in the resource header and in the frontend's name table, and nothing requests it" source_ref: "resource/resource.h:51, source/frontends/mariani/MarianiFrame.cpp:175" - filename: ThunderClockPlus.rom reason: > @@ -541,7 +541,7 @@ analysis: DebugInitialize runs from InitialiseEmulator, so the preload happens even when the debugger window is never opened. Only APPLE2E.SYM and A2_BASIC.SYM are in the bundle. The user slots and the source and assembler tables have - no distributed content and are written by whoever needs them; a missing + no distributed content and are written by whoever needs them. A missing table leaves the debugger running without those names. debugger_scripts: @@ -550,7 +550,7 @@ analysis: note: > Run once at the first DebugInitialize, from the current directory and then from the support directory. Holds debugger commands written by the - user; the copy in the source tree is empty. + user. The copy in the source tree is empty. user_supplied_roms: options: diff --git a/emulators/mastergear.yml b/emulators/mastergear.yml index 9c84f66e..9d74f664 100644 --- a/emulators/mastergear.yml +++ b/emulators/mastergear.yml @@ -24,7 +24,7 @@ notes: | MasterSystem 2, GameGear, SG1000, the keyboard-equipped SC3000 and the disk-based SF7000. Two builds of version 4.9 were read. The Android package com.fms.mg is sold on Google Play and not carried on the author's site, so it - came from a mirror; that copy has versionName 4.9, versionCode 4900, sha256 + came from a mirror. That copy has versionName 4.9, versionCode 4900, sha256 11c3f3331d6774739c11dfd604f74f545a17ceba3feb7fb294f02bd80943af35, md5 2cb4df11254f8525e0a2253677450555, and is accepted because its v1 certificate is the author's own key, CN=Marat Fayzullin O=Garage Research issued 2011, @@ -32,7 +32,7 @@ notes: | beside a Play distribution source stamp in the signing block. The free MG 4.9 builds for Windows and Ubuntu, published by the author, were read next to it and open the same files. The native libraries keep their symbol tables, so - the Android readings below cite libmain.so offsets in the x86_64 slice; the + the Android readings below cite libmain.so offsets in the x86_64 slice, and the arm64-v8a, armeabi-v7a, armeabi and x86 slices carry the same filename set. No source has ever been published: the site states the code is not available to the general public and the documentation repeats it, while ColEm and fMSX @@ -43,7 +43,7 @@ notes: | SF7000.ROM is the only system ROM either binary names, and it is read through the cartridge loader. ResetSMS loads it whenever the requested hardware - becomes SF7000; LoadROM returning zero makes ResetSMS clear the SF7000 bits + becomes SF7000. LoadROM returning zero makes ResetSMS clear the SF7000 bits and restore the previous hardware, so LoadDSK finds the machine still is not an SF7000, ejects the image and fails, logging "Failed switching into SF7000 mode." when verbose output is on. Nothing about the file is checked: the size @@ -74,7 +74,7 @@ notes: | <PrivateDir>/<basename>, keeping the larger of the two when both open. That directory is external storage joined with the application label up to its first space, so /sdcard/MasterGear, falling back to getExternalFilesDirs(null) - when it is not a writable directory; the author's own cheat file writes the + when it is not a writable directory, and the author's own cheat file writes the same path out in full. The desktop builds have no such directory and open every name where they stand, which the documentation states as the current directory. Every one of these opens ends in zlib, mopen handing the diff --git a/emulators/md-emu.yml b/emulators/md-emu.yml index 70cd472b..8522a9a4 100644 --- a/emulators/md-emu.yml +++ b/emulators/md-emu.yml @@ -30,7 +30,7 @@ notes: | Pico out and CD support in. Content is read from .bin, .smd, .md, .gen and .sms cartridge images and from .cue, .iso and .chd discs (MD.emu/metadata/conf.mk:5, MD.emu/src/main/system.ccm:91-101). A .sms name switches the machine to Power - Base Converter mode (MD.emu/src/genplus-gx/loadrom.cc:383-387); Game Gear and + Base Converter mode (MD.emu/src/genplus-gx/loadrom.cc:383-387). Game Gear and SG-1000 sit inside #if 0 blocks in the renderer with no SYSTEM_GG or SYSTEM_SG defined anywhere in the tree (MD.emu/src/genplus-gx/vdp_render.cc:934-962,974-989, MD.emu/src/genplus-gx/system.h:35-40). @@ -52,7 +52,7 @@ notes: | imagine/src/base/common/ApplicationContext.cc:542-562, imagine/src/fs/ArchiveFS.cc:75-78). init_rom accepts the image only at exactly 131072 bytes with "BOOT" at 0x124 or 0x128 of the raw bytes, which is what raises - sCD.isActive; anything else ends the load with "Invalid BIOS" + sCD.isActive, and anything else ends the load with "Invalid BIOS" (MD.emu/src/genplus-gx/loadrom.cc:426-432, MD.emu/src/main/Main.cc:340-344). Cartridge content never reads it. @@ -104,7 +104,7 @@ files: note: >- Picked by the user from any path, under any name ending in .bin, .smd, .md, .gen or .sms, or inside a .zip, .7z or .rar holding one. The tests are the - length and the "BOOT" text at 0x124 or 0x128; a file failing either aborts + length and the "BOOT" text at 0x124 or 0x128, and a file failing either aborts the load rather than falling back. source_ref: "MD.emu/src/main/Main.cc:311-344 (region choice, read, checks), MD.emu/src/genplus-gx/loadrom.cc:426-432 (size and signature), MD.emu/src/main/EmuMenuViews.cc:290-295,317-345 (picker and filter)" diff --git a/emulators/mednafen.yml b/emulators/mednafen.yml index ef474ca9..13040d6c 100644 --- a/emulators/mednafen.yml +++ b/emulators/mednafen.yml @@ -49,8 +49,8 @@ notes: | Modules compiled by default that load no external file: gb, snes, snes_faust, vb, wswan, ngp, sms, gg. The snes module (bsnes 0.059) has every coprocessor - ROM compiled in; snes_faust synthesises the DSP-1 and CX4 data ROMs - (cart/dsp1-datarom-synth.h, cart/cx4.cpp:58); ngp installs a reverse + ROM compiled in, snes_faust synthesises the DSP-1 and CX4 data ROMs + (cart/dsp1-datarom-synth.h, cart/cx4.cpp:58), and ngp installs a reverse engineered HLE BIOS (ngp/bios.cpp:182-239). The nes_new module is declared but never built: configure.ac:392-393 keeps @@ -87,7 +87,7 @@ files: sha256: "fc3e9d41e9428534a883df5aa10eb55b73ea53d2fcbb3ee4f39bed1b07a82905" validation: [size] source_ref: "apple2/apple2.cpp:1342-1350, 1869, 2282, 1473-1476" - note: "System firmware for model ii+, ROM card for model ii. Read as 0x3000 bytes at $D000. The hash is in the ROMDB table and only labels the dump in the startup log; nothing rejects a mismatch." + note: "System firmware for model ii+, ROM card for model ii. Read as 0x3000 bytes at $D000. The hash is in the ROMDB table and only labels the dump in the startup log. Nothing rejects a mismatch." - name: "apple2-int-auto.rom" system: apple-ii @@ -127,7 +127,7 @@ files: sha256: "68198ae95923926b0307893d03ec286f00822c93a0b6dabfca565f6718dd5a56,fbb9620e01f4f728e5a8ba86544900978d7803f6a7d577d384e288dfed9a4907" validation: [size] source_ref: "apple2/apple2.cpp:2331-2351, 1498-1506" - note: "The first hash is 342-0132-B, the second the revised IIe dump 342-0132-C; both are recognised at this filename and neither is checked. Read as 0x800 bytes." + note: "The first hash is 342-0132-B, the second the revised IIe dump 342-0132-C. Both are recognised at this filename and neither is checked. Read as 0x800 bytes." - name: "apple2e-enh.rom" system: apple-iie @@ -207,7 +207,7 @@ files: min_size: 512 validation: [size] source_ref: "lynx/system.cpp:101, lynx/rom.cpp:55-74" - note: "Loaded for every cartridge, before the cart itself. Throws if the file is under 512 bytes; the first 512 bytes are used. No hash check and no HLE fallback." + note: "Loaded for every cartridge, before the cart itself. Throws if the file is under 512 bytes, and the first 512 bytes are used. No hash check and no HLE fallback." # --- nes --- @@ -226,7 +226,7 @@ files: required: false min_size: 4352 source_ref: "nes/cart.cpp:570-597, nes/nes.cpp:298-299, nes/nes.cpp:454-455" - note: "Loaded only when nes.gg is enabled; that setting defaults to 0. Path comes from nes.ggrom. A raw image is read as 4352 contiguous bytes. An iNES image takes 4096 bytes of PRG after the 16-byte header, then 256 bytes of CHR at offset 16400, so it needs at least 16656 bytes. The image here is the raw form: the 4096 byte Game Genie PRG, crc 1a3a22a1, followed by the first 256 bytes of its CHR, both from the MAME ggenie set." + note: "Loaded only when nes.gg is enabled, and that setting defaults to 0. Path comes from nes.ggrom. A raw image is read as 4352 contiguous bytes. An iNES image takes 4096 bytes of PRG after the 16-byte header, then 256 bytes of CHR at offset 16400, so it needs at least 16656 bytes. The image here is the raw form: the 4096 byte Game Genie PRG, crc 1a3a22a1, followed by the first 256 bytes of its CHR, both from the MAME ggenie set." # --- pce and pce_fast --- @@ -263,7 +263,7 @@ files: required: false min_size: 524288 source_ref: "pcfx/pcfx.cpp:620-632, 1116" - note: "Path comes from pcfx.fxscsi, which defaults to \"0\" and is skipped for the values 0, none and the empty string. Mednafen names no default file and opens the path with a bare FileStream, so it is not resolved under the firmware directory; the name here is the one the dump circulates under, to point the setting at. Marked developer-only upstream. 524288 bytes are read and mapped at 0x80780000." + note: "Path comes from pcfx.fxscsi, which defaults to \"0\" and is skipped for the values 0, none and the empty string. Mednafen names no default file and opens the path with a bare FileStream, so it is not resolved under the firmware directory. The name here is the one the dump circulates under, to point the setting at. Marked developer-only upstream. 524288 bytes are read and mapped at 0x80780000." # --- psx --- @@ -276,7 +276,7 @@ files: sha256: "9c0421858e217805f4abe18698afea8d5aa36ff0727eb8484944e00eb5e7eadb" validation: [size, sha256] source_ref: "psx/psx.cpp:1764-1769, 1773-1781, 2373, 251" - note: "Default of psx.bios_jp. Size must be exactly 524288. With psx.bios_sanity on, which is the default, a hash listed as a bad dump or as belonging to another region throws; an unknown hash only logs a warning." + note: "Default of psx.bios_jp. Size must be exactly 524288. With psx.bios_sanity on, which is the default, a hash listed as a bad dump or as belonging to another region throws, while an unknown hash only logs a warning." - name: "scph5501.bin" system: sony-playstation @@ -328,7 +328,7 @@ files: sha256: "96e106f740ab448cf89f0dd49dfbac7fe5391cb6bd6e14ad5e3061c13330266f" validation: [size, sha256] source_ref: "ss/ss.cpp:1431-1434, 1437-1445, 2442, 1461" - note: "Default of ss.bios_na_eu, read for every area but Japan and Asia NTSC; disc area E maps to EU_PAL and no Oceania area exists (ss/ss.cpp:1096, 1431-1434)." + note: "Default of ss.bios_na_eu, read for every area but Japan and Asia NTSC. Disc area E maps to EU_PAL and no Oceania area exists (ss/ss.cpp:1096, 1431-1434)." - name: "sega1003.bin" system: sega-saturn @@ -361,7 +361,7 @@ files: sha256: "87293093fad802fcff31fcab427a16caff1acbc5184899b8383b360fd58efb73" validation: [size, sha256] source_ref: "ss/ss.cpp:1460, 1447-1492" - note: "Recognised alternative for ss.bios_na_eu, read for every area but Japan and Asia NTSC; disc area E maps to EU_PAL and no Oceania area exists (ss/ss.cpp:1096, 1431-1434)." + note: "Recognised alternative for ss.bios_na_eu, read for every area but Japan and Asia NTSC. Disc area E maps to EU_PAL and no Oceania area exists (ss/ss.cpp:1096, 1431-1434)." - name: "epr-20091.ic8" system: sega-stv @@ -438,4 +438,4 @@ files: size: 16384 validation: [size] source_ref: "gba/GBA.cpp:2470-2494, 3278, 772" - note: "Path comes from gba.bios, which defaults to the empty string and is skipped for the values 0, none and the empty string, so Mednafen names no default file; the name here is the one the dump circulates under, to point the setting at. When set, the file must be exactly 16384 bytes. Otherwise the built-in HLE BIOS myROM is used, and the setting is ignored outright for GSF playback." + note: "Path comes from gba.bios, which defaults to the empty string and is skipped for the values 0, none and the empty string, so Mednafen names no default file. The name here is the one the dump circulates under, to point the setting at. When set, the file must be exactly 16384 bytes. Otherwise the built-in HLE BIOS myROM is used, and the setting is ignored outright for GSF playback." diff --git a/emulators/mednafen_pce.yml b/emulators/mednafen_pce.yml index 4c4a7ed2..f1d8d0fc 100644 --- a/emulators/mednafen_pce.yml +++ b/emulators/mednafen_pce.yml @@ -19,7 +19,7 @@ notes: > Arcade Card mode (pce_arcadecard option, enabled by default) extends System Card 3 with extra RAM mapping. No hash or size validation on BIOS load. - Upstream pce module has configurable pce.cdbios/pce.gecdbios string settings; + Upstream pce module has configurable pce.cdbios/pce.gecdbios string settings, and the 6-option dropdown is a libretro addition. files: diff --git a/emulators/mednafen_pce_fast.yml b/emulators/mednafen_pce_fast.yml index fb9e1a85..f249c52b 100644 --- a/emulators/mednafen_pce_fast.yml +++ b/emulators/mednafen_pce_fast.yml @@ -15,9 +15,9 @@ notes: > Separate codebase from beetle_pce (mednafen/pce_fast/ vs mednafen/pce/). BIOS loaded via HuCLoadCD() at CD-ROM load time. Core option "pce_fast_cdbios" selects which card image to use (default: System Card 3). - No Games Express auto-detection (unlike beetle_pce); user must select manually. + No Games Express auto-detection (unlike beetle_pce), so the user must select manually. No hash or size validation on BIOS load. - Upstream pce_fast module only has a single pce_fast.cdbios string setting; + Upstream pce_fast module only has a single pce_fast.cdbios string setting: the 6-option dropdown is a libretro addition. files: diff --git a/emulators/mednafen_stv.yml b/emulators/mednafen_stv.yml index 50a82680..3a12dd91 100644 --- a/emulators/mednafen_stv.yml +++ b/emulators/mednafen_stv.yml @@ -16,7 +16,7 @@ systems: notes: | Libretro core by beudbeud built on the Saturn/ST-V module of Mednafen 1.32.1, with an Asia ST-V BIOS setting and a stvbios.zip fallback added - to ss.cpp. Recalbox runs it for ST-V; the loader also accepts Saturn + to ss.cpp. Recalbox runs it for ST-V, and the loader also accepts Saturn disc images (cue, toc, ccd, chd, m3u). retro_init() points filesys.path_firmware at the frontend system @@ -27,12 +27,12 @@ notes: | A Saturn disc takes sega_101.bin for Japan and Asia NTSC and mpr-17933.bin otherwise (ref: mednafen/ss/ss.cpp:1447-1453). - The loose file is tried first and must be exactly 524288 bytes; when it + The loose file is tried first and must be exactly 524288 bytes. When it is missing or the wrong size, the same name is looked up at the root of stvbios.zip in the system directory, then without the leading slash (ref: mednafen/ss/ss.cpp:1455-1491). With ss.bios_sanity on, the default, a file named like one of the five Saturn BIOS images must - match its SHA-256; the ST-V images are not in that table and only the + match its SHA-256. The ST-V images are not in that table and only the size check applies (ref: mednafen/ss/ss.cpp:1493-1540, 2549). Saturn games that need the KoF 95 or Ultraman ROM cartridge, and the @@ -80,7 +80,7 @@ files: required: false description: "ST-V BIOS archive" source_ref: "mednafen/ss/ss.cpp:1472-1491" - note: "Read only when the loose BIOS file is missing or not 524288 bytes. The member is found by the BIOS file name; its size is not checked." + note: "Read only when the loose BIOS file is missing or not 524288 bytes. The member is found by the BIOS file name, and its size is not checked." contents: - name: "epr-20091.ic8" - name: "epr-19854.ic8" @@ -109,13 +109,13 @@ files: required: false description: "The King of Fighters '95 ROM cartridge" source_ref: "mednafen/ss/ss.cpp:1348, 1404-1412, 2542" - note: "Opened only for the game that needs the cart; that game does not start without it." + note: "Opened only for the game that needs the cart, and that game does not start without it." - name: "mpr-19367-mx.ic1" system: "sega-saturn" required: false description: "Ultraman ROM cartridge" source_ref: "mednafen/ss/ss.cpp:1349, 1404-1412, 2543" - note: "Opened only for the game that needs the cart; that game does not start without it." + note: "Opened only for the game that needs the cart, and that game does not start without it." - name: "satar4mp.bin" system: "sega-saturn" required: false diff --git a/emulators/mednafen_supergrafx.yml b/emulators/mednafen_supergrafx.yml index 273b56f3..cab68b82 100644 --- a/emulators/mednafen_supergrafx.yml +++ b/emulators/mednafen_supergrafx.yml @@ -13,7 +13,7 @@ verification: existence notes: > Port of Mednafen's pce_fast module with SuperGrafx and CD support. The card image is read from the system directory by HuC_LoadCD() at - CD-ROM load time (mednafen/pce_fast/huc.cpp:221-245); the load fails when + CD-ROM load time (mednafen/pce_fast/huc.cpp:221-245), and the load fails when the file cannot be opened. Core option "sgx_cdbios" selects which image to use (default: System Card 3). With "sgx_detect_gexpress" enabled (the default), DetectGECD() recognises Games Express discs and loads diff --git a/emulators/melonds-nightly.yml b/emulators/melonds-nightly.yml index 57e5e6d3..fe797733 100644 --- a/emulators/melonds-nightly.yml +++ b/emulators/melonds-nightly.yml @@ -15,7 +15,7 @@ mode: standalone notes: | Android port of melonDS. The emulation code is the melonDS-android-lib submodule, a fork of melonDS-emu/melonDS pinned at 431ab4bd and declaring - version 1.1 (CMakeLists.txt:20); the app around it is Kotlin plus a JNI layer + version 1.1 (CMakeLists.txt:20), and the app around it is Kotlin plus a JNI layer under app/src/main/cpp. Nightly is a product flavor, not a separate tree: the build dimension "build" @@ -31,7 +31,7 @@ notes: | framework, stored in the preferences bios_dir and dsi_bios_dir (app/src/main/res/xml/pref_custom_firmware.xml:29-39). Both are read by basename, so bios7.bin, bios9.bin and firmware.bin each name a DS image in one - directory and a DSi image in the other; the accepted lengths are what tell them + directory and a DSi image in the other. The accepted lengths are what tell them apart. The app lists the expected names on screen when a directory is unset or rejected (app/src/main/res/values/strings.xml:116,118). Entries below carry the basename the app opens in the path, under the console identifier the picker @@ -59,7 +59,7 @@ notes: | a card is disabled (app/src/main/cpp/SDCardArgsBuilder.cpp:19-20) and the JNI layer hardcodes both the DSi card and the homebrew DLDI card to disabled (app/src/main/cpp/MelonDSAndroidConfiguration.cpp:93-94), with no preference anywhere in the app - to turn either on; the README lists DSi SD card support under missing features. The Action Replay database the core can parse is likewise + to turn either on, and the README lists DSi SD card support under missing features. The Action Replay database the core can parse is likewise never built: ARDatabaseDAT is reached only from src/frontend/qt_sdl, and the Android build sets BUILD_QT_SDL OFF and links the core alone (app/CMakeLists.txt:8,73). Cheats are entered in the app's own database. @@ -117,7 +117,7 @@ files: validation: [size] note: >- Three lengths are accepted and everything else is rejected. Loaded only in - DS mode; DSi mode reads the firmware from the DSi directory but still needs + DS mode. DSi mode reads the firmware from the DSi directory but still needs this file present, because the DSi check re-runs the DS directory check. Nickname, message, language, colour, birthday and MAC are written into the image before it reaches the core. A firmware the core reports as diff --git a/emulators/melonds.yml b/emulators/melonds.yml index 7346e1ef..80ced045 100644 --- a/emulators/melonds.yml +++ b/emulators/melonds.yml @@ -11,7 +11,7 @@ display_name: "Nintendo - DS (melonDS)" systems: [nintendo-ds, nintendo-dsi] notes: | - FreeBIOS fallback for DS mode (NTR); DSi mode requires all native files. + FreeBIOS fallback for DS mode (NTR), while DSi mode requires all native files. Libretro fork based on melonDS ~0.9.x era, validates size only. Upstream adds CRC32 validation on BIOS files (MemConstants.h). DSi SD card emulation controlled by melonds_dsi_sdcard core option. @@ -27,7 +27,7 @@ files: validation: {core: [size], upstream: [size, crc32]} crc32: 2ab23573 source_ref: "src/NDS.h:196, src/NDS.cpp:467-477, src/frontend/Util_ROM.cpp:99-111" - note: "FreeBIOS fallback (src/FreeBIOS.h); native needed for Key1 cartridge crypto" + note: "FreeBIOS fallback (src/FreeBIOS.h), native needed for Key1 cartridge crypto" - name: bios7.bin system: nintendo-ds @@ -38,7 +38,7 @@ files: validation: {core: [size], upstream: [size, crc32]} crc32: 1280f0d5 source_ref: "src/NDS.h:197, src/NDS.cpp:482-492, src/frontend/Util_ROM.cpp:117-131" - note: "FreeBIOS fallback (src/FreeBIOS.h); native needed for Key1 init at offset 0x0030" + note: "FreeBIOS fallback (src/FreeBIOS.h), native needed for Key1 init at offset 0x0030" - name: firmware.bin system: nintendo-ds @@ -49,7 +49,7 @@ files: max_size: 524288 validation: [size] source_ref: "src/SPI.cpp:192-211, src/frontend/Util_ROM.cpp:174-195" - note: "Generated 128KB firmware as fallback; native must be 256KB or 512KB for boot" + note: "Generated 128KB firmware as fallback, native must be 256KB or 512KB for boot" # --- Nintendo DSi (TWL) --- - name: dsi_bios9.bin @@ -94,4 +94,4 @@ files: description: "DSi SD card image" required: false source_ref: "src/frontend/Util_ROM.cpp:237-243, src/libretro/libretro.cpp:837,553" - note: "Created if missing; requires melonds_dsi_sdcard core option enabled" + note: "Created if missing, requires melonds_dsi_sdcard core option enabled" diff --git a/emulators/melonds_ds.yml b/emulators/melonds_ds.yml index 0472657b..1119887e 100644 --- a/emulators/melonds_ds.yml +++ b/emulators/melonds_ds.yml @@ -21,14 +21,14 @@ notes: | DS mode: the firmware named by the core option is loaded when BIOS/Firmware Mode is Native, otherwise (or when it fails to load) a generated firmware is used (src/libretro/config/console.cpp:337-364). bios7.bin and bios9.bin - are only read with a native firmware; if either fails the core falls back + are only read with a native firmware. If either fails the core falls back to FreeBIOS (src/libretro/config/console.cpp:379-410). With FreeBIOS an encrypted retail ROM is refused (src/libretro/config/console.cpp:420-424), and booting without content needs native BIOS and a bootable firmware (src/libretro/config/console.cpp:398-401). DSi mode requires dsi_bios7.bin, dsi_bios9.bin, bios7.bin, bios9.bin, a DSi - firmware and a NAND image; each missing file throws + firmware and a NAND image, and each missing file throws (src/libretro/config/console.cpp:490-551). Firmware and NAND images have no fixed name. RegisterCoreOptions() scans @@ -97,11 +97,11 @@ files: description: "DSi firmware image" required: true source_ref: "src/libretro/config/console.cpp:497-499, src/libretro/config/console.cpp:536-551, src/libretro/config/constants.cpp:102-176" - note: "Any file name, selected through a core option; the firmware header must declare the DSi console type." + note: "Any file name, selected through a core option, and the firmware header must declare the DSi console type." - name: dsi_nand.bin system: nintendo-dsi description: "DSi NAND dump" required: true source_ref: "src/libretro/config/console.cpp:490-495, src/libretro/config/console.cpp:564-592, src/libretro/config/console.cpp:1401-1416, src/libretro/config/constants.cpp:44-100, src/libretro/config/constants.hpp:283-287" - note: "Any file name, selected through a core option or picked automatically by region. 251658240 or 257425408 bytes, plus 64 when the no$gba footer is appended; the footer magic must be present at the end or at offset 0xFF800." + note: "Any file name, selected through a core option or picked automatically by region. 251658240 or 257425408 bytes, plus 64 when the no$gba footer is appended. The footer magic must be present at the end or at offset 0xFF800." diff --git a/emulators/mesence.yml b/emulators/mesence.yml index a2e40b18..311c6df1 100644 --- a/emulators/mesence.yml +++ b/emulators/mesence.yml @@ -46,7 +46,7 @@ notes: | LIBRETRO defined (Makefile.libretro:165-166,183-184). The fork branched from af2342818ca81a93b346146802047760400fc7b1 and does not touch Core/Shared/FirmwareHelper.h, so both builds read the same names with the - same size checks. The buildbot publishes it as mesen2_libretro; the port + same size checks. The buildbot publishes it as mesen2_libretro, and the port announces library_version 2.0.0 (Libretro/libretro.cpp:2803) while the compiled core reports 2.2.1 (Core/Shared/EmuSettings.cpp:165-168). @@ -61,7 +61,7 @@ notes: | Size checks are exact at load time (FirmwareHelper.h AttemptLoadFirmware). The standalone UI additionally knows SHA256 values per file (UI/Interop/FirmwareTypeExtensions.cs) and warns on mismatch when - importing through the firmware prompt; a mismatched file can still be + importing through the firmware prompt, but a mismatched file can still be used. The sha256 values below come from that table. The libretro port has no prompt: a MissingFirmware notification reaches no listener, the retry in FirmwareHelper fails the same way and the error goes to the OSD @@ -74,12 +74,12 @@ notes: | path, Core/Shared/FirmwareHelper.h:132-135). GB/GBC/SGB boot ROM images are compiled into the core - (Core/Gameboy/GbBootRom.h:8,49,99); the external files override them. + (Core/Gameboy/GbBootRom.h:8,49,99), and the external files override them. Super Game Boy mode falls back to the plain GB core when the SNES-side ROM is missing (Core/SNES/BaseCartridge.cpp:698-716). GameboyConfig keeps UseSgb2 at true and no core option changes it (Core/Shared/SettingTypes.h:433), so the libretro build only ever asks - for SGB2.sfc and sgb2_boot.bin; SGB1.sfc and sgb_boot.bin are standalone + for SGB2.sfc and sgb2_boot.bin. SGB1.sfc and sgb_boot.bin are standalone reads. The libretro port also offers a "Super Game Boy" subsystem taking a GB ROM plus an SNES-side ROM (Libretro/libretro.cpp:1041-1052): the second entry is copied into the system directory as SGB1.sfc or SGB2.sfc @@ -104,7 +104,7 @@ notes: | the home folder on the first lookup (Core/NES/GameDatabase.cpp:92-103), merging its 10668 entries over the embedded ones. Standalone deploys the file from the application's Dependencies.zip. Five Satellaview stream - files ship the same way and are extracted to the home folder at startup; + files ship the same way and are extracted to the home folder at startup, and user replacements are preserved (UI/Utilities/DependencyHelper.cs:14-67). Nothing deploys them for libretro. NES and SNES cheat databases (CheatDb.Nes.json, CheatDb.Snes.json) are read directly from the @@ -128,7 +128,7 @@ exclusion_note: >- path opens those names: the CD firmware loader reads "[BIOS] Super CD-ROM System (Japan) (v3.0).pce" or syscard3.pce and the Games Express loader reads "[BIOS] Games Express CD Card (Japan).pce" or - gecard.pce (Core/Shared/FirmwareHelper.h:330-368); the libretro stub + gecard.pce (Core/Shared/FirmwareHelper.h:330-368). The libretro stub adds syscard3.bin, syscard.pce and syscard.bin as sources for the Super CD-ROM image only (Libretro/libretro.cpp:114). @@ -381,7 +381,7 @@ files: min_size: 32768 validation: [size] sha256: "27cfdb99f7e4252bf3740d420147b63c4c88616883bc5e7fe43f2f30bf8c8cbb,a49827b45ff9ac9cf5b4658190e1428e59251bc82d8a63d8e9e0f71e439f008f,3ce321496edc5d77038de2034eb3fb354d7724afd0bc7fd0319f3eb5d57b984d,77d94d64d745014bf8b51280a4204056cdeb9d41ea30eae80dbc006675bebef8" - note: "BS-X application cartridge ROM, mandatory for .bs Satellaview files. Core accepts any file of 32 KB or more; the known dumps are 1 MB (Japan/English, with and without DRM)." + note: "BS-X application cartridge ROM, mandatory for .bs Satellaview files. Core accepts any file of 32 KB or more. The known dumps are 1 MB (Japan/English, with and without DRM)." source_ref: "Core/SNES/BaseCartridge.cpp:60-64, Core/Shared/FirmwareHelper.h:81-92,172-188, UI/Interop/FirmwareTypeExtensions.cs:23-31" - name: "SufamiTurbo.sfc" @@ -480,7 +480,7 @@ files: size: 16384 validation: [size] sha256: "fd2547724b505f487e6dcb29ec2ecff3af35a841a77ab2e85fd87350abd36570" - note: "GBA BIOS. When missing, the boot ROM region is zero-filled and games calling BIOS routines fail; there is no HLE replacement." + note: "GBA BIOS. When missing, the boot ROM region is zero-filled and games calling BIOS routines fail. There is no HLE replacement." source_ref: "Core/GBA/GbaConsole.cpp:76-79, Core/Shared/FirmwareHelper.h:272-291, UI/Interop/FirmwareTypeExtensions.cs:35" # ------------------------------------------------------- @@ -526,7 +526,7 @@ files: system: nintendo-nes required: false size: 262144 - note: "Famicom Network System kanji ROM. Read without size validation; a zero-filled 256 KB buffer is used when absent." + note: "Famicom Network System kanji ROM. Read without size validation, and a zero-filled 256 KB buffer is used when absent." source_ref: "Core/NES/Mappers/Nintendo/FnsMmc1.h:31-36" - name: "MesenNesDB.txt" @@ -536,7 +536,7 @@ files: required: false size: 548608 sha256: "7eee6516f351ccc7db286587917bec415a1d8042ff5ef87c279f38200a3418dd" - note: "NES game database for mapper and input detection, read from the home folder root on the first lookup. Standalone deploys it from the application's embedded Dependencies.zip; the libretro build starts from a 6213-line embedded copy and merges this file over it when present." + note: "NES game database for mapper and input detection, read from the home folder root on the first lookup. Standalone deploys it from the application's embedded Dependencies.zip, while the libretro build starts from a 6213-line embedded copy and merges this file over it when present." source_ref: "Core/NES/GameDatabase.cpp:92-103, UI/Utilities/DependencyHelper.cs:14-67, Libretro/libretro.cpp:85-86,592-594" - name: "MesenPalette.pal" @@ -561,7 +561,7 @@ files: size: 262144 validation: [size] sha256: "e11527b3b96ce112a037138988ca72fd117a6b0779c2480d9e03eaebece3d9ce" - note: "Super CD-ROM System card, mandatory for CD games. Load fails without it. Both builds read this name or syscard3.pce at exactly 256 KB; the libretro build first builds the canonical file from syscard3.pce, syscard3.bin, syscard.pce or syscard.bin, skipping a 512-byte header, for the duration of a .cue load." + note: "Super CD-ROM System card, mandatory for CD games. Load fails without it. Both builds read this name or syscard3.pce at exactly 256 KB. The libretro build first builds the canonical file from syscard3.pce, syscard3.bin, syscard.pce or syscard.bin, skipping a 512-byte header, for the duration of a .cue load." source_ref: "Core/PCE/PceConsole.cpp:61-63,151-164, Core/Shared/FirmwareHelper.h:330-349, Libretro/libretro.cpp:108-183,2347-2358, UI/Interop/FirmwareTypeExtensions.cs:61-62" - name: "[BIOS] Games Express CD Card (Japan).pce" @@ -585,7 +585,7 @@ files: system: sega-mastersystem required: false sha256: "477617917a12a30f9f43844909dc2de6e6a617430f5c9a36306c86414a670d50,1eb16fc06ceaf05651d7cfd69d1713e6ddccc4349a511f6fd17e037d71f9d85b,67846e26764bd862f19179294347f7353a4166b62ac4198a5ec32933b7da486e,cb01de3464797a77b52e82f5f9b05398540df8c1151d31128d49584028589062,6f4e6de10f1d07bda695c629c67457bb0248eeb8ffa0c61a2742b8529274de30,0c08e17b0ecc3967e1094f12841fdc97fdcbbf986e3bf9a06b35b69e7d95e4cd,1a73bc6e1a9973b98432774a1480b3ac1259027a97590d5e67d52745159abbbc,e9eb04ec80ded8658f765c4eca75cdbe23cbc7d8fed73f9c3db7a868dbf649ff,13c0639cc037167f53e6151dbdea013758c3d09a76b064a894bf15c39c0a3897,aaf39841be10f9cd6908a95a7451c3a0c8ac77125eb412b7a41cad260c888ab5,57abf3c00c82a8e042ebeb2bfe412adac9ba005e9009845236390de3ee645248,c51ec80b7a609c5ee3d203ceee2b602ae4dfb4479caf15dc1d030c40c0364e93" - note: "Master System boot ROM, also read for SG-1000 content, mapped when present. Loaded without any size check; known dumps are 8/16/128/256 KB." + note: "Master System boot ROM, also read for SG-1000 content, mapped when present. Loaded without any size check. Known dumps are 8/16/128/256 KB." source_ref: "Core/SMS/SmsConsole.cpp:71-76, Core/Shared/FirmwareHelper.h:369-379, UI/Interop/FirmwareTypeExtensions.cs:71-77" - name: "bios.gg" @@ -606,7 +606,7 @@ files: size: 8192 validation: [size] sha256: "990bf1956f10207d8781b619eb74f89b00d921c8d45c95c334c16c8cceca09ad,fb4a898eb93b19b36773d87a6c70eb28f981b2686bebdd2d431b05dcdf9cffd4" - note: "ColecoVision BIOS, NTSC or PAL console dump. The system boots through it; games cannot start without it." + note: "ColecoVision BIOS, NTSC or PAL console dump. The system boots through it, and games cannot start without it." source_ref: "Core/SMS/SmsConsole.cpp:71-74, Core/Shared/FirmwareHelper.h:381-398, UI/Interop/FirmwareTypeExtensions.cs:70" # ------------------------------------------------------- @@ -620,7 +620,7 @@ files: size: 4096 validation: [size] sha256: "bf4480dbea1c47c8b54ce7be9382bc1006148f431fbe4277e136351fa74f635e" - note: "WonderSwan boot ROM, also used for Pocket Challenge V2. Loaded only when the UseBootRom setting is enabled (default off); without it the boot screen is skipped." + note: "WonderSwan boot ROM, also used for Pocket Challenge V2. Loaded only when the UseBootRom setting is enabled (default off). Without it the boot screen is skipped." source_ref: "Core/WS/WsConsole.cpp:145-150, Core/Shared/SettingTypes.h:806, Core/Shared/FirmwareHelper.h:400-437, UI/Interop/FirmwareTypeExtensions.cs:80" - name: "bootrom.wsc" @@ -655,7 +655,7 @@ files: required: false size: 34 sha256: "ba0c17b5786724959bc206714fc18f708c16fdcd77f8fb19aaf9768338e3ce01" - note: "Satellaview data stream for channel 0120 (time channel), read from <home>/Satellaview/. Standalone deploys it from the application's embedded Dependencies.zip and preserves user replacements; the libretro build reads it from system/Satellaview/ and deploys nothing." + note: "Satellaview data stream for channel 0120 (time channel), read from <home>/Satellaview/. Standalone deploys it from the application's embedded Dependencies.zip and preserves user replacements, while the libretro build reads it from system/Satellaview/ and deploys nothing." source_ref: "Core/SNES/Coprocessors/BSX/BsxStream.cpp:68-74, UI/Utilities/DependencyHelper.cs:44-48" - name: "BSX0121-0.bin" @@ -665,7 +665,7 @@ files: required: false size: 34 sha256: "fbe51a53638dd366b50ea53adf92f54447667d7767c502e508d89b008e31c53f" - note: "Satellaview data stream for channel 0121. Deployed by the standalone UI; user replacements are preserved." + note: "Satellaview data stream for channel 0121. Deployed by the standalone UI, and user replacements are preserved." source_ref: "Core/SNES/Coprocessors/BSX/BsxStream.cpp:68-74, UI/Utilities/DependencyHelper.cs:44-48" - name: "BSX0122-0.bin" @@ -675,7 +675,7 @@ files: required: false size: 1031 sha256: "a0329450e1d42cd18d30070a86e0e481a876cb5c9cfbaab4a0d8895150976ee7" - note: "Satellaview data stream for channel 0122. Deployed by the standalone UI; user replacements are preserved." + note: "Satellaview data stream for channel 0122. Deployed by the standalone UI, and user replacements are preserved." source_ref: "Core/SNES/Coprocessors/BSX/BsxStream.cpp:68-74, UI/Utilities/DependencyHelper.cs:44-48" - name: "BSX0123-0.bin" @@ -685,7 +685,7 @@ files: required: false size: 16 sha256: "dbf5ef12ce586712ee666fc5805e6dfcaa1e253fdd36644f773909514868a590" - note: "Satellaview data stream for channel 0123. Deployed by the standalone UI; user replacements are preserved." + note: "Satellaview data stream for channel 0123. Deployed by the standalone UI, and user replacements are preserved." source_ref: "Core/SNES/Coprocessors/BSX/BsxStream.cpp:68-74, UI/Utilities/DependencyHelper.cs:44-48" - name: "BSX0124-0.bin" @@ -695,7 +695,7 @@ files: required: false size: 97 sha256: "4d7d7bf5afe5c4f71b96965e58003816c70c13e8af9b581431504d5e52a0cec1" - note: "Satellaview data stream for channel 0124. Deployed by the standalone UI; user replacements are preserved." + note: "Satellaview data stream for channel 0124. Deployed by the standalone UI, and user replacements are preserved." source_ref: "Core/SNES/Coprocessors/BSX/BsxStream.cpp:68-74, UI/Utilities/DependencyHelper.cs:44-48" platform_details: diff --git a/emulators/mess2015.yml b/emulators/mess2015.yml index 2ebbabe2..ecaa26e5 100644 --- a/emulators/mess2015.yml +++ b/emulators/mess2015.yml @@ -23,7 +23,7 @@ notes: | Software list support via 375 XML hash files in system_dir/mess2015/hash/. Hash files are bundled in the source repo at /hash/. Not on libretro buildbot. - .info incorrectly says SYSTEMDIR\ume\hash — actual path is mess2015/hash. + .info incorrectly says SYSTEMDIR\ume\hash, the actual path is mess2015/hash. hiscore.c integrated (libretro addition, not in upstream MAME 0.159). SAMPLES sound driver disabled in mess.mak. @@ -42,5 +42,5 @@ files: size: 216250 source_ref: "src/emu/hiscore.c:122-138,335-337" note: >- - high score definitions, loaded via f.open without explicit search path. metadata/hiscore.dat of the core repository; is_mem_range reads + high score definitions, loaded via f.open without explicit search path. metadata/hiscore.dat of the core repository. is_mem_range reads only "cpu:addr:len:start:end" lines under a "gamename:" header. diff --git a/emulators/meteor.yml b/emulators/meteor.yml index 507e18a3..9d3a16c7 100644 --- a/emulators/meteor.yml +++ b/emulators/meteor.yml @@ -29,5 +29,5 @@ platform_details: source_ref: "ameteor/source/bios.cpp, ameteor/source/cpu.cpp:245-311" note: | Full HLE BIOS. The libretro port never loads an external BIOS file. - Cpu::SoftwareInterrupt() checks HasBios() — if false (always in + Cpu::SoftwareInterrupt() checks HasBios(). If false (always in libretro), SWI calls are routed to C++ reimplementations. diff --git a/emulators/mfme.yml b/emulators/mfme.yml index 21bc1b47..47311cc2 100644 --- a/emulators/mfme.yml +++ b/emulators/mfme.yml @@ -17,7 +17,7 @@ notes: | Closed-source Delphi emulator for fruit machine and slot machine hardware, written by Chris Wren (Wizard) and distributed as a Windows installer. MFME.exe carries FileVersion 20.1.0.0, FileDescription "Multiple Fruit Machine Emulator" and - copyright "C.J.Wren 1997-2020"; the installer targets Windows 10, defaults to + copyright "C.J.Wren 1997-2020", and the installer targets Windows 10, defaults to C:\MFME\v20 (history.txt:323) and writes HKCU\Software\CJW\MFME. The binary is ASPack compressed, imports dinput8, xaudio2_9, d2d1 and d3d11 for input, sound and the hardware accelerated scaler added in v19.0 (history.txt:8-9), and holds @@ -33,10 +33,10 @@ notes: | set. The .gam is plain text: a System line naming the tech, DIP switch, reel, stake, jackpot, percentage and meter state, a Layout line naming the .fml, a Game line, and one ROM line per ROM file. Layouts before v5 used .dat and are - converted by loading them in v5 or v6 and saving; v20 loads .fml only. The .fml + converted by loading them in v5 or v6 and saving, while v20 loads .fml only. The .fml is an AACS container whose password is derived from a four byte seed at the end of the file through a mixer, hashed with RIPEMD-128 into a Rijndael key, and - each chunk is zlib compressed; it holds the Delphi layout stream with every + each chunk is zlib compressed. It holds the Delphi layout stream with every bitmap embedded, carries no external file path, and text components name a font family rather than a font file. MFME.exe is started with the .gam path as its argument (history.txt:271). @@ -64,7 +64,7 @@ notes: | SYS85, SYSTEM80 and spACE, with cabinet subfolders Eclipse for ADDER5, SCORPION4 and SCORPION5, Elegance for EPOCH, and Genesis for MPU4 and MPU5. DefaultSounds/Readme.txt:35-37 lists the electronic token mech effects as - CoinInToken, CoinInTokenSwitch and CoinInTokenRejected; the files that ship and + CoinInToken, CoinInTokenSwitch and CoinInTokenRejected, but the files that ship and the entry that introduced them name them TokenIn, TokenInSwitch and TokenInRejected (history.txt:80). @@ -90,7 +90,7 @@ files: Listed in the MFME.exe import descriptors, so the Windows loader resolves it at process start and MFME does not launch when it is absent from the application directory. Drives real cabinet lamps, hoppers and meters through - Ultimarc boards; v20.0 updated the library and added PacLed64 and UltimateIO + Ultimarc boards. v20.0 updated the library and added PacLed64 and UltimateIO support. # -- Fonts, scanned from the Fonts folder beside MFME.exe -- diff --git a/emulators/mkxp_z.yml b/emulators/mkxp_z.yml index 32ec2c48..1440c073 100644 --- a/emulators/mkxp_z.yml +++ b/emulators/mkxp_z.yml @@ -55,7 +55,7 @@ files: category: game_data path: "mkxp-z/Fonts/" required: false - unsourceable: "the core creates this directory empty and mounts it for fonts the user adds; the fallback font is compiled into the binary" + unsourceable: "the core creates this directory empty and mounts it for fonts the user adds, and the fallback font is compiled into the binary" source_ref: "src/core.cpp:1199-1211, src/display/font.cpp:61-90" - name: "Preload" @@ -64,7 +64,7 @@ files: category: game_data path: "mkxp-z/Scripts/Preload/" required: false - unsourceable: "the core creates this directory empty for the user's own scripts; its default preload scripts are mounted from memory" + unsourceable: "the core creates this directory empty for the user's own scripts, and its default preload scripts are mounted from memory" source_ref: "src/core.cpp:891-934" - name: "Postload" diff --git a/emulators/model2.yml b/emulators/model2.yml index 2e139936..b6e503b5 100644 --- a/emulators/model2.yml +++ b/emulators/model2.yml @@ -20,12 +20,12 @@ notes: | Uses MAME-format merged ROM sets. Each game ZIP contains all required ROMs (program, geometry, texture, sound, protection chips). No shared parent BIOS - set exists for Sega Model 2 hardware; each game board has its own ROM chips. + set exists for Sega Model 2 hardware, as each game board has its own ROM chips. EmuDeck packages version 1.1c from SeongGino/edc-repo0004. Installs to romsPath/model2/ with emulator_multicpu.exe as main binary. Ships with Lua scripts for game-specific patches (widescreen, fixes). No checkBIOS - entry in EmuDeck; EMULATOR.INI references only a roms/ subdirectory. + entry in EmuDeck, and EMULATOR.INI references only a roms/ subdirectory. Source code never published. Original distribution via nebula.emulatronia.com (archived). PhilrocWP/Model2 GitHub repo no longer exists. @@ -35,5 +35,5 @@ files: [] exclusion_note: > Uses MAME-format merged ROM sets where all required ROMs are contained within each game's ZIP file. No standalone BIOS or firmware files are loaded by the - emulator. The Sega Model 2 hardware has no shared system BIOS; each game board + emulator. The Sega Model 2 hardware has no shared system BIOS: each game board has its own set of program, geometry, texture, and sound ROMs. diff --git a/emulators/mpv.yml b/emulators/mpv.yml index 17dd61fc..925f2c96 100644 --- a/emulators/mpv.yml +++ b/emulators/mpv.yml @@ -14,10 +14,10 @@ systems: [] notes: | Libretro wrapper around libmpv. Links against the mpv shared library for video/audio decoding and OpenGL rendering. Experimental, proof of - concept. No system directory access — the core only loads the content + concept. No system directory access: the core only loads the content file passed by RetroArch. -# source_ref: mpv-libretro.c — single-file core (672 lines). No call to +# source_ref: mpv-libretro.c, a single-file core (672 lines). No call to # RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY. Only file access is the content # path via retro_load_game(info->path) forwarded to mpv loadfile command # (line 241, 296). No fopen, no system_dir path construction. diff --git a/emulators/msx-emu.yml b/emulators/msx-emu.yml index 6e07eb9d..d6b7135d 100644 --- a/emulators/msx-emu.yml +++ b/emulators/msx-emu.yml @@ -53,19 +53,19 @@ notes: | Paths are resolved against the user's BIOS folder first and the application bundle second (MSX.emu/src/main/RomLoader.cc:57-92,94-133,135-144). That folder may be a directory or an archive and is refused unless it carries a Machines entry - (MSX.emu/src/main/options.cc:212-228); with none set the app falls back to the asset + (MSX.emu/src/main/options.cc:212-228). With none set the app falls back to the asset path on Linux and to the storage path elsewhere (MSX.emu/src/main/options.cc:230-243). The machine picker lists every subdirectory holding a config.ini and appends the three bundled C-BIOS names on Android, where the asset directory enumeration skips directories (MSX.emu/src/main/EmuMenuViews.cc:32-97,548-608). - The default machine is MSX2 and the default Coleco machine is COL - ColecoVision; a + The default machine is MSX2 and the default Coleco machine is COL - ColecoVision. A .col name picks the second and a session setting overrides both (MSX.emu/src/main/system.ccm:75-76, MSX.emu/src/main/Main.cc:534,563-577). Neither default is bundled. The application ships only the three C-BIOS machines in its assets (MSX.emu/res/firmware/Machines, symlinked into MSX.emu/res/android/assets), - which run cartridge images; the definitions and ROMs behind every other name come + which run cartridge images, while the definitions and ROMs behind every other name come from MSX.emu.zip, the firmware set on the author's site, whose Machines folder holds MSX, MSX2, MSX2+, MSXturboR, COL - ColecoVision and Shared Roms. Its MSXturboR definition spells MSXTR, MSXTREXT, MSXTRMUS, MSXTROPT and MSXDOS23 with a lowercase @@ -86,7 +86,7 @@ notes: | No hash is checked anywhere, and the sizes below are the ones the shipped set carries. The machine definitions still carry one, because config.ini is the name of - every definition there is and nothing else tells two of them apart; the values are + every definition there is and nothing else tells two of them apart. The values are those of the emulator's own assets and of the author's firmware set. A single length test exists, the Kanji mapper taking 131072 or 262144 bytes and nothing else (MSX.emu/src/blueMSX/Memory/romMapperKanji.c:141-149). The other diff --git a/emulators/mu.yml b/emulators/mu.yml index 68796165..d6b69574 100644 --- a/emulators/mu.yml +++ b/emulators/mu.yml @@ -20,7 +20,7 @@ notes: | Tungsten T3 / Palm OS 6.0 -> palmos60-en-t3.rom ROM path: RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY + "/" + osVersion + ".rom". - No hash or size validation; the code reads whatever file is present. + No hash or size validation: the code reads whatever file is present. The bootloader is optional and ignored for Tungsten T3. Supports no-game mode (boots Palm OS desktop from ROM without content). diff --git a/emulators/mupen64plus-ae.yml b/emulators/mupen64plus-ae.yml index f10e4e7a..9b8d1697 100644 --- a/emulators/mupen64plus-ae.yml +++ b/emulators/mupen64plus-ae.yml @@ -45,7 +45,7 @@ notes: | the slot is the one loaded. A disk is recognised only when its system data header matches and carries one of three region words, 0xe848d316 for Japan, 0x2263ee56 for the United States and 0x00000000 for development - (app/src/main/java/paulscode/android/mupen64plusae/util/RomHeader.java:180-220); the word sets a country code used for the ROM + (app/src/main/java/paulscode/android/mupen64plusae/util/RomHeader.java:180-220). The word sets a country code used for the ROM database and cheat lookup, never for picking the IPL. Launching a bare disk with the global slot empty stops before the core starts (app/src/main/java/paulscode/android/mupen64plusae/jni/CoreService.java:638-639), and since disk only games still need a cartridge @@ -69,11 +69,11 @@ notes: | core (mupen64plus-core/upstream/src/main/rom.c:473-490 from mupen64plus-core/upstream/src/api/frontend.c:106) and by the gallery (app/src/main/java/paulscode/android/mupen64plusae/SplashActivity.java:447). mupencheat.default is copied over Profiles/customCheats.txt into mupencheat.txt and parsed in Java - (app/src/main/java/paulscode/android/mupen64plusae/SplashActivity.java:443, app/src/main/java/paulscode/android/mupen64plusae/cheat/CheatUtils.java:88-96, app/src/main/java/paulscode/android/mupen64plusae/persistent/GamePrefsActivity.java:548); - the core's own cheat.c opens no file. font.ttf is reached by GLideN64 only + (app/src/main/java/paulscode/android/mupen64plusae/SplashActivity.java:443, app/src/main/java/paulscode/android/mupen64plusae/cheat/CheatUtils.java:88-96, app/src/main/java/paulscode/android/mupen64plusae/persistent/GamePrefsActivity.java:548), + while the core's own cheat.c opens no file. font.ttf is reached by GLideN64 only after /system/fonts/DroidSans.ttf fails, that name being what the front end writes as the configured font (mupen64plus-video-gliden64/upstream/src/TextDrawer.cpp:209-210,222-228, - app/src/main/java/paulscode/android/mupen64plusae/jni/NativeConfigFiles.java:291); the core's OSD, the other upstream reader of + app/src/main/java/paulscode/android/mupen64plusae/jni/NativeConfigFiles.java:291). The core's OSD, the other upstream reader of that name (mupen64plus-core/upstream/src/osd/osd.c:40), is absent from the Android source list (mupen64plus-core/mupen64plus-core.mk:24-101). RiceVideoLinux.ini holds rice's per ROM settings (rice Config.cpp:38,933-953), Glide64mk2.ini glide64mk2's @@ -132,8 +132,8 @@ files: setting is named for. No name is fixed by the code: the path comes from a document picker and the file is copied to dd_rom.n64 before the core sees it. The core reads it whole, then byteswaps after identifying the first - word as one of 0x80270740 (z64), 0x40072780 (n64) or 0x27804007 (v64); - any other value logs an invalid IPL and disables 64DD. Size is not + word as one of 0x80270740 (z64), 0x40072780 (n64) or 0x27804007 (v64). + Any other value logs an invalid IPL and disables 64DD. Size is not checked and no hash is computed. source_ref: "app/src/main/java/paulscode/android/mupen64plusae/jni/CoreService.java:606-620,638-639, app/src/main/java/paulscode/android/mupen64plusae/jni/CoreInterface.java:459-488, app/src/main/java/paulscode/android/mupen64plusae/persistent/GlobalPrefs.java:421,727, mupen64plus-core/upstream/src/main/main.c:1080-1145" diff --git a/emulators/my-boy.yml b/emulators/my-boy.yml index 423ffac3..83707c84 100644 --- a/emulators/my-boy.yml +++ b/emulators/my-boy.yml @@ -36,14 +36,14 @@ notes: | any location, and the choice is stored as the persisted URI biosUri (settings/EmulatorSettings.java:65-73,121-135). A document is accepted only when its reported size is exactly 16384 bytes, or, for an - application/zip document, when an entry declares that size; the name is never + application/zip document, when an entry declares that size. The name is never examined (g.java:66-68,80-100,102-111). One that fails leaves the preference reading "Unrecognized BIOS file." at pick time and on every later visit to the screen (settings/EmulatorSettings.java:101-108,131-133). At game start the stream is read until 16384 bytes are in hand and anything shorter raises, which reports "Load BIOS failed." and passes null (EmulatorActivity.java:1564-1599). - The read happens only while Use BIOS is on, off until the user turns it on; both Boot + The read happens only while Use BIOS is on, off until the user turns it on. Both Boot BIOS and the file picker depend on that switch, and the advanced reset returns all three to their defaults (res/xml/settings_advanced.xml, settings/EmulatorSettings.java:79-80). diff --git a/emulators/nanoboyadvance.yml b/emulators/nanoboyadvance.yml index 15ae81b5..c6edfe09 100644 --- a/emulators/nanoboyadvance.yml +++ b/emulators/nanoboyadvance.yml @@ -24,7 +24,7 @@ notes: | src/platform/core/include/platform/config.hpp:17, src/platform/sdl/main.cpp:98-102 The BIOS is required. BIOSLoader refuses a missing path, a directory, and any - size other than 16 KB; the frontend prints the reason and exits. There is no + size other than 16 KB, and the frontend prints the reason and exits. There is no built-in replacement. bios_skip only jumps past the boot screen after the BIOS is loaded. ref: src/platform/core/src/loader/bios.cpp:17-48, src/platform/sdl/main.cpp:177-192, @@ -43,5 +43,5 @@ files: validation: [size] config_key: "general.bios_path" description: "Game Boy Advance BIOS" - note: "Any file name through general.bios_path or --bios; bios.bin beside the executable when neither is set. ROCKNIX points the key at gba_bios.bin in its BIOS directory." + note: "Any file name through general.bios_path or --bios, or bios.bin beside the executable when neither is set. ROCKNIX points the key at gba_bios.bin in its BIOS directory." source_ref: "src/platform/core/src/loader/bios.cpp:17-48, src/platform/core/src/config.cpp:36, src/platform/sdl/main.cpp:177-192" diff --git a/emulators/nekop2.yml b/emulators/nekop2.yml index 6ac2f778..b684c094 100644 --- a/emulators/nekop2.yml +++ b/emulators/nekop2.yml @@ -2,7 +2,7 @@ emulator: nekop2 type: libretro core_classification: community_fork source: "https://github.com/libretro/libretro-meowPC98" -upstream: "https://np2.yui.ne.jp (dead; source preserved in libretro repo)" +upstream: "https://np2.yui.ne.jp" profiled_date: "2026-03-24" source_commit: "5fdbb2187f6b14ca7bf668dd52b36c820b989995" core_version: "0.86" @@ -11,6 +11,8 @@ cores: [nekop2, meowpc98] systems: [pc-98] # Neko Project II (NP2) by Yui, ported to libretro by meepingsnesroms. +# np2.yui.ne.jp now serves its host's invalid-URL page (checked 2026-10-19). +# The libretro repository is where the source survives. # PC-9801/9821 emulator (80286/IA-32 CPU). All files load from <system>/np2/. # The libretro shim sets np2cfg.biospath to "<system>/np2/" and # file_setcd() to the same path (libretro/libretro.c:856-864,196). @@ -20,7 +22,7 @@ systems: [pc-98] # Font data falls back to built-in 8x8 tables. Sound ROM falls back # to a 9-byte stub. IDE/SCSI/SASI all have built-in stubs. # -# .info declares firmware_count=0; the core loads several BIOS, font and +# .info declares firmware_count=0, but the core loads several BIOS, font and # sound files, each with a built-in fallback. files: @@ -35,15 +37,15 @@ files: required: false hle_fallback: true note: > - PC-9801 system BIOS ROM. The first 0x18000 bytes are read to 0xe8000; - a file shorter than that is ignored and the built-in BIOS simulator + PC-9801 system BIOS ROM. The first 0x18000 bytes are read to 0xe8000. + A file shorter than that is ignored and the built-in BIOS simulator is used, as when the file is absent. source_ref: "bios/bios.c:232-237, common/strres.c:53" # -- PC-9821 IDE BIOS, the ROM at D8000h -- # Opened in bios/bios.c:263-264 via getbiospath(). The first 0x2000 # bytes are read to 0xd8000 (bios/bios.c:266), then the word at 0xd8009 - # is cleared (bios/bios.c:269); the comment above that line reads + # is cleared (bios/bios.c:269), and the comment above that line reads # "crush the IDE BIOS". Only compiled when SUPPORT_PC9821 is defined # (libretro/compiler.h:169). GETBIOS writes BIOS9821.ROM on a PC-9821 # from segment D800h, length 0x2000 (np2tool/GETBIOS.ASM:96-106). @@ -58,7 +60,7 @@ files: it. The first 0x2000 bytes are read to 0xd8000 and the word at 0xd8009 is then zeroed, which leaves the ROM mapped with its IDE BIOS disabled. A file shorter than 0x2000 bytes fails the read test - and the word is left alone; nothing past 0x2000 is read. No other + and the word is left alone. Nothing past 0x2000 is read. No other file name is tried. source_ref: "bios/bios.c:262-272, np2tool/GETBIOS.ASM:96-106, libretro/compiler.h:169" @@ -97,7 +99,7 @@ files: # -- YM2608 OPNA rhythm samples -- # Loaded by rhythm_load() in sound/rhythmc.c:60-71 via getbiospath(). - # The core has no fmgen engine; only lowercase filenames are used. + # The core has no fmgen engine, and only lowercase filenames are used. - name: "2608_bd.wav" path: "np2/2608_bd.wav" required: false diff --git a/emulators/neo-emu.yml b/emulators/neo-emu.yml index 244a2702..4716e9fc 100644 --- a/emulators/neo-emu.yml +++ b/emulators/neo-emu.yml @@ -40,7 +40,7 @@ notes: | in the directory holding the content, not in a system directory (NEO.emu/src/gngeo/roms.c:1202-1211, NEO.emu/src/main/Main.cc:465-471, EmuFramework/src/EmuSystem.cc:83). Members are matched on name or on CRC32, - so an image carrying the expected CRC is taken whatever it is called; turning + so an image carrying the expected CRC is taken whatever it is called. Turning on Strict ROM Checking, off by default, drops the name test and leaves CRC32 alone (NEO.emu/src/main/unzip.cc:49-50, NEO.emu/src/main/Main.cc:316-319, NEO.emu/src/main/system.ccm:87). The archive itself is never hashed. @@ -57,7 +57,7 @@ notes: | BIOS Type defaults to Unibios 2.3 and MVS Region to USA (NEO.emu/src/main/system.ccm:74-81, NEO.emu/src/main/options.cc:45-46). The menu offers the six Universe BIOS versions and MVS - (NEO.emu/src/main/EmuMenuViews.cc:127-136); under MVS the region picks + (NEO.emu/src/main/EmuMenuViews.cc:127-136). Under MVS the region picks vs-bios.rom for Japan, usa_2slt.bin for USA, asia-s3.rom for Asia and sp-s2.sp1 for Europe and any other value (NEO.emu/src/gngeo/roms.c:1269-1300, NEO.emu/src/main/EmuMenuViews.cc:103-116). aes-bios.bin sits on the SYS_HOME @@ -87,19 +87,19 @@ notes: | (src/roms.c:1372-1376). The romset definitions and the CMC42/CMC50 key tables ship with the app. On - Android they are assets read through the asset manager; elsewhere they are read + Android they are assets read through the asset manager. Elsewhere they are read from gngeo_data.zip beside the executable (NEO.emu/src/main/Main.cc:64-67, 198-206,321-369, imagine/src/base/linux/ApplicationContext.cc:44-47). Upstream ships the same archive with 237 definitions plus a skin/ set for its own SDL - menu; the app carries 240, adds bbbuster, ironclad, ironclado and totcarib, + menu. The app carries 240, adds bbbuster, ironclad, ironclado and totcarib, drops mslug3n, changes 31 others and keeps no skin, its resource loader being replaced wholesale (NEO.emu/src/main/Main.cc:321-369, src/resfile.c:71-115, gngeo.dat/gngeo_data.zip). The two key tables are byte identical to upstream's. Divergences from gngeo 0.8 in what is read: upstream passes 0 for every member - CRC, so it verifies nothing and matches on name alone; it knows one Universe + CRC, so it verifies nothing and matches on name alone. It knows one Universe BIOS under the name uni-bios.rom and falls back to a loose uni-bios.rom beside - the archive when the archive lacks it; and it opens the BIOS archive only as + the archive when the archive lacks it. It also opens the BIOS archive only as .zip, under a configured rompath (src/roms.c:1217-1320,1078-1087). Nothing else is read from outside. The per-game gngeo configuration path is @@ -131,7 +131,7 @@ files: required: true crc32: "5a86cff2" description: "Zoom lookup table" - note: "Read for every game; a miss ends the load." + note: "Read for every game, and a miss ends the load." source_ref: "NEO.emu/src/gngeo/roms.c:1213-1218, NEO.emu/src/gngeo/video.c:757" - name: "sfix.sfx" @@ -275,7 +275,7 @@ files: Holds rom/<set>.drv for 240 sets plus rom/cmc42.xor and rom/cmc50.xor. A definition is read before anything else and a miss ends the load with "This game isn't recognized". On Android the members are read as assets - through the asset manager; elsewhere they are read from this archive at the + through the asset manager. Elsewhere they are read from this archive at the executable's own directory. source_ref: "NEO.emu/src/main/Main.cc:64-67,198-206,217-221,321-355, imagine/src/base/linux/ApplicationContext.cc:44-47" diff --git a/emulators/nes-emu.yml b/emulators/nes-emu.yml index ff058671..8ee37414 100644 --- a/emulators/nes-emu.yml +++ b/emulators/nes-emu.yml @@ -32,7 +32,7 @@ notes: | snapshots and on-disk states return an empty string (NES.emu/src/main/FceuApi.cc:367-379). Content is read from .nes, .unf, .unif, .fds and .nsf files (NES.emu/metadata/conf.mk:5, - NES.emu/src/main/system.ccm:108-118, NES.emu/src/main/AppMeta.cc:34); an + NES.emu/src/main/system.ccm:108-118, NES.emu/src/main/AppMeta.cc:34). An archive is opened by the framework, which keeps the first entry passing that same filter (EmuFramework/src/EmuSystem.cc:394-412). @@ -42,7 +42,7 @@ notes: | set through a selector that accepts a name ending .rom or .bin caselessly, or an archive holding such an entry (NES.emu/src/main/EmuMenuViews.cc:609-624, NES.emu/src/main/system.ccm:107, NES.emu/src/main/FceuApi.cc:233-254). The - image must measure exactly 8192 bytes; a shorter or longer one is refused as + image must measure exactly 8192 bytes. A shorter or longer one is refused as "Incompatible FDS BIOS" and an unset path as "No FDS BIOS set" (NES.emu/src/main/FceuApi.cc:227-231,244-248,257-263). Either answer makes the loader free the disk data and return an error, so the content never runs @@ -94,7 +94,7 @@ files: validation: [size] description: "Famicom Disk System BIOS" note: >- - Read through a path the user sets, so no name is compiled in; the selector + Read through a path the user sets, so no name is compiled in. The selector accepts any name ending .rom or .bin caselessly, or an archive whose first entry with one of those extensions is used. The size must be exactly 8192 bytes, and a mismatch or an unset path ends the load of any .fds content. diff --git a/emulators/nesoid.yml b/emulators/nesoid.yml index 0f120259..2a64be26 100644 --- a/emulators/nesoid.yml +++ b/emulators/nesoid.yml @@ -19,13 +19,13 @@ systems: notes: | Android package com.androidemu.nes, launched on the path of the content with - android.intent.action.VIEW; the activity declares the file scheme with the + android.intent.action.VIEW, and the activity declares the file scheme with the application/zip and application/octet-stream types (app/src/main/AndroidManifest.xml:59-71). Two build families answer to that package id. Yongzh's own closed builds come first, and 2.3 (versionCode 56) and 2.5.0 (versionCode 62) are read here, both carrying his certificate sha256 744b1df1b3610d58e447d243521a0957cc5f4ebd50b12d2816a92396d1aa32f2 (C=CN, - O=androidemu.com, freeman.yong@gmail.com). He later published the sources; the + O=androidemu.com, freeman.yong@gmail.com). He later published the sources. The SourceForge project carried them on and Yaroslav Pronin forked that tree to GitHub, where release 2.5-4 (versionName 2.5, versionCode 61, armeabi-v7a, certificate O=Free Software CN=Yaroslav Pronin) is the build ES-DE names. The @@ -83,7 +83,7 @@ notes: | (EmulatorSettingsFragment.java:179-210, FileChooser.java:157-172). A palette named after the content is read from the pal directory of the same - unset base directory as the disk BIOS, 192 bytes taken as 64 RGB triples; a + unset base directory as the disk BIOS, 192 bytes taken as 64 RGB triples. A missing file leaves the built-in table in place (app/jni/neslib/palette.c:205-224, app/jni/neslib/general.c:216-221, app/jni/neslib/fce.c:1212). @@ -115,12 +115,12 @@ files: note: >- Read as 8192 bytes into the 8 KB array mapped over 0xE000 to 0xFFFF. A failed open or a short read frees the disk data and ends the load, so no - .fds content runs; both messages are discarded and the application reports + .fds content runs. Both messages are discarded and the application reports only that the ROM failed to load. Nothing else about the image is examined, so a longer file passes on its first 8192 bytes and no hash is compared. The open is a plain fopen, so neither a zipped nor a gzipped copy answers. Yongzh's builds take the path from the fdsRom setting, whose - picker lists names ending .nes, .rom or .bin; the builds made from the + picker lists names ending .nes, .rom or .bin, while the builds made from the published sources ignore that setting and resolve the compiled name under a base directory that is never set, which puts it at the root of the filesystem. @@ -138,7 +138,7 @@ files: through a picker listing names ending .nes, .rom or .bin. The first 16 bytes decide the format: a leading 0x4E is taken as an iNES image, from which 4096 bytes of program ROM are read, then 256 bytes of character ROM - 16 KB further in, so such a file needs at least 16656 bytes; anything else + 16 KB further in, so such a file needs at least 16656 bytes. Anything else is read as a raw 4352 byte image. A failed open or a short read leaves the Game Genie off and the content still runs. No hash is compared. source_ref: "app/jni/neslib/cart.c:475-521 (open and format branch), app/jni/neslib/svga.c:132-140 (setter), app/jni/neslib/drivers/android/nesengine.cpp:242-243, app/jni/neslib/fce.c:1201-1203 (call site), EmulatorActivity.java:870-874, EmulatorSettingsFragment.java:179-193 (picker)" @@ -153,7 +153,7 @@ files: Opened as pal/<name>.pal under the base directory when content loads, with the name taken from the content. 192 bytes are read as 64 RGB triples and replace the built-in table, without checking how many arrived, so a - shorter file leaves the remaining entries unset; a missing file changes + shorter file leaves the remaining entries unset, and a missing file changes nothing. The base directory is never set on Android, so the name resolves at the root of the filesystem. source_ref: "app/jni/neslib/palette.c:205-224, app/jni/neslib/general.c:216-221, app/jni/neslib/fce.c:1212" diff --git a/emulators/nestopia.yml b/emulators/nestopia.yml index 1d596c74..cf8d9a19 100644 --- a/emulators/nestopia.yml +++ b/emulators/nestopia.yml @@ -22,7 +22,7 @@ notes: | NstDatabase.xml is an optional game database for region autodetection, mapper selection, and 4-player adapter recognition. A copy is baked into the core binary (libretro/nstdatabase.hpp) as fallback. The upstream - Nestopia JG requires this file; the libretro port makes it optional. + Nestopia JG requires this file, while the libretro port makes it optional. An optional custom palette file (custom.pal, 64 RGB triplets) overrides built-in palettes when the nestopia_palette core option is set to Custom. @@ -65,7 +65,7 @@ files: hle_fallback: true size: 192 source_ref: "libretro/libretro.cpp:2099-2120 (palette load)" - note: "64 RGB triplets (64 x 3 bytes = 192 bytes). Loaded unconditionally at startup; applied only when nestopia_palette core option is set to Custom. Falls back to built-in Royaltea palette. Multiple valid palettes exist so no canonical hash." + note: "64 RGB triplets (64 x 3 bytes = 192 bytes). Loaded unconditionally at startup, applied only when nestopia_palette core option is set to Custom. Falls back to built-in Royaltea palette. Multiple valid palettes exist so no canonical hash." # --- ADPCM audio samples (optional, game-specific) --- - name: "nestopia/samples/moepro/" diff --git a/emulators/nethersx2-turnip-classic.yml b/emulators/nethersx2-turnip-classic.yml index 940066ba..5eef85f1 100644 --- a/emulators/nethersx2-turnip-classic.yml +++ b/emulators/nethersx2-turnip-classic.yml @@ -6,7 +6,7 @@ source: "https://github.com/nckstwrt/NetherSX2-Turnip" upstream: "https://github.com/Trixarian/AetherSX2" author: "nckstwrt" profiled_date: "2026-08-12" -pin_frozen: "the classic build is this revision. v0.7 ships a newer shim, and its rules are described in the notes; recaling would repoint these refs at code this build never had." +pin_frozen: "the classic build is this revision. v0.7 ships a newer shim, and its rules are described in the notes. Recaling would repoint these refs at code this build never had." source_commit: "8e17e584884e19b0a912f1988730d576d6d5aa84" upstream_commit: "1d1f795dfc70e38da67724c7298779260f513889" core_version: "2.2n-3668-Turnip-v0.7" @@ -33,7 +33,7 @@ notes: | nethersx2-turnip-classic v0.7 libemucore.so 0xcdcba The package pairs two revisions of the project. libemucore.so is the blob the - v0.7 commit carries, byte for byte; libvulkad.so is the one committed for + v0.7 commit carries, byte for byte, and libvulkad.so is the one committed for v0.6 and reports its own build date. libhook_impl.so, libmain_hook.so and the six packed drivers are the same at both revisions. The shim rules described here are therefore those of the older revision, which this profile pins: @@ -79,7 +79,7 @@ notes: | Detection is by content. The scan lists the BIOS folder with a * mask, keeps files between 4194304 and 8388608 bytes, and accepts an image whose romdir - carries a RESET entry followed by a readable ROMVER; the fifth ROMVER + carries a RESET entry followed by a readable ROMVER. The fifth ROMVER character gives the zone, A for USA, C for China, E for Europe, H for Asia, J for Japan, P for Free, T for T10K and X for Test, any other character standing for itself. The sixth character is read only to pick the word @@ -116,7 +116,7 @@ notes: | sets. A compiled-in image stands in for the first and a card filled with 0xFF for the second. DEV9hdd.raw is the default name of the empty disk image its settings page writes. An IRX named in the configuration is read into the ROM - region at 0x3C0000 at boot; the field is empty by default and names no file of + region at 0x3C0000 at boot. The field is empty by default and names no file of its own. ref: aethersx2/pcsx2/DEV9/DEV9.cpp:73, aethersx2/pcsx2/DEV9/DEV9.cpp:145-160, aethersx2/pcsx2/DEV9/flash.cpp:76-103, @@ -171,7 +171,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and a readable ROMVER is accepted, - whatever its name. The 4 to 8 MB range gates the folder scan; an image + whatever its name. The 4 to 8 MB range gates the folder scan, and an image named in the configuration skips both that range and the romdir test. source_ref: "aethersx2/pcsx2/ps2/BiosTools.cpp:27-28, aethersx2/pcsx2/ps2/BiosTools.cpp:235-260, nethersx2-turnip-classic v0.7 libemucore.so 0x81bc00-0x81bc24 (size window), nethersx2-turnip-classic v0.7 libemucore.so 0x81c1c0 (acceptance flag set outright)" @@ -311,7 +311,7 @@ files: description: "Turnip driver, default branch" note: >- Chosen when no other branch matches. Loaded by name from the library - directory through the hook; a load failure falls back to the vendor + directory through the hook. A load failure falls back to the vendor driver. source_ref: "VulkanShim2/vulkan_shim.cpp:1011, VulkanShim2/vulkan_shim.cpp:1079-1080, VulkanShim2/hook_impl.cpp:127-135" @@ -799,22 +799,22 @@ exclusion_note: > Left out are the libraries the package carries for the dynamic linker rather than for its own code. libc.so, libm.so, libdl.so, ld-android.so, liblog.so and libc++_shared.so sit beside the drivers so the namespace built over that - directory can satisfy their DT_NEEDED, and no code path names any of them; + directory can satisfy their DT_NEEDED, and no code path names any of them. android_linker_ns.o is a relocatable object nothing can open. libc++.so and libsync.so are named in the fallback and promote arrays but the package carries neither, and the promote call passes RTLD_NOLOAD, which never reads from disk. libfile_redirect_hook.so and libgsl_alloc_hook.so are reachable only under feature flags the shim never sets, the only flag passed being the custom driver one. The system Vulkan loader and libandroid.so come from the - platform. Also left out are the assets no code path on this platform opens: - game_controller_db.txt, whose name appears in neither the library nor the dex, - pad input arriving through handleControllerButtonEvent and - handleControllerAxisEvent; the seven Direct3D shader sources under - shaders/dx11; icons/AppIconLarge.png and cover-placeholder.png; - fonts/Roboto-Regular-copyright and sounds/achievements/README.txt, which are - licence and credit texts; and dexopt/baseline.prof and baseline.profm, which - the Android runtime consumes. Everything the emulator produces for itself - under the data directory is out as well: memory cards as Mcd<nnn>.ps2 and + platform. Also left out are the assets no code path on this platform opens. + game_controller_db.txt is named in neither the library nor the dex, pad input + arriving through handleControllerButtonEvent and handleControllerAxisEvent. + The others are the seven Direct3D shader sources under shaders/dx11, + icons/AppIconLarge.png and cover-placeholder.png, the licence and credit texts + fonts/Roboto-Regular-copyright and sounds/achievements/README.txt, and + dexopt/baseline.prof and baseline.profm, which the Android runtime consumes. + Everything the emulator produces for itself under the data directory is out + as well: memory cards as Mcd<nnn>.ps2 and Mcd-Multitap<n>-Slot<nn>.ps2, DEV9hdd.raw for the internal disk, save states, screenshots, covers, texture dumps, playtime.dat, emulog.txt, imgui.ini, per-game settings, input profiles, the gamedb and gl_programs caches, and diff --git a/emulators/nethersx2-turnip.yml b/emulators/nethersx2-turnip.yml index 692cb43f..23101ad5 100644 --- a/emulators/nethersx2-turnip.yml +++ b/emulators/nethersx2-turnip.yml @@ -27,7 +27,7 @@ notes: | it derives from. That build is NetherSX2 v2.2n-4248, itself a patch of the AetherSX2 v1.5-4248 package, and the library still reports itself as NetherSX2 v2.2n-4248 (Patched). The project publishes its shim sources and - the libraries it packs; lib/libvulkad.so, lib/libhook_impl.so and + the libraries it packs, and lib/libvulkad.so, lib/libhook_impl.so and lib/libmain_hook.so at the pinned revision are byte for byte the ones in the v0.7 package, so the sources describe the shipped binaries. Everything below was read from that package: lib/arm64-v8a/libemucore.so, libvulkad.so, the @@ -70,7 +70,7 @@ notes: | Detection is by content. The scan lists the BIOS folder with a * mask, keeps files between 4194304 and 8388608 bytes, and accepts an image whose romdir - carries a RESET entry followed by a readable ROMVER; the fifth ROMVER + carries a RESET entry followed by a readable ROMVER. The fifth ROMVER character gives the zone, A for USA, C for China, E for Europe, H for Asia, J for Japan, P for Free, T for T10K and X for Test, any other character standing for itself. The sixth character is compared against D and the result @@ -102,7 +102,7 @@ notes: | sets. A compiled-in image stands in for the first and a card filled with 0xFF for the second. DEV9hdd.raw is the default name of the empty disk image its settings page writes. An IRX named in the configuration is read into the ROM - region at 0x3C0000 at boot; the field is empty by default and names no file + region at 0x3C0000 at boot. The field is empty by default and names no file of its own. ref: aethersx2/pcsx2/DEV9/DEV9.cpp:146-161, aethersx2/pcsx2/DEV9/flash.cpp:76-103, @@ -153,7 +153,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and a readable ROMVER is accepted, - whatever its name. The 4 to 8 MB range gates the folder scan; an image + whatever its name. The 4 to 8 MB range gates the folder scan, and an image named in the configuration skips both that range and the romdir test. source_ref: "aethersx2/pcsx2/ps2/BiosTools.cpp:27-28, aethersx2/pcsx2/ps2/BiosTools.cpp:235-260, nethersx2-turnip v0.7 libemucore.so 0x828e20-0x828e44 (size window), nethersx2-turnip v0.7 libemucore.so 0x829244-0x829248 (device type result discarded)" @@ -291,7 +291,7 @@ files: description: "Turnip driver, default branch" note: >- Chosen when no other branch matches. Loaded by name from the library - directory through the hook; a load failure falls back to the vendor + directory through the hook. A load failure falls back to the vendor driver. source_ref: "VulkanShim2/vulkan_shim.cpp:1014, VulkanShim2/vulkan_shim.cpp:1086-1087, VulkanShim2/hook_impl.cpp:127-135" @@ -775,7 +775,7 @@ exclusion_note: > Left out are the libraries the package carries for the dynamic linker rather than for its own code. libc.so, libm.so, libdl.so, ld-android.so and libc++_shared.so sit beside the drivers so the namespace built over that - directory can satisfy their DT_NEEDED, and no code path names any of them; + directory can satisfy their DT_NEEDED, and no code path names any of them. android_linker_ns.o is a relocatable object nothing can open. libc++.so and libsync.so are named in the fallback and promote arrays but the package carries neither, and the promote call passes RTLD_NOLOAD, which never reads @@ -783,14 +783,14 @@ exclusion_note: > needs, come from the system through the link to the default namespace. The deps cache the shim would fill under cache/vulkan_deps is unreachable: the functions that build it have no call site and the compiler dropped their - strings. Also left out are the assets no code path on this platform opens: - shaders/vulkan/New and shaders/vulkan/Old, reference copies for which no path - string exists in the library; game_controller_db.txt, whose name appears in - neither the library nor the dex, pad input arriving through - handleControllerButtonEvent and handleControllerAxisEvent; the seven Direct3D - shader sources under shaders/dx11; icons/AppIconLarge.png and - cover-placeholder.png; fonts/Roboto-Regular-copyright and - sounds/achievements/README.txt, which are licence and credit texts; and + strings. Also left out are the assets no code path on this platform opens. + shaders/vulkan/New and shaders/vulkan/Old are reference copies for which no + path string exists in the library. game_controller_db.txt is named in neither + the library nor the dex, pad input arriving through + handleControllerButtonEvent and handleControllerAxisEvent. The others are the + seven Direct3D shader sources under shaders/dx11, icons/AppIconLarge.png and + cover-placeholder.png, the licence and credit texts + fonts/Roboto-Regular-copyright and sounds/achievements/README.txt, and dexopt/baseline.prof and baseline.profm, which the Android runtime consumes. Everything the emulator produces for itself under the data directory is out as well: memory cards as Mcd<nnn>.ps2, DEV9hdd.raw for the internal disk, diff --git a/emulators/nethersx2.yml b/emulators/nethersx2.yml index 39a6cf31..b3d4ca7d 100644 --- a/emulators/nethersx2.yml +++ b/emulators/nethersx2.yml @@ -49,7 +49,7 @@ notes: | folder names under it come from the Folders section, Bios defaulting to bios. A script in the repository moves that root to /storage/emulated/0/NetherSX2 once all-files access is granted, and patches out the library check that - requires the package name in the path; the published packages do not carry it. + requires the package name in the path. The published packages do not carry it. ref: nethersx2 v2.1-4248 libemucore.so 0xf70a9, nethersx2 v2.1-4248 libemucore.so 0x7ea914-0x7eaa8c, xyz/aethersx2/android/NativeLibrary.smali initializeOnce, @@ -57,13 +57,13 @@ notes: | Detection is by content. The scan lists the BIOS folder with a * mask, keeps files between 4194304 and 8388608 bytes, and accepts an image whose romdir - carries a RESET entry followed by a readable ROMVER; the fifth ROMVER + carries a RESET entry followed by a readable ROMVER. The fifth ROMVER character gives the zone, A for USA, C for China, E for Europe, H for Asia, J for Japan, P for Free, T for T10K and X for Test, any other character standing for itself, and an EXTINFO entry is read along the way. Stock 4248 also required - the sixth character to differ from D, which turned away development images; - the patch forces that result to true, and the 3668 line never carried the + the sixth character to differ from D, which turned away development images. + The patch forces that result to true, and the 3668 line never carried the test. An image named in the configuration is combined with the BIOS folder and opened at that path when it exists, without the size filter and without the romdir test. No name and no hash is matched anywhere. The image is read into @@ -93,7 +93,7 @@ notes: | sets. A compiled-in image stands in for the first and a card filled with 0xFF for the second. DEV9hdd.raw is the default name of the empty disk image its settings page writes. An IRX named in the configuration is read into the ROM - region at 0x3C0000 at boot; the field is empty by default and names no file of + region at 0x3C0000 at boot. The field is empty by default and names no file of its own. ref: aethersx2/pcsx2/DEV9/DEV9.cpp:146-161, aethersx2/pcsx2/DEV9/flash.cpp:76-104, @@ -126,7 +126,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and a readable ROMVER is accepted, - whatever its name. The 4 to 8 MB range gates the folder scan; an image + whatever its name. The 4 to 8 MB range gates the folder scan, and an image named in the configuration skips both that range and the romdir test. The sixth ROMVER character is not examined here, the patch having replaced the test that rejected images carrying D. diff --git a/emulators/ngp-emu.yml b/emulators/ngp-emu.yml index d5c960fb..9da8dafd 100644 --- a/emulators/ngp-emu.yml +++ b/emulators/ngp-emu.yml @@ -32,7 +32,7 @@ notes: | The TLCS-900h disassembler is left out of the build (NGP.emu/src/CMakeLists.txt:6-32). Content is read from .ngp, .ngc, .npc and .ngpc files (NGP.emu/metadata/conf.mk:5, NGP.emu/src/main/AppMeta.cc:31-34, - NGP.emu/src/ngp/neopop.cpp:336-337); an archive is opened by the framework, + NGP.emu/src/ngp/neopop.cpp:336-337). An archive is opened by the framework, which keeps the first entry passing that same filter (EmuFramework/src/EmuSystem.cc:392-412). diff --git a/emulators/nicaiemu.yml b/emulators/nicaiemu.yml index 94f82f7f..07cda4f9 100644 --- a/emulators/nicaiemu.yml +++ b/emulators/nicaiemu.yml @@ -17,8 +17,8 @@ notes: | Rust by AloysHF. The libretro core and the nicaiemu standalone binary share the nicaiemu-core crate. A .cbe archive is read whole from its full path (need_fullpath = true, - crates/nicaiemu-libretro/src/libretro/api.rs:181; load_machine, - crates/nicaiemu-libretro/src/libretro/api.rs:360-364; CbeArchive::load, + crates/nicaiemu-libretro/src/libretro/api.rs:181, then load_machine, + crates/nicaiemu-libretro/src/libretro/api.rs:360-364, then CbeArchive::load, crates/nicaiemu-core/src/cbe/archive.rs:68-94). Code, scenes, maps, actors, scripts, images and audio are sections of that archive, and installed resource packages are parsed from the same bytes @@ -32,7 +32,7 @@ notes: | (crates/nicaiemu-core/src/machine/drawing.rs:58, crates/nicaiemu-core/src/machine/drawing.rs:709). MIDI resources are synthesised as decaying sine tones without a sound bank - (crates/nicaiemu-core/src/audio_engine.rs:270-275); WAV and MP3 are + (crates/nicaiemu-core/src/audio_engine.rs:270-275), while WAV and MP3 are decoded with symphonia. The libretro crate asks the frontend for no directory. The standalone diff --git a/emulators/noods.yml b/emulators/noods.yml index 3ab1b121..063903d2 100644 --- a/emulators/noods.yml +++ b/emulators/noods.yml @@ -29,7 +29,7 @@ files: hle_fallback: true size: 4096 source_ref: "src/memory.cpp:130-141" - note: "HLE fallback for all SWI calls; native needed for firmware boot and logo verification (copyBiosLogo)" + note: "HLE fallback for all SWI calls. Native needed for firmware boot and logo verification (copyBiosLogo)" - name: "bios7.bin" system: nintendo-ds @@ -38,7 +38,7 @@ files: hle_fallback: true size: 16384 source_ref: "src/memory.cpp:144-155" - note: "HLE fallback for all SWI calls; native needed for firmware boot" + note: "HLE fallback for all SWI calls. Native needed for firmware boot" - name: "firmware.bin" system: nintendo-ds @@ -46,7 +46,7 @@ files: required: false hle_fallback: true source_ref: "src/spi.cpp:62-160" - note: "Auto-generated 128KB non-bootable firmware as fallback; native dump (>128KB) needed for firmware boot" + note: "Auto-generated 128KB non-bootable firmware as fallback, native dump (>128KB) needed for firmware boot" - name: "gba_bios.bin" system: nintendo-gba @@ -55,11 +55,11 @@ files: hle_fallback: true size: 16384 source_ref: "src/memory.cpp:158-168, src/core.cpp:252-256" - note: "HLE fallback via swiTableGba; native BIOS disables HLE and enables real GBA boot" + note: "HLE fallback via swiTableGba. Native BIOS disables HLE and enables real GBA boot" - name: "nds_sd_card.bin" system: nintendo-ds description: "DLDI SD card image for homebrew" required: false source_ref: "src/dldi.cpp:80-83, src/libretro/libretro.cpp:324" - note: "Opened on DLDI startup() call from homebrew ROMs; user-created FAT image" + note: "Opened on DLDI startup() call from homebrew ROMs. User-created FAT image" diff --git a/emulators/np2kai.yml b/emulators/np2kai.yml index c57c416f..fdaf015c 100644 --- a/emulators/np2kai.yml +++ b/emulators/np2kai.yml @@ -46,8 +46,8 @@ files: required: false hle_fallback: true note: > - PC-9801 system BIOS ROM. The first 0x18000 bytes are read to 0xe8000; - a file shorter than that is ignored and the built-in BIOS simulator + PC-9801 system BIOS ROM. The first 0x18000 bytes are read to 0xe8000. + A file shorter than that is ignored and the built-in BIOS simulator is used, as when the file is absent. source_ref: "bios/bios.c:440-447, pccore.c:129, common/strres.c:67" @@ -180,12 +180,12 @@ files: note: > IDE BIOS of a PC-9821, the ROM a real machine maps at D8000h. The first 0x2000 bytes of the first name found are read to - idebaddr << 12 and nothing past them; a shorter file is dropped. + idebaddr << 12 and nothing past them. A shorter file is dropped. Without a loaded ROM the emulated IDE BIOS is used. source_ref: "cbus/ideio.c:1928-1930, cbus/ideio.c:1944-1981" # -- SCSI BIOS ROM -- - # Read into a 0x4000 buffer; any non-empty read is kept. Falls back to the + # Read into a 0x4000 buffer, and any non-empty read is kept. Falls back to the # scsibios[] stub. - name: "scsi.rom" path: "np2kai/scsi.rom" diff --git a/emulators/nuance.yml b/emulators/nuance.yml index f5dbf299..5bd9a56f 100644 --- a/emulators/nuance.yml +++ b/emulators/nuance.yml @@ -20,7 +20,7 @@ notes: | The three BIOS files are not firmware dumps. bios.cof, minibios.cof and minibiosX.cof are Aries assembly implementations of BIOS routines, - assembled from bios.s, minibios.s and minibiosX.s in the source tree; every + assembled from bios.s, minibios.s and minibiosX.s in the source tree. Every other BIOS call is handled in C++ through BiosJumpTable (src/bios.cpp:395-547). The entries left to the assembly code are the comm bus calls, TimeToSleep, MPEWait and BiosGetInfo. @@ -32,25 +32,25 @@ notes: | loads bios.cof into MPE3 and MediaInitMPE loads minibios.cof into MPE0 (minibiosX.cof on MPEs 1 to 3). A failed load prints "Missing File!" and emulation continues without the routines. LoadCoffFile checks the COFF magic - 0x0120 and copies the sections to their physical addresses; no size or hash + 0x0120 and copies the sections to their physical addresses. No size or hash is checked (src/coff.cpp:47-176). Two builds of bios.cof exist. The source tree carries the NuanceExperimental - build (23938 bytes, 12 sections, with commrecv_vars and commrecv_queues); - the 0.6.6 and 0.6.7 release archives ship the 2007 build (19410 bytes, 10 + build (23938 bytes, 12 sections, with commrecv_vars and commrecv_queues). + The 0.6.6 and 0.6.7 release archives ship the 2007 build (19410 bytes, 10 sections). Both carry the same biosvars, haltab, biosinfo, halstub, biosdata, halts and controllerdata sections and the C++ side references neither extra section. nuance.cfg is read from the working directory, then from the directory of - the running executable (src/NuonEnvironment.cpp:547-563); without it the + the running executable (src/NuonEnvironment.cpp:547-563). Without it the values set in NuonEnvironment::Init apply. The GLSL shaders are opened from the working directory and fall back to the copies compiled into the binary (src/ShaderProgram.cpp:94-144, src/embedded_shaders.h). FlashEEPROM.bin is read by the FlashEEPROM constructor and written by the destructor, both relative to the process working directory at load and unload of the core (src/FlashEEPROM.h:36-51). Game data (nuon.run, nuon.dat) is read from the - loaded disc image or directory; no other fixed file is opened. + loaded disc image or directory, and no other fixed file is opened. files: - name: "bios.cof" @@ -119,7 +119,7 @@ files: has_builtin: true source_ref: "src/video.cpp:129, src/ShaderProgram.cpp:94-144, src/embedded_shaders.h:31-52" note: > - Opened from the working directory; the copy compiled into the binary is + Opened from the working directory, and the copy compiled into the binary is used when the file is absent. The release archives ship the file without the EMBED_HLSL guards (413 bytes). @@ -135,7 +135,7 @@ files: source_ref: "src/video.cpp:130, src/ShaderProgram.cpp:94-144, src/embedded_shaders.h:31-52" note: > Selected when UseCRTshader is disabled in nuance.cfg. Same lookup and - fallback as video_generic.vs; the release copy is 6090 bytes. + fallback as video_generic.vs. The release copy is 6090 bytes. - name: "video_m32_o32_crt.fs" path: "nuance/video_m32_o32_crt.fs" @@ -149,7 +149,7 @@ files: source_ref: "src/video.cpp:130, src/ShaderProgram.cpp:94-144, src/embedded_shaders.h:31-52" note: > Selected when UseCRTshader is enabled, the shipped default. Same lookup - and fallback as video_generic.vs; the release copy is 8052 bytes. + and fallback as video_generic.vs. The release copy is 8052 bytes. - name: "FlashEEPROM.bin" description: "Atmel AT49BV162A flash ROM image, 2 MB at 0xF0000000" @@ -160,7 +160,7 @@ files: note: > Read by the FlashEEPROM constructor from the process working directory when the core is loaded, truncated to 2 MB, and written back by the - destructor. The release archives ship one; its content is the flash + destructor. The release archives ship one, and its content is the flash state of the session that produced it. - name: "breakpoint.txt" @@ -169,6 +169,6 @@ files: mode: standalone source_ref: "src/NuanceMain_linux.cpp:124, src/NuanceMain.cpp:446" note: > - Read from the working directory by the standalone executables only; + Read from the working directory by the standalone executables only: NuanceMain.cpp and NuanceMain_linux.cpp are excluded from the libretro build (CMakeLists.txt:214). diff --git a/emulators/oberon.yml b/emulators/oberon.yml index d80ae9f5..ac9745e0 100644 --- a/emulators/oberon.yml +++ b/emulators/oberon.yml @@ -15,7 +15,7 @@ systems: [oberon] # Emulates the Oberon RISC processor designed by Niklaus Wirth. # Bootloader (512 words) compiled into the binary from risc-boot.inc, # loaded into ROM at 0xFFFFF800 on startup (risc.c:75-77,93). -# No retro_get_system_directory() call — no files from system dir. +# No retro_get_system_directory() call, so no files from system dir. # Content: .dsk disk images loaded via retro_load_game (libretro.c:209-214). # Upstream and libretro core emulation code (risc.c, disk.c) are identical. diff --git a/emulators/omicron.yml b/emulators/omicron.yml index 77e154b6..03a11335 100644 --- a/emulators/omicron.yml +++ b/emulators/omicron.yml @@ -21,7 +21,7 @@ notes: | and fileN.bin resources, all read from inside the cartridge (omicron-player/omicron-loader/src/main/java/org/github/msx80/omicron/fantasyconsole/cartridges/JarCartridge.java:20-25, omicron-player/omicron-engine/src/main/java/org/github/msx80/omicron/GameRun.java:74-100). - The libretro core is the experimental frontend of the same repository; the + The libretro core is the experimental frontend of the same repository. The libretro fork is the 2020-09-29 tree plus a GitLab CI file and a Makefile that takes the JNI headers from JAVA_HOME. The CI builds the shared library for Linux x64, i686 and aarch64 only (.gitlab-ci.yml:48-66). @@ -37,7 +37,7 @@ notes: | with no option (libretro/LibretroOmicronCore/ejava.c:249-250). A Bootstrap class compiled into the core binary (libretro/LibretroOmicronCore/bootstrap.h) is defined through JNI and - given the jar path; it opens the jar in a URLClassLoader and instantiates + given the jar path. It opens the jar in a URLClassLoader and instantiates org.github.msx80.omicron.libretro.entrypoint.EntryPoint (libretro/LibretroOmicronCore/ejava.c:258-287, libretro/omicron-libretro-java/src/Bootstrap.java:33-39). One JVM per @@ -60,7 +60,7 @@ notes: | The cartridge class loader installs a SecurityManager (omicron-player/omicron-loader/src/main/java/org/github/msx80/omicron/fantasyconsole/crazyclassloader/NonAggressiveClassLoader.java:19-20). From Java 18 on System.setSecurityManager throws unless the JVM starts - with java.security.manager=allow, which the core never passes; the C side + with java.security.manager=allow, which the core never passes, and the C side does not check the pending exception, so the game is reported as loaded with a 0x0 geometry. Java 8 to 17 runs it. @@ -72,4 +72,4 @@ files: validation: [existence] description: "Omicron libretro Java backend: engine, libGDX, LWJGL and their natives" source_ref: "libretro/LibretroOmicronCore/omicron_libretro.c:364-387 (GET_SYSTEM_DIRECTORY, omicron/omicron.jar, fileExists), libretro/LibretroOmicronCore/ejava.c:258-287 (Bootstrap main with the jar path), libretro/omicron-libretro-java/src/Bootstrap.java:33-39 (URLClassLoader, EntryPoint), libretro/omicron-libretro-java/pom.xml:13-61" - note: "Built with mvn package assembly:single in libretro/omicron-libretro-java after the omicron-api, omicron-loader and omicron-engine Gradle modules are published to the local Maven repository; the jar-with-dependencies output is renamed omicron.jar. Only its presence is checked." + note: "Built with mvn package assembly:single in libretro/omicron-libretro-java after the omicron-api, omicron-loader and omicron-engine Gradle modules are published to the local Maven repository. The jar-with-dependencies output is renamed omicron.jar. Only its presence is checked." diff --git a/emulators/openjazz.yml b/emulators/openjazz.yml index 8a07d710..f3dc205e 100644 --- a/emulators/openjazz.yml +++ b/emulators/openjazz.yml @@ -12,7 +12,7 @@ systems: [jazz-jackrabbit] notes: | Open-source reimplementation of Jazz Jackrabbit 1 (Epic MegaGames, - 1994). Reads the original DOS game data; no asset bundling in the + 1994). Reads the original DOS game data, with no asset bundling in the engine binary. File lookup walks a path list (platform paths, command-line paths, @@ -20,7 +20,7 @@ notes: | the first match. ref: src/io/file.cpp:51-77 (File::File), src/main.cpp:186-220 - PANEL.000 is the first file opened at startup; the engine aborts with + PANEL.000 is the first file opened at startup, and the engine aborts with "Unable to find game data files" if that probe fails. The five .0FN fonts follow and abort startup the same way. ref: src/main.cpp:279-295, src/main.cpp:308-333 @@ -34,7 +34,7 @@ notes: | src/menu/gamemenu.cpp:557-566 JJ2 engine support is experimental and gated by `ENABLE_JJ2` at build - time (off by default); it reads JJ2's .j2l/.j2t files directly (no + time (off by default). It reads JJ2's .j2l/.j2t files directly (no conversion step). ref: CMakeLists.txt:241-255, src/jj2/level/jj2level.cpp:54-67 @@ -174,9 +174,9 @@ files: note: "Cutscene played when a bonus level is won." # ================================================================ - # Level data. Not every episode is required to run; a user may own - # only one. The episode menu probes LEVEL0.<world> for the first - # world of each episode; the levels that follow are named by the + # Level data. Not every episode is required to run, since a user may + # own only one. The episode menu probes LEVEL0.<world> for the first + # world of each episode, and the levels that follow are named by the # level data itself (next level and next world numbers). # ================================================================ diff --git a/emulators/openjk.yml b/emulators/openjk.yml index 1bbc3216..b3c364f7 100644 --- a/emulators/openjk.yml +++ b/emulators/openjk.yml @@ -12,7 +12,7 @@ systems: [jediacademy, jediknight2] notes: | id Tech 3 source port for Star Wars Jedi Knight: Jedi Academy (JKA, single and multiplayer) and Star Wars Jedi Knight II: Jedi Outcast (JK2, single - player only; JK2 MP is not supported, upstream points users to JK2MV). + player only, as JK2 MP is not supported and upstream points users to JK2MV). One source tree, three binaries: openjk_sp JKA SP, built from code/ with BuildSPEngine @@ -83,7 +83,7 @@ files: # ================================================================ # Jedi Outcast retail (base/, assets0.pk3, assets1.pk3, assets2.pk3, - # assets5.pk3). Loaded by openjo_sp (JK2_MODE); openjk upstream does + # assets5.pk3). Loaded by openjo_sp (JK2_MODE). openjk upstream does # not build a JK2 MP engine. # ================================================================ @@ -93,7 +93,7 @@ files: path: "base/assets0.pk3" required: true source_ref: "code/qcommon/files.cpp:3002-3003 (default.cfg ERR_FATAL), code/CMakeLists.txt:450-453 (JK2_MODE build)" - note: "Retail JK2 base archive. Carries default.cfg; openjo_sp aborts without it." + note: "Retail JK2 base archive. Carries default.cfg, and openjo_sp aborts without it." - name: "assets1.pk3" category: game_data diff --git a/emulators/openmohaa.yml b/emulators/openmohaa.yml index aaf05b6e..cd6b87e2 100644 --- a/emulators/openmohaa.yml +++ b/emulators/openmohaa.yml @@ -13,7 +13,7 @@ systems: [mohaa, mohaa-spearhead, mohaa-breakthrough] notes: | Reimplementation of the id Tech 3-derived engine that powers Medal of Honor: Allied Assault (2002) and its expansions Spearhead and - Breakthrough. BASEGAME = "main" (code/qcommon/q_shared.h:35); the target + Breakthrough. BASEGAME = "main" (code/qcommon/q_shared.h:35), and the target game is selected at startup via the com_target_game cvar (0 = Allied Assault / TG_MOH, 1 = Spearhead / TG_MOHTA, 2 = Breakthrough / TG_MOHTT, code/qcommon/common.c:3164-3237). @@ -22,21 +22,21 @@ notes: | for every "*.pk3" via Sys_ListFiles(curpath, ".pk3", ...) at line 3136, sorts them with paksort and mounts each one. It does not look up individual retail names and does not refuse an unknown pak. FS_Startup - (code/qcommon/files.cpp:3640-3650) always loads com_basegame = "main"; + (code/qcommon/files.cpp:3640-3650) always loads com_basegame = "main". Spearhead additionally sets fs_basegame = "mainta" (common.c:3200) and Breakthrough sets fs_basegame = "maintt" (common.c:3227), which triggers a second FS_AddGameDirectories call for that folder. The only hard failure during init is "Couldn't load default.cfg" (code/qcommon/files.cpp:4108), i.e. no pak in the active search path - provides default.cfg. Retail Pak0.pk3 (main/) carries it; Spearhead and + provides default.cfg. Retail Pak0.pk3 (main/) carries it. Spearhead and Breakthrough ship a default.cfg inside their own pak1.pk3 so they can run with or without a main/ install under openmohaa. The retail pak names are documented in-source as reference arrays fs_originalPaks_main / fs_originalPaks_mainta / fs_originalPaks_maintt (code/qcommon/files.cpp:324-350). They are declared but not currently - consulted by the loader; they encode the files the engine was authored + consulted by the loader. They encode the files the engine was authored against. Capitalisation ("Pak0.pk3" under main/, "pak1.pk3" under mainta/ and maintt/) matches the retail ISO filenames and is preserved below for case-sensitive filesystems. FS_FilenameCompare and @@ -48,7 +48,7 @@ notes: | versions to pin a checksum, so no CRC / MD5 is enforced on the paks. com_target_demo 1 selects the demo protocol. The Allied Assault demo - is read from main/ like the full game; the Spearhead and Breakthrough + is read from main/ like the full game, while the Spearhead and Breakthrough demos are read from demota/ and demott/ (code/qcommon/common.c:3168-3182, 3203, 3230, 3249). @@ -64,8 +64,8 @@ files: path: "main/Pak0.pk3" required: true source_ref: "code/qcommon/files.cpp:326 (fs_originalPaks_main[0]), 4108 (Couldn't load default.cfg)" - note: "Carries default.cfg; without it FS_Startup aborts with ERR_FATAL." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + note: "Carries default.cfg. Without it FS_Startup aborts with ERR_FATAL." + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak1.pk3" category: game_data @@ -73,7 +73,7 @@ files: path: "main/Pak1.pk3" required: false source_ref: "code/qcommon/files.cpp:327 (fs_originalPaks_main[1])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak2.pk3" category: game_data @@ -81,7 +81,7 @@ files: path: "main/Pak2.pk3" required: false source_ref: "code/qcommon/files.cpp:328 (fs_originalPaks_main[2])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak3.pk3" category: game_data @@ -89,7 +89,7 @@ files: path: "main/Pak3.pk3" required: false source_ref: "code/qcommon/files.cpp:329 (fs_originalPaks_main[3])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak4.pk3" category: game_data @@ -97,7 +97,7 @@ files: path: "main/Pak4.pk3" required: false source_ref: "code/qcommon/files.cpp:330 (fs_originalPaks_main[4])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak5.pk3" category: game_data @@ -105,7 +105,7 @@ files: path: "main/Pak5.pk3" required: false source_ref: "code/qcommon/files.cpp:331 (fs_originalPaks_main[5])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "Pak6.pk3" category: game_data @@ -127,8 +127,8 @@ files: path: "mainta/pak1.pk3" required: true source_ref: "code/qcommon/files.cpp:337 (fs_originalPaks_mainta[0]), 3200 (fs_basegame=mainta), 4108" - note: "Spearhead default.cfg lives here; required when com_target_game=1." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + note: "Spearhead default.cfg lives here, so the file is required when com_target_game=1." + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak2.pk3" category: game_data @@ -136,7 +136,7 @@ files: path: "mainta/pak2.pk3" required: false source_ref: "code/qcommon/files.cpp:338 (fs_originalPaks_mainta[1])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak3.pk3" category: game_data @@ -174,8 +174,8 @@ files: path: "maintt/pak1.pk3" required: true source_ref: "code/qcommon/files.cpp:346 (fs_originalPaks_maintt[0]), 3227 (fs_basegame=maintt), 4108" - note: "Breakthrough default.cfg lives here; required when com_target_game=2." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + note: "Breakthrough default.cfg lives here, so the file is required when com_target_game=2." + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak2.pk3" category: game_data @@ -183,7 +183,7 @@ files: path: "maintt/pak2.pk3" required: false source_ref: "code/qcommon/files.cpp:347 (fs_originalPaks_maintt[1])" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak3.pk3" category: game_data diff --git a/emulators/openmsx.yml b/emulators/openmsx.yml index 989fc9f0..516f79e8 100644 --- a/emulators/openmsx.yml +++ b/emulators/openmsx.yml @@ -25,12 +25,12 @@ notes: | ROM resolution via FilePool (src/file/FilePool.cc, FilePoolCore.cc): searches configured directories for files matching SHA1 checksums. - Filenames are secondary hints; SHA1 is the primary lookup key. + Filenames are secondary hints, while SHA1 is the primary lookup key. Files may be gzipped or individually zipped. Each user data directory contributes share/systemroms, scanned recursively (src/file/FilePool.cc:27, FilePoolCore.cc:369-385). RetroBat sets OPENMSX_HOME to bios/openmsx and refuses to start a machine whose - ROMs are not in bios/openmsx/share/systemroms; RetroPie links + ROMs are not in bios/openmsx/share/systemroms. RetroPie links share/systemroms to BIOS/openmsx and Batocera adds bios/openmsx to the pool, both scanned recursively, so openmsx/share/systemroms serves all three. diff --git a/emulators/opentyrian.yml b/emulators/opentyrian.yml index c918d96d..86412c33 100644 --- a/emulators/opentyrian.yml +++ b/emulators/opentyrian.yml @@ -240,9 +240,9 @@ files: # Level tileset shapes (loaded per-level from .lvl data) # The level file specifies a character via fgetc() at tyrian2.c:3039, # which maps to shapes{char}.dat at tyrian2.c:3079. - # The shipped set is ), W, X, Y, Z; lvlmast.c:128-131 writes } for the + # The shipped set is ), W, X, Y, Z. lvlmast.c:128-131 writes } for the # Episode 4 tileset, which no distributed file matches. - # Note: shapeFile[34] in lvlmast.c is a DIFFERENT mechanism — + # Note: shapeFile[34] in lvlmast.c is a DIFFERENT mechanism: # it maps indices to characters for newsh?.shp (enemy sprites), # NOT for shapes?.dat (level tilesets). # ----------------------------------------------------------- diff --git a/emulators/opera.yml b/emulators/opera.yml index fc595bca..c83aece5 100644 --- a/emulators/opera.yml +++ b/emulators/opera.yml @@ -18,7 +18,7 @@ notes: | Opera Boot, an open boot ROM (trapexit/opera-boot) compiled into the core as a zlib stream and inflated at load, so the core starts with no file at all. The option lists the built-in ROM first, then each BIOS file physically present in - the system directory; a file is read with read_file_from_system_directory() + the system directory. A file is read with read_file_from_system_directory() and byteswapped on little-endian hosts. opera-boot.bin is the same Opera Boot image read from the system directory diff --git a/emulators/oricutron.yml b/emulators/oricutron.yml index b394b6ae..d43a8c27 100644 --- a/emulators/oricutron.yml +++ b/emulators/oricutron.yml @@ -33,7 +33,7 @@ notes: | a failure returns SDL_FALSE, after which the emulator exits (main.c:1442-1446). The four disk controller ROMs are loaded once at startup by load_diskroms (main.c:1407, machine.c:1249-1255) whatever the machine and - the drive setting; a failure only clears the matching flag and startup + the drive setting. A failure only clears the matching flag and startup continues. Of those flags only pravetzrom_valid is read afterwards (machine.c:1055): the Microdisc, BD-500 and Jasmin buffers are mapped into the CPU address space whether or not the file was read, so a missing file @@ -217,7 +217,7 @@ analysis: note: "Read with SDL_LoadBMP and passed to SDL_COMPAT_WM_SetIcon, which takes a null surface." unused: - filename: status_bar.bmp - reason: "the gimgs table names statusbar.bmp; no code path reads this second file" + reason: "the gimgs table names statusbar.bmp and no code path reads this second file" rom_sidecars: note: > @@ -282,27 +282,27 @@ analysis: - filename: 8dos.sym implies: "the earlier Pravetz 8-DOS boot PROM, offered as pravetz8drom in oricutron.cfg:44" - filename: cumana.sym - implies: "a Cumana controller ROM; its symbols run from $F800, the window jasminrom feeds" + implies: "a Cumana controller ROM, whose symbols run from $F800, the window jasminrom feeds" - filename: sedoric.sym - implies: "a Sedoric DOS ROM; its symbols name the Microdisc FDC registers at $310-$318" + implies: "a Sedoric DOS ROM, whose symbols name the Microdisc FDC registers at $310-$318" unused_resources: - filename: empty_orix.rom - reason: "no reference anywhere in the tree; not named by any config default nor by twilighte.cfg" + reason: "no reference anywhere in the tree, and not named by any config default nor by twilighte.cfg" - filename: orixbank1.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank2.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank3.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank4.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank5.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank6.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" - filename: orixbank7.rom - reason: "no reference anywhere in the tree; loadable only once a twilbankromNN key names it" + reason: "no reference anywhere in the tree, loadable only once a twilbankromNN key names it" user_supplied_paths: note: "Named on the command line or in the config, with no fixed filename" diff --git a/emulators/pce-emu.yml b/emulators/pce-emu.yml index e28a41a3..82f2af7a 100644 --- a/emulators/pce-emu.yml +++ b/emulators/pce-emu.yml @@ -13,7 +13,7 @@ verification: existence notes: > Android and desktop application by Robert Broglia built on EmuFramework, vendoring Mednafen's pce_fast and pce modules. Both are compiled and - selectable at runtime; pce_fast is what an unset core option resolves to + selectable at runtime, and pce_fast is what an unset core option resolves to (PCE.emu/src/main/system.ccm:125). HuCard content (.pce, .sgx) loads with no external file. CD content @@ -35,7 +35,7 @@ notes: > member ending in .pce, .bin or .bios is used (MDFNFILE.cc:41-76). Neither module hashes the image. pce_fast skips a 512-byte copier header - then reads a fixed 262144 bytes (huc.cpp:299-302); pce reads + then reads a fixed 262144 bytes (huc.cpp:299-302), while pce reads min(rounded length, length) and accepts any size (huc.cpp:225-316). HuC_Load is always called with SYSCARD_3, or SYSCARD_ARCADE when Arcade Card emulation is on (pce.cpp:653). @@ -56,7 +56,7 @@ files: note: > min_size comes from the fixed 262144-byte read in pce_fast (huc.cpp:302) with Stream::read throwing on a short file - (Stream.h:88); a 262656-byte dump passes through the copier-header + (Stream.h:88). A 262656-byte dump passes through the copier-header skip at huc.cpp:299. The pce module imposes no minimum. - name: "gecard.pce" @@ -67,6 +67,6 @@ files: source_ref: "src/pce/pce.cpp:512-551 (DetectGECD), src/pce/pce.cpp:644-646 (gecdbios branch), src/pce/huc.cpp:225-316 (size-agnostic read), src/pce/pce.cpp:1095 (name)" note: > Reached only when the accurate module runs and DetectGECD matches the - disc; pce_fast has no Games Express branch. Served through the same + disc, since pce_fast has no Games Express branch. Served through the same System Card setting, so the user points it at this image to boot those discs. diff --git a/emulators/pcee2.yml b/emulators/pcee2.yml index 61bbd291..93bd4b5f 100644 --- a/emulators/pcee2.yml +++ b/emulators/pcee2.yml @@ -22,9 +22,9 @@ data_directories: notes: | libretro port of current PCSX2, merged up to upstream 6db638dc (v2.7.523, - pcee2-libretro/upstream.version); the build reports that version as + pcee2-libretro/upstream.version). The build reports that version as library_version. Everything the port adds lives in pcee2-libretro/ and in - the libretro renderer bridges; the BIOS, CDVD, patch and database code is + the libretro renderer bridges, while the BIOS, CDVD, patch and database code is upstream PCSX2. InitializeConfig maps the PCSX2 folder layout under <system>/pcsx2: @@ -34,7 +34,7 @@ notes: | snaps, sstates, logs, covers, inputprofiles and videos from DataRoot (pcee2-libretro/Libretro.cpp:414-428, pcsx2/Pcsx2Config.cpp:2319-2336). A standalone PCSX2.ini dropped in pcsx2/inis contributes nine emulation - sections as the baseline (Libretro.cpp:504-535); the core options and the + sections as the baseline (Libretro.cpp:504-535), and the core options and the port overrides apply on top. BIOS detection is filename-agnostic. The core option pcsx2_bios lists every @@ -45,14 +45,14 @@ notes: | pcsx2/ps2/BiosTools.cpp:80-197, 284-294). When no BIOS is configured or the configured name is missing, LoadBIOS falls back to FindBiosImage, which also filters on size between 4 and 8 MB (BiosTools.cpp:258-282, 317-369). - The image is read into the 4 MB ROM region; a file shorter than 2465792 + The image is read into the 4 MB ROM region, and a file shorter than 2465792 bytes turns off the OSDSys parameter HLE. No hash is matched. Booting with no content starts the BIOS (Libretro.cpp:2090-2096). Companions derive from the selected image: rom1 and rom2 are tried as the full name plus extension, then with the extension replaced, and are skipped - when absent; the nvm is read at the replaced extension and rebuilt with - region and language defaults when missing or blank; the mec is written back + when absent. The nvm is read at the replaced extension and rebuilt with + region and language defaults when missing or blank, and the mec is written back as 0x00020603 when it cannot be read (BiosTools.cpp:214-241, 366-367, pcsx2/CDVD/CDVD.cpp:136-205). @@ -92,7 +92,7 @@ files: source_ref: "pcee2-libretro/Libretro.cpp:578-618, pcsx2/ps2/BiosTools.cpp:16-17, pcsx2/ps2/BiosTools.cpp:80-197, pcsx2/ps2/BiosTools.cpp:258-294, pcsx2/ps2/BiosTools.cpp:317-369" note: > Any file of pcsx2/bios whose romdir carries RESET and ROMVER. The 4 to - 8 MB filter applies in FindBiosImage only; the core option scan and the + 8 MB filter applies in FindBiosImage only. The core option scan and the auto selection accept any size that passes the romdir check. - name: "<bios>.rom1" @@ -134,7 +134,7 @@ files: hle_fallback: true source_ref: "pcsx2/CDVD/CDVD.cpp:49, pcsx2/CDVD/CDVD.cpp:190-204" note: > - Read at <bios>.mec; written as 0x00020603 when it cannot be read. + Read at <bios>.mec, written as 0x00020603 when it cannot be read. - name: "patches.zip" path: "pcsx2/resources/patches.zip" @@ -158,4 +158,4 @@ files: source_ref: "pcsx2/DEV9/DEV9.cpp:60-73, pcsx2/DEV9/DEV9.cpp:97-158" note: > Opened read-write and mapped from the process working directory by - DEV9init; the built-in eeprom table is used when it cannot be opened. + DEV9init. The built-in eeprom table is used when it cannot be opened. diff --git a/emulators/pcsx2-legacy.yml b/emulators/pcsx2-legacy.yml index 5c2b3ec9..26b135f7 100644 --- a/emulators/pcsx2-legacy.yml +++ b/emulators/pcsx2-legacy.yml @@ -25,7 +25,7 @@ notes: | BIOS selection lists every file in the folder with a *.* mask and keeps the ones whose romdir carries a RESET entry followed by a readable ROMVER, which supplies the version, the zone letter and the build date. Neither size nor - hash is checked; the length test that would reject small images is commented + hash is checked, and the length test that would reject small images is commented out. A missing or zero-length image raises BiosLoadFailed. ref: pcsx2/gui/Panels/BiosSelectorPanel.cpp:151-177, pcsx2/ps2/BiosTools.cpp:74-167, pcsx2/ps2/BiosTools.cpp:325-341, diff --git a/emulators/pcsx2x6.yml b/emulators/pcsx2x6.yml index 738cd02d..1930ae30 100644 --- a/emulators/pcsx2x6.yml +++ b/emulators/pcsx2x6.yml @@ -35,7 +35,7 @@ notes: | Detection is by content. The scan lists the BIOS folder with a * mask, keeps files between 4 and 8 MB, and accepts the ones whose romdir carries a RESET - entry followed by a readable ROMVER; EXTINFO supplies the serial. The picker + entry followed by a readable ROMVER. EXTINFO supplies the serial. The picker in the settings window runs the same romdir test without the size filter, so a manually selected image of any length is accepted. No name and no hash is matched anywhere. @@ -87,10 +87,10 @@ files: - 256.BIN note: >- Any image whose romdir holds RESET and ROMVER is accepted, whatever its - name. The 4 to 8 MB range gates the folder scan; a manually selected image + name. The 4 to 8 MB range gates the folder scan, and a manually selected image skips it. Named after the board model by the dumper, extension rom0. The aliases are the three board dumps held here, COH-H31000, System 246C and - System 256; each carries its romdir at 0x2740 and answers the same test. + System 256. Each carries its romdir at 0x2740 and answers the same test. source_ref: "pcsx2/ps2/BiosTools.cpp:268-292, pcsx2/ps2/BiosTools.cpp:80-207, pcsx2/ps2/BiosTools.cpp:327-379" - name: COH-H31100.rom1 @@ -119,7 +119,7 @@ files: hle_fallback: true size: 1024 description: "Board NVRAM" - note: "Read from the BIOS path with the extension replaced by nvm. Carries the iLinkId the 256 games read as a regional signature; a hardcoded id stands in when the file is missing or blank there. A default image is built when the file cannot be read." + note: "Read from the BIOS path with the extension replaced by nvm. Carries the iLinkId the 256 games read as a regional signature, and a hardcoded id stands in when the file is missing or blank there. A default image is built when the file cannot be read." source_ref: "pcsx2/CDVD/CDVD.cpp:47, pcsx2/CDVD/CDVD.cpp:140-178, pcsx2/CDVD/CDVD.cpp:2608" - name: COH-H31100.mec @@ -182,5 +182,5 @@ files: system: namco-system246 required: false description: "SDL controller mapping database" - note: "A copy in the user data root takes precedence over the one in resources. Fed to SDL as a hint; without either, SDL falls back to its built-in mappings and an error is logged." + note: "A copy in the user data root takes precedence over the one in resources. Fed to SDL as a hint. Without either, SDL falls back to its built-in mappings and an error is logged." source_ref: "pcsx2/Input/SDLInputSource.cpp:24, pcsx2/Input/SDLInputSource.cpp:614-629" diff --git a/emulators/pcsx_rearmed.yml b/emulators/pcsx_rearmed.yml index e8766c92..d045533d 100644 --- a/emulators/pcsx_rearmed.yml +++ b/emulators/pcsx_rearmed.yml @@ -66,7 +66,7 @@ files: hle_fallback: true validation: [size] source_ref: "frontend/libretro.c:3864-3867 (listed_bios[3]), frontend/libretro.c:3654-3669 (try_use_bios region guess)" - note: "The core reads the region out of the image: bytes 0x7ff51 are ' J' in this dump, so it takes the JP slot (' E' takes EU, anything else US), one image per slot, first found kept. The disc licence picks the slot at boot (Config.Bios[Config.PsxRegion]); a US or EU disc only reaches this file when its own slot is empty. Must be 512 KB." + note: "The core reads the region out of the image: bytes 0x7ff51 are ' J' in this dump, so it takes the JP slot (' E' takes EU, anything else US), one image per slot, first found kept. The disc licence picks the slot at boot (Config.Bios[Config.PsxRegion]), and a US or EU disc only reaches this file when its own slot is empty. Must be 512 KB." - name: "scph101.bin" description: "SCPH-101 (v4.4 03-24-00 A) - PSone US" diff --git a/emulators/picodrive.yml b/emulators/picodrive.yml index 4b9c1c75..4d7fe0b9 100644 --- a/emulators/picodrive.yml +++ b/emulators/picodrive.yml @@ -38,7 +38,7 @@ notes: | 32X BIOS files (m68k, master SH2, slave SH2) are fully optional. The engine has built-in HLE that generates replacement code at startup when the BIOS pointers are NULL (pico/32x/memory.c:2202 get_bios(), pico/32x/32x.c:172). - No current frontend (libretro or standalone) loads these files; the standalone + No current frontend (libretro or standalone) loads these files, and the standalone loading code is disabled (#if 0 in platform/common/emu.c:1530). carthw.cfg is a cartridge hardware database loaded from the system directory. diff --git a/emulators/piece.yml b/emulators/piece.yml index 71ce60a4..4bdeacfd 100644 --- a/emulators/piece.yml +++ b/emulators/piece.yml @@ -30,7 +30,7 @@ notes: | src/debug/pfi_loader_blob.cpp:20-91). The P/ECE kernel, its PFFS file system and the installed applications (.pex) all live in that flash image. The bus maps internal IRAM, external SRAM, external flash and - I/O only (src/core/bus.hpp:75-79 and src/core/bus.hpp:239); the core + I/O only (src/core/bus.hpp:75-79 and src/core/bus.hpp:239). The core carries no embedded boot code, and retro_set_environment registers core options and nothing else (src/libretro/piece_libretro.cpp:204-218). No environment call asks for the system directory. @@ -47,10 +47,10 @@ notes: | signature at offset 8 of all.bin, writes the boot vector 0x00C02004 into sector 0, leaves sector 1 blank and copies all.bin from sector 2 (src/tools/mkpfi.c:14, 88-95, 115-135). A fresh image boots to the - launcher with startup.pex, date.pex and gamepad.pex installed; games + launcher with startup.pex, date.pex and gamepad.pex installed, and games are added with pfar. - The .info reports display_version 0.3; the code announces 0.1. + The .info reports display_version 0.3, while the code announces 0.1. files: [] diff --git a/emulators/pizza-boy-gba.yml b/emulators/pizza-boy-gba.yml index 89db0666..8971f6b0 100644 --- a/emulators/pizza-boy-gba.yml +++ b/emulators/pizza-boy-gba.yml @@ -38,7 +38,7 @@ notes: | eight the library does not export. The BIOS is the one file the user supplies, and it is read only while Load BIOS file - is on, off by default; the picker and the Run BIOS animation switch, on by default, + is on, off by default. The picker and the Run BIOS animation switch, on by default, both depend on that box (res/xml/pref_general.xml). In the free package the same three preferences are declared android:enabled="false". @@ -65,7 +65,7 @@ files: description: "Game Boy Advance BIOS" note: >- Chosen from any location under any name through the document picker, or, when the - picked document is named .zip, taken from its first entry; the legacy browser + picked document is named .zip, taken from its first entry. The legacy browser offers .gba, .bin and .zip and writes the entry it extracts to bios.bin under the application directory. The absolute path is stored and handed to the library, which copies it into a 256 byte buffer. At load time the 16 KB BIOS area is first diff --git a/emulators/pizza-boy-gbc.yml b/emulators/pizza-boy-gbc.yml index 5ce68f41..63bd7fcd 100644 --- a/emulators/pizza-boy-gbc.yml +++ b/emulators/pizza-boy-gbc.yml @@ -31,7 +31,7 @@ notes: | 6.0.6. The Pro on the store is 7.4.5 (versionCode 324) and no genuine copy of it is reachable: apkcombo bounces the download page of a paid app back to the app page, apkvision carries no copy, and archive.org holds 6.0.6 alone. The Pro ships its core - as a stripped armeabi-v7a build; it carries the same log strings and the same + as a stripped armeabi-v7a build. It carries the same log strings and the same constants as the Basic core, the 64 KB clear, the 8192 byte read cap, the 256 byte header copy and the 256 and 2304 byte gate, and 65 of the 70 entry points it exports are exported by the Basic core as well. The Pro also ships libpizza-jni.so, an @@ -83,7 +83,7 @@ files: description: "Game Boy (DMG) boot ROM" note: >- Chosen from any location under any name through the document picker and copied - into the application directory under the name the picker reports; the legacy + into the application directory under the name the picker reports. The legacy browser offers .gbc, .gb, .bin and .zip and writes the entry it extracts from a zip to bios.bin. The absolute path is stored and handed to the library, which copies it into a 256 byte buffer. It is used when the ROM name ends in .gb or diff --git a/emulators/pizza-boy-sc.yml b/emulators/pizza-boy-sc.yml index d1480850..cb9be243 100644 --- a/emulators/pizza-boy-sc.yml +++ b/emulators/pizza-boy-sc.yml @@ -47,7 +47,7 @@ notes: | are read from cue and chd images through components/cdrom. Four BIOS slots exist, one per machine, set in one call whose log reads - "jni setBIOSFiles sms: {} gg: {} cd: {} md: {}" (lib.rs:424); a fifth setter stores + "jni setBIOSFiles sms: {} gg: {} cd: {} md: {}" (lib.rs:424). A fifth setter stores a single path in a slot of its own that engine start never reads (lib.rs:416), and setBIOSBoot logs "TODO jni setBIOSboot" and does nothing. Each branch reads the slots its machines use, the Master System one reading the Game Gear slot as well, @@ -85,12 +85,12 @@ files: note: >- Chosen from any location under any name through the document picker, or, when the picked document is named .zip, taken from its first entry. The stored path - is read at engine start and the byte count compared with 131072; the machine + is read at engine start and the byte count compared with 131072, and the machine compares it a second time and panics when it differs. An absent path ends the run with "MegaCD Bios not provided", an empty one with "MegaCD BIOS path is missing", a failed read with "Error loading BIOS file", and a wrong length with "Invalid BIOS len". The core holds one Mega CD slot and applies no other test, - so the boot ROM of any region satisfies it; the three are listed because the + so the boot ROM of any region satisfies it. The three are listed because the region of the discs decides which one has to be installed. source_ref: "Pizza Boy SC Basic 1.2.4 libsc.so frontend/android/src/lib.rs:424 (four slot handoff), :517 (SegaCD branch), :564 (absent), :567 (validation @@ -167,7 +167,7 @@ files: note: >- Its own slot, separate from the Master System one, both read on the branch that serves the two machines. Picked and stored the same way, handed to the machine - as a path, and never examined; an empty slot is not an error. + as a path, and never examined. An empty slot is not an error. source_ref: "Pizza Boy SC Basic 1.2.4 libsc.so frontend/android/src/lib.rs:424 (slot), :481 (system name match, GameGear), :538 (branch reading the Master System and Game Gear slots)" @@ -180,7 +180,7 @@ files: note: >- Read on the Genesis branch, the one engine start falls through to when the system name is neither SMS, GameGear nor SegaCD. Picked and stored the same - way and never examined; the machine reports it as "BIOS detected" and runs + way and never examined. The machine reports it as "BIOS detected" and runs without it when the slot is empty. source_ref: "Pizza Boy SC Basic 1.2.4 libsc.so frontend/android/src/lib.rs:424 (slot), :550 (Genesis branch and slot read), diff --git a/emulators/plastic.yml b/emulators/plastic.yml index c183d1f8..658505b4 100644 --- a/emulators/plastic.yml +++ b/emulators/plastic.yml @@ -40,7 +40,7 @@ notes: | and reloaded on the next run (plastic_core/src/cartridge/mod.rs:319-348, :457-463). Save state slots 0 to 9 are <rom-stem>_<slot>.pst under the data directory, ~/.local/share/plastic/saved_states on Linux - (plastic_ui/src/main.rs:16-32,95-118; plastic_tui/src/ui.rs:38-51,144-176; + (plastic_ui/src/main.rs:16-32,95-118, plastic_tui/src/ui.rs:38-51,144-176, plastic_core/src/nes.rs:393-406). Gamepad support comes from gilrs, which compiles the SDL controller database diff --git a/emulators/play.yml b/emulators/play.yml index 358ad1c2..60ea3838 100644 --- a/emulators/play.yml +++ b/emulators/play.yml @@ -25,8 +25,8 @@ systems: # # source_ref: Source/ee/Ee_SubSystem.cpp:232 (LoadBIOS commented out) # source_ref: Source/iop/IopBios.cpp:279-290 (HLE module table) -# source_ref: Source/PS2VM.cpp:483-537 (ResetVM — no BIOS loading) -# source_ref: Source/ui_libretro/main_libretro.cpp:546-568 (retro_init — no file I/O) +# source_ref: Source/PS2VM.cpp:483-537 (ResetVM, no BIOS loading) +# source_ref: Source/ui_libretro/main_libretro.cpp:546-568 (retro_init, no file I/O) # source_ref: README.md:4 ("Using an external BIOS file is not necessary or possible.") # source_ref: play_libretro.info (firmware_count absent = 0) diff --git a/emulators/pokketstation.yml b/emulators/pokketstation.yml index 15f6a9ff..d5e8b9f9 100644 --- a/emulators/pokketstation.yml +++ b/emulators/pokketstation.yml @@ -20,7 +20,7 @@ notes: | frontends/libretro/libretro.c:189-196). read_bios opens <system>/pocketstation.bin, reads 16384 bytes and fails when - fewer are read; a longer file is accepted and truncated + fewer are read, while a longer file is accepted and truncated (frontends/libretro/libretro.c:545-559). psemu_load_bios copies the image and rejects any size other than PSEMU_BIOS_SIZE (core/src/psemu.c:92-99). retro_load_game returns false when read_bios fails, and psemu_run executes @@ -36,17 +36,17 @@ notes: | 211-234, 326-347). Save RAM is the full 128 KB flash image. psemu_settings_offsets_known hashes the loaded image with FNV-1a and compares - it with 0xB2E46838, the retail 110 revision the project traced; a match + it with 0xB2E46838, the retail 110 revision the project traced, and a match enables the date, time and volume override writes into kernel RAM (core/src/psemu.c:1150-1175). Any 16 KB image boots. Two mask ROM revisions - are documented: 061, from prototype hardware, and 110, the retail one; the + are documented: 061, from prototype hardware, and 110, the retail one. The ASCII tags at offsets 0x1DFC (C061 or C110) and 0x3FFC (J061 or J110) identify them. SWI 0Fh FlashWriteSerial works on 061 and locks the CPU on 110 (docs/hardware-notes.md:1046-1056). The desktop application takes the BIOS path from the command line, then from the bios= key of settings.cfg beside the executable, then falls back - to bios.bin beside the executable; File > Load BIOS opens any path and + to bios.bin beside the executable. File > Load BIOS opens any path and writes it to settings.cfg (frontends/desktop/main.c:653-700, 1216-1254, 3016-3020, 3071-3091). The Vita frontend loads no BIOS yet (frontends/vita/main.c:31-33), and the Emscripten build leaves the BIOS to @@ -62,6 +62,6 @@ files: source_ref: "frontends/libretro/libretro.c:545-559, frontends/libretro/libretro.c:586-595, core/src/psemu.c:92-99, core/src/psemu.c:808-812, core/src/psemu.c:1150-1175, core/include/psemu/psemu.h:19" note: > Read from the frontend system directory. The desktop application reads - the whole file and psemu_load_bios rejects any size other than 16384; - the libretro core reads the first 16384 bytes. FNV-1a 0xB2E46838 + the whole file and psemu_load_bios rejects any size other than 16384, + while the libretro core reads the first 16384 bytes. FNV-1a 0xB2E46838 identifies the retail 110 revision for the settings overrides only. diff --git a/emulators/pom2.yml b/emulators/pom2.yml index 8598b99c..ff6f3c5a 100644 --- a/emulators/pom2.yml +++ b/emulators/pom2.yml @@ -49,7 +49,7 @@ notes: | Character generators follow charRomProbeOrder per profile, or the locale picked in the toolbar (src/CharRomCatalog.cpp:42-91, src/ProfileSwitch.cpp:135-141). Memory::loadCharRom accepts 2 KB, 4 KB - and 8 KB dumps (src/Memory.cpp:325-358); an 8 KB dump is two 4 KB banks, + and 8 KB dumps (src/Memory.cpp:325-358). An 8 KB dump is two 4 KB banks, loaded as one bank or kept dual-bank with annunciator 2 selecting the live set. @@ -58,22 +58,22 @@ notes: | sequencer built in (src/DiskIICard.cpp:136-149). CFFA, Liron, Workstation, the MC68705 mouse card, the 1981 Grappler, the Apple Parallel Interface and the Videx Videoterm leave the slot empty without - their dump; Grappler+, ThunderClock+ and the Super Serial Card run a + their dump. Grappler+, ThunderClock+ and the Super Serial Card run a synthetic ROM instead, and TransWarp accelerates without its boot firmware. The catalogue behind the ROM Status panel (src/RomCatalog.h) lists every name in probe order with the size the loader enforces, what a missing dump costs (degraded, card unavailable, unused) and, - where POM2 vouches for a dump, its CRC32; the panel hashes each present + where POM2 vouches for a dump, its CRC32. The panel hashes each present file (src/RomStatus_ImGui.cpp:169-181, 311). Help > Download missing ROMs (src/RomFetch.cpp:68-301) fetches 45 files, 43 distinct dumps, with curl from raw.githubusercontent.com/Abdess/retrobios, pinned to HTTPS (src/RomFetch.cpp:732-748). Every entry carries a - SHA-256, fourteen a CRC32 as well; a download is installed only when its + SHA-256, fourteen a CRC32 as well, and a download is installed only when its size, CRC32 and SHA-256 match (src/RomFetch.cpp:629-665). A present file is re-checked with the same gate and, when it is not the catalogued dump, replaced after a copy to roms-replaced/ under the data directory - (src/RomFetch.cpp:579-627, 833-853, 862-880); a 12 KB apple2p.rom is the + (src/RomFetch.cpp:579-627, 833-853, 862-880). A 12 KB apple2p.rom is the one alternate size kept as is. Nine entries are members of MAME romsets, read in-process (src/ZipMember.cpp): apple2e_unenh.rom is 342-0135-b.64 then 342-0134-a.64 from apple2e.zip, mouse_341-0270-c.bin is @@ -86,21 +86,21 @@ notes: | The floppy mechanical sounds are MAME's samples/floppy set, read from roms/floppy_samples/ as two banks of ten WAV files prefixed 525_ and 35_ - (src/FloppySoundDevice.cpp:81-119, src/MainWindow.cpp:345-358); a + (src/FloppySoundDevice.cpp:81-119, src/MainWindow.cpp:345-358). A missing sample is logged and the drive stays silent. A second bank, the Virtual ][ recordings, is read from roms/virtual_ii_sons/ when that directory exists (src/MainWindow.cpp:362-376): eight drive and switch takes under lecteur/ and interface/ (src/FloppySoundDevice.cpp:195-204) and one printer loop under imprimante/. The bank is selectable once Disk Rotation, Move arm, Disk Insertion and Disk Removal have loaded - (src/FloppySoundDevice.cpp:205-225); an .aiff name is retried as .wav + (src/FloppySoundDevice.cpp:205-225). An .aiff name is retried as .wav (src/FloppySoundDevice.cpp:166-187). The packaging manifest keeps the directory out of release packages (packaging/bundle.manifest:75-78). Media named by the code are not firmware and are not listed here: the browser demo boots floppyemu/DIX.po (wasm/shell.html:89) or, when the shell passes no disk, floppyemu/Total Replay v6.1.hdv - (src/main.cpp:285-289); the headless CLI mounts + (src/main.cpp:285-289), and the headless CLI mounts disks_5.4/dos33_master.dsk by default (src/pom2_headless.cpp:262-264). Disk, tape and hard-disk images are browsed from disks_5.4/, disks_3.5/, hdv/, floppyemu/, cassettes/ and prodos_folder/ next to the executable. @@ -116,7 +116,7 @@ files: sha1: "78008be557f643e956a106121bcc182c0fb9ea6d" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:38, src/Memory.cpp:174-237, src/RomFetch.cpp:72-75" - note: "First candidate of the Apple ][ Original profile; apple2.rom is probed next." + note: "First candidate of the Apple ][ Original profile. apple2.rom is probed next." - name: "apple2.rom" path: "roms/apple2.rom" description: "Apple ][ generic 12 KB fallback, Autostart monitor and Applesoft" @@ -138,7 +138,7 @@ files: sha1: "29a53f3bb158b160433369e8e4a1d7cd5bf68ac6" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:54, src/Memory.cpp:222-232, src/RomFetch.cpp:84-96, src/RomFetch.cpp:862-873" - note: "First candidate of the ][+ profile and of the first-run fallback (src/MainWindow.cpp:242-246). The loader drops the leading 4 KB of the 20 KB dump. The fetch gate names that dump; a 12 KB six-chip image already on disk is kept as present without a digest check." + note: "First candidate of the ][+ profile and of the first-run fallback (src/MainWindow.cpp:242-246). The loader drops the leading 4 KB of the 20 KB dump. The fetch gate names that dump, but a 12 KB six-chip image already on disk is kept as present without a digest check." - name: "apple2e.rom" path: "roms/apple2e.rom" description: "Apple //e Enhanced firmware, 32 KB dump with the 16 KB firmware in the upper half" @@ -161,7 +161,7 @@ files: sha1: "61fa9254628e5bb7236fb474006116d67684d747" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:78-79, src/SystemProfile.cpp:267-279, src/RomFetch.cpp:51-56, src/RomFetch.cpp:101-109" - note: "First candidate of the //e Unenhanced profiles; 342-0135-b.64.rom is probed second, apple2e.rom third. The fetcher assembles it from the two 8 KB chips of the MAME apple2e set, 342-0135-b.64 then 342-0134-a.64." + note: "First candidate of the //e Unenhanced profiles. 342-0135-b.64.rom is probed second, apple2e.rom third. The fetcher assembles it from the two 8 KB chips of the MAME apple2e set, 342-0135-b.64 then 342-0134-a.64." - name: "apple2c-32Kv0.rom" path: "roms/apple2c-32Kv0.rom" description: "Apple //c two-bank firmware, bank 0 in the lower 16 KB" @@ -210,7 +210,7 @@ files: sha1: "1a27ae26966bbafd825d08ad1a24742d3e33557c" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:204-205, src/SystemProfile.cpp:429-434, src/RomFetch.cpp:122-125" - note: "First candidate of the //c Plus profile; apple2c-plus.rom is probed second and apple2c-32Kv0.rom third." + note: "First candidate of the //c Plus profile. apple2c-plus.rom is probed second and apple2c-32Kv0.rom third." - name: "apple2_char.rom" path: "roms/apple2_char.rom" description: "Apple ][ and ][+ character generator, 2 KB uppercase set" @@ -233,7 +233,7 @@ files: sha1: "b2b5d87f52693817fc747df087a4aa1ddcdb1f10" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:105, src/SystemProfile.cpp:144, src/SystemProfile.cpp:206, src/CharRomCatalog.cpp:48-49, src/RomFetch.cpp:132-144, src/Memory.cpp:325-358" - note: "First candidate of the //e Enhanced, //c and //c Plus profiles; the same dump answers to apple2e_char_us.rom in the locale picker, and the fetcher writes both names." + note: "First candidate of the //e Enhanced, //c and //c Plus profiles. The same dump answers to apple2e_char_us.rom in the locale picker, and the fetcher writes both names." - name: "apple2e_char_us_unenh.rom" path: "roms/apple2e_char_us_unenh.rom" description: "Apple //e Unenhanced character generator 342-0133-A, 4 KB" @@ -245,7 +245,7 @@ files: sha1: "58ad0008df72896a18601e090ee0d58155ffa5be" validation: [size, sha256] source_ref: "src/SystemProfile.cpp:83-84, src/CharRomCatalog.cpp:50-51, src/RomFetch.cpp:145-152, src/Memory.cpp:325-358" - note: "The //e Unenhanced profile probes apple2e_char_2k.rom then 341-0265-a.chr.rom then apple2_char.rom; the same dump ships under both names and the fetcher writes both." + note: "The //e Unenhanced profile probes apple2e_char_2k.rom then 341-0265-a.chr.rom then apple2_char.rom. The same dump ships under both names and the fetcher writes both." - name: "apple2e_char_fr.rom" path: "roms/apple2e_char_fr.rom" description: "Apple //e French character generator, 4 KB" @@ -268,7 +268,7 @@ files: sha1: "4043e0808af8be096660827445e41149d16c5c85" validation: [size, sha256] source_ref: "src/CharRomCatalog.cpp:54-55, src/CharRomCatalog.cpp:165-180, src/RomFetch.cpp:159-162, src/Memory.cpp:325-358" - note: "Locale picker entry; equals the low bank of 342-0274-a.e9." + note: "Locale picker entry, equal to the low bank of 342-0274-a.e9." - name: "apple2e_char_uk.rom" path: "roms/apple2e_char_uk.rom" description: "Apple //e UK Enhanced character generator 342-0273-A, 4 KB" @@ -323,7 +323,7 @@ files: sha1: "c81c1bbf237e70f8c3e5eef3c8fd5bd9b9f54d1e" validation: [size, sha256] source_ref: "src/CharRomCatalog.cpp:81-84, src/CharRomCatalog.cpp:158-163, src/RomFetch.cpp:179-184, src/RomStatus_ImGui.cpp:250, src/Memory.cpp:325-358" - note: "Locale picker entries select bank 0 or bank 1; loaded whole, both banks stay live and annunciator 2 picks the set." + note: "Locale picker entries select bank 0 or bank 1. Loaded whole, both banks stay live and annunciator 2 picks the set." - name: "apple2e_char_ft_blockascii.rom" path: "roms/apple2e_char_ft_blockascii.rom" description: "French Touch Block ASCII dual-bank character generator, 8 KB" @@ -345,7 +345,7 @@ files: sha256: "097cd3500afe6c15d710d2e96af539a8e5065853986289294aac08ee7a1f070a" validation: [size] source_ref: "src/CharRomCatalog.cpp:87-88, src/CharRomCatalog.cpp:165-180, src/RomStatus_ImGui.cpp:250, src/Memory.cpp:325-358" - note: "Locale picker entry. Shipped in roms/; the fetcher does not serve it, so only the size is checked." + note: "Locale picker entry. Shipped in roms/. The fetcher does not serve it, so only the size is checked." - name: "apple2e_char_reactive.rom" path: "roms/apple2e_char_reactive.rom" description: "ReActive custom Apple //e character generator, 4 KB" @@ -356,7 +356,7 @@ files: sha256: "49716e2804b119810c22ab668ae37cebadf0cd53bc8911b5f17c4a62a3acb514" validation: [size] source_ref: "src/CharRomCatalog.cpp:89-90, src/CharRomCatalog.cpp:165-180, src/RomStatus_ImGui.cpp:250, src/Memory.cpp:325-358" - note: "Locale picker entry. Shipped in roms/; the fetcher does not serve it, so only the size is checked." + note: "Locale picker entry. Shipped in roms/. The fetcher does not serve it, so only the size is checked." - name: "Videx Lower Case Chip ROM.bin" path: "roms/Videx Lower Case Chip ROM.bin" description: "Videx LOWER CASE CHIP character generator for the ][ and ][+, 2 KB" @@ -367,7 +367,7 @@ files: sha1: "447874fe0850c8add3fd5b13fa98f6648fe6f999" validation: [size, crc32, sha256] source_ref: "src/CharRomCatalog.cpp:44-45, src/RomCatalog.h:208-214, src/RomFetch.cpp:190-194, src/RomStatus_ImGui.cpp:311" - note: "Locale picker entry for the ][ and ][+ profiles; without it the picker keeps the stock uppercase set." + note: "Locale picker entry for the ][ and ][+ profiles. Without it the picker keeps the stock uppercase set." - name: "disk2.rom" path: "roms/disk2.rom" description: "Disk II 16-sector boot PROM 341-0027-A" @@ -378,7 +378,7 @@ files: sha1: "d4181c9f046aafc3fb326b381baac809d9e38d16" validation: [size, sha256] source_ref: "src/SlotCardFactory.cpp:102-115, src/DiskIICard.cpp:136-141, src/DiskIICard.cpp:151-174, src/RomFetch.cpp:197-200" - note: "The card carries the same PROM built in; the file replaces it when present." + note: "The card carries the same PROM built in, and the file replaces it when present." - name: "diskii_p6.rom" path: "roms/diskii_p6.rom" description: "Disk II 16-sector P6 logic state sequencer PROM 341-0028-A" @@ -389,7 +389,7 @@ files: sha1: "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4" validation: [size, sha256] source_ref: "src/SlotCardFactory.cpp:102-115, src/DiskIICard.cpp:142-149, src/DiskIICard.cpp:176-202, src/DiskIICard.cpp:251-263, src/RomFetch.cpp:201-204" - note: "Loading the file switches the bit-level LSS path on for every image; without it the legacy 32-cycle nibble gate serves non-WOZ images and the built-in PROM serves WOZ images." + note: "Loading the file switches the bit-level LSS path on for every image. Without it the legacy 32-cycle nibble gate serves non-WOZ images and the built-in PROM serves WOZ images." - name: "disk2_13.rom" path: "roms/disk2_13.rom" description: "Disk II 13-sector boot PROM 341-0009" @@ -399,7 +399,7 @@ files: sha1: "afd060e6f35faf3bb0146fa889fc787adf56330a" validation: [size, sha256] source_ref: "src/SlotCardFactory.cpp:102-115, src/DiskIICard.cpp:204-221, src/DiskIICard.cpp:264-288, src/RomCatalog.h:90-93, src/RomFetch.cpp:205-208" - note: "A mounted 13-sector disk switches the card to this PROM at $Cn00 and forces the bit-level LSS; without it the disk mounts but cannot boot." + note: "A mounted 13-sector disk switches the card to this PROM at $Cn00 and forces the bit-level LSS. Without it the disk mounts but cannot boot." - name: "diskii_p6_13.rom" path: "roms/diskii_p6_13.rom" description: "Disk II 13-sector P6 logic state sequencer PROM 341-0010" @@ -420,7 +420,7 @@ files: sha1: "080ff88f19de22328e162954ee2b51ee65f9d5cd" validation: [size, crc32, sha256] source_ref: "src/SlotCardFactory.cpp:124-148, src/CffaCard.cpp:26-40, src/RomCatalog.h:119-123, src/RomFetch.cpp:223-226" - note: "Preferred when the CPU is a 65C02, the 6502 build is the fallback; the slot stays empty when neither is found." + note: "Preferred when the CPU is a 65C02, the 6502 build is the fallback, and the slot stays empty when neither is found." - name: "cffa20ee02.bin" path: "roms/cffa20ee02.bin" description: "CFFA 2.0 firmware, 6502 build" @@ -520,7 +520,7 @@ files: sha1: "19f69011ed7d2551c39d5c1cac1f5a2defc8f8fb" validation: [size, crc32, sha256] source_ref: "src/SlotCardFactory.cpp:235-246, src/SlotCardFactory.cpp:254-264, src/VidexVideotermCard.cpp:40-47, src/RomCatalog.h:165-171, src/RomFetch.cpp:263-266" - note: "First firmware candidate of the Videoterm card; the 50 Hz dump is probed second. With neither the slot stays empty. The fetcher extracts it from the MAME a2vidtrm set." + note: "First firmware candidate of the Videoterm card. The 50 Hz dump is probed second. With neither the slot stays empty. The fetcher extracts it from the MAME a2vidtrm set." - name: "videx_videoterm_v24_50hz.bin" path: "roms/videx_videoterm_v24_50hz.bin" description: "Videx Videoterm firmware v2.4 with the 50 Hz CRTC table, 1 KB, MAME a2videoterm videx videoterm rom 2.4.bin" @@ -565,7 +565,7 @@ files: sha1: "60f434f5325899d7ea257a6e56e6f53eae65146a" validation: [size, sha256] source_ref: "src/ClockCard.cpp:469-530, src/RomCatalog.h:216-226, src/RomFetch.cpp:227-230" - note: "The card loads a 256-byte slot ROM or the 2 KB chip, which supplies the $C800 expansion ROM as well; the fetch gate names the 2 KB dump and replaces a 256-byte file. The first four even bytes must read $08, $28, $58, $70, the ProDOS clock signature, or the synthetic ROM stays in place." + note: "The card loads a 256-byte slot ROM or the 2 KB chip, which supplies the $C800 expansion ROM as well. The fetch gate names the 2 KB dump and replaces a 256-byte file. The first four even bytes must read $08, $28, $58, $70, the ProDOS clock signature, or the synthetic ROM stays in place." - name: "liron.rom" path: "roms/liron.rom" description: "Apple Liron SmartPort controller firmware, 4 KB" @@ -587,7 +587,7 @@ files: sha1: "59c8e8c88bac5c31ada1306b412edfcf5912a720" validation: [size, crc32, sha256] source_ref: "src/SlotCardFactory.cpp:274-297, src/WorkstationCard.cpp:60-74, src/RomCatalog.h:198-206, src/RomFetch.cpp:291-294" - note: "The Workstation card leaves its slot empty without it; the card runs its own 65C02 on the upper 32 KB." + note: "The Workstation card leaves its slot empty without it. The card runs its own 65C02 on the upper 32 KB." - name: "341-0438-a.bin" path: "roms/341-0438-a.bin" description: "Apple II 3.5 Disk Controller SuperDrive firmware 341-0438-A, MAME a2superdrive" @@ -598,7 +598,7 @@ files: sha1: "440c3f84176c7b9f542da0b6ddf4fb13ec326c46" validation: [size, crc32, sha256] source_ref: "src/RomCatalog.h:105-111, src/RomStatus_ImGui.cpp:169-181, src/RomFetch.cpp:287-290" - note: "No card reads it; the ROM Status panel and the fetch gate check it." + note: "No card reads it. The ROM Status panel and the fetch gate check it." - name: "342-0326-a.f12" path: "roms/342-0326-a.f12" description: "Apple //e French keyboard decode ROM 342-0326-A, MAME apple2eefr" @@ -609,7 +609,7 @@ files: sha1: "806a602195c18ffec637c03b6bb3405188b0dc1e" validation: [size, crc32, sha256] source_ref: "src/RomCatalog.h:112-118, src/RomStatus_ImGui.cpp:169-181, src/RomStatus_ImGui.cpp:311, src/RomFetch.cpp:295-298" - note: "Host keys are mapped directly, no keyboard decode ROM is emulated; the ROM Status panel and the fetch gate check the file only." + note: "Host keys are mapped directly, no keyboard decode ROM is emulated. The ROM Status panel and the fetch gate check the file only." - name: "525_seek_2ms.wav" path: "roms/floppy_samples/525_seek_2ms.wav" description: "MAME floppy sample, 5.25 inch drive, 2 ms head seek" @@ -618,7 +618,7 @@ files: size: 5336 sha1: "2d046a880476218685ed738fe8c8381962afd74a" source_ref: "src/FloppySoundDevice.cpp:81-119, src/MainWindow.cpp:345-358" - note: "One of ten samples per drive bank; a missing sample is logged and that sound stays silent." + note: "One of ten samples per drive bank. A missing sample is logged and that sound stays silent." - name: "525_seek_6ms.wav" path: "roms/floppy_samples/525_seek_6ms.wav" description: "MAME floppy sample, 5.25 inch drive, 6 ms head seek" @@ -699,7 +699,7 @@ files: size: 7450 sha1: "55caafbd19486b8d517e4b33a6fa65250df55e25" source_ref: "src/FloppySoundDevice.cpp:81-119, src/MainWindow.cpp:345-358" - note: "One of ten samples per drive bank; a missing sample is logged and that sound stays silent." + note: "One of ten samples per drive bank. A missing sample is logged and that sound stays silent." - name: "35_seek_6ms.wav" path: "roms/floppy_samples/35_seek_6ms.wav" description: "MAME floppy sample, 3.5 inch drive, 6 ms head seek" @@ -792,7 +792,7 @@ files: required: false aliases: ["Move arm.wav"] source_ref: "src/FloppySoundDevice.cpp:198, src/FloppySoundDevice.cpp:166-187, src/FloppySoundDevice.cpp:205-225, src/MainWindow.cpp:362-376" - note: "Needed for the bank; the .wav name is tried when the .aiff does not decode." + note: "Needed for the bank. The .wav name is tried when the .aiff does not decode." - name: "Disk Insertion.aiff" path: "roms/virtual_ii_sons/lecteur/Disk Insertion.aiff" description: "Virtual ][ recording, drive lid, disk inserted" @@ -800,7 +800,7 @@ files: required: false aliases: ["Disk Insertion.wav"] source_ref: "src/FloppySoundDevice.cpp:199, src/FloppySoundDevice.cpp:166-187, src/FloppySoundDevice.cpp:205-225, src/MainWindow.cpp:362-376" - note: "Needed for the bank; the .wav name is tried when the .aiff does not decode." + note: "Needed for the bank. The .wav name is tried when the .aiff does not decode." - name: "Disk Removal.aiff" path: "roms/virtual_ii_sons/lecteur/Disk Removal.aiff" description: "Virtual ][ recording, drive lid, disk removed" @@ -808,7 +808,7 @@ files: required: false aliases: ["Disk Removal.wav"] source_ref: "src/FloppySoundDevice.cpp:200, src/FloppySoundDevice.cpp:166-187, src/FloppySoundDevice.cpp:205-225, src/MainWindow.cpp:362-376" - note: "Needed for the bank; the .wav name is tried when the .aiff does not decode." + note: "Needed for the bank. The .wav name is tried when the .aiff does not decode." - name: "I-O Error.wav" path: "roms/virtual_ii_sons/lecteur/I-O Error.wav" description: "Virtual ][ recording, read error one-shot" @@ -835,7 +835,7 @@ files: category: game_data required: false source_ref: "src/MainWindow.cpp:372-374, src/PrinterSoundDevice.cpp:272-299" - note: "Loaded when present; the printer sound is generated otherwise." + note: "Loaded when present, otherwise the printer sound is generated." - name: "DejaVuSans.ttf" path: "fonts/DejaVuSans.ttf" description: "DejaVu Sans, the frontend text font" @@ -874,4 +874,4 @@ files: size: 794259 sha1: "a178f37661078739637ff7642cd6450c762993aa" source_ref: "src/MainWindow_MiscPanels.cpp:480" - note: "The window hotspots are fractions of this image; without it the window has nothing to click." + note: "The window hotspots are fractions of this image. Without it the window has nothing to click." diff --git a/emulators/potator.yml b/emulators/potator.yml index 0962e1e3..27040651 100644 --- a/emulators/potator.yml +++ b/emulators/potator.yml @@ -14,6 +14,6 @@ systems: notes: | Watara Supervision emulator. No BIOS required. - The Supervision has no BIOS ROM; games execute directly from cartridge. + The Supervision has no BIOS ROM, and games execute directly from cartridge. files: [] diff --git a/emulators/prboom-plus.yml b/emulators/prboom-plus.yml index 0092d775..8c5aca64 100644 --- a/emulators/prboom-plus.yml +++ b/emulators/prboom-plus.yml @@ -51,7 +51,7 @@ notes: | snd_midiplayer picks the MIDI backend and defaults to fluidsynth on Windows, sdl elsewhere (prboom2/src/m_misc.c:444-450). Only the sdl value leaves use_experimental_music clear and routes MIDI through SDL_mixer - (SDL/i_sound.c:1662-1668, 1221-1225); every other value brings up the + (SDL/i_sound.c:1662-1668, 1221-1225), while every other value brings up the in-tree players. Their init results are recorded once at startup (SDL/i_sound.c:1383-1384) and consulted per song, a player that failed to init being logged and passed over for the next entry of music_player_order @@ -74,7 +74,7 @@ files: neither IWAD nor PWAD (prboom2/src/w_wad.c:216-218). Hashes are those of the file rdatawad produces from the data/ assets at this revision, which matches the copy in the v2.6.66 release archive byte for byte. They identify the - 2.6.66 build; other versions carry different lumps. + 2.6.66 build, and other versions carry different lumps. - name: "TimGM6mb.sf2" system: doom diff --git a/emulators/project64.yml b/emulators/project64.yml index 25654626..f447218f 100644 --- a/emulators/project64.yml +++ b/emulators/project64.yml @@ -17,7 +17,7 @@ mode: standalone notes: | Nintendo 64 and 64DD emulator for Windows. Project64.exe plus the plugin DLLs the same solution builds, driven by the plugin spec in Source/Project64-plugin-spec. - ES-DE passes the ROM as the only argument. AppVeyor builds Win32 and x64 only; + ES-DE passes the ROM as the only argument. AppVeyor builds Win32 and x64 only, and Source/Android holds no build file. Cartridge boot reads no file. PostPif is hardcoded true, so Reset seeds the @@ -56,7 +56,7 @@ notes: | GLideN64 ships as a bundled plugin, pinned as a submodule at gonetz/GLideN64 c8ef81c7d9aede9f67f6ed3d3426c90541f9f13e, and brings its own GLideN64.ini, GLideN64.custom.ini and translations. Project64's own code names - none of them; only Installer.iss and package_zip.cmd copy them + none of them. Only Installer.iss and package_zip.cmd copy them (Source/Installer/Installer.iss:38, Source/Script/package_zip.cmd:42-47). Generated at runtime, never supplied: Project64.cfg, Project64.rdn, diff --git a/emulators/punes.yml b/emulators/punes.yml index 8583263c..04377b07 100644 --- a/emulators/punes.yml +++ b/emulators/punes.yml @@ -25,7 +25,7 @@ notes: | the loaded image, then the bios folder of the data directory. nes20db.xml and dip.cfg are read from the XDG data directories under a puNES subdirectory, then the base of the data directory, then the application - directory (src/gui/nes20db.cpp:50-79, src/gui/dipswitch.cpp:61-85); the + directory (src/gui/nes20db.cpp:50-79, src/gui/dipswitch.cpp:61-85), and the installer writes both into the shared data directory (CMakeLists.txt:227-228). diff --git a/emulators/pygame.yml b/emulators/pygame.yml index b3755ec4..37bf7d8e 100644 --- a/emulators/pygame.yml +++ b/emulators/pygame.yml @@ -16,7 +16,7 @@ notes: | bindings for Python, used by batocera as a launcher that runs user-supplied Python scripts (file.py) as the "ROM". Batocera's package batocera/emulators/python-pygame2 pins the standard pygame/pygame 2.6.1 - wheel; nothing about pygame itself ships game data. + wheel. Nothing about pygame itself ships game data. The content executed by this launcher is the user's own Python file, which plays the role of the cartridge. No file in the pack belongs here. diff --git a/emulators/pyxel.yml b/emulators/pyxel.yml index c022de91..5a3dadde 100644 --- a/emulators/pyxel.yml +++ b/emulators/pyxel.yml @@ -5,7 +5,7 @@ source: "https://github.com/kitao/pyxel" upstream: "https://github.com/kitao/pyxel" profiled_date: "2026-10-04" source_commit: "50f9bd77780c993aca62b5b221766bde5791081d" -upstream_gone: "github.com/kitao/pyxel answers HTTP 404 to the API and the web, with no redirect. Observed 2026-10-18; no mirror found." +upstream_gone: "github.com/kitao/pyxel answers HTTP 404 to the API and the web, with no redirect. Observed 2026-10-18, no mirror found." core_version: "v2.9.9" display_name: "Pyxel" cores: [pyxel] @@ -28,10 +28,10 @@ notes: | Batocera's packaging (package/batocera/emulators/python-pyxel/python-pyxel.mk) installs the wheel into site-packages, drops the examples, and provides a pyxel.keys evmapy layout. The content run by Pyxel is the user's .pyxapp or - .py file, which plays the role of a cartridge; those are user content, not + .py file, which plays the role of a cartridge. Those are user content, not pack contents. - The engine refuses nothing on startup; a bare `pyxel init` plus a user + The engine refuses nothing on startup: a bare `pyxel init` plus a user script is enough to run. files: [] diff --git a/emulators/race.yml b/emulators/race.yml index 621f629a..8dc14255 100644 --- a/emulators/race.yml +++ b/emulators/race.yml @@ -17,7 +17,7 @@ notes: | by theelf, then adapted for libretro. No external BIOS files are required. The upstream versions (GP2X, PSP) load - NPBIOS.BIN optionally; the libretro port's loadBIOS() returns 0 + NPBIOS.BIN optionally, but the libretro port's loadBIOS() returns 0 unconditionally, and the disabled file-reading body it once carried under #if 0 was removed in June 2026, so the port no longer names the file. The core never queries the system directory: the only files it opens are the @@ -44,7 +44,7 @@ analysis: note: | loadBIOS() returns 0 unconditionally in the libretro port, so mem_init() always takes the HLE branch. The #if 0 body that opened NPBIOS.BIN with - filestream_open() was dropped by commit 0e4783a on 2026-06-15; the + filestream_open() was dropped by commit 0e4783a on 2026-06-15, and the libretro tree no longer contains the name. In upstream, loadBIOS() opens NPBIOS.BIN from the working directory with fopen(), requires exactly 0x10000 bytes, and falls back to HLE when the file is absent or short. diff --git a/emulators/radio.yml b/emulators/radio.yml index 6f689e01..0b794229 100644 --- a/emulators/radio.yml +++ b/emulators/radio.yml @@ -31,7 +31,7 @@ notes: | each is given a fake FM frequency for the tuner. A playlist that parses to zero entries counts as no content and the chain above continues, which is what the zero-byte empty.m3u in the repository is for. Local audio is - opened from the path the playlist or the frontend gives; a WAV must be + opened from the path the playlist or the frontend gives, and a WAV must be PCM or float with a fmt and a data chunk. ref: libretro-radio.c:1965-1971, libretro-radio.c:37, libretro-radio.c:2221-2291, libretro-radio.c:2419-2435, @@ -40,14 +40,14 @@ notes: | Streaming is a hand-written HTTP/1.0 client over an AF_INET socket: the URL scheme is stripped, an https:// entry is joined in clear on the port it names or 80, ICY status lines are accepted and up to five redirects - are followed. No TLS library, certificate store or font file is read; the + are followed. No TLS library, certificate store or font file is read: the 8x8 glyphs are a table in the binary. MP3 decoding is libmad, compiled in from the libretro-deps submodule. ref: libretro-radio.c:517-548, libretro-radio.c:564-743, libretro-radio.c:81, Makefile:30-45, .gitlab-ci.yml:13-17 The presets are the loaded list seen through the Active Preset core - option, which selects entries 1 to 100 by index; a list longer than that + option, which selects entries 1 to 100 by index, and a list longer than that is still walked with up and down on the pad. retro_load_game accepts a null game, but retro_set_environment only sets the pixel format and the variables and never announces SET_SUPPORT_NO_GAME, so the frontend still @@ -73,7 +73,7 @@ files: Opened from the system directory, then from the save directory, then from the working directory, each only while no station has been loaded yet. Parsed like a content playlist and accepted once one entry - comes out of it; a missing or empty file hands over to the + comes out of it. A missing or empty file hands over to the radio-browser.info API and then to the eight built-in SomaFM streams. A file put here replaces those two fallbacks for every start without content. diff --git a/emulators/raze.yml b/emulators/raze.yml index 7428969f..112e5415 100644 --- a/emulators/raze.yml +++ b/emulators/raze.yml @@ -45,7 +45,7 @@ notes: | The directory of the first identified resource is mounted as well, so loose files beside it are read by name. Tiles come from tiles000.art to tiles199.art, from the `loadart` list of the block and - from the -art switch; no other ART name is looked up. + from the -art switch. No other ART name is looked up. ref: source/core/initfs.cpp:342-372, source/core/textures/tiletexture.cpp:468-481, source/core/gamecontrol.cpp:424 @@ -66,7 +66,7 @@ files: path: "soundfonts/raze.sf2" required: false source_ref: "source/common/audio/music/i_soundfont.cpp:334-352, 427-430, 439-459, source/CMakeLists.txt:1452" - note: "Default soundfont, used when the soundfont directories hold none. Every file of those directories is taken by its content; when no soundfont is named raze the first SF2 found is used." + note: "Default soundfont, used when the soundfont directories hold none. Every file of those directories is taken by its content, and when no soundfont is named raze the first SF2 found is used." # ================================================================ # Duke Nukem 3D family @@ -419,7 +419,7 @@ files: path: "SOUNDS.RFF" required: false source_ref: "wadsrc/static/engine/grpinfo.txt:494, 510, 526, 542" - note: "Named by loadgrp in every Blood block; loaded with the main resource." + note: "Named by loadgrp in every Blood block and loaded with the main resource." - name: "GUI.RFF" category: game_data @@ -427,7 +427,7 @@ files: path: "GUI.RFF" required: false source_ref: "wadsrc/static/engine/grpinfo.txt:494, 510, 526, 542" - note: "Named by loadgrp in every Blood block; loaded with the main resource." + note: "Named by loadgrp in every Blood block and loaded with the main resource." - name: "BLOOD.GRP" category: game_data @@ -435,7 +435,7 @@ files: path: "BLOOD.GRP" required: false source_ref: "wadsrc/static/engine/grpinfo.txt:494, 510, 526, 542" - note: "Named by loadgrp in every Blood block; loaded with the main resource." + note: "Named by loadgrp in every Blood block and loaded with the main resource." - name: "SURFACE.DAT" category: game_data @@ -443,7 +443,7 @@ files: path: "SURFACE.DAT" required: false source_ref: "source/games/blood/src/tile.cpp:67-75, source/core/initfs.cpp:351-372" - note: "Surface type of each tile. Read from the directory of the main resource; skipped when absent." + note: "Surface type of each tile. Read from the directory of the main resource, skipped when absent." - name: "VOXEL.DAT" category: game_data @@ -451,7 +451,7 @@ files: path: "VOXEL.DAT" required: false source_ref: "source/games/blood/src/tile.cpp:77-93, source/core/initfs.cpp:351-372" - note: "Voxel index of each tile. Read from the directory of the main resource; skipped when absent." + note: "Voxel index of each tile. Read from the directory of the main resource, skipped when absent." - name: "SHADE.DAT" category: game_data @@ -459,7 +459,7 @@ files: path: "SHADE.DAT" required: false source_ref: "source/games/blood/src/tile.cpp:95-103, source/core/initfs.cpp:351-372" - note: "Shade offset of each tile. Read from the directory of the main resource; skipped when absent." + note: "Shade offset of each tile. Read from the directory of the main resource, skipped when absent." - name: "CRYPTIC.INI" category: game_data @@ -467,7 +467,7 @@ files: path: "CRYPTIC.INI" required: false source_ref: "wadsrc/static/engine/grpinfo.txt:574-585, source/core/gamecontrol.cpp:361-367, source/core/searchpaths.cpp:712-730" - note: "Cryptic Passage addon. Detected next to the Blood files when CRYPTIC.INI, CP01.MAP and CP02.MAP are all present; depends on One Unit Whole Blood and loads CPART07.AR_ and CPART15.AR_." + note: "Cryptic Passage addon. Detected next to the Blood files when CRYPTIC.INI, CP01.MAP and CP02.MAP are all present. Depends on One Unit Whole Blood and loads CPART07.AR_ and CPART15.AR_." # ================================================================ # Shadow Warrior diff --git a/emulators/rb5000.yml b/emulators/rb5000.yml index d564d285..93eb1c72 100644 --- a/emulators/rb5000.yml +++ b/emulators/rb5000.yml @@ -33,9 +33,9 @@ notes: | table and decoder. The libretro core can map a user cartridge file over 0x0000-0x3FFF - when one is configured (ref: source/Engine.cpp:302-316); that file is + when one is configured (ref: source/Engine.cpp:302-316), and that file is content. The on-screen display font is an Ubuntu TTF from the host system fonts directory (ref: source/Video.cpp:90-92). -exclusion_note: "VG 5000 system ROM is encoded in a compiled-in image table and decoded on first access; no file is read" +exclusion_note: "VG 5000 system ROM is encoded in a compiled-in image table and decoded on first access, so no file is read" files: [] diff --git a/emulators/real3doplayer.yml b/emulators/real3doplayer.yml index 1ce966a0..d7ce49ec 100644 --- a/emulators/real3doplayer.yml +++ b/emulators/real3doplayer.yml @@ -23,7 +23,7 @@ notes: | certificate sha256 336dca7bf758d4d4d3e31783a1cb3f777cf0f0791ff6b1a8bbf698892f8860a9 (C=RU, L=Tula, O=AltmerSoft, CN=MAXIM GRISHIN): versionCode 33, minSdk 14, targetSdk 23, seven ABIs. Java line numbers below are jadx output of that build and - native addresses are its arm64-v8a library; the armeabi-v7a library carries the same + native addresses are its arm64-v8a library, and the armeabi-v7a library carries the same strings and the same constants. The decompiled tree published as BoUnCe587/Real3DOPlayer was rejected: it is signed with the AOSP test key a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc. @@ -42,7 +42,7 @@ notes: | (MainActivity.java:469-471,412-414). Nothing is recognised by name. A ROM candidate is measured, and a file of 3 MB or - more is dropped before it is read; the remainder is scanned on four byte boundaries + more is dropped before it is read. The remainder is scanned on four byte boundaries for the RomTag signature 01 5A 5A 5A 5A 5A 01 00, and the 0x84 byte header at that point is read back. The null terminated string at header offset 0x28 is what sorts the file: "rom" fills the BIOS list, "rom2" the font list, and "fmvrom" is compared @@ -70,8 +70,8 @@ notes: | 0xe98cc), and no ext-fmv key exists. Files the app makes for itself, in its storage directory rather than the scan - directory: nvram.bin, the 32 KB console save area, erasable from the interface; - configs.xml and settings.ini; save states; and the controller maps. madam.bin and + directory: nvram.bin (the 32 KB console save area, erasable from the interface), + configs.xml and settings.ini, save states, and the controller maps. madam.bin and clio.bin name 2 KB and 64 KB regions of the emulator's own state blob and are reached only in mode 2 (0x8ce8c-0x8d064). @@ -108,7 +108,7 @@ files: note: >- Found by the same scan of the same directory, and taken as the font when the RomTag header names itself "rom2". Held in its own list and mapped into a second - 1 MB window of the machine. Japanese titles draw their kanji from it; the + 1 MB window of the machine. Japanese titles draw their kanji from it. The emulator starts and runs without one, and the core carries GRAFERR_NO_FONT and GRAFERR_BADFONTFILE for that case. source_ref: "Real3DOPlayer 1.0.32 MainActivity.java:413,471 (ext-font), diff --git a/emulators/redream.yml b/emulators/redream.yml index 3919f6cf..3f030d30 100644 --- a/emulators/redream.yml +++ b/emulators/redream.yml @@ -1,4 +1,4 @@ -# Redream — Sega Dreamcast (libretro) +# Redream: Sega Dreamcast (libretro) # ref: libretro/redream, docs.libretro.com/library/redream # Uses dc/boot.bin and dc/flash.bin (different names from Flycast) # Same BIOS data as Flycast's dc_boot.bin / dc_flash.bin diff --git a/emulators/reicast.yml b/emulators/reicast.yml index a425fc2e..66ebc0d0 100644 --- a/emulators/reicast.yml +++ b/emulators/reicast.yml @@ -15,7 +15,7 @@ systems: notes: | Dreamcast emulator descended from nullDC. The Linux build is compiled - for one platform; the default is dreamcast, which sets the ROM prefix + for one platform, and the default is dreamcast, which sets the ROM prefix dc_, a 2 MB boot ROM, a 128 KB flash and NVR_OPTIONAL 0 (ref: core/types.h:209-217). diff --git a/emulators/reminiscence.yml b/emulators/reminiscence.yml index b2078414..a6fd2c39 100644 --- a/emulators/reminiscence.yml +++ b/emulators/reminiscence.yml @@ -27,7 +27,7 @@ notes: | LEVEL1.MAP -> DOS LEVEL1.LEV -> Amiga DEMO.LEV -> Amiga Demo - Only kResourceTypeDOS is accepted (line 199); Amiga data is rejected. + Only kResourceTypeDOS is accepted (line 199), so Amiga data is rejected. Language detection (src/libretro.cpp:142-166) probes for: ENGCINE.TXT -> English @@ -44,10 +44,10 @@ notes: | like "LEVEL1.MAP", "GLOBAL.ICN", "PERSO.SPR", "FB_TXT.FNT", etc. The core never calls RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY. All data files must live - alongside the loaded .MAP content file. No BIOS or firmware files; the required files + alongside the loaded .MAP content file. No BIOS or firmware files: the required files are the original Flashback DOS game data. - Music loaded from .mod files (mod_player.cpp, staticres.cpp:3198-3225). Optional; + Music loaded from .mod files (mod_player.cpp, staticres.cpp:3198-3225). Optional: the core has a built-in SFX player for in-game action music (sfx_player.cpp with embedded music data in staticres.cpp). diff --git a/emulators/rosalies-mupen-gui.yml b/emulators/rosalies-mupen-gui.yml index 235ee5cd..77efbb79 100644 --- a/emulators/rosalies-mupen-gui.yml +++ b/emulators/rosalies-mupen-gui.yml @@ -24,7 +24,7 @@ notes: | softrdp, and the raphnetraw input plugin are vendored alongside it, plus RMG's own audio and input plugins. softrdp opens no data file. ES-DE runs it as `--nogui -q <rom>` for both n64 and n64dd. Against mupen64plus-core 6dca4c15 the media loader, the DD region - enum and load_dd_rom are unchanged; the fork diverges on SDL3, video + enum and load_dd_rom are unchanged. The fork diverges on SDL3, video capture, netplay and the dynarec. Cartridge boot needs no boot ROM. The PIF boot ROM is simulated @@ -57,20 +57,20 @@ notes: | (Source/3rdParty/mupen64plus-core/src/device/gb/gb_cart.c:999-1012) and fixes no name, size or hash, so neither the cart nor its save carries an entry here. - Data the install places in the shared data directory (CMakeLists.txt:130-153; + Data the install places in the shared data directory (CMakeLists.txt:130-153, /usr/share/RMG, or Data beside the executable for portable and Windows builds, Source/RMG-Core/Directories.cpp:406-431): mupen64plus.ini, read as the ROM database (Source/3rdParty/mupen64plus-core/src/main/rom.c:585-604) and used by GLideN64 to locate that same directory - (Source/3rdParty/mupen64plus-video-GLideN64/src/mupenplus/CommonAPIImpl_mupenplus.cpp:77-85); GLideN64.custom.ini, per ROM + (Source/3rdParty/mupen64plus-video-GLideN64/src/mupenplus/CommonAPIImpl_mupenplus.cpp:77-85). GLideN64.custom.ini holds per ROM overrides keyed on the uppercased header name - (Source/3rdParty/mupen64plus-video-GLideN64/src/mupenplus/Config_mupenplus.cpp:331-350); font.ttf, reached only after the + (Source/3rdParty/mupen64plus-video-GLideN64/src/mupenplus/Config_mupenplus.cpp:331-350). font.ttf is reached only after the configured font name fails both as a system font path and as a full path - (Source/3rdParty/mupen64plus-video-GLideN64/src/TextDrawer.cpp:202-230); Cheats/<name>.cht, named from the header CRC pair + (Source/3rdParty/mupen64plus-video-GLideN64/src/TextDrawer.cpp:202-230). Cheats/<name>.cht is named from the header CRC pair and country code, or from the ROM MD5 when all three are zero, and merged with a user copy under the config directory - (Source/RMG-Core/Cheats.cpp:82-116,579-598); InputProfileDB.json - (Source/RMG-Input/Utilities/InputProfileDB.cpp:26-36); gamecontrollerdb.txt - (Source/RMG-Input/main.cpp:1071-1077); and for VRU builds + (Source/RMG-Core/Cheats.cpp:82-116,579-598). The directory also holds InputProfileDB.json + (Source/RMG-Input/Utilities/InputProfileDB.cpp:26-36), gamecontrollerdb.txt + (Source/RMG-Input/main.cpp:1071-1077) and, for VRU builds, vosk-model-small-en-us-0.15.zip, extracted into the user data directory when any of the thirteen model files it checks for is missing (Source/RMG-Input/VRU.cpp:154-232). The published AppImage is the features-on build, @@ -99,7 +99,7 @@ notes: | data/mupencheat.txt, which RMG neither installs nor parses since cheats use its own .cht format and the core's cheat.c opens no file, and cxd4's rsp_conf.bin, whose reader is the zilmar variant of update_conf behind - #if !defined(M64P_PLUGIN_API); the variant this build compiles takes settings + #if !defined(M64P_PLUGIN_API). The variant this build compiles takes settings from the core config API and ignores its filename argument (Source/3rdParty/mupen64plus-rsp-cxd4/module.c:89-99,652-673). @@ -115,7 +115,7 @@ files: 0xe848d316, which covers the retail library. The path is set in the settings dialog and no name is fixed by the code. Loaded whole, then byteswapped after identifying the first word as one of 0x80270740 (z64), - 0x40072780 (n64) or 0x27804007 (v64); any other value disables 64DD. + 0x40072780 (n64) or 0x27804007 (v64). Any other value disables 64DD. Size is not checked and no hash is computed. source_ref: "Source/RMG-Core/MediaLoader.cpp:47-74, Source/RMG-Core/Settings.cpp:284-286, Source/3rdParty/mupen64plus-core/src/main/main.c:1189-1254, Source/3rdParty/mupen64plus-core/src/device/dd/disk.c:434-445" diff --git a/emulators/rust_dos.yml b/emulators/rust_dos.yml index d8ea7a8a..37d89c9c 100644 --- a/emulators/rust_dos.yml +++ b/emulators/rust_dos.yml @@ -47,7 +47,7 @@ notes: | logged (src/sc55/mod.rs:112-122, src/sound.rs:99-106). - Roland MT-32 ROMs: played by munt (libmt32emu) loaded at runtime - (src/mt32.rs:1-6). munt identifies the ROMs from their contents; + (src/mt32.rs:1-6). munt identifies the ROMs from their contents, and rust-dos declares no hashes and picks a control and PCM pair by munt's ids (src/mt32.rs:254-278). Without them (or without libmt32emu on the host), midisynth=mt32 fails with a warning and @@ -241,7 +241,7 @@ files: category: bios sha256: "ceb7b9d3d9d264efe5dc3ba992b94f3be35eb6d0451abc574b6f6b5dc3db237b" validation: [sha256] - description: "Roland SC-155 rev1 program ROM 2 (ROM1 shared with mk1-v2.00; Wave1/2/3 shared with mk1 family)" + description: "Roland SC-155 rev1 program ROM 2 (ROM1 shared with mk1-v2.00, Wave1/2/3 shared with mk1 family)" source_ref: "src/sc55/rom.rs:289" - name: "sc55-roms/cm300-v1.30/rom1.bin" @@ -297,7 +297,7 @@ files: validation: [sha256] description: "Roland CM-300 / SCC-1 v1.10 program ROM 1 (shared with v1.20)" source_ref: "src/sc55/rom.rs:236" - unsourceable: "no public dump located (2026-10-04); a same-named ROM of another set must not stand in" + unsourceable: "no public dump located (2026-10-04), and a same-named ROM of another set must not stand in" - name: "sc55-roms/cm300-v1.10/rom2.bin" system: dos @@ -325,7 +325,7 @@ files: validation: [sha256] description: "Roland SCB-55 v2.00 program ROM 1 (shared with RLP-3237)" source_ref: "src/sc55/rom.rs:269" - unsourceable: "no public dump located (2026-10-04); a same-named ROM of another set must not stand in" + unsourceable: "no public dump located (2026-10-04), and a same-named ROM of another set must not stand in" - name: "sc55-roms/scb55-v2.00/rom2.bin" system: dos @@ -344,7 +344,7 @@ files: validation: [sha256] description: "Roland RLP-3237 v2.01 program ROM 2" source_ref: "src/sc55/rom.rs:280" - unsourceable: "no public dump located (2026-10-04); a same-named ROM of another set must not stand in" + unsourceable: "no public dump located (2026-10-04), and a same-named ROM of another set must not stand in" - name: "sc55-roms/rlp3237-v2.01/wave1.bin" system: dos @@ -354,4 +354,4 @@ files: validation: [sha256] description: "Roland RLP-3237 Wave1 PCM" source_ref: "src/sc55/rom.rs:281" - unsourceable: "no public dump located (2026-10-04); a same-named ROM of another set must not stand in" + unsourceable: "no public dump located (2026-10-04), and a same-named ROM of another set must not stand in" diff --git a/emulators/rustation.yml b/emulators/rustation.yml index a256acfc..082333d3 100644 --- a/emulators/rustation.yml +++ b/emulators/rustation.yml @@ -19,7 +19,7 @@ notes: > "Boot to BIOS menu" core option allows booting without a disc. Database contains 24 entries (22 good, 2 known-bad rejected) covering BIOS versions 1.0 through 4.5. - .info declares firmware_count=0; incorrect. + .info declares firmware_count=0, which is incorrect. Project abandoned, superseded by rustation-ng. files: diff --git a/emulators/rustynes.yml b/emulators/rustynes.yml index a33c47ad..d7305210 100644 --- a/emulators/rustynes.yml +++ b/emulators/rustynes.yml @@ -27,12 +27,12 @@ notes: | (crates/rustynes-libretro/src/lib.rs:921-938). A missing file, or a frontend without a system directory, makes retro_load_game fail with an error. Fds::new rejects a BIOS that is not exactly 8192 bytes - (crates/rustynes-mappers/src/fds.rs:1351-1357); no hash is checked. The + (crates/rustynes-mappers/src/fds.rs:1351-1357). No hash is checked. The FDS device maps the BIOS and boots from its reset vector. The version comes from the workspace Cargo.toml. The .info in - libretro-core-info says v2.3.5 and the copy in the repository v2.6.12; - the md5 in the .info notes is not enforced by the code. + libretro-core-info says v2.3.5 and the copy in the repository v2.6.12. + The md5 in the .info notes is not enforced by the code. files: - name: "disksys.rom" diff --git a/emulators/samcoupe.yml b/emulators/samcoupe.yml index 31157419..e753d033 100644 --- a/emulators/samcoupe.yml +++ b/emulators/samcoupe.yml @@ -35,13 +35,13 @@ notes: | either drive is configured as drvAtomLite, atom.rom when drive 2 is drvAtom, and otherwise stays on samcoupe.rom. The default option atombootrom = true (Base/Options.h:46) enables this path, so a user - running an Atom-configured machine needs the matching ROM; a plain + running an Atom-configured machine needs the matching ROM, while a plain SAM Coupe never opens them. sp0256-al2.bin is the Microchip SP0256-AL2 allophone data loaded by the Blue Alpha VoiceBox device (Base/VoiceBox.cpp:35-40). VoiceBox is enabled by default (Base/Options.h:124, voicebox = true) and the - constructor opens the file at reset; if it is absent the SP0256 + constructor opens the file at reset. If it is absent the SP0256 stays zero-initialised and the device returns silence to any program that queries port 0xFF (Base/SAMIO.cpp:538-539, 760). diff --git a/emulators/same_cdi.yml b/emulators/same_cdi.yml index 63d42aa5..3e55cb82 100644 --- a/emulators/same_cdi.yml +++ b/emulators/same_cdi.yml @@ -22,12 +22,12 @@ notes: | MAME expects each romset as a ZIP containing the individual ROM files. The ZIP filenames match the MAME driver names. Only cdimono1.zip is required - for consumer CD-i games; the other ZIPs are for alternate hardware models + for consumer CD-i games. The other ZIPs are for alternate hardware models (unreachable without boot_from_cli core option). ROM definitions: src/mame/drivers/cdi.cpp:639-704. The fork carries four sets, cdimono1, cdimono2, cdi910 and cdi490a, declared at - src/mame/drivers/cdi.cpp:713-716; the Quizard game ROMs upstream MAME + src/mame/drivers/cdi.cpp:713-716. The Quizard game ROMs upstream MAME keeps in this driver are not in it. The .info also lists cdibios.zip, a set this driver does not declare. diff --git a/emulators/saturn-emu.yml b/emulators/saturn-emu.yml index 4c23b59c..5983e977 100644 --- a/emulators/saturn-emu.yml +++ b/emulators/saturn-emu.yml @@ -96,7 +96,7 @@ notes: | Per content the app writes and reads back a .bkr backup RAM image, a .smpc real time clock block, .mca save states and, when a memory cart is selected, a - gzipped .bcr cart image; settings live in SaturnEmu.config + gzipped .bcr cart image. Settings live in SaturnEmu.config (Saturn.emu/src/main/Main.cc:50-129,152-155, Saturn.emu/src/main/system.ccm:180, Saturn.emu/src/ss/cart/backup.cpp:69-73, Saturn.emu/src/main/AppMeta.cc:28). Mednafen's image reader picks up an .sbi @@ -195,7 +195,7 @@ files: note: > Read when the cart type is KoF '95, which the internal database forces for MK-81088 and T-3101G and which the Cart Type menu also offers. Those two - discs end the load when the path is unset; every other disc ignores it. + discs end the load when the path is unset, and every other disc ignores it. CART_ROM_Init takes a fixed 2097152 bytes and Stream::read throws on a shorter file, so anything smaller aborts and anything larger has its tail ignored. The name comes from the module's setting table, which this build diff --git a/emulators/sdl2trs.yml b/emulators/sdl2trs.yml index 0210b870..b4b7dffb 100644 --- a/emulators/sdl2trs.yml +++ b/emulators/sdl2trs.yml @@ -18,7 +18,7 @@ notes: | TRS-80 Model I, III, 4 and 4P emulator. Jens Guenther's GitLab tree continues Mark Grebe's SDLTRS, itself an SDL port of Tim Mann's xtrs, whose licence still ships as xtrs.LICENSE. The sdl2 branch builds the sdl2trs binary that - ES-DE and RetroDECK look for; master builds sdltrs for hosts without SDL2 + ES-DE and RetroDECK look for, while master builds sdltrs for hosts without SDL2 (README.md:106-111). The branches diverge only in the display and paste code: trs_cmd_rom.c and trs_memory.c are byte-identical between them. @@ -77,7 +77,7 @@ files: max_size: 18432 source_ref: "src/trs_options.c:82 (romfile3), src/trs_options.c:898 (default name), src/trs_cmd_rom.c:885-889 (trs_model 3 and 4)" note: > - Serves Model III and Model 4 alike; the stub text spells out that Model 4 + Serves Model III and Model 4 alike. The stub text spells out that Model 4 mode needs a Model 3 image (src/trs_cmd_rom.c:110-115). This is the one slot that also accepts a MODELA/III CMD file, which html/index.html presents as the substitute for a real Model III ROM. Same truncating ceiling as the @@ -97,7 +97,7 @@ files: image is what restores Model III mode and hard-drive booting. Hard drive unit 0 is tried before floppy by the Radio Shack ROM, and F2 held at boot forces floppy (html/Features.html). The image is the 4 KB gate-array boot - ROM 8075332.u69, the only ROM the machine carries; the Model III code + ROM 8075332.u69, the only ROM the machine carries, and the Model III code comes from a boot disk. analysis: @@ -169,7 +169,7 @@ analysis: slot: model3.rom image_size: 18432 source_ref: "src/trs_memory.c:570-580, src/trs_memory.c:1043-1065" - note: "4 KB VID-80 ROM with the Model III ROM appended behind it; this pairing is what sets MAX_ROM_SIZE." + note: "4 KB VID-80 ROM with the Model III ROM appended behind it. This pairing is what sets MAX_ROM_SIZE." - machine: "TCS SpeedMaster, also sold as Genie IIs" slot: level2.rom @@ -193,7 +193,7 @@ analysis: slot: level2.rom image_size: 12288 source_ref: "src/trs_memory.c:918-946" - note: "Reads 0x0000-0x2FFF only; the rest of the address space is banked RAM, video and the HRG window." + note: "Reads 0x0000-0x2FFF only. The rest of the address space is banked RAM, video and the HRG window." - machine: "LNW Research LNW80/II" slot: level2.rom @@ -230,7 +230,7 @@ analysis: note: > Declares level1.rom, level2.rom, level3.rom, level4.rom, level4p.rom and boot.dsk under $roms_path/trs-80. Of those the emulator opens only - level2.rom by default; level3.rom, level4.rom and level4p.rom are + level2.rom by default, while level3.rom, level4.rom and level4p.rom are renames of the model3.rom and model4p.rom slots, and level1.rom is a Level I BASIC image for the Model I slot. The manifest hashes come from the frontend, not from the emulator, which computes none. diff --git a/emulators/sdlpop.yml b/emulators/sdlpop.yml index f03383fb..d87755fd 100644 --- a/emulators/sdlpop.yml +++ b/emulators/sdlpop.yml @@ -15,7 +15,7 @@ notes: | SDLPoP is NagyD's open-source port of the DOS Prince of Persia (1989), rebuilt from the leaked Jordan Mechner source and refined through years of community reverse engineering. Unlike the other engines in - this directory, SDLPoP ships with ALL game data in-tree; no retail + this directory, SDLPoP ships with ALL game data in-tree, so no retail data file is required or useful. open_dat() (src/seg009.c:438) reads an archive named FOO.DAT if @@ -42,7 +42,7 @@ notes: | Consequence: retrobios does not supply any file to run the base game. Users can drop MOD folders under mods/<MODNAME>/ to layer custom - level packs on top (open_dat lines 448-452); those are user content, + level packs on top (open_dat lines 448-452). Those are user content, not shared BIOS data, and are not tracked here. exclusion_note: "all required game data ships inside the source repository (data/ and data/<folder>/ trees)" diff --git a/emulators/shadps4.yml b/emulators/shadps4.yml index c33a0973..8b417ad3 100644 --- a/emulators/shadps4.yml +++ b/emulators/shadps4.yml @@ -31,7 +31,7 @@ notes: | System fonts are mounted from fonts/font/ (/preinst/common/font on real PS4) and fonts/font2/ (/system/common/font2 on real PS4). These are SST (Sony Standard Text) typeface files in OTF format. The emulator mounts - the directories wholesale; games load individual fonts by name. Without + the directories wholesale, and games load individual fonts by name. Without fonts, the emulator warns "No dumped system fonts, expect missing text or instability." @@ -63,7 +63,7 @@ files: required: false path: "shadps4/sys_modules/libSceUlt.sprx" description: "PS4 user-level threading library" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:218" - name: "libSceRtc.sprx" @@ -77,7 +77,7 @@ files: required: false path: "shadps4/sys_modules/libSceJpegDec.sprx" description: "PS4 JPEG decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:222" - name: "libSceJpegEnc.sprx" @@ -98,70 +98,70 @@ files: required: false path: "shadps4/sys_modules/libSceJson.sprx" description: "PS4 JSON parser" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:226" - name: "libSceJson2.sprx" required: false path: "shadps4/sys_modules/libSceJson2.sprx" description: "PS4 JSON v2 parser" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:227" - name: "libSceCesCs.sprx" required: false path: "shadps4/sys_modules/libSceCesCs.sprx" description: "PS4 character encoding conversion" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:228" - name: "libSceAt9Enc.sprx" required: false path: "shadps4/sys_modules/libSceAt9Enc.sprx" description: "PS4 ATRAC9 encoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:229" - name: "libSceAudiodec.sprx" required: false path: "shadps4/sys_modules/libSceAudiodec.sprx" description: "PS4 audio decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:230" - name: "libSceAudiodecCpu.sprx" required: false path: "shadps4/sys_modules/libSceAudiodecCpu.sprx" description: "PS4 CPU audio decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:231" - name: "libSceAudiodecCpuDdp.sprx" required: false path: "shadps4/sys_modules/libSceAudiodecCpuDdp.sprx" description: "PS4 CPU Dolby Digital Plus decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:232" - name: "libSceAudiodecCpuM4aac.sprx" required: false path: "shadps4/sys_modules/libSceAudiodecCpuM4aac.sprx" description: "PS4 CPU AAC decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:233" - name: "libSceAudiodecCpuDtsHdLbr.sprx" required: false path: "shadps4/sys_modules/libSceAudiodecCpuDtsHdLbr.sprx" description: "PS4 CPU DTS-HD LBR decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:234" - name: "libSceAudiodecCpuHevag.sprx" required: false path: "shadps4/sys_modules/libSceAudiodecCpuHevag.sprx" description: "PS4 CPU HEVAG decoder" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:235" - name: "libSceFont.sprx" @@ -182,21 +182,21 @@ files: required: false path: "shadps4/sys_modules/libSceFreeTypeOt.sprx" description: "PS4 FreeType OpenType library" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:238" - name: "libSceFreeTypeOl.sprx" required: false path: "shadps4/sys_modules/libSceFreeTypeOl.sprx" description: "PS4 FreeType outline library" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:239" - name: "libSceFreeTypeOptOl.sprx" required: false path: "shadps4/sys_modules/libSceFreeTypeOptOl.sprx" description: "PS4 FreeType optimised outline library" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:240" - name: "libSceRudp.sprx" @@ -210,7 +210,7 @@ files: required: false path: "shadps4/sys_modules/libSceWkFontConfig.sprx" description: "PS4 WebKit font configuration" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:244" - name: "libSceSystemGesture.sprx" @@ -224,5 +224,5 @@ files: required: false path: "shadps4/sys_modules/libSceXml.sprx" description: "PS4 XML parser" - note: "No HLE implementation; the module is stubbed when absent." + note: "No HLE implementation. The module is stubbed when absent." source_ref: "src/core/libraries/sysmodule/sysmodule_internal.cpp:250" diff --git a/emulators/sheepshaver.yml b/emulators/sheepshaver.yml index 281165fc..9528279a 100644 --- a/emulators/sheepshaver.yml +++ b/emulators/sheepshaver.yml @@ -62,9 +62,9 @@ notes: | The SDL2 backend falls back to BasiliskII_keycodes in the same directory (video_sdl2.cpp:98,1232). - The preferences file (.sheepshaver_prefs, prefs_unix.cpp:49; + The preferences file (.sheepshaver_prefs, prefs_unix.cpp:49, or SheepShaver_prefs, prefs_windows.cpp:66) and the NVRAM file - (.sheepshaver_nvram, xpram_unix.cpp:30; SheepShaver_nvram.dat, + (.sheepshaver_nvram, xpram_unix.cpp:30, or SheepShaver_nvram.dat, xpram_windows.cpp:31) are written by the emulator when absent. Passing a .sheepvm directory on the command line reads the preferences from inside it instead (main_unix.cpp:371-384, prefs_unix.cpp:57-69). diff --git a/emulators/simple64.yml b/emulators/simple64.yml index 0f84946c..35604415 100644 --- a/emulators/simple64.yml +++ b/emulators/simple64.yml @@ -23,7 +23,7 @@ notes: | squashed subtrees (pull_repos.sh). The core is compiled with M64P_PARALLEL, M64P_NETPLAY and NO_ASM, and its source list leaves out src/osd and every dynarec (mupen64plus-core/CMakeLists.txt:26,28-104). ES-DE runs the release - binary as `--nogui <rom>`; the GUI registers only verbose, nogui and test + binary as `--nogui <rom>`, and the GUI registers only verbose, nogui and test (simple64-gui/main.cpp:14-24). Development stopped and the repository was archived in February 2025, five commits past v2024.12.1, touching only the README, the build script and a netplay dialog. @@ -34,15 +34,15 @@ notes: | in data/, while simple64 opens the file itself at a fixed length and ships both images. get_pif_path names pif.pal.rom for SYSTEM_PAL and pif.ntsc.rom for SYSTEM_NTSC and SYSTEM_MPAL, then resolves it against the shared data - path (mupen64plus-core/src/main/main.c:1565-1580; - mupen64plus-core/src/api/config.c:1610-1625; + path (mupen64plus-core/src/main/main.c:1565-1580, + mupen64plus-core/src/api/config.c:1610-1625, mupen64plus-core/src/osal/files_unix.c:150-170). The GUI passes the directory holding the executable as that path (simple64-gui/mainwindow.cpp:986-988, mupen64plus-core/src/api/frontend.c:59,90), and build.sh copies both images there (build.sh:26), so a release install always carries them. Absence is not fatal. The lookup returns NULL when the file is not found and - the result reaches fopen unchecked; on a failed open, open_pif is never + the result reaches fopen unchecked. On a failed open, open_pif is never called and g_start_address keeps its initialiser 0xa4000040 (mupen64plus-core/src/main/main.c:112,1624-1633). A digest that matches none of the four accepted values returns M64ERR_INPUT_INVALID, which main_run @@ -51,7 +51,7 @@ notes: | IPL2 in full, quiescing the RSP, PI, VI and AI, deriving s3 to s7 from pif24, copying IPL3 into DMEM and planting the stub CIC x105 needs (mupen64plus-core/src/device/pif/bootrom_hle.c:48-151). It runs on cold boot - and on both reset paths (mupen64plus-core/src/main/main.c:1977; + and on both reset paths (mupen64plus-core/src/main/main.c:1977, mupen64plus-core/src/device/r4300/interrupt.c:445,496). The CIC challenge reads no file either: process_cic_challenge answers with the CIC-NUS-6105 algorithm (mupen64plus-core/src/device/pif/pif.c:252-260, @@ -60,7 +60,7 @@ notes: | 64DD is not reachable. The GUI's media loader supplies only the two Game Boy cartridge callbacks and leaves set_dd_rom_region, get_dd_rom and get_dd_disk null, the two functions that would have answered being commented out - (simple64-gui/interface/common.cpp:129-163,240; + (simple64-gui/interface/common.cpp:129-163,240, mupen64plus-core/src/api/m64p_types.h:186-221). load_dd_rom is only reached after load_dd_disk succeeds, and load_dd_disk bails on a null callback, so the IPL image the core can otherwise load and byteswap is never requested @@ -90,9 +90,9 @@ notes: | Data the build places beside the executable: mupen64plus.ini, parsed as the ROM database and keyed on MD5 then CRC pair, which supplies save type, player count, rumble, Transfer Pak, Controller Pak, bio pak and expansion memory per - title (mupen64plus-core/src/main/rom.c:190-235,674-691; build.sh:25); and + title (mupen64plus-core/src/main/rom.c:190-235,674-691, build.sh:25), and cheats.json, pulled from simple64/cheat-parser at build time and read by - header CRC pair and country code (simple64-gui/cheats.cpp:230-239; + header CRC pair and country code (simple64-gui/cheats.cpp:230-239, build.sh:106-111). Neither is hashed or version checked, romdatabase_open logs and returns when the file is absent, and loadCheatData yields an empty object, so both degrade rather than fail. @@ -100,7 +100,7 @@ notes: | Two data files in the tree this build never reads: data/font.ttf, whose only consumer is src/osd/osd.c, absent from the source list, leaving osd_new_message as the inline no-op behind M64P_OSD - (mupen64plus-core/src/osd/osd.h:93,104,118-121); and data/mupencheat.txt, + (mupen64plus-core/src/osd/osd.h:93,104,118-121), and data/mupencheat.txt, referenced nowhere under src/ since cheats come from the GUI's own JSON. The parallel-rdp shaders are compiled in through shaders/slangmosh.hpp rather than loaded (parallel-rdp-standalone/parallel-rdp/rdp_renderer.cpp:36), and @@ -142,7 +142,7 @@ files: is the image shipped in data/ and the No-Intro entry "[BIOS] Nintendo 64 - PIF (Japan, USA).bin" at 1984 bytes, and the digest of the earlier dump kept for compatibility. On a match the image is byteswapped into PIF - memory and the reset vector moves to 0xbfc00000; on a mismatch the core + memory and the reset vector moves to 0xbfc00000. On a mismatch the core logs "Invalid PIF ROM" and boots through the HLE bootrom instead. source_ref: "mupen64plus-core/src/main/main.c:1565-1580,1624-1633,2097-2135, mupen64plus-core/src/main/rom.c:502-525, mupen64plus-core/src/device/pif/pif.h:36" @@ -162,6 +162,6 @@ files: 0x46 French, 0x49 Italian, 0x50 European, 0x53 Spanish, 0x55 Australian, 0x58 and 0x59 European. Same read length, digest span and fallback as the NTSC image. The current digest is the image shipped in data/ and the - No-Intro entry "[BIOS] Nintendo 64 - PIF (Europe).bin" at 1984 bytes; the + No-Intro entry "[BIOS] Nintendo 64 - PIF (Europe).bin" at 1984 bytes, and the second value is the earlier dump the fork still accepts. source_ref: "mupen64plus-core/src/main/main.c:1565-1580,1624-1633,2097-2135, mupen64plus-core/src/main/rom.c:502-525, mupen64plus-core/src/device/pif/pif.h:36" diff --git a/emulators/sixtyforce.yml b/emulators/sixtyforce.yml index 0c9911c2..66c33ffe 100644 --- a/emulators/sixtyforce.yml +++ b/emulators/sixtyforce.yml @@ -18,7 +18,7 @@ notes: | release in 2001. ES-DE runs it from /Applications/sixtyforce.app/Contents/MacOS/sixtyforce and passes the ROM path. Everything below is read from the distributed 2.0.2 build (CFBundleVersion 87, - single x86_64 slice, macOS 10.9 or later); addresses are the virtual addresses + single x86_64 slice, macOS 10.9 or later). Addresses are the virtual addresses of Contents/MacOS/sixtyforce. None of it appears on the site, in the help pages or in the release notes. @@ -47,7 +47,7 @@ notes: | 64DD support stops at the IPL image. HardwareState carries a cartridge slot (pointer at +0x120, length at +0x128) and an IPL slot (+0x138, +0x140) and no - disk slot; the document types are n64, v64 and z64, and the only occurrences of + disk slot. The document types are n64, v64 and z64, and the only occurrences of the letters ndd in the whole binary are the two NDDJ immediates in the loader. Loading the IPL while a cartridge is open leaves the cartridge in place. @@ -64,7 +64,7 @@ files: byte game code from the header, media format at 0x3b, then the two cartridge id bytes read 0x3d before 0x3c, then country at 0x3e, and keeps the image in the 64DD slot instead of the cartridge slot when that code - reads NDDJ. That is the Japanese retail IPL; the USA image reads NDDE and + reads NDDJ. That is the Japanese retail IPL. The USA image reads NDDE and the development image NDXJ, so neither can reach that slot. No code path opens the file by name, so the entry carries no alias and the name is a label. The image is mapped at 0x06000000 and read diff --git a/emulators/skyemu.yml b/emulators/skyemu.yml index ec7edb1c..4b4bd378 100644 --- a/emulators/skyemu.yml +++ b/emulators/skyemu.yml @@ -19,10 +19,10 @@ systems: notes: | Multi-system emulator by skylersaleh. Libretro core built from the upstream repo. - All BIOS optional; bundles Cult-of-GBA BIOS (GBA), DraStic free BIOS (NDS ARM7/ARM9), + All BIOS optional: bundles Cult-of-GBA BIOS (GBA), DraStic free BIOS (NDS ARM7/ARM9), stub firmware (NDS), and HLE boot skip (GB/GBC). BIOS loading controlled by core options (default: on). Files loaded from system_dir/SkyEmu/ subdirectory. - Standalone validates exact BIOS file size; libretro only rejects files exceeding buffer. + Standalone validates exact BIOS file size, while libretro only rejects files exceeding buffer. .info missing gb_bios.bin (gb.h:1603). files: diff --git a/emulators/skyline.yml b/emulators/skyline.yml index f037214b..e2f3fd1a 100644 --- a/emulators/skyline.yml +++ b/emulators/skyline.yml @@ -16,7 +16,7 @@ mode: standalone notes: | The GitHub repository skyline-emu/skyline was replaced by an archival notice on - 2026-08-18, so the pinned revision is served by Software Heritage; the same tree + 2026-08-18, so the pinned revision is served by Software Heritage. The same tree is in the archive.org bundle github.com_skyline-emu_bundles_20230508, and the signed edge-69 APK carries the built assets. Every path below reads against that revision. @@ -25,14 +25,14 @@ notes: | Android package skyline.emu, versionCode 3, minSdk 29, with the debug variant taking a .dev suffix (build.gradle:23,28-29,120-121). ES-DE reaches it through its SKYLINE find rule and starts it with android.intent.action.VIEW on the content URI of the game. - Development ceased and the README at the pinned commit records it; the code is split + Development ceased and the README at the pinned commit records it. The code is split across skyline and skyline-dev, whose external file surface is identical (key_store.cpp :10-13 and shared_font_core.h:40-47 in both). NCA, NRO, NSO, NSP and XCI are loaded (loader/). Two key files are read, from keys/ under the application internal files directory, which os.cpp:35 hands to the key store as its root. Both arrive through the in-app importer, which accepts only the two names - and rewrites the trimmed pairs into that directory (KeyReader.kt:25-26,56-60); nothing + and rewrites the trimmed pairs into that directory (KeyReader.kt:25-26,56-60). Nothing else is consulted for keys, and there is no dev.keys or console.keys path. No firmware is installed and none is read. The system version is answered from a @@ -57,8 +57,8 @@ notes: | A custom Vulkan driver can be loaded through adrenotools from gpu_drivers/<label>/ under the internal files directory (gpu.cpp:342-357). The label and the library filename are both read from a meta.json inside the archive the user installs - (GpuDriverHelper.kt:19-22,150-191,219), so the code names no driver file of its own; - loading falls back to the built-in driver and then to the system libvulkan.so. Save + (GpuDriverHelper.kt:19-22,150-191,219), so the code names no driver file of its own. + Loading falls back to the built-in driver and then to the system libvulkan.so. Save data and the emulated SD card live under switch/ in the external files directory (IFileSystemProxy.cpp:21,67) and are written by the emulator. @@ -87,7 +87,7 @@ files: Read as rights id to title key pairs from the same directory. A title key normally arrives instead from the .tik tickets carried inside an NSP, which are parsed and pushed into the same store, so this file is only needed when no ticket supplies - one; that case fails with MissingTitleKey. The importer requires both halves of a + one. That case fails with MissingTitleKey. The importer requires both halves of a pair to be 32 hexadecimal characters. source_ref: "app/src/main/cpp/skyline/crypto/key_store.cpp:10-11 (read), app/src/main/cpp/skyline/crypto/key_store.cpp:35-39 (parse), app/src/main/cpp/skyline/loader/nsp.cpp:14-21 (tickets), app/src/main/cpp/skyline/vfs/nca.cpp:108-110 (failure), app/src/main/java/emu/skyline/KeyReader.kt:77-82 (import check)" diff --git a/emulators/snes9x-explus.yml b/emulators/snes9x-explus.yml index bef6302f..7c13db6b 100644 --- a/emulators/snes9x-explus.yml +++ b/emulators/snes9x-explus.yml @@ -44,7 +44,7 @@ notes: | Two firmware images are read, and both differ from upstream in how they are found. Upstream opens BS-X.bin then BS-X.bios in its BIOS directory (bsx.cpp:1204-1236) and STBIOS.bin for a Sufami Turbo load - (memmap.cpp:1663-1686); the app deletes both blocks and reads a URI the user + (memmap.cpp:1663-1686). The app deletes both blocks and reads a URI the user picks instead, so no filename is compiled in (Snes9x/src/snes9x/bsx.cpp:1199-1203, Snes9x/src/snes9x/memmap.cpp:1644-1670, Snes9x/src/main/S9XApi.cc:225-253, @@ -62,7 +62,7 @@ notes: | S9xInitBSX, which copies it into the BIOS area itself and asks for nothing (Snes9x/src/snes9x/bsx.cpp:1213-1233). Broadcast data is read per requested channel as BSXHHHH-D.bin under the Satellaview Files path, which defaults to - the content directory; a miss only leaves the stream unloaded + the content directory, and a miss only leaves the stream unloaded (Snes9x/src/snes9x/bsx.cpp:736-790, Snes9x/src/main/S9XApi.cc:203-216, Snes9x/src/main/system.ccm:108). @@ -74,7 +74,7 @@ notes: | (Snes9x/src/main/S9XApi.cc:64,89-131). Per content the app writes and reads back a .srm, an .rtc for the S-RTC, - .frz states and a .cht cheat list under the cheats path; settings live in + .frz states and a .cht cheat list under the cheats path. Settings live in Snes9xP.config (Snes9x/src/main/Main.cc:78-90,153-172, Snes9x/src/snes9x/memmap.cpp:1791-1812, Snes9x/src/main/Cheats.cc:33-45, Snes9x/src/main/AppMeta.cc:19). A BS game with no save of its own falls back @@ -136,7 +136,7 @@ files: Opened by the name the emulated unit asks for, BSXHHHH-D.bin from the channel registers at 0x2188 and 0x218E, under the Satellaview Files path, which defaults to the content directory. The file is measured to size the - queue and read 22 bytes at a time; a miss leaves the stream unloaded. + queue and read 22 bytes at a time. A miss leaves the stream unloaded. source_ref: "Snes9x/src/snes9x/bsx.cpp:736-790, Snes9x/src/main/S9XApi.cc:203-216, Snes9x/src/main/system.ccm:108, Snes9x/src/main/EmuMenuViews.cc:325-343" - name: "BSX0121-0.bin" diff --git a/emulators/snes9x2002.yml b/emulators/snes9x2002.yml index 76abd1bc..8284ac79 100644 --- a/emulators/snes9x2002.yml +++ b/emulators/snes9x2002.yml @@ -20,5 +20,5 @@ notes: | All ROM I/O via memstream (snes9x.h:54-57). The core never calls GET_SYSTEM_DIRECTORY and performs no file I/O from the system directory. -exclusion_note: "SPC700 IPL ROM embedded in binary (src/globals.c:283); no system_directory access" +exclusion_note: "SPC700 IPL ROM embedded in binary (src/globals.c:283), no system_directory access" files: [] diff --git a/emulators/snes9x2005.yml b/emulators/snes9x2005.yml index 1e0f3963..1f9888db 100644 --- a/emulators/snes9x2005.yml +++ b/emulators/snes9x2005.yml @@ -22,5 +22,5 @@ notes: | are pure HLE. The core never calls GET_SYSTEM_DIRECTORY and performs no file I/O from the system directory. -exclusion_note: "all coprocessor ROMs embedded in binary; no system_directory access" +exclusion_note: "all coprocessor ROMs embedded in binary, no system_directory access" files: [] diff --git a/emulators/snes9x2005_plus.yml b/emulators/snes9x2005_plus.yml index c779dc7e..1045e6f0 100644 --- a/emulators/snes9x2005_plus.yml +++ b/emulators/snes9x2005_plus.yml @@ -23,5 +23,5 @@ notes: | are pure HLE. The core never calls GET_SYSTEM_DIRECTORY and performs no file I/O from the system directory. -exclusion_note: "all coprocessor ROMs embedded in binary; no system_directory access" +exclusion_note: "all coprocessor ROMs embedded in binary, no system_directory access" files: [] diff --git a/emulators/sonic-mania.yml b/emulators/sonic-mania.yml index 6eb79ef8..fab7190d 100644 --- a/emulators/sonic-mania.yml +++ b/emulators/sonic-mania.yml @@ -12,15 +12,15 @@ systems: [sonic-mania] notes: | Full RSDKv5 decompilation of Sonic Mania (Christian Whitehead / Headcannon, - 2017). Links against the shared RSDKv5-Decompilation engine; game code + 2017). Links against the shared RSDKv5-Decompilation engine. Game code lives in SonicMania/ and the engine in the dependencies/RSDKv5 submodule, the upstream repository. The paths below are relative to that repository. LoadDataPack reads an RSDK v5 container: a 4-byte "RSDK" signature, the letter v and a version byte, a 16-bit file count, then an MD5 name - hash, offset and size per entry. The signature is the only validation; - the engine never hashes the full pack. + hash, offset and size per entry. The signature is the only validation. + The engine never hashes the full pack. ref: RSDKv5/RSDK/Core/Reader.cpp:107-164 (LoadDataPack) Settings.ini key Game:dataFile overrides the default "Data.rsdk". If diff --git a/emulators/sonic2013.yml b/emulators/sonic2013.yml index 8741631d..3fc9f936 100644 --- a/emulators/sonic2013.yml +++ b/emulators/sonic2013.yml @@ -13,12 +13,12 @@ systems: [sonic-1-2013, sonic-2-2013] notes: | Shared Retro Engine v4 decompilation driving the 2013 Christian Whitehead mobile ports of Sonic the Hedgehog and Sonic the Hedgehog 2. One binary - per build; the game identity is derived from the GameConfig.bin inside + per build. The game identity is derived from the GameConfig.bin inside the loaded data pack (gameWindowText "Sonic 1" or "Sonic 2"). ref: RSDKv4/RetroEngine.cpp:423, RSDKv4/ModAPI.cpp:428 CheckRSDKFile opens the data pack and compares its first six bytes to - the "RSDKvB" signature; there is no checksum test. The engine falls + the "RSDKvB" signature. There is no checksum test. The engine falls back to a loose Data/ + Bytecode/ tree if the pack is absent. When GameConfig.bin cannot be loaded either way it writes a usage.txt that asks for a pack named Engine.dataFile[0] (default "Data.rsdk"). @@ -26,7 +26,7 @@ notes: | RSDKv4/Userdata.cpp:251-263, RSDKv4/RetroEngine.cpp:483-520 Up to four packs can be mounted (DataFile, DataFile2..4 in the Dev - section of settings.ini); the extras default to Data2.rsdk, Data3.rsdk, + section of settings.ini), and the extras default to Data2.rsdk, Data3.rsdk, Data4.rsdk once declared. ref: RSDKv4/Reader.hpp:38, RSDKv4/RetroEngine.cpp:324-331, RSDKv4/Userdata.cpp:396-408 @@ -40,7 +40,7 @@ files: note: | Sonic the Hedgehog (2013) assets. Shipped with the official Sonic Origins release and the delisted iOS/Android apps. The engine checks - the six-byte signature only; content identity is read from the + the six-byte signature only. Content identity is read from the embedded GameConfig.bin, not the pack hash. - name: "Data.rsdk" @@ -51,4 +51,4 @@ files: note: | Sonic the Hedgehog 2 (2013) assets. Shipped with the official Sonic Origins release and the delisted iOS/Android apps. Same default - file name as Sonic 1; Dev:DataFile in settings.ini names another. + file name as Sonic 1. Dev:DataFile in settings.ini names another. diff --git a/emulators/sonic3-air.yml b/emulators/sonic3-air.yml index c1f08973..35711a2d 100644 --- a/emulators/sonic3-air.yml +++ b/emulators/sonic3-air.yml @@ -12,7 +12,7 @@ systems: [sonic3-air] notes: | Sonic 3 - Angel Island Revisited by Eukaryot. The Oxygen Engine runs the decompiled game logic (lemon scripts) against the original Genesis ROM - loaded at runtime; the ROM is not shipped with the engine. + loaded at runtime. The ROM is not shipped with the engine. ROM search order (ResourcesCache::loadRom): 1. GameAppData/<SteamRomName> @@ -40,7 +40,7 @@ notes: | The engine ships four data packages (enginedata.bin, gamedata.bin, audiodata.bin, audioremaster.bin). Three are required and part of the - release; audioremaster.bin is optional and downloaded on demand from + release, while audioremaster.bin is optional and downloaded on demand from https://sonic3air.org/download/audioremaster.bin when the user enables the remastered soundtrack. ref: Oxygen/sonic3air/oxygenproject.json:32-38, @@ -57,7 +57,7 @@ notes: | Each package is a flat container: "OPCK", format version 3, content version BUILD_NUMBER, then one entry per file keyed by its path relative to the base directory, in std::map order. Packing reads the data - directories only; the ROM is not involved. + directories only. The ROM is not involved. ref: Oxygen/sonic3air/source/sonic3air/main.cpp:92-97, Oxygen/sonic3air/source/sonic3air/helper/PackageBuilder.cpp:16-63, Oxygen/oxygenengine/source/oxygen/file/FilePackage.cpp:44-151, @@ -73,7 +73,7 @@ notes: | Oxygen/oxygenengine/source/oxygen/application/Configuration.cpp:288-289 Only one RomInfo is declared (S3K_Steam). The engine does not support - on-the-fly Sonic 3 + Sonic & Knuckles lock-on concatenation at run time; + on-the-fly Sonic 3 + Sonic & Knuckles lock-on concatenation at run time, so the user must supply the 4 MiB combined ROM (as distributed with Sega Mega Drive & Genesis Classics / Sonic Origins). @@ -89,7 +89,7 @@ files: Sonic 3 & Knuckles combined ROM as shipped on Steam (Sega Mega Drive and Genesis Classics / Sonic Origins). Expected size 0x400000 bytes. After the engine overwrites offset 0x2001f0 with 0x4a, Murmur2_64 of - the whole buffer must equal 0x344983ffcfeff8cb (not CRC32; the hash + the whole buffer must equal 0x344983ffcfeff8cb (not CRC32: the hash is computed with rmx::getMurmur2_64 over mRom). The engine also accepts a user-picked .bin via the native file-selection dialog that satisfies the same post-modification check. @@ -143,5 +143,5 @@ files: Remastered soundtrack package (131677405 bytes). Downloaded on demand from https://sonic3air.org/download/audioremaster.bin, saved as data/audioremaster.bin under the app-data directory and reloaded - via EngineMain::reloadFilePackage. Absent at first launch; the + via EngineMain::reloadFilePackage. Absent at first launch. The engine falls back to the emulated FM soundtrack. diff --git a/emulators/soniccd.yml b/emulators/soniccd.yml index 27559933..33a00a05 100644 --- a/emulators/soniccd.yml +++ b/emulators/soniccd.yml @@ -11,9 +11,9 @@ systems: [soniccd] notes: | Retro Engine v3 decompilation of Sonic CD (2011 Christian Whitehead - mobile/Steam port). Single binary; one data pack per install. + mobile/Steam port). Single binary, one data pack per install. - CheckRSDKFile only fopen()s the pack; there is no signature test. If + CheckRSDKFile only fopen()s the pack. There is no signature test. If the file is absent the engine falls back to a loose Data/ tree. When GameConfig.bin cannot be loaded either way it writes usage.txt describing the layout it wants. @@ -38,6 +38,6 @@ files: note: | Sonic CD assets (RSDK v3 container). Shipped with the official Sonic CD release (Steam, iOS, Android, Sonic Origins). The engine - opens the file with fopen(); content is validated by trying to + opens the file with fopen(). Content is validated by trying to load Data/Scripts/ByteCode/GlobalCode.bin or GS000.bin from inside, not by hashing the pack. diff --git a/emulators/speccy.yml b/emulators/speccy.yml index 333244a6..16b1fd1d 100644 --- a/emulators/speccy.yml +++ b/emulators/speccy.yml @@ -37,7 +37,7 @@ notes: | Play for it, apkcombo bounces its download page back to the app page, apkpure redirects to its generic downloader, apkvision holds no copy and archive.org none either. The native libraries keep their symbol tables, so the readings - below cite libmain.so offsets in the x86_64 slice; the arm64-v8a slice carries + below cite libmain.so offsets in the x86_64 slice, and the arm64-v8a slice carries the same nineteen ROM names. The free Speccy 5.9 builds for Windows and Ubuntu were read beside it and open the same names with the same lengths and the same order. No source has ever been published: every download on the site, from 1.7 @@ -53,7 +53,7 @@ notes: | of when it is done. That directory is external storage joined with the application label up to its first space, so /sdcard/Speccy for the package read here, falling back to getExternalFilesDirs(null) when it is - not a writable directory; the author's own instructions give the same + not a writable directory. The author's own instructions give the same placement. Every open goes through mopen, which calls OpenRealFile first: the name is tried as given, and again as <PrivateDir>/<basename>, keeping the larger of the two when both open. mopen then layers gzdopen over the @@ -344,7 +344,7 @@ files: sha1: 0b53d51635a2ce3d4e12c2077df9aeffeac02517 crc32: "b58e81f1" description: "cheat database read by the Cheatopedia browser" - note: "The package ships no cheat set. Cheatopedia looks for the file in the package assets, then in the home directory and its subdirectories, and takes it from Speccy-Cheats.zip in the Downloads directory when that is newer, unpacking it into <HomeDir>/Cheats. The author publishes that archive at fms.komkon.org/EmuAndroid/Speccy-Cheats.zip and states it is what re-enables the cheat features Google Play made him disable in March 2019; the copy read here holds this one file." + note: "The package ships no cheat set. Cheatopedia looks for the file in the package assets, then in the home directory and its subdirectories, and takes it from Speccy-Cheats.zip in the Downloads directory when that is newer, unpacking it into <HomeDir>/Cheats. The author publishes that archive at fms.komkon.org/EmuAndroid/Speccy-Cheats.zip and states it is what re-enables the cheat features Google Play made him disable in March 2019. The copy read here holds this one file." source_ref: "CheatHelper.java:17-67, Cheatopedia.java:397-427, EmuAndroid \"Cheats support\"" - name: Controls.png diff --git a/emulators/spmp8000emu.yml b/emulators/spmp8000emu.yml index 9dabbadc..218adb72 100644 --- a/emulators/spmp8000emu.yml +++ b/emulators/spmp8000emu.yml @@ -16,7 +16,7 @@ notes: | Emulator for Sunplus SPMP8000 NGame1.0 games written in Rust by AloysHF. The libretro core and the spmp8000-emu standalone binary share the spmp8000emu-core crate. A .bin game is read from its full path - (need_fullpath = true, crates/spmp8000emu-libretro/src/libretro/api.rs:96; + (need_fullpath = true, crates/spmp8000emu-libretro/src/libretro/api.rs:96, from_path_with_config, crates/spmp8000emu-core/src/emulator.rs:63-68), its header parsed, the payload DES-decrypted and LZ77/RLE-decompressed with keys and tables compiled into the core, then loaded at the code @@ -27,7 +27,7 @@ notes: | NativeGE_writeRecord) resolve the guest path under the directory of the loaded .bin (crates/spmp8000emu-core/src/emulator.rs:129-131, crates/spmp8000emu-core/src/api/mod.rs:125-127, - crates/spmp8000emu-core/src/api/emu_fs.rs:9-13); what a game reads or + crates/spmp8000emu-core/src/api/emu_fs.rs:9-13). What a game reads or writes there is its own data and saves. RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY and GET_SAVE_DIRECTORY are defined (crates/spmp8000emu-libretro/src/libretro/constants.rs:36, @@ -38,7 +38,7 @@ notes: | bank is the SPMP8000 firmware's own PCM tone library, compiled into the core with include_bytes! (crates/spmp8000emu-core/src/tone_library.rs:8, crates/spmp8000emu-core/src/audio_resource.rs:498-499). It is the only - embedded data and the only firmware-derived component; nothing is read + embedded data and the only firmware-derived component, and nothing is read from disk for it. files: @@ -57,5 +57,5 @@ files: and never opened at run time. 256-entry patch table (128 melodic, 128 percussion) followed by per-zone PCM samples, read by the NativeGE MIDI path. Hashes are of the file in the emulator - repository; the repository states the SHA-256. + repository, which states the SHA-256. source_ref: "crates/spmp8000emu-core/src/tone_library.rs:8, crates/spmp8000emu-core/src/tone_library.rs:24-26, crates/spmp8000emu-core/src/audio_resource.rs:498-499, crates/spmp8000emu-core/assets/README.md:3-9" diff --git a/emulators/ssf.yml b/emulators/ssf.yml index 439ab2e5..0dd191c8 100644 --- a/emulators/ssf.yml +++ b/emulators/ssf.yml @@ -20,7 +20,7 @@ notes: | binary. Two artifacts are read here and they describe the same emulator: the Windows build SSF_PreviewVer_R38.zip of 2026-01-01, sha256 7325a9b9d666560ddf632f747fb42ab880f82c45391e51fe0716beb1c535f00b, whose - emulator is the 64-bit SSF.exe and which is cited by virtual address; and the + emulator is the 64-bit SSF.exe and which is cited by virtual address, and the Android build SSF_AndroidVer.zip of 2022-08-07, package com.xrea.g2.aaaaaaaa.ssf, whose lib/arm64-v8a/libnative-lib.so keeps its 40738 dynamic symbols and which is cited by symbol. Prose references name the @@ -103,7 +103,7 @@ files: required: false category: game_data description: "cartridge image mapped at A-Bus CS0" - note: "[Peripheral] DataCartridge, gated by DataCartridgeEnable and off by default. SSF reads the file at the configured path into the 32 MiB A-Bus CS0 window and identifies it in no way; the dumps that belong there are the two Saturn ROM carts, mpr-18811-mx.ic1 for The King of Fighters '95 and mpr-19367-mx.ic1 for Ultraman. Readme.txt records the option as unverified." + note: "[Peripheral] DataCartridge, gated by DataCartridgeEnable and off by default. SSF reads the file at the configured path into the 32 MiB A-Bus CS0 window and identifies it in no way. The dumps that belong there are the two Saturn ROM carts, mpr-18811-mx.ic1 for The King of Fighters '95 and mpr-19367-mx.ic1 for Ultraman. Readme.txt records the option as unverified." source_ref: "SSF.exe 0x43e26b (DataCartridge 0x1298838), SSF.exe 0x43e178 (DataCartridgeEnable 0x1298820), SSF.exe 0x129a340, SSF.exe 0x916e5e-0x916e84, SSF-archive Document/Readme.txt Data Cartridge option" - name: "<name>.cht" @@ -113,5 +113,5 @@ files: bundled: true category: game_data description: "cheat script" - note: "Read when [Program4] EnableCheat is set, from the directory named after the disc product number. The format is a script language: triggers on first read, field, file, sector, CDDA and scanline, memory reads and writes, storage slots, branches and labels. Six ship with the emulator; the memory cheat dialog saves its own with the target address in the name." + note: "Read when [Program4] EnableCheat is set, from the directory named after the disc product number. The format is a script language: triggers on first read, field, file, sector, CDDA and scanline, memory reads and writes, storage slots, branches and labels. Six ship with the emulator, and the memory cheat dialog saves its own with the target address in the name." source_ref: "SSF.exe 0x4403c0 (EnableCheat 0x1298de0), SSF.exe 0x12998a0, SSF.exe 0x129a658, SSF.exe command table 0x128c570-0x128c808" diff --git a/emulators/starboard.yml b/emulators/starboard.yml index 018503f9..ce8b511d 100644 --- a/emulators/starboard.yml +++ b/emulators/starboard.yml @@ -77,7 +77,7 @@ files: it: the gate reads usr/bin/env and bin/sh in the extracted tree beside libproot.so in the native library directory. Integrity comes from a .sha256 sidecar requested next to the asset, whose first whitespace token - must be 64 hex characters; the file is hashed and dropped on a mismatch, + must be 64 hex characters. The file is hashed and dropped on a mismatch, while a missing sidecar logs "No rootfs checksum sidecar available" and the download is kept on TLS trust alone, which is what happens today since that sidecar answers 404. The size and hash recorded here identify release diff --git a/emulators/stella.yml b/emulators/stella.yml index f9993894..97eaa220 100644 --- a/emulators/stella.yml +++ b/emulators/stella.yml @@ -13,6 +13,6 @@ systems: note: | Identical codebase to stella2014-libretro. Both repos share the same HEAD commit and produce a binary reporting library_name "Stella 2014". The - stella_libretro.info incorrectly lists display_version "6.6"; the actual + stella_libretro.info incorrectly lists display_version "6.6", while the actual embedded version is 3.9.3. See stella2014.yml for firmware requirements and KidVid audio files. diff --git a/emulators/stella2014.yml b/emulators/stella2014.yml index 77dd472a..2cac3854 100644 --- a/emulators/stella2014.yml +++ b/emulators/stella2014.yml @@ -13,14 +13,14 @@ systems: - atari_2600 notes: | - Frozen snapshot of Stella 3.9.3. The Atari 2600 has no BIOS ROM; the TIA, + Frozen snapshot of Stella 3.9.3. The Atari 2600 has no BIOS ROM: the TIA, RIOT, and 6507 CPU are fully emulated in software. The SuperCharger (Starpath) BIOS is emulated via a built-in dummy ROM (ourDummyROMCode in stella/src/emucore/CartAR.cxx:518). - Game properties database (stella.pro) is compiled into DefProps.hxx; external + Game properties database (stella.pro) is compiled into DefProps.hxx, and external loading is disabled in the libretro port (stella/src/emucore/PropsSet.cxx:35). The core does not call GET_SYSTEM_DIRECTORY. KidVid Voice Module audio tapes (7 WAV files) are opened by rfopen with bare filenames, relative to the process working - directory (stella/src/emucore/KidVid.cxx:166-185); absence is handled gracefully. EEPROM save data for + directory (stella/src/emucore/KidVid.cxx:166-185), and absence is handled gracefully. EEPROM save data for AtariVox and SaveKey peripherals is managed as NVRAM, not user-supplied. files: diff --git a/emulators/stella2023.yml b/emulators/stella2023.yml index b6531145..27741f40 100644 --- a/emulators/stella2023.yml +++ b/emulators/stella2023.yml @@ -18,10 +18,10 @@ notes: | The .info reports display_version 6.6 which does not match the source (src/common/Version.hxx defines STELLA_VERSION as "7.0_pre"). - The Atari 2600 has no BIOS ROM; TIA, RIOT, and 6507 CPU are fully + The Atari 2600 has no BIOS ROM: TIA, RIOT, and 6507 CPU are fully emulated in software. The SuperCharger (Starpath) BIOS is emulated via a built-in dummy ROM (ourDummyROMCode in src/emucore/CartAR.cxx:279). The game - properties database is compiled into DefProps.hxx; external loading is + properties database is compiled into DefProps.hxx, and external loading is disabled in the libretro port (OSystemLIBRETRO returns CompositeKeyValueRepositoryNoop for the property repository). diff --git a/emulators/stonesoup.yml b/emulators/stonesoup.yml index 427607fc..496e9142 100644 --- a/emulators/stonesoup.yml +++ b/emulators/stonesoup.yml @@ -16,19 +16,19 @@ notes: | Accepts .crawlrc config files as content (supported_extensions: crawlrc). The libretro wrapper sets -dir to the content directory. - ref: libretro/libretro.cc:178-198 — main_wrap() passes -dir content_dir + ref: libretro/libretro.cc:178-198 (main_wrap() passes -dir content_dir) Game data loaded at runtime from dat/ tree via datafile_path(). - ref: source/files.cc:375-458 — _get_base_dirs() + datafile_path() - No DATA_DIR_PATH defined in Makefile.libretro — falls back to SysEnv.crawl_dir. + ref: source/files.cc:375-458 (_get_base_dirs() + datafile_path()) + No DATA_DIR_PATH defined in Makefile.libretro, so it falls back to SysEnv.crawl_dir. Data is NOT compiled into the binary. dat/ tree contents (532 files, 16 MB): - - dat/tiles/*.png (floor, wall, feat, player, main, gui, icons) — tiletex.cc:89-97 - - dat/DejaVuSans.ttf, dat/DejaVuSansMono.ttf — fontwrapper-ft.cc:79 - - dat/descript/*.txt, dat/database/*.txt — database.cc:72-140 - - dat/des/*.des (level generation) — maps.cc:1457 - - dat/dlua/*.lua, dat/clua/*.lua — maps.cc:1465 + - dat/tiles/*.png (floor, wall, feat, player, main, gui, icons) (tiletex.cc:89-97) + - dat/DejaVuSans.ttf, dat/DejaVuSansMono.ttf (fontwrapper-ft.cc:79) + - dat/descript/*.txt, dat/database/*.txt (database.cc:72-140) + - dat/des/*.des (level generation) (maps.cc:1457) + - dat/dlua/*.lua, dat/clua/*.lua (maps.cc:1465) - dat/defaults/ (settings) Not on buildbot.libretro.com/assets/system/. @@ -39,4 +39,4 @@ data_directories: source_ref: "source/files.cc:375-458" files: [] -# no BIOS/firmware — game data loaded via data_directories +# no BIOS/firmware, game data loaded via data_directories diff --git a/emulators/sugarbox2.yml b/emulators/sugarbox2.yml index 8d584c42..5d5b2543 100644 --- a/emulators/sugarbox2.yml +++ b/emulators/sugarbox2.yml @@ -15,7 +15,7 @@ systems: notes: | Libretro core by Recalbox wrapping Tom1975's SugarboxV2 (CPC 464, 664, 6128, 464+, 6128+ and GX-4000). Recalbox 10.1.1 builds - tag v1.5 from a token-gated copy of this repository; the public + tag v1.5 from a token-gated copy of this repository, but the public repository carries v0.9 only, which is the revision read here. Every ROM is compiled into the core as a zlib stream: OS and BASIC for @@ -32,5 +32,5 @@ notes: | Keyboards/101_keyboard_linux (ref: libretro/LibretroCore.cpp:1477-1502, 2169-2173). -exclusion_note: "all CPC, Plus and GX-4000 ROMs compiled into the core as zlib blobs; keyboard maps written by the core into the save directory" +exclusion_note: "all CPC, Plus and GX-4000 ROMs compiled into the core as zlib blobs, and keyboard maps written by the core into the save directory" files: [] diff --git a/emulators/super3.yml b/emulators/super3.yml index 1f671471..59b6666f 100644 --- a/emulators/super3.yml +++ b/emulators/super3.yml @@ -70,7 +70,7 @@ notes: | board program, the MPEG program and the MPEG music, all declared as regions of one game in Games.xml. The set is identified by the basename of the zip, not by a scan, and the ErrorLog asks for an appropriately named archive when no game answers to that - name; the individual members are then matched by name or by crc32. A child set names a + name. The individual members are then matched by name or by crc32. A child set names a parent and the loader opens <same directory>/<parent>.zip for the rest of its regions, which the front end prepares for by walking the parent chain and staging every zip it names into romcache, refusing to start and naming what is missing when one cannot be @@ -99,7 +99,7 @@ notes: | the game zip and from nowhere else. Assets/p1crosshair.bmp and Assets/p2crosshair.bmp are documented by the inherited Manual for a crosshair-style option that does not exist here, and the tree holds no bitmap reader at all, Src/Util/BMPFile.h being a - writer; the Crosshairs setting is a two bit mask and the presenter draws the crosshair + writer. The Crosshairs setting is a two bit mask and the presenter draws the crosshair as geometry. A build that wires either feature up would turn these into files to collect. ref: android/app/src/main/assets/Config/Music.xml, Manual.txt:99-102, @@ -150,7 +150,7 @@ files: note: >- Read after the built-in defaults have been applied, the Global section first and then the section named after the loaded game, each merged over what is already - set; a file that is absent or unparseable leaves the defaults standing. The hashes + set. A file that is absent or unparseable leaves the defaults standing. The hashes are those of the copy in the package assets, which is not the 13290 byte copy in the repository root Config directory: the Android build ships its own. They describe the file as shipped, since AssetInstaller rewrites it on first run, diff --git a/emulators/supermodel-legacy.yml b/emulators/supermodel-legacy.yml index 47c85215..5dde17f5 100644 --- a/emulators/supermodel-legacy.yml +++ b/emulators/supermodel-legacy.yml @@ -16,7 +16,7 @@ systems: notes: | Supermodel at trzy/Supermodel 0eef09b of 2022-08-19, the revision Batocera builds as supermodel-legacy for boards without OpenGL 4.1, the version the - renderer moved to after it. Batocera applies five patches; 001 rewrites the + renderer moved to after it. Batocera applies five patches: 001 rewrites the fixed paths below, the others touch the INI template, the build rules, audio volume and an evdev light gun input system. ref: Src/Version.h:32 @@ -31,7 +31,7 @@ notes: | ROM sets are MAME format per game archives identified by the CRC32 values in Games.xml, 60 sets at this revision. A child set missing files makes the loader - open <parent>.zip from the same directory; parents are regional or revision + open <parent>.zip from the same directory. Parents are regional or revision variants of one game, not a shared BIOS. Each Model 3 board carries its own program, video, sound and drive board ROMs, so no system ROM is read outside those archives. @@ -49,7 +49,7 @@ notes: | pass through the service menu. ref: Src/OSD/SDL/Main.cpp:656-688, Src/OSD/SDL/Main.cpp:900, Src/OSD/SDL/Main.cpp:1297 - Crosshairs are drawn as GL primitives; no Assets/ bitmap and no Music.xml are + Crosshairs are drawn as GL primitives. No Assets/ bitmap and no Music.xml are read at this revision. External GLSL shaders are read only when a VertexShader or FragmentShader key names a file, and all six keys default to empty. ref: Src/OSD/SDL/Main.cpp:703-712, Src/OSD/SDL/Main.cpp:1420-1425, @@ -64,7 +64,7 @@ files: sha1: "599a74894c61c1849e2aeff17507c233e2f459d6" md5: "84b66c6c9eb9370e983d88c4d187ea05" description: "ROM set definitions" - note: "Parsed by the GameLoader constructor before the ROM archive is opened. A file that fails to parse leaves no game defined, no set in the archive is recognised, and main returns 1. The path is the GameXMLFile key, so -game-xml-file moves it; Batocera's patch sets the default to /usr/share/supermodel/Games.xml. The hash is that of Config/Games.xml at the pinned revision, which Batocera installs." + note: "Parsed by the GameLoader constructor before the ROM archive is opened. A file that fails to parse leaves no game defined, no set in the archive is recognised, and main returns 1. The path is the GameXMLFile key, so -game-xml-file moves it, and Batocera's patch sets the default to /usr/share/supermodel/Games.xml. The hash is that of Config/Games.xml at the pinned revision, which Batocera installs." source_ref: "Src/OSD/SDL/Main.cpp:1321, Src/OSD/SDL/Main.cpp:1412, Src/OSD/SDL/Main.cpp:1866-1874, Src/GameLoader.cpp:492-502, Src/GameLoader.cpp:689-693, Src/GameLoader.cpp:895-898" exclusion_note: > diff --git a/emulators/supermodel.yml b/emulators/supermodel.yml index e787bbb2..20ece205 100644 --- a/emulators/supermodel.yml +++ b/emulators/supermodel.yml @@ -47,7 +47,7 @@ notes: | the same relative directories are used when Config/ exists in the working directory, otherwise ~/.supermodel/ when present, otherwise the XDG data and config homes. Supermodel.ini is written from a compiled-in default when it is - absent and rewritten after interactive input configuration; NVRAM/<game>.nv + absent and rewritten after interactive input configuration. NVRAM/<game>.nv and Saves/<game>.st<slot> are written by the emulator itself. ref: Src/OSD/Windows/FileSystemPath.cpp:28-49, Src/OSD/OSX/FileSystemPath.cpp:28-48, Src/OSD/Unix/FileSystemPath.cpp:51-157, Src/OSD/SDL/Main.cpp:1394-1413, @@ -67,7 +67,7 @@ notes: | Libretro NVRAM is the frontend .srm through the memory API. On the first frame a <game>.nv written by the standalone build is imported from the save directory - when the .srm is empty; it is never written back. Save states are serialised in + when the .srm is empty. It is never written back. Save states are serialised in memory, and a state file on disk is loaded only when InitStateFile names one, which the core option layer leaves empty. ref: Src/OSD/libretro/libretro.cpp:766-781, Src/OSD/libretro/libretro.cpp:1380-1409, @@ -75,7 +75,7 @@ notes: | Src/OSD/libretro/LibretroWrapper.cpp:544-545, Src/OSD/libretro/LibretroConfigProvider.h:15 The Legacy3D renderer compiles its shaders from built-in strings and reads a - file only when VertexShader or FragmentShader names one; both default to an + file only when VertexShader or FragmentShader names one, and both default to an empty string in either build. ref: Src/Graphics/Shader.cpp:52-63, Src/Graphics/Shader.cpp:100-108, Src/OSD/libretro/LibretroConfigProvider.h:22-23 @@ -93,7 +93,7 @@ files: sha1: "6871a47de90ca67f9ff8e4e280416851a8164563" md5: "0c7cfc0cba2f2cd674d94e093936f9f8" description: "ROM set definitions" - note: "Parsed at startup into the game database (Src/GameLoader.cpp:549-559, 1014-1017). Every ROM region, file name and CRC32 the loader matches against comes from here, so an unreadable file leaves no set to resolve and the launch returns before the emulator is built. The path is a config key, so -game-xml-file moves it. Nothing about the file is verified beyond parsing; the hash is that of the copy the pinned revision ships." + note: "Parsed at startup into the game database (Src/GameLoader.cpp:549-559, 1014-1017). Every ROM region, file name and CRC32 the loader matches against comes from here, so an unreadable file leaves no set to resolve and the launch returns before the emulator is built. The path is a config key, so -game-xml-file moves it. Nothing about the file is verified beyond parsing. The hash is that of the copy the pinned revision ships." source_ref: "Src/OSD/SDL/Main.cpp:117, Src/OSD/SDL/Main.cpp:1500, Src/OSD/SDL/Main.cpp:1957, Src/OSD/SDL/Main.cpp:2319-2329" - name: Games.xml @@ -110,7 +110,7 @@ files: - "2d16307ceb658636a05d34c7ba935b48" - "29fd5bc40cea222e040c1a1cfd60ea2e" description: "ROM set definitions, libretro copy" - note: "Read through the VFS from {system}/supermodel/Games.xml, or Config/Games.xml under it, and parsed from memory (Src/GameLoader.cpp:1019-1030). When the read yields nothing the bytes compiled in from Config/Games.xml are parsed instead, so the core identifies every set without a file on disk; a file that is present takes precedence. The second hash is the embedded array, which predates the indentation cleanup of the repository copy by one tab." + note: "Read through the VFS from {system}/supermodel/Games.xml, or Config/Games.xml under it, and parsed from memory (Src/GameLoader.cpp:1019-1030). When the read yields nothing the bytes compiled in from Config/Games.xml are parsed instead, so the core identifies every set without a file on disk, but a file that is present takes precedence. The second hash is the embedded array, which predates the indentation cleanup of the repository copy by one tab." source_ref: "Src/OSD/libretro/LibretroWrapper.cpp:187-206, Src/OSD/libretro/LibretroWrapper.cpp:221-222, Src/OSD/libretro/LibretroWrapper.cpp:822, Src/OSD/libretro/LibretroWrapper.cpp:834-859, Makefile:651-653" - name: Supermodel.ini @@ -123,7 +123,7 @@ files: sha1: "cbda2b3fa65e37c5c2824a4630f95f145533c360" md5: "06533608174992f6ea180ae190011778" description: "Configuration override" - note: "Read from {system}/supermodel/Supermodel.ini, or Config/Supermodel.ini under it, when present; a file that fails to parse aborts the load. Core options are applied over it afterwards, so it only reaches keys the options do not set and per-game sections. Extracted from the embedded copy when absent." + note: "Read from {system}/supermodel/Supermodel.ini, or Config/Supermodel.ini under it, when present, and a file that fails to parse aborts the load. Core options are applied over it afterwards, so it only reaches keys the options do not set and per-game sections. Extracted from the embedded copy when absent." source_ref: "Src/OSD/libretro/LibretroWrapper.cpp:187-206, Src/OSD/libretro/LibretroWrapper.cpp:219-220, Src/OSD/libretro/LibretroWrapper.cpp:812-817, Src/OSD/libretro/LibretroWrapper.cpp:858, Src/OSD/libretro/LibretroWrapper.cpp:865-866, Makefile:659-661" - name: p1crosshair.bmp diff --git a/emulators/supersnes9x.yml b/emulators/supersnes9x.yml index 1ab8a9ca..c59d0c5f 100644 --- a/emulators/supersnes9x.yml +++ b/emulators/supersnes9x.yml @@ -36,7 +36,7 @@ notes: | header at 0x7FC0 reads "Super GAMEBOY", the next byte deciding SGB2. Without one the built-in BIOS-less Game Boy core runs the cart. In BIOS mode a 256-byte GB-side boot ROM is read too, and used only when it contains the - 3E F1 handshake sequence; otherwise an embedded SGB boot ROM is used. + 3E F1 handshake sequence. Otherwise an embedded SGB boot ROM is used. ref: libretro/libretro.cpp:657-671, memmap.cpp:1088-1155, memmap.cpp:1165-1213, memmap.cpp:1655-1686, memmap.cpp:1858-1883 @@ -46,7 +46,7 @@ notes: | Sufami Turbo: a cart loads only with STBIOS.bin (256 KB). The Sufami Turbo subsystem asks LoadBIOS for 0x100000 bytes, so a 256 KB STBIOS.bin fails that - path; the plain content path and the two-cart path ask for 0x40000. + path, while the plain content path and the two-cart path ask for 0x40000. ref: libretro/libretro.cpp:1302-1305, libretro/libretro.cpp:1413-1425, libretro/libretro.cpp:1445-1455 @@ -99,7 +99,7 @@ files: size: 256 validation: [size] description: "Super Game Boy 2 GB-side boot ROM" - note: "Read in SGB2 BIOS mode; used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." + note: "Read in SGB2 BIOS mode and used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." source_ref: "memmap.cpp:1165-1213, memmap.cpp:1858-1883" - name: "sgb.boot.rom" @@ -110,7 +110,7 @@ files: size: 256 validation: [size] description: "Super Game Boy GB-side boot ROM" - note: "Read in SGB1 BIOS mode; used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." + note: "Read in SGB1 BIOS mode and used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." source_ref: "memmap.cpp:1165-1213, memmap.cpp:1858-1883" - name: "KROM1.BIN" diff --git a/emulators/superzsnes.yml b/emulators/superzsnes.yml index 91d8181d..cbd557f0 100644 --- a/emulators/superzsnes.yml +++ b/emulators/superzsnes.yml @@ -16,7 +16,7 @@ mode: standalone notes: | Super Famicom emulator by zsKnight and _Demo_, written from scratch with a GPU-rendered PPU and unrelated to the ZSNES codebase. Shipped as binaries - only, for Windows, macOS, Linux and Android; the desktop builds are Unity + only, for Windows, macOS, Linux and Android. The desktop builds are Unity Mono, so the emulator is Assembly-CSharp.dll and the per-game tables are serialized into the level0 scene. The Windows and Linux 0.230b builds carry the same tables and the same emulation sources. @@ -46,7 +46,7 @@ notes: | files: # NEC uPD7725 microcode, program and data ROM in one file. - # The name is chosen by CRC32 of the 21-byte header title; dsp1b.rom is the + # The name is chosen by CRC32 of the 21-byte header title, and dsp1b.rom is the # default when no entry in the table matches. - name: "dsp1b.rom" diff --git a/emulators/swan-emu.yml b/emulators/swan-emu.yml index 24e12599..74f8823d 100644 --- a/emulators/swan-emu.yml +++ b/emulators/swan-emu.yml @@ -36,7 +36,7 @@ notes: | Swan.emu/src/wswan/eeprom.cpp:164-169). The debugger and the disassembler are left out of the build (Swan.emu/src/CMakeLists.txt:6-22). Content is read from .ws, .wsc and .bin files (Swan.emu/metadata/conf.mk:5, - Swan.emu/src/main/AppMeta.cc:30); an archive is opened by the framework, which + Swan.emu/src/main/AppMeta.cc:30). An archive is opened by the framework, which keeps the first entry passing that same filter (EmuFramework/src/EmuSystem.cc:394-412). @@ -59,7 +59,7 @@ notes: | eight identifier bytes the boot ROM would have left (Swan.emu/src/wswan/memory.cpp:801-808). The internal EEPROM is a built-in 0x400 byte image copied at init, then personalized in place with the name, - birth date, sex and blood type of the WonderSwan User Profile menu; the + birth date, sex and blood type of the WonderSwan User Profile menu, and the language flag reaches the hardware the same way (Swan.emu/src/wswan/eeprom.cpp:31,33,183-214, Swan.emu/src/wswan/memory.cpp:748-772, Swan.emu/src/wswan/main.cpp:377, diff --git a/emulators/swanstation.yml b/emulators/swanstation.yml index e4f1e30f..f1941917 100644 --- a/emulators/swanstation.yml +++ b/emulators/swanstation.yml @@ -13,7 +13,7 @@ notes: | Fork of DuckStation maintained by the libretro community after stenzek removed libretro support. Frozen at an early DuckStation state. - Boot loads a BIOS image; when none is found a built-in OpenBIOS copy + Boot loads a BIOS image. When none is found a built-in OpenBIOS copy (dep/openbios) boots instead. ref: src/core/system.cpp:650,678-682 diff --git a/emulators/swf-player.yml b/emulators/swf-player.yml index 4301acff..3c252422 100644 --- a/emulators/swf-player.yml +++ b/emulators/swf-player.yml @@ -32,7 +32,7 @@ notes: | Two engines ship in the package, one activity each, both exported and both answering android.intent.action.VIEW for application/swf, application/x-shockwave-flash and video/x-flv. FlashPlayerActivity is labelled "SWF Player by Ruffle" and runs the movie - in a WebView; AirPlayerActivity is labelled "SWF Player by AdobeAIR", lives in a :air + in a WebView. AirPlayerActivity is labelled "SWF Player by AdobeAIR", lives in a :air process and drives a captive Adobe AIR runtime. ES-DE names the first one and passes the movie as the content URI of its own provider, so it always gets the Ruffle engine. ref: AndroidManifest.xml activity com.issess.flashplayer.player.FlashPlayerActivity and @@ -52,9 +52,9 @@ notes: | The Ruffle engine serves everything over a virtual host. FlashPlayerActivity.g0 writes <cache>/assetLoader/swf.html from the bundled contents.html template, substituting the - movie URL and the wmode, scale, quality, background and density preferences; + movie URL and the wmode, scale, quality, background and density preferences. FlashPlayerActivity.h0 builds a WebViewAssetLoader on the domain localhost.issess.net - mapping /ruffle/ to the package assets and / to that cache directory; i0 then loads + mapping /ruffle/ to the package assets and / to that cache directory, and i0 then loads https://localhost.issess.net/swf.html one second later. The template pulls /ruffle/ruffle/ruffle.js, which resolves to assets/ruffle/ruffle.js, and declares the movie as a plain <object type="application/x-shockwave-flash">, which the Ruffle polyfill @@ -271,7 +271,7 @@ files: exclusion_note: > Four files the package carries are left out because no code path opens them. The assets - cached.swf, Hello2.swf and empty.html are named in no class; the cached.swf the AIR + cached.swf, Hello2.swf and empty.html are named in no class. The cached.swf the AIR runtime reads is the copy of the user's movie written into the cache, not the one in the assets. libysshared.so, which exports only ysEncrypt and ysDecrypt, is loaded by nothing: the three loadLibrary calls in the package name swfplayer, c++_shared and Core, no diff --git a/emulators/syobonaction.yml b/emulators/syobonaction.yml index b2e8dbad..47ea0a3a 100644 --- a/emulators/syobonaction.yml +++ b/emulators/syobonaction.yml @@ -14,11 +14,11 @@ notes: > Japanese platformer by z_gundam_tanosii. Game assets required in system_dir/SyobonAction/ with BGM/, SE/, and res/ subdirectories. Level data hardcoded in source. The original libretro/syobonaction-libretro - repo was deleted; source points to the archived original by iyzsong. + repo was deleted, so source points to the archived original by iyzsong. The .info display_version is "0.1" but the code reports "0.3". files: - # ── res/ - Graphics (required: LoadGraph → exit(1) on failure) ── + # res/ - Graphics (required: LoadGraph failure calls exit(1)) - name: player.PNG path: SyobonAction/res/player.PNG @@ -83,7 +83,7 @@ files: category: game_data source_ref: "loadg.cpp:56" - # ── res/ - Font (required: TTF_OpenFont → exit(1) on failure) ── + # res/ - Font (required: TTF_OpenFont failure calls exit(1)) - name: sazanami-gothic.ttf path: SyobonAction/res/sazanami-gothic.ttf @@ -92,7 +92,7 @@ files: category: game_data source_ref: "DxLib.cpp:73" - # ── BGM/ - Music (optional: LoadMusicMem → NULL on failure, game continues) ── + # BGM/ - Music (optional: LoadMusicMem returns NULL on failure, game continues) - name: field.ogg path: SyobonAction/BGM/field.ogg @@ -129,7 +129,7 @@ files: category: game_data source_ref: "loadg.cpp:224" - # ── SE/ - Sound effects (optional: LoadSoundMem → NULL on failure, game continues) ── + # SE/ - Sound effects (optional: LoadSoundMem returns NULL on failure, game continues) - name: jump.ogg path: SyobonAction/SE/jump.ogg diff --git a/emulators/taradino.yml b/emulators/taradino.yml index 8fc2ef04..58640d58 100644 --- a/emulators/taradino.yml +++ b/emulators/taradino.yml @@ -15,16 +15,16 @@ notes: | original 1995 Apogee/3D Realms source release. Build-time switch: SHAREWARE=0 (default, "registered") expects - DARKWAR.WAD / DARKWAR.RTL / DARKWAR.RTC; SHAREWARE=1 (dropped by the + DARKWAR.WAD / DARKWAR.RTL / DARKWAR.RTC, while SHAREWARE=1 (dropped by the CMakeLists SHAREWARE option) expects HUNTBGIN.WAD / HUNTBGIN.RTL / HUNTBGIN.RTC (rott/rt_main.h:33-45). The repo distributes the - non-shareware binary; shareware builds are compiled by users from the + non-shareware binary. Shareware builds are compiled by users from the same tree. Startup assembles argv in SetupWadFile (rott/rt_main.c:808-842), joining `datadir` and STANDARDGAMEWAD, then feeds it to W_InitMultipleFiles (rott/rt_main.c:842, rott/w_wad.c). The WAD search tries each path - registered through add_datadir() (rott/rt_datadir.c:198-209); a missing + registered through add_datadir() (rott/rt_datadir.c:198-209). A missing main WAD aborts with FileNotFoundError(STANDARDGAMEWAD) (rott/rt_main.c:812). @@ -35,7 +35,7 @@ notes: | ROTT_SITELICENSE, ROTT_SUPERCD or ROTT_REGISTERED. Shareware builds stay on ROTT_SHAREWARE. - REMOTE1.RTS carries the "Remote Ridicule" speech bank; its absence is + REMOTE1.RTS carries the "Remote Ridicule" speech bank, and its absence is silently tolerated (rott/rt_main.c:830-834). No hash is validated: the loader relies on WAD lump names and the @@ -91,7 +91,7 @@ files: # ================================================================ # Shareware build (SHAREWARE=1, rott/rt_main.h:41-43) - # Produced only when users set -DSHAREWARE=1; file names differ. + # Produced only when users set -DSHAREWARE=1. File names differ. # ================================================================ - name: "HUNTBGIN.WAD" diff --git a/emulators/test_netplay.yml b/emulators/test_netplay.yml index 02890832..9a8026af 100644 --- a/emulators/test_netplay.yml +++ b/emulators/test_netplay.yml @@ -17,7 +17,7 @@ notes: | exclusion_note: > .info declares no firmware (firmware_count absent). No source code found - to analyze — searched libretro-samples, RetroArch cores, libretro-super, + to analyze: searched libretro-samples, RetroArch cores, libretro-super, and the full libretro GitHub org. files: [] diff --git a/emulators/theforceengine.yml b/emulators/theforceengine.yml index 62bb0969..a348eb8a 100644 --- a/emulators/theforceengine.yml +++ b/emulators/theforceengine.yml @@ -29,7 +29,7 @@ notes: | c_gobFileNames[] = DARK.GOB, SOUNDS.GOB, TEXTURES.GOB, SPRITES.GOB c_optionalGobFileNames[] = enhanced.gob The DOS retail Dark Forces floppy and CD both ship DARK.GOB, SOUNDS.GOB, - TEXTURES.GOB, SPRITES.GOB; enhanced.gob is the TFE-only HD asset pack. + TEXTURES.GOB, SPRITES.GOB, and enhanced.gob is the TFE-only HD asset pack. Dark Forces official patch v1.22 (df_patch4) is pulled by the build script as df_patch4.zip from df-21.net and dropped under Mods/, so the engine applies @@ -40,7 +40,7 @@ notes: | Outlaws: every method of TFE_Outlaws/outlawsMain.cpp is a stub and runGame() returns false. The only Outlaws file the code names is Outlaws.lab, tested by the settings dialog before it stores the Outlaws - source path (TFE_FrontEndUI/frontEndUi.cpp:1340); the line that would + source path (TFE_FrontEndUI/frontEndUi.cpp:1340). The line that would make it the active source path is commented out (:1344). files: diff --git a/emulators/thextech.yml b/emulators/thextech.yml index bd3602c6..0e87877f 100644 --- a/emulators/thextech.yml +++ b/emulators/thextech.yml @@ -11,7 +11,7 @@ systems: [smbx] notes: | C++ reimplementation of the SMBX 1.3 engine. The engine itself ships - no game assets; asset packs are searched at startup under every root + no game assets. Asset packs are searched at startup under every root of AppPathManager::assetsSearchPath(): the root itself (legacy layout), then each directory or archive of its assets/ folder. ref: src/main/asset_pack.cpp:249-378 (s_find_asset_packs), @@ -23,7 +23,7 @@ notes: | matching the running target, pack-id) gameinfo.ini directory pack ([game] id, menu images under [android]) - A pack under assets/ is ignored when no id could be read; the legacy + A pack under assets/ is ignored when no id could be read, while the legacy root pack needs none. ref: src/main/asset_pack.cpp:125-207, 334-339 @@ -39,12 +39,12 @@ notes: | TheXTech is content-agnostic. The reference packs that TheXTech releases alongside the engine are the SMBX 1.3 asset pack (`thextech-assets-smbx13`) and the free Adventures of Demo pack - (`thextech-assets-adventures-of-demo`); any pack that satisfies the + (`thextech-assets-adventures-of-demo`). Any pack that satisfies the structure above runs. Paths below are written from a search root. TheXTech/ is the name the build gives its user directory (THEXTECH_DIRECTORY_PREFIX) and its - system directory; the application directory is searched the same way. + system directory, and the application directory is searched the same way. ref: CMakeLists.txt:297, lib/AppPath/private/app_path_unix.cpp:46, 103, lib/AppPath/private/app_path.cpp:87 @@ -59,7 +59,7 @@ files: path: "TheXTech/assets/" required: false source_ref: "src/main/asset_pack.cpp:131-181, 290-300, 313-319" - note: "Every file directly under assets/ is opened as an archive and kept as a pack when it holds _meta.ini; every subdirectory is kept when it holds graphics/ui/. _meta.ini is read only through the archive prefix: [content] engine must be TheXTech, platform must match the build, pack-id names the pack." + note: "Every file directly under assets/ is opened as an archive and kept as a pack when it holds _meta.ini, and every subdirectory is kept when it holds graphics/ui/. _meta.ini is read only through the archive prefix: [content] engine must be TheXTech, platform must match the build, pack-id names the pack." - name: "gameinfo.ini" category: game_data @@ -91,7 +91,7 @@ files: path: "TheXTech/graphics/ui/MenuGFX2.png" required: true source_ref: "src/main/asset_pack.cpp:116, 226-230, 334-335, src/gfx.cpp:201" - note: "Main menu logo. Pack ignored if no logo loads; GFX_t::load requires it as well." + note: "Main menu logo. Pack ignored if no logo loads, and GFX_t::load requires it as well." - name: "background2-2.png" category: game_data @@ -102,7 +102,7 @@ files: # ================================================================ # Core content (engine iterates on disk, filenames are the pack's - # own; the directory contract is what the engine checks) + # own, the directory contract is what the engine checks) # ================================================================ - name: "graphics/" @@ -111,7 +111,7 @@ files: path: "TheXTech/graphics/" required: true source_ref: "src/main/asset_pack.cpp:274, 326-327, src/gfx.cpp:121-229, src/load_gfx.cpp:120-123" - note: "graphics/ui/ must exist for a directory to be scanned as a pack; GFX_t::load rejects the pack when a required UI image is missing." + note: "graphics/ui/ must exist for a directory to be scanned as a pack, and GFX_t::load rejects the pack when a required UI image is missing." - name: "fonts/" type: directory @@ -172,7 +172,7 @@ files: aliases: ["intro.lvl"] required: true source_ref: "src/game_main.cpp:172-185, 224-250, 1095-1106" - note: "Level shown behind the main menu. intro.lvl is opened when intro.lvlx is absent, and a level picked from introset/ takes the place of both; with none of the three the game exits on a fatal error." + note: "Level shown behind the main menu. intro.lvl is opened when intro.lvlx is absent, and a level picked from introset/ takes the place of both. With none of the three the game exits on a fatal error." - name: "introset/" type: directory @@ -180,7 +180,7 @@ files: path: "TheXTech/introset/" required: false source_ref: "src/game_main.cpp:194-222, 247, src/main/level_file.cpp:321-339" - note: "Directory of .lvl/.lvlx intro levels; one is picked at random when present, otherwise the root intro level is opened. The Adventures of Demo pack carries none; these 19 levels come from the introset/ of the Nostalgic Paradise pack (Blue Edition 0.2.8b, nostalgic-paradise-stable.7z). A level reads custom graphics from introset/ and from the subfolder named after it (07/, 08/, 10/); every other block, BGO, NPC and background ID they use is present in the Adventures of Demo graphics." + note: "Directory of .lvl/.lvlx intro levels. One is picked at random when present, otherwise the root intro level is opened. The Adventures of Demo pack carries none, and these 19 levels come from the introset/ of the Nostalgic Paradise pack (Blue Edition 0.2.8b, nostalgic-paradise-stable.7z). A level reads custom graphics from introset/ and from the subfolder named after it (07/, 08/, 10/), and every other block, BGO, NPC and background ID they use is present in the Adventures of Demo graphics." - name: "outro.lvlx" category: game_data diff --git a/emulators/tia.yml b/emulators/tia.yml index 1d84b087..04289ad1 100644 --- a/emulators/tia.yml +++ b/emulators/tia.yml @@ -14,7 +14,7 @@ systems: files: [] exclusion_note: > The core opens no file. src/ has no fopen, filestream or opendir call and - libretro.c never asks for RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY; its + libretro.c never asks for RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY. Its environment calls cover options, logging, controller info, input descriptors, messages, pixel format and AV info. The Supercharger BIOS is a 294-byte routine compiled in (src/cart.c:195-235) and written into the @@ -24,6 +24,6 @@ exclusion_note: > (src/palette.c). Content arrives in memory (src/libretro.c:596). notes: | Tia is an Atari 2600 core written for libretro by Eric Warmenhoven, with - no standalone build; the repository is its own upstream. The version + no standalone build, so the repository is its own upstream. The version string is the commit count and short hash the Makefile bakes in (Makefile:36-37, src/libretro.c:595). The .info shows 26. diff --git a/emulators/tic80.yml b/emulators/tic80.yml index 811d2890..1c57e555 100644 --- a/emulators/tic80.yml +++ b/emulators/tic80.yml @@ -15,7 +15,7 @@ systems: notes: | Fantasy computer for making, playing and sharing tiny games. - The libretro repo wraps nesbox/TIC-80 as a submodule; the libretro + The libretro repo wraps nesbox/TIC-80 as a submodule, and the libretro wrapper (tic80_libretro.c) lives in the upstream repo itself. Content loaded entirely via libretro data buffer (need_fullpath = false, diff --git a/emulators/touchhle.yml b/emulators/touchhle.yml index 81e7c2a5..19703ee4 100644 --- a/emulators/touchhle.yml +++ b/emulators/touchhle.yml @@ -31,7 +31,7 @@ notes: | Fonts are opened the first time an app draws text in that face, and a missing or unparsable file is a panic. The Liberation families stand in for - the iPhone OS faces; Noto Sans JP is used for strings holding kana or kanji. + the iPhone OS faces, and Noto Sans JP is used for strings holding kana or kanji. ROCKNIX installs only the LiberationSans files, so an app that asks for a monospace, serif or Japanese face stops there. ref: src/font.rs:70-129, src/frameworks/uikit/ui_font.rs:26-43, @@ -83,7 +83,7 @@ files: md5: "e59b87dce1497a1ba08d472667722916" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:88-90" - name: "LiberationMono-Bold.ttf" @@ -94,7 +94,7 @@ files: md5: "e52e17953632fd6f1da5e51c84a6dea7" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:91-93" - name: "LiberationMono-BoldItalic.ttf" @@ -105,7 +105,7 @@ files: md5: "00bed708fb7614c12c92cfd16f1fb7b8" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:94-96" - name: "LiberationMono-Italic.ttf" @@ -116,7 +116,7 @@ files: md5: "fe762a65e22e23c935aff8eda38eaaf3" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:97-99" - name: "LiberationSans-Regular.ttf" @@ -127,7 +127,7 @@ files: md5: "d7b4e92b03deb1865aa61328fd5ff400" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:100-102" - name: "LiberationSans-Bold.ttf" @@ -138,7 +138,7 @@ files: md5: "ab3823f8c454609eab661b54751fd55e" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:103-105" - name: "LiberationSans-BoldItalic.ttf" @@ -149,7 +149,7 @@ files: md5: "ad144bbd42d9dccb07db1aae6682b98b" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:106-108" - name: "LiberationSans-Italic.ttf" @@ -160,7 +160,7 @@ files: md5: "333f554fddaa0faf89afc3621a6a18c8" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:109-111" - name: "LiberationSerif-Regular.ttf" @@ -171,7 +171,7 @@ files: md5: "732ab01395f607bf178d0f32d841cc71" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:112-114" - name: "LiberationSerif-Bold.ttf" @@ -182,7 +182,7 @@ files: md5: "184a866d565bae797baa39458fde7ac4" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:115-117" - name: "LiberationSerif-BoldItalic.ttf" @@ -193,7 +193,7 @@ files: md5: "23e615c7010f0ad9f1d2817009733cb9" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:118-120" - name: "LiberationSerif-Italic.ttf" @@ -204,7 +204,7 @@ files: md5: "31defdf69fc00c20b9caabe3e76d53e1" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:121-123" - name: "NotoSansJP-Regular.otf" @@ -215,7 +215,7 @@ files: md5: "f82ef23cfbf8b46a234465b0151ee71f" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:124-126" - name: "NotoSansJP-Bold.otf" @@ -226,7 +226,7 @@ files: md5: "77921099a1d3fce6fb64a7b3b678b7dc" bundled: true description: "Bundled font" - note: "Opened on first use of its face; touchHLE panics when it is missing." + note: "Opened on first use of its face. touchHLE panics when it is missing." source_ref: "src/font.rs:70-85, src/font.rs:127-129" - name: "touchHLE_default_options.txt" diff --git a/emulators/tr1x.yml b/emulators/tr1x.yml index 1ce39fda..33344927 100644 --- a/emulators/tr1x.yml +++ b/emulators/tr1x.yml @@ -27,7 +27,7 @@ notes: | FMV extension probing (src/trx/game/paths.c:76-79): .mp4 .mkv .mpeg .avi .webm .ogv .rpl .fmv .bik - The retail Core/Eidos cutscenes are .rpl; the gameflow still names + The retail Core/Eidos cutscenes are .rpl. The gameflow still names them .avi, resolution picks whichever extension exists. Music backend (src/trx/game/music/backend_files.c:25-49): @@ -43,7 +43,7 @@ files: # Enumerated by data/trx/ship/games/tr1/gameflow.json5 "levels" array. - name: "title.phd" path: "games/tr1/levels/title.phd" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" required: true category: game_data source_ref: "data/trx/ship/games/tr1/gameflow.json5:38" @@ -63,7 +63,7 @@ files: - name: "level2.phd" path: "games/tr1/levels/level2.phd" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" required: true category: game_data source_ref: "data/trx/ship/games/tr1/gameflow.json5:116" @@ -190,7 +190,7 @@ files: # FMV cutscenes # Enumerated by data/trx/ship/games/tr1/gameflow.json5 "fmvs" array. - # The retail files on disc carry a .rpl extension; the gameflow still + # The retail files on disc carry a .rpl extension. The gameflow still # lists .avi, resolution picks whichever extension is present. - name: "core.avi" aliases: [core.rpl] @@ -668,7 +668,7 @@ files: # PC demo # Known game tr1-demo-pc, extends tr1 (src/trx/game/shell/mod.c:32-33). # tools/download_assets and the installer fetch tr1-demo-pc.zip from the - # project's host; it holds games/tr1-demo-pc/levels/{title,level2}.phd. + # project's host. It holds games/tr1-demo-pc/levels/{title,level2}.phd. - name: "title.phd" path: "games/tr1-demo-pc/levels/title.phd" required: false diff --git a/emulators/tr2x.yml b/emulators/tr2x.yml index 98d488ab..88631141 100644 --- a/emulators/tr2x.yml +++ b/emulators/tr2x.yml @@ -33,7 +33,7 @@ notes: | FMV extension probing (src/trx/game/paths.c:76-79): .mp4 .mkv .mpeg .avi .webm .ogv .rpl .fmv .bik - The retail Core/Eidos cutscenes are .rpl; the gameflow still names + The retail Core/Eidos cutscenes are .rpl. The gameflow still names them .AVI, resolution picks whichever extension exists. Music backend (src/trx/game/music/backend_files.c:25-49): @@ -46,7 +46,7 @@ files: # Soundbank - name: "main.sfx" path: "games/tr2/main.sfx" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" required: true category: game_data source_ref: "data/trx/ship/games/tr2/gameflow.json5:33" @@ -56,7 +56,7 @@ files: # Enumerated by data/trx/ship/games/tr2/gameflow.json5 "levels" array. - name: "title.tr2" path: "games/tr2/levels/title.tr2" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" required: true category: game_data source_ref: "data/trx/ship/games/tr2/gameflow.json5:15" @@ -224,7 +224,7 @@ files: # FMV cutscenes # Enumerated by data/trx/ship/games/tr2/gameflow.json5 "fmvs" array. - # The retail files on disc carry a .rpl extension; the gameflow still + # The retail files on disc carry a .rpl extension. The gameflow still # lists .AVI, resolution picks whichever extension is present. - name: "LOGO.AVI" aliases: [logo.rpl] @@ -286,7 +286,7 @@ files: # Music tracks (retail CD audio, ripped as N.<ext>). # Enumerated by the ship tree in docs/trx/INSTALLING.md (TR2 uses the - # bare-number form, not the trackNN form; the loader accepts either). + # bare-number form, not the trackNN form, and the loader accepts either). - name: "2.mp3" path: "games/tr2/music/2.mp3" required: false @@ -652,7 +652,7 @@ files: # Enumerated by data/trx/ship/games/tr2-gm/gameflow.json5 "levels" array. # Its FMVs and music fall back to games/tr2. # tools/download_assets and the installer fetch tr2-gm.zip from the - # project's host; it holds games/tr2-gm/main.sfx and games/tr2-gm/levels/*.tr2. + # project's host. It holds games/tr2-gm/main.sfx and games/tr2-gm/levels/*.tr2. # Installing from a retail directory maps data/main_gm.sfx to # games/tr2-gm/main_gm.sfx and data/*.tr2 to games/tr2-gm/levels/. - name: "main.sfx" diff --git a/emulators/triforce.yml b/emulators/triforce.yml index 844b425a..9c112078 100644 --- a/emulators/triforce.yml +++ b/emulators/triforce.yml @@ -22,7 +22,7 @@ notes: | the serial interface, AM-Mediaboard on the disc interface) and the Wii Arcade boards on top of GameCube and Wii emulation. The tree self-reports Dolphin 2407 (CMake/ScmRevGen.cmake:34-35) and builds DolphinQt. crediar publishes the source - on crediar.dev; the commit profiled here is the REG-Linux mirror of it, whose + on crediar.dev. The commit profiled here is the REG-Linux mirror of it, whose Data/Sys tree matches the Hancock33 and ReaverTeknoGods mirrors byte for byte. ES-DE looks for dolphin-emu-triforce on Linux and Triforce.exe or Triforce/DolphinWX.exe on Windows, RetroBat installs it as dolphin-triforce. @@ -243,7 +243,7 @@ files: swaps every 16 bit word before storing it, so the Adler32 in the source is taken over the swapped data (Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:100-102). The pair is matched against seven known sets, the first being the Nintendo - ROMs; a miss asks the user whether to stop + ROMs, and a miss asks the user whether to stop (Source/Core/Core/DSP/DSPCore.cpp:60-84). - name: "dsp_coef.bin" diff --git a/emulators/tyrquake.yml b/emulators/tyrquake.yml index 82684b3a..f5e9c656 100644 --- a/emulators/tyrquake.yml +++ b/emulators/tyrquake.yml @@ -13,7 +13,7 @@ notes: > Quake engine source port by Kevin Shanahan (Tyrann). Plays Quake (id1), mission packs Scourge of Armagon (hipnotic) and Dissolution of Eternity (rogue), Quoth mod, and custom mods via -game parameter. Content is loaded directly from the - PAK file path — the directory containing the PAK becomes basedir + PAK file path: the directory containing the PAK becomes basedir (libretro.c:988,1050). The engine auto-detects game variant by checking the content path for id1, hipnotic, rogue, or quoth substrings (common/libretro.c:1313-1377). All engine assets (gfx/palette.lmp, gfx/colormap.lmp, diff --git a/emulators/ume2015.yml b/emulators/ume2015.yml index 3de25a92..07c8a68c 100644 --- a/emulators/ume2015.yml +++ b/emulators/ume2015.yml @@ -47,7 +47,7 @@ systems: - konami-twinkle notes: | - Universal Machine Emulator — combined MAME + MESS before the official + Universal Machine Emulator: combined MAME + MESS before the official merge at MAME 0.162. Same repo as mame2015 (mame2015-libretro), built with -DWANT_UME including both mame.mak and mess.mak. 69 arcade BIOS root sets (identical to mame2015), plus 619 MESS computer/console @@ -73,7 +73,7 @@ files: size: 216250 source_ref: "src/emu/hiscore.c:122-138,335-337" note: >- - high score definitions, external file, not embedded. metadata/hiscore.dat of the core repository; is_mem_range reads + high score definitions, external file, not embedded. metadata/hiscore.dat of the core repository. is_mem_range reads only "cpu:addr:len:start:end" lines under a "gamename:" header. # SNK Neo Geo MVS/AES diff --git a/emulators/uqm.yml b/emulators/uqm.yml index 4abaa3ff..b55c1495 100644 --- a/emulators/uqm.yml +++ b/emulators/uqm.yml @@ -20,14 +20,14 @@ notes: | prepareContentDir() in src/options.c:136 searches for content/ relative to the executable (default locations are CONTENTDIR, "", - "content", "../../content"; macOS also probes the app bundle). A + "content", "../../content", while macOS also probes the app bundle). A sentinel file content/version must exist (lines 138-150) or the game logs "Could not find content" and exits. mountContentDir() (src/options.c:329) mounts content/ at the uio root and then auto-mounts every .uqm file found under content/packages/ as an overlay archive (lines 354-359). The engine itself does not treat - individual .uqm packages as mandatory; the fatal check is the + individual .uqm packages as mandatory: the fatal check is the content/ tree. In practice content/packages/uqm-0.8.0-content.uqm is "Core Data" in the Windows installer (uqm-installer.nsi:289-306, SectionIn 1 2 3 4 6) and the game is unplayable without it. @@ -39,10 +39,10 @@ notes: | content/base, content/addons and the two .key sentinel files (uqm.key, menu.key) are shipped verbatim in the source repository - and are not external data; they are not listed here. + and are not external data, so they are not listed here. MD5 and size values come from build/win32_install/packages.nsh, - autogenerated by procpkgs.sh at release time; sizes are the KiB + autogenerated by procpkgs.sh at release time. Sizes are the KiB values the NSIS installer uses with AddSize. files: diff --git a/emulators/vaporspec.yml b/emulators/vaporspec.yml index 3f0985da..1b88ee3d 100644 --- a/emulators/vaporspec.yml +++ b/emulators/vaporspec.yml @@ -14,5 +14,5 @@ notes: > Fantasy console with fixed specs (256x192 display, 4-channel audio, 256-color palette). Runs .vaporbin cartridge bundles containing code and optional ROM data. All content is self-contained in the bundle - passed by the frontend; no system directory files loaded. + passed by the frontend. No system directory files loaded. firmware_count=0 confirmed by code analysis. diff --git a/emulators/veesem.yml b/emulators/veesem.yml index c8d0fb9b..57abbf5e 100644 --- a/emulators/veesem.yml +++ b/emulators/veesem.yml @@ -46,7 +46,7 @@ notes: | Region is a jumper, not a file. The low nibble of Port C carries the region code and bit 4 the VTech logo jumper (vsmile.cc:148-152), defaulting to 0xe with the logo on (main.cc:44-45) and settable with -region and -novtech. One - system ROM image serves every region; the table at vsmile.cc:3-25 maps the + system ROM image serves every region. The table at vsmile.cc:3-25 maps the sixteen jumper values to the intro each revision produces, and names revisions 1.00, 1.02 and 1.03. diff --git a/emulators/vice_x128.yml b/emulators/vice_x128.yml index 2768db5d..e4cc0127 100644 --- a/emulators/vice_x128.yml +++ b/emulators/vice_x128.yml @@ -15,7 +15,7 @@ notes: > plus all drive ROMs (1540, 1541, 1541-II, 1551, 1570, 1571, 1571CR, 1581, 1001, 2031, 2040, 3040, 4040, 9000). Embedded ROM check in sysfile_load takes priority over filesystem. Localized kernal/chargen variants (DE, FI, FR, IT, NO, SE, CH) are in the embedded list - with NULL data pointers; selecting a non-international model produces uninitialized ROM data. + with NULL data pointers, so selecting a non-international model produces uninitialized ROM data. JiffyDOS requires True Drive Emulation enabled and a 1541/1571/1581 drive type. C64 BASIC/kernal use shared names (basic-901226-01.bin, kernal-901227-03.bin) instead of upstream c128-specific names (basic64-901226-01.bin, kernal64-901227-03.bin) to share diff --git a/emulators/vice_x64.yml b/emulators/vice_x64.yml index da9d981e..aa69c91c 100644 --- a/emulators/vice_x64.yml +++ b/emulators/vice_x64.yml @@ -16,7 +16,7 @@ notes: > plus all drive ROMs (1540, 1541, 1541-II, 1551, 1570, 1571, 1571CR, 1581, 1001, 2031, 2040, 3040, 4040, 9000) and VIC-II palettes. Embedded ROM check in sysfile_load takes priority over filesystem. Kernal Rev 1 (901227-01) and - Rev 2 (901227-02) are NOT embedded; selecting C64 OLD NTSC or C64 OLD PAL model + Rev 2 (901227-02) are NOT embedded: selecting C64 OLD NTSC or C64 OLD PAL model requires them on the filesystem in system/vice/C64/. JiffyDOS requires True Drive Emulation enabled and a 1541/1571/1581 drive type. SX-64 models use a separate JiffyDOS kernal (JiffyDOS_SX-64.bin) not declared in the .info. diff --git a/emulators/vice_x64dtv.yml b/emulators/vice_x64dtv.yml index c219cdd2..9c8453d9 100644 --- a/emulators/vice_x64dtv.yml +++ b/emulators/vice_x64dtv.yml @@ -14,7 +14,7 @@ notes: > (901227-03), chargen (901225-01), plus all drive ROMs (1540, 1541, 1541-II, 1551, 1570, 1571, 1571CR, 1581, 1001, 2031, 2040, 3040, 4040, 9000). Embedded ROM check in sysfile_load takes priority over filesystem. - DTV has its own color system (viciidtv-color.c); external palette loading + DTV has its own color system (viciidtv-color.c), and external palette loading is disabled. JiffyDOS is not supported (excluded from build conditionals). The .info declares 4 JiffyDOS firmware (firmware_count=4) but the code never loads them for this core. The .info also omits dtvrom.bin. @@ -32,4 +32,4 @@ files: found, the core copies embedded BASIC, kernal and chargen ROMs into flash memory. Without it, the DTV operates as a basic C64 without the built-in DTV games and firmware. The original DTV ROM has distorted - colors; a patched ROM is recommended. + colors, so a patched ROM is recommended. diff --git a/emulators/vice_x64sc.yml b/emulators/vice_x64sc.yml index a45aafd2..0beca070 100644 --- a/emulators/vice_x64sc.yml +++ b/emulators/vice_x64sc.yml @@ -17,7 +17,7 @@ notes: > plus all drive ROMs (1540, 1541, 1541-II, 1551, 1570, 1571, 1571CR, 1581, 1001, 2031, 2040, 3040, 4040, 9000) and VIC-II palettes. Embedded ROM check in sysfile_load takes priority over filesystem. Kernal Rev 1 (901227-01) and - Rev 2 (901227-02) are NOT embedded; selecting C64 OLD NTSC or C64 OLD PAL model + Rev 2 (901227-02) are NOT embedded: selecting C64 OLD NTSC or C64 OLD PAL model requires them on the filesystem in system/vice/C64/. JiffyDOS requires True Drive Emulation enabled and a 1541/1571/1581 drive type. SX-64 models use a separate JiffyDOS kernal (JiffyDOS_SX-64.bin) not declared in the .info. diff --git a/emulators/vice_xplus4.yml b/emulators/vice_xplus4.yml index 4b8e9460..f8ccac1a 100644 --- a/emulators/vice_xplus4.yml +++ b/emulators/vice_xplus4.yml @@ -17,7 +17,7 @@ notes: > 1571CR, 1581, 1001, 2031, 2040, 3040, 4040, 9000). TED palettes embedded (colodore_ted, BT601, BT709, BT2020, yape-pal, yape-ntsc). Embedded check in sysfile_load takes priority over filesystem. Models: C16 PAL/NTSC, Plus/4 - PAL/NTSC, V364 NTSC, 232 NTSC — all use embedded kernal variants. No JiffyDOS + PAL/NTSC, V364 NTSC, 232 NTSC. All use embedded kernal variants. No JiffyDOS support (C64/C128/SCPU64 only). 3+1 function ROMs loaded for Plus/4 and V364 models, cleared to 0xFF for C16 and 232 models. c2lo loaded only for V364 model. diff --git a/emulators/vice_xscpu64.yml b/emulators/vice_xscpu64.yml index 36c45b9f..1d543706 100644 --- a/emulators/vice_xscpu64.yml +++ b/emulators/vice_xscpu64.yml @@ -18,7 +18,7 @@ notes: > system/vice/SCPU64/ when SuperCPU Kernal core option is changed from Internal. JiffyDOS requires True Drive Emulation enabled and a non-internal SuperCPU kernal (the internal ROM is not JiffyDOS-compatible). The .info incorrectly - declares JiffyDOS_C64.bin (firmware_count=4); the C64 kernal replacement is + declares JiffyDOS_C64.bin (firmware_count=4), but the C64 kernal replacement is only loaded for x64/x64sc/x128, never for xscpu64. Correct firmware_count=5 (2 SCPU64 kernals + 3 JiffyDOS drive DOSes). diff --git a/emulators/video_processor.yml b/emulators/video_processor.yml index 4d950616..9469582e 100644 --- a/emulators/video_processor.yml +++ b/emulators/video_processor.yml @@ -39,7 +39,7 @@ notes: | video_processor_v4l2.c:244-268, video_processor_v4l2.c:448-455 The frame rate is the frameperiod of the active V4L2 standard and the - pixel aspect comes from VIDIOC_CROPCAP; retro_get_region reports NTSC when + pixel aspect comes from VIDIOC_CROPCAP. retro_get_region reports NTSC when the standard carries the NTSC bit and PAL otherwise. A device that does not enumerate its active standard makes retro_load_game fail. ref: video_processor_v4l2.c:457-480, video_processor_v4l2.c:593-617, @@ -52,13 +52,13 @@ notes: | packages, and the buildbot binary for linux x86_64 links libv4l2.so.0, libasound.so.2 and libudev.so.1. RetroArch also compiles a diverged copy of this core into its own binary under cores/libretro-video-processor when - HAVE_VIDEOPROCESSOR is set; that copy declares no-content support and adds + HAVE_VIDEOPROCESSOR is set. That copy declares no-content support and adds capture and output mode options, and opens the same device nodes only. ref: video_processor_v4l2.c:45-57, Makefile:107-124 Written by Jared McNeill in July 2016 as libretro-v4l2. The libretro fork carries the author's last commits, the audio batch callback and the ALSA - overrun recovery, then the 2026 CI and dependency autodetection change; the + overrun recovery, then the 2026 CI and dependency autodetection change. The original repository stopped at the RGB24 conversion commit. files: [] diff --git a/emulators/virtual-virtual-boy.yml b/emulators/virtual-virtual-boy.yml index e962993a..d12b6893 100644 --- a/emulators/virtual-virtual-boy.yml +++ b/emulators/virtual-virtual-boy.yml @@ -25,7 +25,7 @@ notes: | VIRTUAL-VIRTUAL-BOY find rule, which hands the game over as an ACTION_VIEW intent on a content URI (MainActivity.kt:126-131, MainActivity.kt:40-45). The hardware sits in a Rust library packaged as libvvb.so and loaded when the - application starts (VvbApplication.kt:69, Cargo.toml [lib]); the Kotlin side + application starts (VvbApplication.kt:69, Cargo.toml [lib]), and the Kotlin side owns the menus, the input mapping and every file access. Display goes through mono, anaglyph, stereo, Google Cardboard and Leia CNSDK renderers, each carrying its GLSL as string constants in the Rust sources diff --git a/emulators/virtualjaguar.yml b/emulators/virtualjaguar.yml index 7d55c027..75383dfc 100644 --- a/emulators/virtualjaguar.yml +++ b/emulators/virtualjaguar.yml @@ -17,10 +17,10 @@ notes: | longer only uses them. Staging moved out of retro_load_game into stage_cart_boot_rom, which reads a file first and falls back to the embedded array (libretro.c:5339-5382). BT_M_SERIES tries jagboot_m.rom in - the system directory; BT_CUSTOM, a value the enum did not carry before, + the system directory. BT_CUSTOM, a value the enum did not carry before, searches six names across the system directory and two subdirectories (libretro.c:5293-5337). Either way the file has to be 0x20000 bytes, the - size copied to jagMemSpace + 0xE00000; anything shorter is a short read and + size copied to jagMemSpace + 0xE00000. Anything shorter is a short read and the embedded Series K takes over. The Jaguar CD BIOS is the larger change. stage_cd_bios calls @@ -69,7 +69,7 @@ files: note: >- Searched in the system directory and under Atari - Jaguar, Atari - Jaguar CD, jaguar and jaguarcd. Accepted at exactly 262144 - bytes and recognised by its CRC32; a file of the right size whose + bytes and recognised by its CRC32. A file of the right size whose checksum matches neither constant is counted as rejected and the embedded BIOS is used. The generic names are tried after the type the virtualjaguar_cd_bios_type option selects. @@ -104,7 +104,7 @@ files: source_ref: "libretro.c:5293-5337, libretro.c:5339-5356" note: >- Reached only through BT_CUSTOM. Searched in the system directory and - under Atari - Jaguar and jaguar. No checksum is tested; a read shorter + under Atari - Jaguar and jaguar. No checksum is tested, and a read shorter than 131072 bytes leaves the embedded Series K in place. - name: jagboot_m.rom diff --git a/emulators/visual-pinball.yml b/emulators/visual-pinball.yml index 867e3c38..72314b7b 100644 --- a/emulators/visual-pinball.yml +++ b/emulators/visual-pinball.yml @@ -21,7 +21,7 @@ notes: | other than the Windows editor compiles the shared source set with __STANDALONE__ and links libwinevbs, Wine's VBScript engine with its COM and ATL headers, beside SDL3, SDL3_ttf, FreeImage, hidapi, libspatialaudio and - libmysofa with zlib; PinMAME, AltSound, + libmysofa with zlib. PinMAME, AltSound, DMDUtil, DOF, FlexDMD, B2S, PUP, Serum, VNI and ScoreView are plugins staged in plugins/ next to the binary (make/CMakeLists_app.txt:533-554,605-615, make/CMakeLists_sources.txt:811-817, make/CMakeLists_plugins.txt:21-25,39-56). @@ -62,7 +62,7 @@ notes: | table's user folder, created on demand, TablesDirectory the system documents folder or the installation folder when SDL reports none, MusicDirectory the table's music folder with an optional subfolder, ScriptsDirectory scripts/ - under the installation folder; each fails when its directory does not exist + under the installation folder. Each fails when its directory does not exist (src/core/ScriptGlobalTable.cpp:383-424, src/core/FileLocator.cpp:251-259). In AppPrefData mode user/, music/, cache/ and autosave/ sit beside the table; a folder missing there on a read is looked up the AppOnly way, where user/ @@ -87,7 +87,7 @@ notes: | four (src/core/AppCommands.cpp:277-283, src/ui/live/EditorUI.cpp:338-357). OpenGL builds also get shaders-10.8.1/, the .glfx and .fxh sources parsed at runtime (src/core/FileLocator.cpp:223, src/renderer/Shader.cpp:1827-1828,2231-2234, - make/CMakeLists_app.txt:637-647); the directory is not copied for the BGFX + make/CMakeLists_app.txt:637-647), and the directory is not copied for the BGFX renderer. Three plugins carry resources of their own: plugins/flexdmd/assets/ holds the bitmap fonts UltraDMD asks for by resource name, the FlexDMD.Resources. prefix being stripped before the lookup @@ -124,12 +124,12 @@ notes: | A ROM set is one zip per machine, and every ROM is looked up in the game's zip first, then up its parent chain (pinmame src/common.c:1343-1348). - PinMAME carries neither GAME_IS_BIOS_ROOT nor ROM_SYSTEM_BIOS; what it has + PinMAME carries neither GAME_IS_BIOS_ROOT nor ROM_SYSTEM_BIOS. What it has are nine container sets flagged NOT_A_DRIVER, gts1, gts1s, gts80, gts80s, gts80a, gts80as, allied, gp_110 and recel, each the parent of its family's games and holding the family's system ROMs. A game declares its system ROMs in its own set as well, so they are read from the game zip when it carries - them and from the container zip otherwise; the Allied Leisure and Game Plan + them and from the container zip otherwise. The Allied Leisure and Game Plan 110 games declare nothing else. The nine are listed below. Two shared data files sit outside that ROM content and are listed below as @@ -140,12 +140,12 @@ notes: | (pinmame src/common.c:271), the two files that register that option live in src/windows/config.c and src/unix/sound.c and neither is in the libpinmame source list, and PinmameSetConfig zeroes the whole options struct - (pinmame src/libpinmame/libpinmame.cpp:1071); independently, SAMPLESINTERFACE + (pinmame src/libpinmame/libpinmame.cpp:1071). Independently, SAMPLESINTERFACE is defined in the PinMAME tree (pinmame src/wpc/wpcsam.h:23) and no driver references it. history.dat and mameinfo.dat (pinmame src/datafile.c:619-623, 649-653) are read only by displayhistory, a page of the MAME on-screen menu (pinmame src/usrintrf.c:2846-2851), and by the listing path in - pinmame src/info.c:820 which libpinmame never calls; VPX passes NULL for + pinmame src/info.c:820 which libpinmame never calls. VPX passes NULL for fn_IsKeyPressed, the thirteenth member of PinmameConfig (plugins/pinmame/PinMAMEPlugin.cpp:304-320, pinmame src/libpinmame/libpinmame.h:422-438), so osd_is_key_pressed always answers 0 @@ -165,7 +165,7 @@ files: source_ref: "pinmame src/wpc/gts1games.c:15-22,33-34, pinmame src/wpc/gts1.h:229-233, pinmame src/common.c:1343-1348, pinmame src/fileio.c:953-966" note: >- Container set, parent of every System 1 game. The path is the layout - beside a table; roms/ sits the same way under the PinMAMEPath setting or + beside a table, and roms/ sits the same way under the PinMAMEPath setting or $HOME/.pinmame. Each game declares the same two ROMs and reads them from its own zip first, so this archive is only reached when the game zip lacks them. A member is matched by name, then by checksum. @@ -376,7 +376,7 @@ files: source_ref: "src/audio/SpatialAudio.cpp:49-56,344-360, make/CMakeLists_app.txt:631-635" note: >- Read from assets/ under the installation folder when libspatialaudio is - built with libmysofa, which every build script does; the headphone and VR + built with libmysofa, which every build script does. The headphone and VR binauralizer then runs second order ambisonics on it. A missing or unreadable file logs "Failed to load the binaural HRTF" and audio falls back to loudspeaker decoding. The file sits in the repository's top-level @@ -424,7 +424,7 @@ analysis: note: >- One zip per machine. The root is the pinmame folder beside the table when it holds roms/, else the PinMAMEPath setting, else $HOME/.pinmame - on Linux and macOS; Batocera patches that last fallback to + on Linux and macOS. Batocera patches that last fallback to <prefpath>/pinmame. - what: "PinMAME game aliases, <pinmame root>/alias.txt" source_ref: "pinmame src/libpinmame/libpinmame.cpp:304-337,343-346" @@ -439,10 +439,10 @@ analysis: note: "The legacy plugin checks the file version against the B2S server version on load." - what: "Serum colorizations, <table folder>/serum/<rom>/<rom>.cROMc or .cRZ, else the SerumPath setting" source_ref: "plugins/serum/serum.cpp:49,561-602" - note: "A namespace folder may sit above the ROM folder; PinMAME games are also looked up in <table folder>/pinmame/altcolor." + note: "A namespace folder may sit above the ROM folder, and PinMAME games are also looked up in <table folder>/pinmame/altcolor." - what: "VNI colorizations, <table folder>/vni/<rom>/<rom>.pal with an optional .vni, else the VniPath setting" source_ref: "plugins/vni/vni.cpp:39,326-376" - note: "pin2dmd.pal and pin2dmd.vni are accepted in the same folder; PinMAME games are also looked up in <table folder>/pinmame/altcolor." + note: "pin2dmd.pal and pin2dmd.vni are accepted in the same folder, and PinMAME games are also looked up in <table folder>/pinmame/altcolor." - what: "alternative sound packages, <table folder>/altsound/<rom>, else <table folder>/pinmame/altsound/<rom>, else the plugin's Folder setting" source_ref: "plugins/altsound/AltSoundPlugin.cpp:28,110-143" - what: "PUP video packs, <table folder>/pupvideos/<rom>, else pupvideos/ under the PUPFolder setting" @@ -461,11 +461,11 @@ analysis: - what: "VPinballX.ini, the settings file" source_ref: "src/core/VPApp.cpp:270-284, src/core/AppCommands.cpp:533-539" note: >- - Looked up in the preferences folder, then beside the binary; when + Looked up in the preferences folder, then beside the binary. When neither holds one the preferences path is kept. -Ini names another file. Batocera seeds it from the assets/Default_VPinballX.ini its pinned tree carries and rewrites it before every launch. - - what: "VPReg.ini, values saved by table scripts in the table's user folder; vpinball.log in the preferences folder" + - what: "VPReg.ini, values saved by table scripts in the table's user folder, and vpinball.log in the preferences folder" source_ref: "src/core/ScriptGlobalTable.cpp:527-557, src/utils/Logger.cpp:164-165" - what: "PinMAME state: nvram/, cfg/, hi/, inp/, memcard/ and sta/" source_ref: "pinmame src/libpinmame/libpinmame.cpp:1081,1083-1087" diff --git a/emulators/vkquake.yml b/emulators/vkquake.yml index 23737143..e3bfaa04 100644 --- a/emulators/vkquake.yml +++ b/emulators/vkquake.yml @@ -20,10 +20,10 @@ notes: | opens <basedir>/<dir>/pak0.pak, pak1.pak, ... and stops at the first index that does not open (Quake/common.c:2241-2245). Right after id1/pak0.pak it mounts vkquake.pak, built from Misc/vq_pak and embedded - in the binary (Quake/common.c:2257-2282); it carries default.cfg, three + in the binary (Quake/common.c:2257-2282). It carries default.cfg, three menu pictures and entity fixes, no gfx.wad and no palette. - gfx.wad and gfx/colormap.lmp come from id1/pak0.pak; without either the + gfx.wad and gfx/colormap.lmp come from id1/pak0.pak, and without either the engine stops with Sys_Error (Quake/wad.c:80-87, Quake/host.c:1093-1095). gfx/pop.lmp, present only in the registered id1/pak1.pak, sets the registered cvar (Quake/common.c:1458-1484). @@ -50,7 +50,7 @@ files: path: "id1/pak0.pak" required: true source_ref: "Quake/common.c:2241-2245 (pak%i.pak loop), 2496 (id1 by default); Quake/wad.c:80-87 (gfx.wad fatal)" - note: "Shareware and registered Quake data, one file in both releases. Directory CRC compared to v1.00, v1.01, v1.06; a mismatch does not refuse the file." + note: "Shareware and registered Quake data, one file in both releases. Directory CRC compared to v1.00, v1.01, v1.06, but a mismatch does not refuse the file." - name: "pak1.pak" category: game_data @@ -59,7 +59,7 @@ files: required: false source_ref: "Quake/common.c:2241-2245 (pak%i.pak loop), 1458-1470 (gfx/pop.lmp, registered check)" note: "Registered episodes 2 to 4. Read only after pak0.pak opens. Needed by -hipnotic, -rogue and -game." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -68,7 +68,7 @@ files: required: false source_ref: "Quake/common.c:2509-2510 (-hipnotic), 2241-2245 (pak%i.pak loop)" note: "Scourge of Armagon data. Loaded with -hipnotic." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -77,4 +77,4 @@ files: required: false source_ref: "Quake/common.c:2507-2508 (-rogue), 2241-2245 (pak%i.pak loop)" note: "Dissolution of Eternity data. Loaded with -rogue." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" diff --git a/emulators/vkquake2.yml b/emulators/vkquake2.yml index 6669fb50..0be16cda 100644 --- a/emulators/vkquake2.yml +++ b/emulators/vkquake2.yml @@ -25,7 +25,7 @@ notes: | commented out (qcommon/files.c:24, 28, 484-489). No pak is rejected for its contents. The Vulkan renderer, vid_ref default "vk" (linux/vid_so.c:448), stops with ERR_FATAL when pics/colormap.pcx is - missing (ref_vk/vk_image.c:1640-1642); that file is in baseq2/pak0.pak. + missing (ref_vk/vk_image.c:1640-1642). That file is in baseq2/pak0.pak. Batocera 43.1 copies /usr/bin/vkquake2 (binary, ref_*.so and the game libraries of baseq2, ctf, rogue, smd, xatrix, zaero) into @@ -69,7 +69,7 @@ files: required: false source_ref: "qcommon/files.c:878-880 (game cvar), 640 (game dir mounted), 537-542" note: "The Reckoning data. Loaded with `+set game xatrix`." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -78,7 +78,7 @@ files: required: false source_ref: "qcommon/files.c:878-880 (game cvar), 640 (game dir mounted), 537-542" note: "Ground Zero data. Loaded with `+set game rogue`." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -95,7 +95,7 @@ files: required: false source_ref: "qcommon/files.c:878-880 (game cvar), 640 (game dir mounted), 537-542" note: "Zaero data. Loaded with `+set game zaero`." - unsourceable: "data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -104,4 +104,4 @@ files: required: false source_ref: "qcommon/files.c:878-880 (game cvar), 640 (game dir mounted), 537-542" note: "Slight Mechanical Destruction data. Loaded with `+set game smd`." - unsourceable: "data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "data the collection does not hold, and a same-named file of another game must not stand in" diff --git a/emulators/vkquake3.yml b/emulators/vkquake3.yml index c3c716df..a56e87d0 100644 --- a/emulators/vkquake3.yml +++ b/emulators/vkquake3.yml @@ -50,7 +50,7 @@ files: required: true source_ref: "code/qcommon/files.c:180 (pak_checksums[0]=1566731103u), 3486 (checksum compare), 3596-3619 (fatal when a baseq3 pak is absent)" note: "Retail Quake III Arena pak. A checksum mismatch prints a warning, the file is not refused." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak1.pk3" category: game_data @@ -114,7 +114,7 @@ files: path: "demoq3/pak0.pk3" required: false source_ref: "code/qcommon/files.c:178 (DEMO_PAK0_CHECKSUM=2985612116u), 3475-3479 (demoq3 pak0 checksum compare), 3580-3590 (counted as baseq3/pak0.pk3)" - note: "Demo pak. Recognised only under demoq3/ with this checksum; the engine then prints a warning and counts baseq3/pak0.pk3 as found." + note: "Demo pak. Recognised only under demoq3/ with this checksum, and the engine then prints a warning and counts baseq3/pak0.pk3 as found." - name: "pak0.pk3" category: game_data @@ -123,7 +123,7 @@ files: required: false source_ref: "code/qcommon/files.c:193 (missionpak_checksums[0]=2430342401u), 3622-3640 (fatal when a Team Arena pak is absent)" note: "Team Arena pak. Read with `+set fs_game missionpack`." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak1.pk3" category: game_data diff --git a/emulators/vvvvvv.yml b/emulators/vvvvvv.yml index 26cbf29b..2aad3722 100644 --- a/emulators/vvvvvv.yml +++ b/emulators/vvvvvv.yml @@ -14,7 +14,7 @@ systems: notes: | Terry Cavanagh's VVVVVV game, desktop build. The source release holds - the engine, the level data, the language files and the fonts; graphics, + the engine, the level data, the language files and the fonts. Graphics, music and sounds are in data.zip, which is not in the repository. FILESYSTEM_init() mounts data.zip from the -assets argument, or from @@ -27,7 +27,7 @@ notes: | The lang/ and fonts/ directories are mounted ahead of data.zip from the binary's directory (ref: desktop_version/src/FileSystemUtils.cpp:81-177, - 312-315); Recalbox installs them from the source tree beside the + 312-315). Recalbox installs them from the source tree beside the binary. gamecontrollerdb.txt is read from the binary's directory when present (ref: desktop_version/src/FileSystemUtils.cpp:349-353). @@ -37,14 +37,14 @@ files: category: game_data path: "data.zip" required: true - unsourceable: "game data the collection does not hold; a same-named archive of another game must not stand in" + unsourceable: "game data the collection does not hold, and a same-named archive of another game must not stand in" description: "VVVVVV game assets (graphics, music, sounds)" source_ref: "desktop_version/src/FileSystemUtils.cpp:318-346, desktop_version/src/main.cpp:433-438" - note: "Path given by -assets, otherwise data.zip next to the binary. Retail and Make and Play Edition archives are both accepted; the code checks neither size nor hash." + note: "Path given by -assets, otherwise data.zip next to the binary. Retail and Make and Play Edition archives are both accepted, and the code checks neither size nor hash." - name: "gamecontrollerdb.txt" system: "vvvvvv" path: "gamecontrollerdb.txt" required: false description: "SDL game controller mappings" source_ref: "desktop_version/src/FileSystemUtils.cpp:349-353" - note: "Read from the binary's directory; a missing file is logged and ignored." + note: "Read from the binary's directory. A missing file is logged and ignored." diff --git a/emulators/wqxemu.yml b/emulators/wqxemu.yml index be43c677..41c1cfff 100644 --- a/emulators/wqxemu.yml +++ b/emulators/wqxemu.yml @@ -23,7 +23,7 @@ notes: | wqxemu-core crate, which runs the original firmware of five models on an emulated 6502 SoC: NC1020, PC1000, CC800, NC2000 and NC3000. The git.libretro.com repository is a mirror of the GitHub one at the same - commit; the buildbot consumes its .gitlab-ci.yml. + commit, and the buildbot consumes its .gitlab-ci.yml. The core takes no content. retro_load_game refuses a non-null game info (crates/wqxemu-libretro/src/lib.rs:596-599) and the machine is @@ -38,13 +38,13 @@ notes: | crates/wqxemu-core/src/machine.rs:35-43). File names are free: each regular file is assigned to a slot by its extension, case-insensitive, .rom or .bin to the system ROM, .fls or .nor to NOR, .nand to NAND and - .nand0 to the first NAND plane; anything else is ignored + .nand0 to the first NAND plane. Anything else is ignored (crates/wqxemu-core/src/machine.rs:94-126). A slot matched by two files fails the start with "Multiple <slot> dumps", and so does a directory with no dump at all (crates/wqxemu-core/src/machine.rs:128-161). The set is then checked against the model: NC1020, PC1000 and CC800 need a - ROM and a NOR and refuse NAND files; NC2000 needs NOR, NAND and NAND0 - and refuses a ROM; NC3000 needs NOR and NAND, NAND0 optional, and + ROM and a NOR and refuse NAND files. NC2000 needs NOR, NAND and NAND0 + and refuses a ROM. NC3000 needs NOR and NAND, NAND0 optional, and refuses a ROM (crates/wqxemu-core/src/machine.rs:164-207). Any failure is shown and retro_load_game returns false (crates/wqxemu-libretro/src/lib.rs:608-622). Only the directory of the @@ -79,7 +79,7 @@ notes: | (crates/wqxemu/src/main.rs:57-59, crates/wqxemu/src/keypad.rs:72-91). The libretro-core-info file names the PC1000 NOR image pc1000.fls. Any - single .fls or .nor file in WQXEmu/pc1000/ is read; pc1000.fls and + single .fls or .nor file in WQXEmu/pc1000/ is read, but pc1000.fls and pc1000.nor side by side stop the PC1000 from starting. files: @@ -92,7 +92,7 @@ files: description: "NC1020 system ROM, three 8 MiB volumes" note: >- The .rom/.bin file of {system}/WQXEmu/nc1020/, read whole. The image must - be at least 0x8000 * 0x300 bytes or the loader fails; a larger file + be at least 0x8000 * 0x300 bytes or the loader fails, and a larger file is kept whole. Each 32 KiB bank is stored with its 16 KiB halves swapped and is swapped back on load, and the BBS pages are mapped from it. @@ -107,7 +107,7 @@ files: description: "NC1020 NOR flash, 32 banks of 32 KiB" note: >- The .fls/.nor file of {system}/WQXEmu/nc1020/, read whole. The image must - be at least 0x8000 * 0x20 bytes or the loader fails; only the first + be at least 0x8000 * 0x20 bytes or the loader fails. Only the first 1 MiB is used, with the same 16 KiB half swap as the ROM. Writes go to the in-memory copy and are persisted in the .wqxs session file, never to this file. @@ -124,7 +124,7 @@ files: The .rom/.bin file of {system}/WQXEmu/pc1000/, read whole and stored linearly. Exactly 12 MiB (obj1, obj2, obj3 back to back) or 16 MiB (the PC1000EMUX and Android layout, obj3 at 12 MiB with 8 to 12 MiB - unused) is accepted; any other size fails the loader. The volume + unused) is accepted. Any other size fails the loader. The volume tables are rebuilt for the layout found. source_ref: "crates/wqxemu-core/src/machine.rs:119-123, crates/wqxemu-core/src/machines/pc1000.rs:38-40, crates/wqxemu-core/src/machines/pc1000.rs:236-283" @@ -137,7 +137,7 @@ files: description: "PC1000 NOR flash, 16 banks of 32 KiB" note: >- The .fls/.nor file of {system}/WQXEmu/pc1000/, read whole. The image must - be at least 0x80000 bytes or the loader fails; only the first + be at least 0x80000 bytes or the loader fails. Only the first 512 KiB is used. A dump stored with swapped 16 KiB halves is recognised by the info-block signature at bank 0 offset 0x4000 and unswapped. The libretro-core-info file names it pc1000.fls. @@ -152,7 +152,7 @@ files: description: "CC800 system ROM, two volumes of 256 banks" note: >- The .rom/.bin file of {system}/WQXEmu/cc800/, read whole. The image must be at - least 0x1000000 bytes or the loader fails; only the first 16 MiB is + least 0x1000000 bytes or the loader fails. Only the first 16 MiB is used. Each 32 KiB bank is stored with its 16 KiB halves swapped and is swapped back on load. Volume 0 is banks 0 to 255, volume 1 banks 256 to 511. @@ -167,7 +167,7 @@ files: description: "CC800 NOR flash, 16 banks of 32 KiB" note: >- The .fls/.nor file of {system}/WQXEmu/cc800/, read whole. The image must be - at least 0x80000 bytes or the loader fails; only the first 512 KiB + at least 0x80000 bytes or the loader fails. Only the first 512 KiB is used, with the same 16 KiB half swap as the ROM. source_ref: "crates/wqxemu-core/src/machine.rs:119-123, crates/wqxemu-core/src/machines/cc800.rs:40, crates/wqxemu-core/src/machines/cc800.rs:252-267" @@ -181,7 +181,7 @@ files: note: >- The .fls/.nor file of {system}/WQXEmu/nc2000/, read whole in physical order, no bank swap. The image must be at least 16 * 0x8000 bytes or the - loader fails; only the first 512 KiB is used. Bank 0 is the fixed + loader fails. Only the first 512 KiB is used. Bank 0 is the fixed BIOS page at 0xE000. source_ref: "crates/wqxemu-core/src/machine.rs:119-123, crates/wqxemu-core/src/machines/nc2000.rs:20, crates/wqxemu-core/src/machines/nc2000.rs:28, crates/wqxemu-core/src/machines/nc2000.rs:265-277" @@ -221,7 +221,7 @@ files: note: >- The .fls/.nor file of {system}/WQXEmu/nc3000/, read whole in physical order, no bank swap. The image must be at least 32 * 0x8000 bytes or the - loader fails; only the first 1 MiB is used. Bank 0 is the fixed + loader fails. Only the first 1 MiB is used. Bank 0 is the fixed BIOS page at 0xE000. source_ref: "crates/wqxemu-core/src/machine.rs:119-123, crates/wqxemu-core/src/machines/nc3000.rs:23, crates/wqxemu-core/src/machines/nc3000.rs:33, crates/wqxemu-core/src/machines/nc3000.rs:272-284" @@ -247,7 +247,7 @@ files: description: "NC3000 NAND flash first plane, 64 pages of 528 bytes" note: >- The .nand0 file of {system}/WQXEmu/nc3000/, read whole into the first - 64 pages of the NAND array when the file exists; validate_for_model + 64 pages of the NAND array when the file exists, and validate_for_model does not require it for this model. Without it the core writes the marker "ggv nc3000" at offset 528 of an erased first plane and the machine boots the same way. diff --git a/emulators/x1-box.yml b/emulators/x1-box.yml index 456744c6..0f1b37ae 100644 --- a/emulators/x1-box.yml +++ b/emulators/x1-box.yml @@ -36,7 +36,7 @@ notes: | folder. The two ROM pickers keep .bin, .rom and .img, the disk picker .qcow2 and .img. A pick is fingerprinted before anything is written, and only a file that passes is copied into x1box under the external files directory as - mcpx.bin, flash.bin or hdd.img; a file chosen as a path in place is kept as + mcpx.bin, flash.bin or hdd.img. A file chosen as a path in place is kept as that path instead. Those names, the eeprom the wizard never asks for and the disc are written to x1box/xemu.toml under sys.files. The disc is handed to QEMU as a file descriptor through -add-fd and only copied to x1box/dvd.iso @@ -100,7 +100,7 @@ files: note: >- The only file the app verifies by content. A pick is accepted just when its MD5 equals the value hardcoded in the wizard, which is the v1.0 boot - ROM; anything else is refused with the expected hash quoted, and the + ROM. Anything else is refused with the expected hash quoted, and the 512-byte dump whose MD5 is 196a5f59a13382c185636e691d6c323d is named separately as a known bad dump to re-dump. The check runs again over the stored copy every time the wizard opens, so a file that stops matching @@ -122,9 +122,9 @@ files: Passed as -bios, and the one image whose absence stops the run on its own: a path that cannot be opened queues an error and clears autostart. The picker only refuses what looks like the boot ROM, a 512-byte file or - either MCPX hash, and asks for a BIOS instead; there is no positive hash + either MCPX hash, and asks for a BIOS instead. There is no positive hash to match. The image is mapped at 0xFF000000 and mirrored to the top of - the address space; a size that is zero or not a multiple of 64 KB, or a + the address space. A size that is zero or not a multiple of 64 KB, or a short read, falls back to 256 KB filled with 0xFF. A retail image cannot launch unsigned code, so a debug or modified image is what boots a title. source_ref: "system/vl.c:3057-3072, hw/xbox/xbox.c:64-102, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:64, 93-116, 487-495" @@ -140,7 +140,7 @@ files: unopenable one only queues a message, but the launcher refuses to leave the wizard until the file resolves. The formatter builds FATX partitions inside an image that already exists and needs at least 0x1DD156000 bytes - for the retail layout; it never creates the image. Partitions C and E of + for the retail layout. It never creates the image. Partitions C and E of this image are what the dashboard import writes into. source_ref: "system/vl.c:3078-3092, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:65, 118-139, android/app/src/main/java/com/izzy2lost/x1box/XboxHddFormatter.kt:7-16, 46-50, android/app/src/main/cpp/xemu_android.cpp:822-843" @@ -155,7 +155,7 @@ files: Always pointed at x1box/eeprom.bin, a path the wizard never asks for. Generated as XBOX_EEPROM_VERSION_R1 when it does not exist, so a dump is needed only to carry over a console serial, region or HDD key. It is - attached through the smbus-storage device; a size other than 256 bytes, + attached through the smbus-storage device. A size other than 256 bytes, or a generation that fails, clears autostart. Preparing Insignia and the EEPROM editor write to it in place. source_ref: "system/vl.c:2921-2964, 3045-3055, android/app/src/main/cpp/xemu_android.cpp:757-759, 719, android/app/src/main/cpp/xemu_settings_android.cc:246-286, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2748-2751" @@ -221,7 +221,7 @@ files: Read from the assets of the package as the game controller subsystem comes up and handed to SDL as a memory stream. The asset manager reads inside the archive and the path is a constant, so there is no search - order and nothing outside the package replaces this copy; an added pad + order and nothing outside the package replaces this copy. An added pad mapping goes in through controller_map.txt instead. The revision shipped here is 589031 bytes and is not the one other releases carry under this name. diff --git a/emulators/x1.yml b/emulators/x1.yml index 01de113d..69fe9f88 100644 --- a/emulators/x1.yml +++ b/emulators/x1.yml @@ -46,7 +46,7 @@ notes: | Place all files in: <system_dir>/xmil/ The core selects between IPLROM.X1 and IPLROM.X1T based on the "X1_ROMTYPE" core option. A 575-byte built-in IPL stub provides limited boot without the - real ROMs. Font files add Japanese character support; the libretro port has a + real ROMs. Font files add Japanese character support. The libretro port has a path resolution quirk where fonts are searched in "./" instead of "xmil/" (missing file_setcd call). @@ -57,7 +57,7 @@ files: required: false hle_fallback: true description: "X1 IPL ROM. Loaded when ROM_TYPE=1 (X1 model)." - note: "file_read copies up to 0x8000 bytes into biosmem, unchecked; the X1 IPL dump is 4 KiB." + note: "file_read copies up to 0x8000 bytes into biosmem, unchecked. The X1 IPL dump is 4 KiB." source_ref: "io/memio.c:82,96-108" - name: IPLROM.X1T diff --git a/emulators/x64sdl.yml b/emulators/x64sdl.yml index b71eb1c8..80001e8d 100644 --- a/emulators/x64sdl.yml +++ b/emulators/x64sdl.yml @@ -12,7 +12,7 @@ systems: [commodore-c64] notes: > Old port of VICE 3.1 using an SDL-to-libretro shim (r-type/sdlvice-libretro). Separate codebase from the newer vice-libretro port. Marked experimental and - superseded. Unlike the newer port, this core does NOT embed system ROMs; all ROMs + superseded. Unlike the newer port, this core does NOT embed system ROMs: all ROMs must be on disk in <system_dir>/data/C64/ and <system_dir>/data/DRIVES/. The .info declares firmware_count=0 which is incorrect. No JiffyDOS support. No save states, no netplay, no cheats. diff --git a/emulators/xash3d_fwgs.yml b/emulators/xash3d_fwgs.yml index 19d7646c..47e3ad52 100644 --- a/emulators/xash3d_fwgs.yml +++ b/emulators/xash3d_fwgs.yml @@ -27,19 +27,19 @@ notes: | every .pk3, .pk3dir and .wad, each kind in sorted name order and each above the previous one, then the folder itself on top, so loose files win over packed ones (filesystem/searchpath.c:188-224). No archive name - is required. The engine does not hash any file; the pak header is the + is required. The engine does not hash any file: the pak header is the only sanity check (filesystem/pak.c:98-157). liblist.gam ships inside each retail mod and is also written out by the engine as gameinfo.txt the first time it imports a Valve folder (filesystem/gameinfo.c:538-544). A Quake-engine game dir is recognised separately by FS_CheckForQuakeGameDir (filesystem/gameinfo.c:578-603), which looks - for pak0.pak + progs.dat / quake.rc; Xash3D FWGS can run Quake 1 total + for pak0.pak + progs.dat / quake.rc, so Xash3D FWGS can run Quake 1 total conversions this way. Below are the folders Half-Life retail / official addon releases install under the Steam install root. The descriptor is what makes the - engine detect a folder (filesystem/gameinfo.c:614-630); the pak entries + engine detect a folder (filesystem/gameinfo.c:614-630), and the pak entries name the archives the retail releases ship. Map / model / sound trees that live beside them are too open-ended to enumerate and are counted as part of the same game data. @@ -72,8 +72,8 @@ files: path: "valve/pak1.pak" required: false source_ref: "filesystem/searchpath.c:188-224, filesystem/pak.c:98-157" - note: "Mounted above pak0.pak when present, as any second .pak of the folder would be. The only valve/pak1.pak released is the one the Blue Shift High Definition Pack installer writes (7839196 bytes, 99 entries: HD models, sounds and sprites for Half-Life); Steam ships no .pak in valve/." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + note: "Mounted above pak0.pak when present, as any second .pak of the folder would be. The only valve/pak1.pak released is the one the Blue Shift High Definition Pack installer writes (7839196 bytes, 99 entries: HD models, sounds and sprites for Half-Life). Steam ships no .pak in valve/." + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Counter-Strike 1.6 (cstrike/) @@ -86,7 +86,7 @@ files: required: true source_ref: "filesystem/gameinfo.c:617, filesystem/searchpath.c:327 (cstrike -> valve chain)" note: "Declares fallback_dir \"valve\". Counter-Strike 1.6 retail descriptor." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -94,7 +94,7 @@ files: path: "cstrike/pak0.pak" required: false source_ref: "filesystem/pak.c" - note: "Loose files (maps/, sprites/, sound/, models/) are the usual retail layout; a bundled pak0.pak is optional." + note: "Loose files (maps/, sprites/, sound/, models/) are the usual retail layout, and a bundled pak0.pak is optional." unsourceable: "The Linux dedicated servers hlds_l 1.1.2.0 and hlds_l_11262003 ship cstrike/ as loose files with no .pak." # ================================================================ @@ -107,7 +107,7 @@ files: path: "czero/liblist.gam" required: true source_ref: "filesystem/searchpath.c:327 (czero -> cstrike -> valve chain)" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -115,7 +115,7 @@ files: path: "czero/pak0.pak" required: false source_ref: "filesystem/pak.c" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Condition Zero: Deleted Scenes (czeror/) @@ -127,7 +127,7 @@ files: path: "czeror/liblist.gam" required: true source_ref: "filesystem/searchpath.c:327 (czeror -> czero -> cstrike -> valve chain)" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -135,7 +135,7 @@ files: path: "czeror/pak0.pak" required: false source_ref: "filesystem/pak.c" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Deathmatch Classic (dmc/) @@ -187,7 +187,7 @@ files: path: "bshift/liblist.gam" required: true source_ref: "filesystem/gameinfo.c:617" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" - name: "pak0.pak" category: game_data @@ -195,7 +195,7 @@ files: path: "bshift/pak0.pak" required: false source_ref: "filesystem/pak.c" - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Ricochet (ricochet/) diff --git a/emulators/xemu.yml b/emulators/xemu.yml index a39bbe6d..74119257 100644 --- a/emulators/xemu.yml +++ b/emulators/xemu.yml @@ -26,7 +26,7 @@ notes: | the RetroPads into the Duke controllers and blits the NV2A surface into the frontend's framebuffer through an OpenGL 4.0 core context, and content is a .iso or .xiso image that QEMU opens from its full path. Save states are not - implemented; game saves live inside the hard disk image. + implemented, and game saves live inside the hard disk image. ref: meson_options.txt:52-53, ui/xemu-libretro.c:1-27, ui/xemu-libretro.c:609-617, ui/xemu-libretro.c:680-697, ui/xemu-libretro.c:874-876 @@ -38,7 +38,7 @@ notes: | locked=on. The standalone keeps them in xemu.toml, read from the SDL preference directory or from the directory of the executable when a xemu.toml already sits there, and the file pickers of the settings menu fill - the four paths; nothing is searched by name and only the EEPROM has a + the four paths. Nothing is searched by name and only the EEPROM has a default location. ref: config_spec.yml:353-367, system/vl.c:2983-3006, system/vl.c:3030-3074, ui/xemu-settings.cc:70-133, ui/xemu.c:1382-1402, @@ -75,7 +75,7 @@ files: the file cannot be opened or is not 512 bytes, and the machine then runs the flash alone. The core option xemu_bootrom names the file, default mcpx_1.0.bin, with mcpx.bin, MCPX_1.0.bin and boot_rom.bin offered as - alternatives; the core refuses to load when the chosen file is absent. + alternatives. The core refuses to load when the chosen file is absent. source_ref: standalone: "system/vl.c:2983-3006, hw/xbox/xbox.c:143-171, hw/xbox/xbox.c:468-470" libretro: "ui/xemu-libretro.c:113-114, ui/xemu-libretro.c:192-193, ui/xemu-libretro.c:210-236" @@ -85,7 +85,7 @@ files: required: true size: [262144, 524288, 1048576] validation: [size] - size_note: "Any size that is a positive multiple of 64 KiB is mapped; the image is mirrored across the 16 MB flash window" + size_note: "Any size that is a positive multiple of 64 KiB is mapped, and the image is mirrored across the 16 MB flash window" config_key: sys.files.flashrom_path description: "Xbox flash ROM image" note: >- @@ -95,7 +95,7 @@ files: anyway. An unreadable path clears autostart in the standalone. The core option xemu_flashrom names the file, default Complex_4627.bin, with Complex_4627_v1.03.bin, complex_4627.bin, cerbios.bin, Cerbios.bin, - bios.bin, xbox_bios.bin and Complex.bin offered as alternatives; the + bios.bin, xbox_bios.bin and Complex.bin offered as alternatives. The core refuses to load when the chosen file is absent. source_ref: standalone: "system/vl.c:3041-3053, hw/xbox/xbox.c:63-123" @@ -116,7 +116,7 @@ files: whole file at realize and writes it back on every guest write. A missing file is generated as a retail 1.0 image with a random serial, MAC, hard disk key and online key, the North American region and the NTSC-M video - standard; a file of any size other than 256 bytes is rejected and + standard. A file of any size other than 256 bytes is rejected and autostart is cleared. The standalone defaults to eeprom.bin next to xemu.toml. The core option xemu_eeprom names the file, default xbox_eeprom.bin, with eeprom.bin and EEPROM.bin offered as alternatives, @@ -132,12 +132,12 @@ files: description: "Xbox hard disk image, 8 GB with the retail partition layout" note: >- Attached as the IDE drive at index 0 with locked=on when the path is set - and the file opens; an unreadable file only queues an error and an empty + and the file opens. An unreadable file only queues an error and an empty path attaches no drive. Snapshots are stored inside the image. The project publishes a formatted image carrying its own unsigned dashboard and empty TDATA and UDATA folders. The core option xemu_hdd names the file, default xbox_hdd.qcow2, with xbox_hdd_8gb.qcow2, hdd.qcow2 and - xbox_hdd.img offered as alternatives; the core refuses to load when the + xbox_hdd.img offered as alternatives. The core refuses to load when the chosen file is absent. source_ref: standalone: "system/vl.c:3060-3074, ui/xemu-snapshots.c:156" @@ -148,7 +148,7 @@ files: description: "Npcap packet capture library" note: >- Loaded by name on Windows, with every entry point resolved individually, - when networking is enabled with the pcap backend; the netdev is not + when networking is enabled with the pcap backend, and the netdev is not created when the library or one of its symbols is missing. Networking is off by default and the backend defaults to NAT. source_ref: "winpcap-loader/loader.c:79-113, ui/xemu-net.c:68-78, system/vl.c:2870-2875, config_spec.yml:327-335" diff --git a/emulators/xendroid.yml b/emulators/xendroid.yml index cb16a3f2..ff3e2a05 100644 --- a/emulators/xendroid.yml +++ b/emulators/xendroid.yml @@ -35,7 +35,7 @@ notes: | app/src/main/java/xendroid/compose/ui/content/InstallContentViewModel.kt:127-172 Releases are tagged XenDroid-<short commit> and the version name is the git - hash handed to the build, so 0b11201 is the current release; the two commits + hash handed to the build, so 0b11201 is the current release. The two commits main carries past it touch the README only. version.h names canary_experimental dc561e4df, carried over from the ax360e tree the project started as, and it does not describe the vendored code. The Edge revision is @@ -91,7 +91,7 @@ files: note: >- Imported through a picker restricted to application/zip. The archive is read whole, meta.json names the library to keep, and a single .so is taken - instead when no meta.json is present; the .so files and meta.json are + instead when no meta.json is present. The .so files and meta.json are unpacked into a directory named after the archive, in internal storage. The configured path is read before the instance is created and opened through adrenotools when the file exists, otherwise the system libvulkan.so @@ -190,7 +190,7 @@ exclusion_note: > never reads the file. Edge's in-binary patch bundle, its game compatibility bundle and its game title database are packed from build/data_repos, which xenia-build.py fetches and the Gradle build never runs, so the bundle compiled - in is empty and the APK assets are the only patch source; the locale bundle is + in is empty and the APK assets are the only patch source, and the locale bundle is guarded off when the CMake system name is Android. Two profile files sit beside the Account and are not listed: tile_32.png is written and never read back, and tile_64.png is written by the frontend from a picture the user picks and read diff --git a/emulators/xenia-edge.yml b/emulators/xenia-edge.yml index 240e68d9..5a3057ee 100644 --- a/emulators/xenia-edge.yml +++ b/emulators/xenia-edge.yml @@ -24,7 +24,7 @@ notes: | game library, and Direct3D 12, Vulkan and Metal backends. Releases are tagged by short commit on the edge branch and ship as xenia_edge_linux.AppImage, xenia_edge_macos.dmg and xenia_edge_windows.zip. ES-DE finds it through the - XENIA-EDGE rule and runs `xenia_edge <rom>`; RetroDECK unpacks the AppImage + XENIA-EDGE rule and runs `xenia_edge <rom>`. RetroDECK unpacks the AppImage into a xenia-edge component and executes bin/xenia_edge. The libretro core xenia_edge_libretro is built from libretro/xenia-libretro @@ -62,7 +62,7 @@ notes: | rather than read from a flash image (src/xenia/kernel/xconfig.cc:87-246, 259-272). When the launched title is itself a system title the kernel resolves xam.xex, then $flash_xam.xex, through the guest filesystem under the \SystemRoot symlink - pointing at that title's own directory (src/xenia/emulator.cc:777-792); that is a + pointing at that title's own directory (src/xenia/emulator.cc:777-792). That is a companion module inside the dump the user launched, not a host-side lookup. The fork's data ships inside the executable. assets/font/Inter-VariableFont @@ -124,14 +124,14 @@ files: system search path, because the signer's own plain-name load skips D3D12/. D3D12 rejects an unsigned shader, so PipelineCache::Initialize stops when IsSignerAvailable() is false and asks for a recent dxil.dll in - the D3D12 folder; that failure propagates to "Failed to setup + the D3D12 folder, and that failure propagates to "Failed to setup graphics_system!" (src/xenia/emulator.cc:435-446). Windows defaults to gpu = "d3d12" (src/xenia/emulator.cc:119) and the backend factory only falls back when D3D12GraphicsSystem::IsAvailable() is false, which tests the D3D12 API itself, not the redistributable. Taken from bin/x64/dxil.dll in dxc_2026_05_27.zip of DirectXShaderCompiler release v1.9.2602.24, pinned at sha256 - cf658aacf070d3045e31b8f1f8a696c2945f37c1095019481ef7c513368db3b4; + cf658aacf070d3045e31b8f1f8a696c2945f37c1095019481ef7c513368db3b4, and bin/arm64 on ARM64 builds. It is the single entry the installer extracts from that archive. The libretro core writes its own embedded copy to Xenia-Edge/D3D12/ in the system directory and loads it from there. @@ -149,7 +149,7 @@ files: it, offers the download, and returns false when it is still absent. Taken from build/native/bin/x64/D3D12Core.dll in the Microsoft.Direct3D.D3D12 1.619.3 NuGet package, pinned at sha256 - 43a7d5a3973812eb4b42623fae5275c790a005b8e48b8d7f5bb43cef39e073c5; + 43a7d5a3973812eb4b42623fae5275c790a005b8e48b8d7f5bb43cef39e073c5, and build/native/bin/arm64 on ARM64 builds. The package version has to match the exported number. diff --git a/emulators/xenios.yml b/emulators/xenios.yml index 4f6da3ff..a54e4551 100644 --- a/emulators/xenios.yml +++ b/emulators/xenios.yml @@ -48,7 +48,7 @@ notes: | (src/xenia/kernel/xconfig.cc:87-246). Launching a system title symlinks \SystemRoot to that title's own mount and resolves xam.xex, then $flash_xam.xex, through the guest filesystem - (src/xenia/emulator.cc:744-759); spa.bin is resolved the same way inside an + (src/xenia/emulator.cc:744-759). spa.bin is resolved the same way inside an installed DLC package (src/xenia/kernel/xam/content_manager.cc:31, 425-426). The fork's data ships inside the executable. The UI font and the app icon are @@ -101,7 +101,7 @@ exclusion_note: > is synthesised. Its own data (UI font, icons, locale catalogues, SDL controller mappings, game patches, compatibility lists) is compressed into the executable through xe_embed_binary_assets and xe_embed_compressed_bundle, so - none of it exists as a file beside the binary; the shipped bundle carries only + none of it exists as a file beside the binary. The shipped bundle carries only the executable, its property list, an icon, a compiled asset catalog and the two shader translation dylibs. The three cvars that accept a path default to empty and fall back to those embedded copies. libmetalirconverter.dylib and diff --git a/emulators/xm6pro68k.yml b/emulators/xm6pro68k.yml index 6ffd6b6a..9914dbb4 100644 --- a/emulators/xm6pro68k.yml +++ b/emulators/xm6pro68k.yml @@ -24,7 +24,7 @@ notes: | release, 120303, forked XM6 v2.05. XM6.exe is a 32-bit MFC application whose import directory names mfc90u.dll and MSVCR90.dll, so the Visual C++ 2008 runtime carried by the DLL Package, or the redistributable, must sit beside the executable - for the process to start; a second non-Unicode build lives in MBCS/ and needs the + for the process to start. A second non-Unicode build lives in MBCS/ and needs the same files duplicated there. ES-DE launches it through the XM6PRO68K and XM6PRO68K-WINDOWS find rules with the working directory set to the emulator folder, on Linux under Wine or Proton. RetroBat registers it as xm6pro @@ -63,7 +63,7 @@ notes: | Two menu tools synthesise replacements. Synthesize replacement CG-ROM builds CGROM.TMP from the installed MS Gothic and MS Mincho fonts and aborts when either - is absent; README.txt:294-296 warns that different machines produce different + is absent, and README.txt:294-296 warns that different machines produce different files. Synthesize replacement SCSI ROMs asks for a Human68k version 3.02 disk image, dialog default HUMAN302.XDF with filter *HUMAN*3*02*.???, extracts /BIN/FORMAT.X and writes SCSIINROM.DAT and SCSIEXROM.DAT. @@ -71,7 +71,7 @@ notes: | The ROM Warning section of the Advanced options holds three startup checks, all enabled by default and individually suppressible: an IPLROM.DAT version check naming version 1.0 (05/07/1987) as recommended, a CGROM.DAT contents check and a - SCSIEXROM.DAT / SCSIINROM.DAT contents check. Each raises a dialog; none rejects + SCSIEXROM.DAT / SCSIINROM.DAT contents check. Each raises a dialog, but none rejects the file, so no hash below is enforced by the program. Reference Manual.txt ships with the program and Software Notes.txt is fetched by @@ -97,7 +97,7 @@ files: present, so the emulator boots without it. The embedded copy sits at file offset 1337256 in .rdata of the Unicode build and 1288176 in the MBCS build, stored in the 16-bit pairwise swapped form the loader produces at - vm/memory.cpp:278-285; unswapped it is the 131072-byte dump hashed here, + vm/memory.cpp:278-285. Unswapped it is the 131072-byte dump hashed here, catalogued by TOSEC as Sharp X68000 Boot ROM (1987)(Sharp), and it is the version 1.0 (05/07/1987) the startup warning recommends. README.txt:23-25 advises against installing the file at all because reading and swapping it @@ -112,7 +112,7 @@ files: source_ref: "XM6 2.06 vm/memory.cpp:178-180, 261-263" note: >- Probed after the base machine loads. Its presence, together with - SCSIINROM.DAT, is what makes the XVI machine available; absent, the base + SCSIINROM.DAT, is what makes the XVI machine available. Absent, the base X68000 still runs. No internal copy is compiled into XM6.exe. - name: IPLROMCO.DAT @@ -167,11 +167,11 @@ files: source_ref: "README.txt:277-278, Change Log.txt:129, XM6 2.06 vm/memory.cpp:287-295" note: >- Supplies the glyphs for text the X68000 renders. Stock XM6 v2.06 fails - initialisation when neither font file loads; XM6 Pro-68k dropped that + initialisation when neither font file loads, but XM6 Pro-68k dropped that requirement, so a missing font ROM shows garbage glyphs and the emulator keeps running, and what remains is the suppressible contents warning. The mandatory DLL Package ships this exact 786432-byte file, catalogued by - TOSEC as Sharp X68000 CG ROM (1987)(Sharp); the hash identifies that copy and + TOSEC as Sharp X68000 CG ROM (1987)(Sharp). The hash identifies that copy and is not verified by the program. - name: CGROM.TMP @@ -204,7 +204,7 @@ files: Needed to use internal SCSI drives, and also loaded as part of the XVI and Compact machines, so those two models are unavailable without it whatever their IPL. The mandatory DLL Package ships this exact 8192-byte file and the - hash identifies that copy; the startup contents check only warns. + hash identifies that copy, while the startup contents check only warns. - name: SCSIEXROM.DAT system: sharp-x68000 diff --git a/emulators/xm6typeg.yml b/emulators/xm6typeg.yml index 00098988..935242d6 100644 --- a/emulators/xm6typeg.yml +++ b/emulators/xm6typeg.yml @@ -21,7 +21,7 @@ notes: | PI's XM6 page as a single archive, xm6_typeg_338_20260223.zip, holding an x64 xm6g.exe, the Visual C++ 2015-2019 runtime it imports (mfc140u.dll, msvcp140.dll, vcruntime140.dll, vcruntime140_1.dll) and the 32-page manual - xm6g.pdf. No source is published; the analysis below reads xm6g.exe, and the + xm6g.pdf. No source is published. The analysis below reads xm6g.exe, and the XM6 v2.06 sources cited alongside are PI's own release, xm6_206s.zip from the same page. ES-DE launches it through the XM6TYPEG and XM6TYPEG-WINDOWS find rules with the working directory set to the emulator folder, on Linux under @@ -61,7 +61,7 @@ notes: | SCSI ROM requirements follow the machine (xm6g.pdf p.17). SCSIINROM.DAT is needed by SUPER, XVI and Compact and by any machine set to the internal SCSI - interface; SCSIEXROM.DAT drives the CZ-6BS1 external board, which is the only + interface. SCSIEXROM.DAT drives the CZ-6BS1 external board, which is the only SCSI variant the SASI models can take. X68030 needs neither, its SCSI ROM being part of IPLROM30.DAT or IPLROM30S.DAT. IPLROM30S.DAT and ROM30S.DAT are a pair used only when Expansion ROM is enabled on the X68030 options tab, for @@ -69,7 +69,7 @@ notes: | The Mercury Unit carries an OPN (YMF288) whose rhythm section is sampled from external files. The fmgen and X68Sound engines read six WAV files named from a - table at xm6g.exe:0x1405c0090 (0x1404ed610, CreateFileW at 0x1404ed8bf); the + table at xm6g.exe:0x1405c0090 (0x1404ed610, CreateFileW at 0x1404ed8bf), and the ymfm engine reads ym2608_adpcm_rom.bin instead (0x140574fec, ReadFile at 0x140575095), which is why the rhythm level control is documented as inert for ymfm. @@ -94,7 +94,7 @@ files: Covers the first model, ACE, EXPERT, PRO and SUPER. LoadROM reads 0x20000 bytes and fails when fewer are returned, and the failure aborts initialisation. The startup warning naming version 1.00 (05/07/1987) as - recommended only advises; it does not reject the file. The recommended + recommended only advises: it does not reject the file. The recommended source is the free X68BIOSE.LZH package (xm6g.pdf p.6). - name: IPLROMXV.DAT @@ -274,7 +274,7 @@ files: note: >- Holds the boot device and memory switch settings for the first model, ACE, EXPERT, PRO and SUPER. A supplied image preloads those settings. The - standard capacity is the 16 KB X68000 SRAM; the SRAM64K modification the + standard capacity is the 16 KB X68000 SRAM, and the SRAM64K modification the emulator reproduces raises it to 64 KB. No size is enforced. - name: SRAMXVI.DAT @@ -325,7 +325,7 @@ files: source_ref: "xm6g.exe:0x140574eb0 (name at 0x140574fec, read at 0x140575095)" note: >- Rhythm source for the Mercury Unit OPN when the FM engine is set to ymfm. - The name is appended to a directory and the file is read whole; when it is + The name is appended to a directory and the file is read whole. When it is absent the rhythm section stays silent and the emulator runs. - name: 2608_BD.WAV @@ -383,7 +383,7 @@ files: source_ref: "xm6g.pdf p.29, p.31, xm6g.exe:LoadLibraryW at 0x140488dfb" note: >- One of the three FM engines the sound options offer, alongside the - built-in fmgen and ymfm. Not shipped in the archive; without it that + built-in fmgen and ymfm. Not shipped in the archive, and without it that engine cannot be selected. - name: c86ctl.dll diff --git a/emulators/xrick.yml b/emulators/xrick.yml index 25365246..72031edc 100644 --- a/emulators/xrick.yml +++ b/emulators/xrick.yml @@ -14,7 +14,7 @@ systems: notes: | XRick is an open-source reimplementation of the Rick Dangerous engine (Core Design, 1989), - ported to libretro. It is not a general-purpose emulator; it only plays Rick Dangerous. + ported to libretro. It is not a general-purpose emulator: it only plays Rick Dangerous. The core sets need_fullpath = true, valid_extensions = "*|zip", and supports launching without content (RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME = true, libretro/core/libretro-core.c:93-97). diff --git a/emulators/xroar.yml b/emulators/xroar.yml index 2e6e0a60..45d4c909 100644 --- a/emulators/xroar.yml +++ b/emulators/xroar.yml @@ -421,7 +421,7 @@ files: description: "Ikon Ultra Drive Dragonfly ROM 2.3" required: false source_ref: "src/xroar.c:715 (romlist ikon), src/ikon.c:151 (default @ikon), src/ikon.c:26 (WANT_EXPERIMENTAL)" - note: "Experimental, compiled only with WANT_EXPERIMENTAL. Ikon Ultra Drive storage interface. First candidate of the ikon romlist; no crclist entry names it." + 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" system: dragon64 diff --git a/emulators/yabause.yml b/emulators/yabause.yml index b24a929b..90676a7b 100644 --- a/emulators/yabause.yml +++ b/emulators/yabause.yml @@ -14,7 +14,7 @@ systems: notes: | Yabause is a software-rendered Sega Saturn emulator. Upstream project is - dead; libretro port maintained by the community on the master branch of + dead. The libretro port is maintained by the community on the master branch of libretro/yabause. Saturn BIOS search order: diff --git a/emulators/yaps2.yml b/emulators/yaps2.yml index 3ba5d5f1..928693d0 100644 --- a/emulators/yaps2.yml +++ b/emulators/yaps2.yml @@ -25,9 +25,9 @@ notes: | native AArch64 EE, IOP and VU recompilers, a persisted VU program cache, libmali and Adreno gates in the Vulkan backend. One tree builds the Qt desktop application, an SDL3 kmsdrm frontend (yaps2-sdl) and a libretro core - (yaps2_libretro.so); the nightly release ships all three for arm64 Linux + (yaps2_libretro.so). The nightly release ships all three for arm64 Linux plus a macOS build. The fork is discontinued and its recompilers moved to - ARMSX2; main is the final state. The tree is PCSX2 at 342db515 (2026-06-19) + ARMSX2, and main is the final state. The tree is PCSX2 at 342db515 (2026-06-19) plus 335 fork commits, and bin/resources is byte for byte that PCSX2 revision. ref: README.md:1-3, CMakeLists.txt:51-53, CMakeLists.txt:92-110, @@ -61,7 +61,7 @@ notes: | pcsx2-qt/QtHost.cpp:1343-1346 A BIOS image is required. VMManager::Initialize calls LoadBIOS before - opening the CDVD, and a false return is a startup failure; only a GS dump + opening the CDVD, and a false return is a startup failure. Only a GS dump replay skips it. In the libretro core that failure ends the CPU thread and no frame is ever presented. Detection is by content: LoadBIOS opens the image named by Filenames/BIOS, or when that is empty or absent scans the @@ -69,7 +69,7 @@ notes: | entry followed by a readable ROMVER. The fifth ROMVER character gives the zone among Japan, USA, Europe, Asia, China, T10K, COH-H, Test and Free, an EXTINFO entry supplies the serial. No name and no hash is matched. The image - is read into the 4 MB ROM region and truncated to it; one shorter than + is read into the 4 MB ROM region and truncated to it, and one shorter than 2465792 bytes turns off the OSDSys parameter HLE. ref: pcsx2/VMManager.cpp:1444-1461, pcsx2-libretro/Main.cpp:670-680, pcsx2/ps2/BiosTools.cpp:16-17, pcsx2/ps2/BiosTools.cpp:80-197, @@ -77,7 +77,7 @@ notes: | pcsx2/Pcsx2Config.cpp:2100-2106 The core option yaps2_bios lists the files of <system>/pcsx2/bios whose name - ends in .bin, sorted, behind an auto entry; auto writes an empty + ends in .bin, sorted, behind an auto entry. The auto entry writes an empty Filenames/BIOS and leaves the choice to the folder scan, a listed name is written as is. The libretro boot always sets fast_boot. ref: pcsx2-libretro/Main.cpp:937-940, pcsx2-libretro/Main.cpp:989-1039, @@ -87,7 +87,7 @@ notes: | full name plus extension, then with the extension replaced, opened case-insensitively, copied to 4 MB regions and skipped with a console line when absent. The nvm is read at the replaced extension and rebuilt in memory - with region and language defaults when missing, short or blank; the mec is + with region and language defaults when missing, short or blank. The mec is read the same way and written back as 0x00020603 when it cannot be read. No EROM path exists. The IRX injection at 0x1630 reads EmuConfig.CurrentIRX, which is set at runtime only and assigned by nothing in this tree. @@ -100,7 +100,7 @@ notes: | resource is read at its own name under EmuFolders::Resources, and GetOverridableResourcePath lets a copy under UserResources take precedence. The libretro core ships as a bare shared object, so the user supplies - <system>/pcsx2/resources from a yaps2 build; the SDL and Qt packages carry + <system>/pcsx2/resources from a yaps2 build, while the SDL and Qt packages carry the folder beside the binary. ref: pcsx2/Pcsx2Config.cpp:2399-2413, pcsx2-libretro/Main.cpp:157-158, pcsx2-sdl/CMakeLists.txt:29-33, .github/workflows/linux_build_libretro.yml:139-150 @@ -111,10 +111,10 @@ notes: | without it, the libretro core only logs a warning, but with no standard font AddTextFont returns null and AddImGuiFonts fails the same way. Every Vulkan shader source is read in GSDeviceVK::Create, cas.glsl and its two - includes with the others, and any read failure fails the device; the + includes with the others, and any read failure fails the device. The OpenGL backend behaves the same except that a missing cas.glsl only turns sharpening off. Vulkan is the only backend the libretro core presents - through; the OpenGL device is what the software renderer opens when the + through. The OpenGL device is what the software renderer opens when the first Vulkan GPU is Intel or a software rasterizer, and what the standalone builds open when OpenGL is selected. Direct3D sources are read by Windows builds only, which the libretro target excludes. The databases, the patch @@ -131,7 +131,7 @@ notes: | The fullscreen interface and its textures are opened by the SDL and Qt frontends, and by the achievements client when it shows a login or a - notification; the libretro core never opens it on its own, and its + notification. The libretro core never opens it on its own, and its achievements stay off unless yaps2-libretro.ini enables them. Achievement sounds play from the resources folder when the sound effects are enabled and no custom sound is set. @@ -173,7 +173,7 @@ files: description: "PS2 BIOS image" note: >- Any image whose romdir holds RESET and ROMVER is accepted, whatever its - name. The 4 to 8 MB range gates the folder scan; an image named in the + name. The 4 to 8 MB range gates the folder scan, and an image named in the configuration skips that range. The libretro option list only shows names ending in .bin. Read into the 4 MB ROM region and truncated to it. Shorter than 2465792 bytes disables the OSDSys parameter HLE. @@ -251,7 +251,7 @@ files: note: >- Opened from the process working directory at network adapter init and read as 1024 blocks of 16 pages of 512 bytes plus 16 ECC bytes. The - card is filled with 0xFF when the file is absent; a short read is + card is filled with 0xFF when the file is absent, and a short read is logged. source_ref: "pcsx2/DEV9/flash.cpp:9-16, pcsx2/DEV9/flash.cpp:62-86" @@ -266,7 +266,7 @@ files: note: >- Read from the resources folder on the first serial lookup, keyed by serial, carrying the per-game fixes, patches and settings overrides. - A console error when absent; no game is then matched. + A console error when absent, and no game is then matched. source_ref: "pcsx2/GameDatabase.cpp:39, pcsx2/GameDatabase.cpp:974-984, pcsx2/GameDatabase.cpp:1020-1034" - name: RedumpDatabase.yaml @@ -311,7 +311,7 @@ files: description: "SDL controller mapping database" note: >- A copy in the data root wins, then the resources folder, and the path - is handed to SDL as a hint; SDL falls back to its built-in mappings + is handed to SDL as a hint. SDL falls back to its built-in mappings when neither exists. Read by the SDL input source, which the libretro core switches off. source_ref: "pcsx2/Input/SDLInputSource.cpp:24, pcsx2/Input/SDLInputSource.cpp:614-629, pcsx2-libretro/Main.cpp:219" @@ -326,7 +326,7 @@ files: description: "Interface font" note: >- Mapped by each frontend and handed to ImGuiManager as the standard - font. The SDL frontend exits without it; the libretro core logs a + font. The SDL frontend exits without it, while the libretro core logs a warning, then AddTextFont has nothing to add and ImGui setup fails with the GS device. source_ref: "pcsx2-libretro/Main.cpp:177-193, pcsx2-sdl/Main.cpp:129-137, pcsx2/ImGui/ImGuiManager.cpp:598-637, pcsx2/ImGui/ImGuiManager.cpp:772-779, pcsx2/GS/GS.cpp:154-172" @@ -605,7 +605,7 @@ files: size: 36862 sha1: 554160d31bb97aca0e9f367f4de811dd8ad1fb21 description: "OpenGL texture function fragment shader" - note: "Read with tfx_vgs.glsl; the OpenGL device fails without it." + note: "Read with tfx_vgs.glsl. The OpenGL device fails without it." source_ref: "pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp:684-694" - name: convert.glsl @@ -827,7 +827,7 @@ files: description: "Fullscreen interface placeholder texture" note: >- Named as the placeholder texture when the fullscreen interface - initialises; that initialisation fails without it and the interface + initialises, and that initialisation fails without it and the interface stays closed. source_ref: "pcsx2/ImGui/FullscreenUI.cpp:335-341, pcsx2/ImGui/ImGuiFullscreen.cpp:216-226, 292-300" @@ -1070,7 +1070,7 @@ files: bundled: true size: 1296 sha1: 630d3cc1a29b86023ab331836acd7ae3791aec07 - description: "Flag icon, game list region PAL-A; BIOS zone Oceania" + description: "Flag icon, game list region PAL-A, BIOS zone Oceania" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113" - name: az.svg @@ -1101,7 +1101,7 @@ files: bundled: true size: 6978 sha1: 00d4d90a54e0cd40122df3763b5b20161d433abd - description: "Flag icon, game list region NTSC-B; interface language pt-BR" + description: "Flag icon, game list region NTSC-B, interface language pt-BR" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: ch.svg @@ -1121,7 +1121,7 @@ files: bundled: true size: 775 sha1: 863b0360572b2d7c9b1a08ce6fbb32ffa1ce3644 - description: "Flag icon, game list region NTSC-C; BIOS zone China; interface language zh-CN" + description: "Flag icon, game list region NTSC-C, BIOS zone China, interface language zh-CN" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: cz.svg @@ -1142,7 +1142,7 @@ files: bundled: true size: 209 sha1: 9003c2aa29d2869772266e9b56c869387541999a - description: "Flag icon, game list region PAL-G; interface language de-DE" + description: "Flag icon, game list region PAL-G, interface language de-DE" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: dk.svg @@ -1163,7 +1163,7 @@ files: bundled: true size: 80294 sha1: 674a3b81dc17c092c26e94b3ede351619854680e - description: "Flag icon, game list region PAL-S; interface language ca-ES and es-ES" + description: "Flag icon, game list region PAL-S, interface language ca-ES and es-ES" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: eu.svg @@ -1173,7 +1173,7 @@ files: bundled: true size: 1295 sha1: ebbe870f77114dc2a12e385c56a5a7c993b3f22d - description: "Flag icon, game list region PAL-E and PAL-M; BIOS zone Europe" + description: "Flag icon, game list region PAL-E and PAL-M, BIOS zone Europe" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113" - name: fi.svg @@ -1183,7 +1183,7 @@ files: bundled: true size: 216 sha1: b10db9c6d1271076effc0c451ad2ce64fa511fa8 - description: "Flag icon, game list region PAL-FI; interface language fi-FI" + description: "Flag icon, game list region PAL-FI, interface language fi-FI" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: fr.svg @@ -1193,7 +1193,7 @@ files: bundled: true size: 220 sha1: 4250bebf6de8e988e864342934beb72c510ea382 - description: "Flag icon, game list region PAL-F; interface language fr-FR" + description: "Flag icon, game list region PAL-F, interface language fr-FR" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: gb.svg @@ -1213,7 +1213,7 @@ files: bundled: true size: 814 sha1: 7fa4815d8ad260e10afb5e9e3f10531a169017df - description: "Flag icon, game list region PAL-GR; interface language el-GR" + description: "Flag icon, game list region PAL-GR, interface language el-GR" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: hk.svg @@ -1223,7 +1223,7 @@ files: bundled: true size: 727 sha1: 74008ed4de892e7028f393138b4fd15a94e71eb8 - description: "Flag icon, game list region NTSC-HK; BIOS zone Asia" + description: "Flag icon, game list region NTSC-HK, BIOS zone Asia" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113" - name: hr.svg @@ -1277,7 +1277,7 @@ files: bundled: true size: 1090 sha1: fa2a2b11f6d78ef7ea1aee9ae341b26a0f398dc8 - description: "Flag icon, game list region PAL-IN; interface language hi-IN" + description: "Flag icon, game list region PAL-IN, interface language hi-IN" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: ir.svg @@ -1298,7 +1298,7 @@ files: bundled: true size: 273 sha1: 7415b7fed9a98587f62ea65ceff5f9ea0689d33e - description: "Flag icon, game list region PAL-I; interface language it-IT" + description: "Flag icon, game list region PAL-I, interface language it-IT" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: jp.svg @@ -1308,7 +1308,7 @@ files: bundled: true size: 438 sha1: 7b40bd2022d8b824d22ee3f480e82aa18d462b28 - description: "Flag icon, game list region NTSC-J; BIOS zone Japan; interface language ja-JP" + description: "Flag icon, game list region NTSC-J, BIOS zone Japan, interface language ja-JP" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: kr.svg @@ -1318,7 +1318,7 @@ files: bundled: true size: 1016 sha1: 09f0d9286160100831513846a1425ff3cf526c5b - description: "Flag icon, game list region NTSC-K; interface language ko-KR" + description: "Flag icon, game list region NTSC-K, interface language ko-KR" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: lt.svg @@ -1351,7 +1351,7 @@ files: mode: standalone size: 83734 sha1: 77e296aab748df78d1b2e92a4cb1631778e39c7b - description: "Flag icon, BIOS zone Mexico; interface language es-419" + description: "Flag icon, BIOS zone Mexico, interface language es-419" source_ref: "pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: nl.svg @@ -1361,7 +1361,7 @@ files: bundled: true size: 212 sha1: eac8781372854f4ce2b7fe100257b714503ac6ff - description: "Flag icon, game list region PAL-NL; interface language nl-NL" + description: "Flag icon, game list region PAL-NL, interface language nl-NL" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: no.svg @@ -1371,7 +1371,7 @@ files: bundled: true size: 302 sha1: 8083fdbbd0f5dcfb1a044b17c934c640dc2c16be - description: "Flag icon, game list region PAL-NO; interface language no-NO" + description: "Flag icon, game list region PAL-NO, interface language no-NO" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: Other.svg @@ -1392,7 +1392,7 @@ files: bundled: true size: 204 sha1: 12edefd7e07dfc56da5840a767d8f346d754741d - description: "Flag icon, game list region PAL-PL; interface language pl-PL" + description: "Flag icon, game list region PAL-PL, interface language pl-PL" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: pt.svg @@ -1402,7 +1402,7 @@ files: bundled: true size: 7890 sha1: 27aa81654a49de86b9bdc5fa803509eac8c6eb1d - description: "Flag icon, game list region PAL-P; interface language pt-PT" + description: "Flag icon, game list region PAL-P, interface language pt-PT" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: ro.svg @@ -1434,7 +1434,7 @@ files: bundled: true size: 212 sha1: 2a502ee04c295946091a85800c634af684e04119 - description: "Flag icon, game list region PAL-R; BIOS zone Russia; interface language ru-RU" + description: "Flag icon, game list region PAL-R, BIOS zone Russia, interface language ru-RU" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: sa.svg @@ -1465,7 +1465,7 @@ files: bundled: true size: 199 sha1: d4e52e7b15063ba562cafe525610e7cc6ad0e4ab - description: "Flag icon, game list region PAL-SW; interface language sv-SE" + description: "Flag icon, game list region PAL-SW, interface language sv-SE" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: tr.svg @@ -1486,7 +1486,7 @@ files: bundled: true size: 2450 sha1: a9014bf94727050ce0c1670debbda2aba22d348c - description: "Flag icon, game list region NTSC-T; interface language zh-TW" + description: "Flag icon, game list region NTSC-T, interface language zh-TW" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: ua.svg @@ -1507,7 +1507,7 @@ files: bundled: true size: 2524 sha1: 141d1636ceff28ecd7762b37ee7f4818137fa7b3 - description: "Flag icon, game list region NTSC-U; BIOS zone USA; interface language en-US" + description: "Flag icon, game list region NTSC-U, BIOS zone USA, interface language en-US" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/Settings/BIOSSettingsWidget.cpp:81-113, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" - name: vn.svg @@ -1528,5 +1528,5 @@ files: bundled: true size: 860 sha1: b8e39cc07766388f5d2759604692c1789f4fb1a8 - description: "Flag icon, game list region PAL-AF; interface language af-ZA" + description: "Flag icon, game list region PAL-AF, interface language af-ZA" source_ref: "pcsx2/ImGui/FullscreenUI.cpp:2846, pcsx2/GameList.cpp:155-190, pcsx2-qt/GameList/GameListModel.cpp:486, pcsx2-qt/QtUtils.cpp:515-552, pcsx2-qt/SetupWizardDialog.cpp:188-190" diff --git a/emulators/ymir.yml b/emulators/ymir.yml index 93b0fc7f..601d423d 100644 --- a/emulators/ymir.yml +++ b/emulators/ymir.yml @@ -35,7 +35,7 @@ notes: | CDBlockROMImages to /userdata/roms/saturn/cdb/, ROMCartImages to /userdata/roms/saturn. - No HLE fallback for IPL ROM. CD Block LLE is optional; falls back to + No HLE fallback for IPL ROM. CD Block LLE is optional and falls back to HLE when disabled or no ROM found. Known CDB versions: 1.04, 1.05, 1.06. ROM cartridges: KoF95 and Ultraman shipped with physical ROM carts. diff --git a/emulators/yquake2.yml b/emulators/yquake2.yml index 5e2e824a..e0ad5752 100644 --- a/emulators/yquake2.yml +++ b/emulators/yquake2.yml @@ -15,7 +15,7 @@ notes: | :36). FS_AddDirToSearchPath (src/common/filesystem.c:1646) loops pak%d.<ext> from 0 to MAX_PAKS-1 (=99) across fs_packtypes = { pak, pk3 } for the active game directory, loading each one as a protected pak. - baseq2/pak0.pak is the retail data; id's 3.20 point release adds + baseq2/pak0.pak is the retail data, and id's 3.20 point release adds baseq2/pak1.pak, baseq2/pak2.pak and the Three Wave CTF data under ctf/. Supported official mods are listed in first_mods[] @@ -78,7 +78,7 @@ files: required: false source_ref: "src/common/filesystem.c:1331 (first_mods[1]=xatrix), 1688" note: "The Reckoning data. Loaded when `+set game xatrix` is passed." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Ground Zero (rogue/), official Mission Pack 2 @@ -92,7 +92,7 @@ files: required: false source_ref: "src/common/filesystem.c:1331 (first_mods[2]=rogue), 1688" note: "Ground Zero data. Loaded when `+set game rogue` is passed." - unsourceable: "retail data the collection does not hold; a same-named file of another game must not stand in" + unsourceable: "retail data the collection does not hold, and a same-named file of another game must not stand in" # ================================================================ # Three Wave Capture The Flag (ctf/), official free addon diff --git a/emulators/yuzu.yml b/emulators/yuzu.yml index 729c10a2..45a5e9ac 100644 --- a/emulators/yuzu.yml +++ b/emulators/yuzu.yml @@ -4,7 +4,7 @@ core_classification: official_port source: "https://github.com/yuzu-emu-mirror/yuzu" upstream: "https://github.com/yuzu-emu/yuzu" profiled_date: "2026-03-26" -upstream_gone: "GitHub withdrew the repository for legal reasons: the API answers HTTP 451 for both yuzu-emu/yuzu and the yuzu-emu-mirror copy. Observed 2026-09-04; no mirror found that serves file content." +upstream_gone: "GitHub withdrew the repository for legal reasons: the API answers HTTP 451 for both yuzu-emu/yuzu and the yuzu-emu-mirror copy. Observed 2026-09-04. No mirror found that serves file content." core_version: "EA 4176" display_name: "Yuzu (Nintendo Switch)" cores: diff --git a/emulators/zesarux.yml b/emulators/zesarux.yml index 710e0088..db261d52 100644 --- a/emulators/zesarux.yml +++ b/emulators/zesarux.yml @@ -61,7 +61,7 @@ notes: | comparison. `--romfile` (src/start.c:4876-4880) overrides the machine ROM with any file the user - picks (src/cpu.c:3520-3523); the ROMs under `alternate_roms/` and the extra + picks (src/cpu.c:3520-3523). The ROMs under `alternate_roms/` and the extra variants in the install root exist for that path and are documented in the shipped src/ALTERNATEROMS file. Interface ROMs are equally overridable (`--divide-rom`, `--divmmc-rom`, `--dandanator-rom`, `--ifrom-rom`, @@ -77,7 +77,7 @@ notes: | `find_sharedfile` path: `keyboards/*.bmp` on-screen keyboard art (src/menu/menu_items.c:19480, 21784, 21805), `z88_shortcuts.bmp` (src/video/screen.c:11254), the `my_soft/` homebrew collection - (src/menu/menu_items.c:32497, 32258; src/menu/menu_items_storage.c:582), the + (src/menu/menu_items.c:32497, 32258 and src/menu/menu_items_storage.c:582), the `copiers/*.zsf` tape copier snapshots (src/menu/menu_items_storage.c:666, 742) and `editionnamegame.tzx` (src/cpu.h:73, src/utils.c:17885). They are application resources rather than system firmware and carry no entry below. @@ -270,7 +270,7 @@ files: bundled: true system: sinclair-zx-spectrum source_ref: "src/cpu.c:3414-3416, src/utils.c:4116" - note: "ZX Evolution BaseConf ROM set. The 13.1 tree ships the Turbo 2+/PentEvo build with New ROM boot v1.06; the 13.0 release shipped the PentEvo edition 2013 image of the same size." + note: "ZX Evolution BaseConf ROM set. The 13.1 tree ships the Turbo 2+/PentEvo build with New ROM boot v1.06, while the 13.0 release shipped the PentEvo edition 2013 image of the same size." # ============================================================ # ZX Spectrum Next (TBBlue) @@ -293,7 +293,7 @@ files: bundled: true system: sinclair-zx-spectrum-next source_ref: "src/menu/menu_items_storage.c:12092-12110, src/configure:1921" - note: "SD card image carrying the Next system software. Assigned as MMC card 0 by the local-tbblue menu action; the emulator reports 'tbblue.mmc image not found' when absent." + note: "SD card image carrying the Next system software. Assigned as MMC card 0 by the local-tbblue menu action, and the emulator reports 'tbblue.mmc image not found' when absent." size_note: "64 MB, so it needs storage: large_file once the image is acquired and uploaded as a release asset." # ============================================================ @@ -452,7 +452,7 @@ files: bundled: true system: sinclair-ql source_ref: "src/cpu.c:3493 (commented alternative), src/start.c:4876-4880" - note: "JM release. Reachable through --romfile; the switch selects ql_js.rom." + note: "JM release. Reachable through --romfile. The switch selects ql_js.rom." - name: "tkii220.rom" sha1: "f364472a81352479290e388e9a5afb57a0de8249" @@ -461,7 +461,7 @@ files: bundled: true system: sinclair-ql source_ref: "src/machines/ql.c:1348-1375, src/start.c:5627-5652, src/cpu.c:3862-3866" - note: "QJUMP Toolkit II 2.20, the ROM ql.c names as the example for --ql-rom-c000-file. ql_load_extra_roms() runs after the system ROM and reads 16K into memoria_ql at 0xC000 from the path the option gives; the read count is not checked." + note: "QJUMP Toolkit II 2.20, the ROM ql.c names as the example for --ql-rom-c000-file. ql_load_extra_roms() runs after the system ROM and reads 16K into memoria_ql at 0xC000 from the path the option gives. The read count is not checked." - name: "qsound_V1.94.rom" sha1: "622a81dce98524148f067780c17eddbaf46e27f6" @@ -471,7 +471,7 @@ files: bundled: true system: sinclair-ql source_ref: "src/soundchips/qsound.h:50, src/soundchips/qsound.c:329-369, src/start.c:6799-6806, src/cpu.c:3863-3866" - note: "QL Qsound firmware, read into memoria_ql at 0xC0000 once --ql-qsound-enabled is set; the read count is not checked and --ql-qsound-rom points the loader at another file. QSOUND_ROM_FILE is spelled qsound_V1.94.rom while the shipped file is Qsound_V1.94.rom, so the default only resolves on a case-insensitive filesystem." + note: "QL Qsound firmware, read into memoria_ql at 0xC0000 once --ql-qsound-enabled is set. The read count is not checked and --ql-qsound-rom points the loader at another file. QSOUND_ROM_FILE is spelled qsound_V1.94.rom while the shipped file is Qsound_V1.94.rom, so the default only resolves on a case-insensitive filesystem." - name: "Z88OZ47.rom" sha1: "35e528e81d8f4e5860adf4160a3da0926525c8fa" @@ -480,7 +480,7 @@ files: bundled: true system: cambridge-z88 source_ref: "src/cpu.c:3460-3465, src/cpu.c:3785-3795" - size_note: "Reads up to 512K and errors only when nothing is read; z88_internal_rom_size is derived from the byte count, so any size is accepted." + size_note: "Reads up to 512K and errors only when nothing is read. z88_internal_rom_size is derived from the byte count, so any size is accepted." - name: "mk14.rom" sha1: "802dc637ce5391a2a6627f76f919b12a869b56ef" diff --git a/install.ps1 b/install.ps1 index 7089ce20..27ec5ac1 100644 --- a/install.ps1 +++ b/install.ps1 @@ -8,7 +8,7 @@ param( $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -$defaultInstallSha256 = "7e74935ae51bf8b0076f637bc640b33f0ca774bec065df56080a0321fa292820" +$defaultInstallSha256 = "8ca436e66f04f3fa202350f84afa0fc339bf60953022509b9d1e5177830b8636" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } @@ -46,7 +46,7 @@ try { } $actual = (Get-FileHash -LiteralPath $temporary -Algorithm SHA256).Hash.ToLowerInvariant() if ($actual -ne $expected.ToLowerInvariant()) { - throw "The downloaded installer does not match its expected fingerprint. Nothing was run and nothing was written. The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages; waiting five minutes settles that." + throw "The downloaded installer does not match its expected fingerprint. Nothing was run and nothing was written. The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." } $installer = $temporary } diff --git a/install.py b/install.py index 81e5ea00..7787e899 100644 --- a/install.py +++ b/install.py @@ -187,7 +187,7 @@ def _os_default_dests(os_type: str) -> dict[str, Path]: "retrobat": _host_path("C:/RetroBat/bios"), } if os_type == "wsl": - # RetroArch may be the Linux one inside the distribution; RetroBat + # RetroArch may be the Linux one inside the distribution, while RetroBat # only exists on the Windows side, reached through /mnt/c. return { "retroarch": home / ".config" / "retroarch" / "system", @@ -220,7 +220,7 @@ def _enable_ansi() -> bool: """Whether escape sequences reach the terminal as colour and redraws. Windows 10 consoles interpret them once virtual terminal processing is - switched on; older ones print them raw, so the answer is then no. + switched on. Older ones print them raw, so the answer is then no. """ if os.name != "nt": return True @@ -240,7 +240,7 @@ def _enable_ansi() -> bool: class Terminal: """What the output stream can show: a live line, colour, or neither. - A pipe or a log gets plain lines; NO_COLOR and TERM=dumb are honoured. + A pipe or a log gets plain lines, and NO_COLOR and TERM=dumb are honoured. """ def __init__(self, stream: TextIO | None = None, quiet: bool = False) -> None: @@ -523,7 +523,7 @@ def _steam_libraries() -> list[Path]: """Every Steam library, the default one first. Steam lists the others in steamapps/libraryfolders.vdf, each as a - "path" line; a RetroArch installed on D:/SteamLibrary was not found + "path" line. A RetroArch installed on D:/SteamLibrary was not found when only Program Files was searched. """ roots: list[Path] = [] @@ -719,9 +719,9 @@ def _parse_ps1_var(path: Path, key: str) -> str | None: # Embedded systems, first match wins: Knulli also carries the Batocera # markers. The registry publishes the same rules as each manifest's -# `detect`; a test holds the two equal. MiSTer is a path rule below. +# `detect`, and a test holds the two equal. MiSTer is a path rule below. _EMBEDDED_RULES: tuple[tuple[str, str, tuple[str, ...], str], ...] = ( - # ROCKNIX writes OS_NAME and no ID since 2025 (scripts/image); older + # ROCKNIX writes OS_NAME and no ID since 2025 (scripts/image). Older # images wrote ID=rocknix. ("rocknix", "os_release", ("OS_NAME=rocknix", "ID=rocknix"), "/storage/roms/bios"), ("batocera", "file_exists", ("/etc/knulli-release",), "/userdata/bios"), @@ -790,7 +790,7 @@ def _detect_android() -> list[tuple[str, Path]]: def _lnk_target(lnk_path: Path, exe_name: str) -> Path | None: """Read the target path of a Windows shortcut. - Shortcuts embed the target as a plain local path; scanning for it avoids + Shortcuts embed the target as a plain local path. Scanning for it avoids parsing the whole .lnk structure for the one field that matters here. """ try: @@ -847,7 +847,7 @@ def launchbox_root(os_type: str) -> Path | None: def launchbox_emulators(emulators_xml: Path) -> dict[str, Path]: """Map each emulator LaunchBox knows about to its installation directory. - LaunchBox stores its emulator list in Data/Emulators.xml; ApplicationPath + LaunchBox stores its emulator list in Data/Emulators.xml. ApplicationPath is either absolute or relative to the LaunchBox root directory. Keys are the lowercase executable names. """ @@ -858,7 +858,7 @@ def launchbox_emulators(emulators_xml: Path) -> dict[str, Path]: if emulators_xml.stat().st_size > 10 * 1024 * 1024: return found raw = emulators_xml.read_text(encoding="utf-8", errors="replace") - # ElementTree expands internal entities; LaunchBox writes no doctype + # ElementTree expands internal entities, and LaunchBox writes no doctype if "<!DOCTYPE" in raw.upper(): return found tree = ET.ElementTree(ET.fromstring(raw)) @@ -951,8 +951,8 @@ def _xemu_bios_dir(emu_dir: Path) -> Path: def launchbox_bios_dirs(root: Path) -> dict[str, Path]: """Map emulator ids to the BIOS directory LaunchBox expects for them. - Only emulators whose destination LaunchBox itself computes are listed; - the rest keep the default locations declared in the manifest. + Only emulators whose destination LaunchBox itself computes are listed. + The rest keep the default locations declared in the manifest. """ emulators = launchbox_emulators(root / "Data" / "Emulators.xml") dirs: dict[str, Path] = {} @@ -990,7 +990,7 @@ def detect_frontends(os_type: str, home: Path | None = None) -> list[str]: # The registry's path_exists rules (platforms/_registry.yml install.detect), # one row each: (os, platform, path, BIOS directory when it is not the path). # The manifests publish them too, but detection runs before any manifest is -# fetched; a test holds this table equal to the registry. Without it a Linux +# fetched. A test holds this table equal to the registry. Without it a Linux # home holding RetroPie/BIOS or .config/BizHawk/Firmware detected nothing. _PATH_RULES: tuple[tuple[str, str, str, str | None], ...] = ( ("windows", "retrobat", "C:\\RetroBat\\bios", None), @@ -1118,7 +1118,7 @@ def detect_platforms(os_type: str) -> list[tuple[str, Path]]: if os_type == "darwin": # open_default_config_file reads <Application Support>/RetroArch/config - # (configuration.c); a value left at default is the documents folder, + # (configuration.c). A value left at default is the documents folder, # or Application Support itself for a portable install # (platform_darwin.m). The config beside it is where older builds # kept it. @@ -1267,7 +1267,7 @@ def core_dirs(plat: str, bios_path: Path) -> list[Path]: """The directories the RetroArch writing to bios_path loads cores from. The config detection read for this system directory names them in - libretro_directory; without one, a retroarch.cfg beside the system + libretro_directory. Without one, a retroarch.cfg beside the system directory is the portable layout. Unset, the setting is cores/ under RetroArch's own directory. """ @@ -1308,7 +1308,7 @@ def keeps_case(directory: Path) -> bool: def fold_case_twins(files: list[dict]) -> tuple[list[dict], list[str]]: - """One file per name where the directory folds case; the others named. + """One file per name where the directory folds case, the others named. The first in manifest order stays, as the pack's own order places it. """ @@ -1495,7 +1495,7 @@ def _check_omission(entry: dict, dest: str) -> None: def _check_download(entry: dict, where: str, dest: str) -> int: - """The size, hashes, source and cores of one downloadable copy; its size.""" + """The size, hashes, source and cores of one downloadable copy, and its size.""" size = entry.get("size") if isinstance(size, bool) or not isinstance(size, int) or not (0 <= size <= MAX_DOWNLOAD_SIZE): raise ValueError(f"invalid size for {dest}") @@ -1535,7 +1535,7 @@ def _check_download(entry: dict, where: str, dest: str) -> int: def _check_slot(entry: dict, where: str, dest: str) -> int: - """The copies a platform file takes as cores and systems drop; the largest size.""" + """The copies a platform file takes as cores and systems drop, and the largest size.""" choices = entry.get("slot_choices", []) declared = entry.get("declared_choices") if declared is None and not choices: @@ -1578,7 +1578,7 @@ def _check_slot(entry: dict, where: str, dest: str) -> int: def _check_entry( entry: object, where: str, seen_destinations: set[str] ) -> tuple[int, int]: - """Check one file entry; return its size and the largest copy it may fetch.""" + """Check one file entry, return its size and the largest copy it may fetch.""" if not isinstance(entry, dict): raise ValueError(f"{where} must be an object") dest = str(_safe_relative_path(entry.get("dest"), f"{where}.dest")) @@ -1866,7 +1866,7 @@ def _fetch_json(url: str, limit: int, label: str) -> object: delay = _retry_delay(attempt, None) problem = str(getattr(exc, "reason", None) or exc) # Said, or three 30-second attempts read as a frozen program. - print(f" The {label} did not arrive ({problem}); trying again " + print(f" The {label} did not arrive ({problem}), trying again " f"({attempt + 1}/{MAX_RETRIES}) in {delay:.0f} s.", file=sys.stderr) time.sleep(delay) raise AssertionError("unreachable") @@ -1882,7 +1882,7 @@ def fetch_manifest(plat: str) -> dict: sys.exit(1) except urllib.error.HTTPError as exc: if exc.code == 404: - # Asked once, a 4xx being final; the name was checked before any + # Asked once, a 4xx being final. The name was checked before any # request, so the revision is what has no such list. print(f" No file list for {plat} at {RELEASE_REF}.", file=sys.stderr) if RELEASE_REF != DEFAULT_RELEASE_REF: @@ -2005,7 +2005,7 @@ def designated_cores(manifest: dict, names: list[str]) -> set[str]: """The cores a list of names designates, the way the pack builder reads it. A target list, or a core found installed, names a core the buildbot's - way (`mednafen_psx`); a file names the profile that reads it + way (`mednafen_psx`), and a file names the profile that reads it (`beetle_psx`). `core_names` gives each profile its other names. """ wanted = set(names) @@ -2110,11 +2110,11 @@ def region_drops( The pack builder's rule (region.resolve_region_drops), replayed over the groups the manifest records. Per group, the best-ranked regional file - stays; a world file beats unmatched regional ones the code does not search - before it (`priority`, lower first); when nothing matches and no world + stays. A world file beats unmatched regional ones the code does not search + before it (`priority`, lower first). When nothing matches and no world file exists, every regional file stays, so a group is never emptied. A file with no region never competes and always stays. - A core extra competes whatever systems are chosen; a platform's own + A core extra competes whatever systems are chosen, while a platform's own declaration competes only when its system is kept, as in the pack. """ if not requested: @@ -2170,7 +2170,7 @@ def region_drops( def entry_systems(entry: dict) -> list[str]: """The platform systems a file or an omission belongs to. - An omission's `system` is spelled the way its profile spells it; only + An omission's `system` is spelled the way its profile spells it. Only `systems` names the platform's own, the ones --system accepts. """ return list(entry.get("systems") or []) @@ -2212,7 +2212,7 @@ def _chosen(entry: dict, wanted: set[str]) -> bool: def records_selection(files: list[dict]) -> bool: - """Whether a manifest carries what narrowing reads; older ones do not.""" + """Whether a manifest carries what narrowing reads. Older ones do not.""" return any("systems" in entry for entry in files) @@ -2486,7 +2486,7 @@ def _download_one( counted += len(chunk) if downloaded != expected_size: raise ValueError( - f"downloaded {downloaded} bytes; expected {expected_size}" + f"downloaded {downloaded} bytes, expected {expected_size}" ) expected_sha256 = f.get("sha256", "") @@ -2503,7 +2503,7 @@ def _download_one( # written with sudo has to stay readable by the emulator's user. os.chmod(tmp_path, (0o777 if f.get("executable") else 0o666) & ~_UMASK) if partial is not None and os.name == "nt": - # Windows renames no open file; elsewhere the lock is held + # Windows renames no open file. Elsewhere the lock is held # until the copy has its final name. partial.close() os.replace(tmp_path, dest) @@ -2511,7 +2511,7 @@ def _download_one( except _Interrupted: # Stopped mid-transfer: a large file keeps its partial copy for - # the next run; a small one is dropped rather than left beside + # the next run, and a small one is dropped rather than left beside # the destination. if tmp_path is not None and partial is None and tmp_path.exists(): tmp_path.unlink() @@ -2575,7 +2575,7 @@ def _download_one( def _partial_size(path: Path) -> int: - """Bytes already held by a partial copy; anything but a plain file is dropped.""" + """Bytes already held by a partial copy. Anything but a plain file is dropped.""" try: info = path.lstat() except FileNotFoundError: @@ -3107,7 +3107,7 @@ def do_standalone_copies( if fnmatch(f.name, entry["pattern"]) and f.is_file() ] else: - # `source` is where this platform's manifest put the file; `file` + # `source` is where this platform's manifest put the file, and `file` # names it as the registry does for every platform, and laid out # that way it was missing wherever the pack places it elsewhere. src = _destination_path(bios_path, entry.get("source") or entry["file"]) @@ -3281,7 +3281,7 @@ def _sized(files: list[dict]) -> str: def _pick(title: str, rows: list[tuple[str, list[dict]]], ordered: bool = False) -> list[str]: - """Numbered list of names; an empty answer keeps every one.""" + """Numbered list of names. An empty answer keeps every one.""" if not rows: return [] print(f"\n{title}") @@ -3316,7 +3316,7 @@ def _prompt_custom_selection( Enter installs everything, the default most runs want. Returns None then, INSTALLED_ONLY for what `installed` (the files the cores found - installed read) holds, or the three choices; each empty list keeps + installed read) holds, or the three choices. Each empty list keeps everything on its axis. """ print(f"\n{plat.capitalize()}: {_sized(files)}.") @@ -3512,7 +3512,7 @@ def main() -> None: "--system", action="append", metavar="NAME", - help="install only these systems (repeat or comma-separate; see " + help="install only these systems (repeat or comma-separate, see " "--list-systems)", ) parser.add_argument( @@ -3541,7 +3541,7 @@ def main() -> None: parser.add_argument( "--no-input", action="store_true", - help="never ask a question; fail where an answer is needed", + help="never ask a question and fail where an answer is needed", ) parser.add_argument( "--dry-run", @@ -3752,7 +3752,7 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: variants = manifest.get("case_variants", []) case_kept = keeps_case(bios_path) if variants and case_kept: - # The list is folded for Windows and macOS; here bios.col and + # The list is folded for Windows and macOS, but here bios.col and # BIOS.col are two files that two cores open. files = files + variants if not case_kept: diff --git a/install.sh b/install.sh index 8c631f09..0552a90f 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ esac TEMP_INSTALLER="" TEMP_DIRECTORY="" DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -DEFAULT_INSTALL_SHA256="7e74935ae51bf8b0076f637bc640b33f0ca774bec065df56080a0321fa292820" +DEFAULT_INSTALL_SHA256="8ca436e66f04f3fa202350f84afa0fc339bf60953022509b9d1e5177830b8636" MAX_INSTALLER_BYTES=2097152 cleanup() { @@ -92,8 +92,8 @@ if [ -z "$INSTALLER" ] || [ ! -f "$INSTALLER" ]; then echo "Error: the downloaded installer does not match its expected fingerprint." >&2 echo " Nothing was run and nothing was written." >&2 echo " The download was most likely cut short: try again. Within minutes of an update" >&2 - echo " of this project the two files can come from caches of different ages; waiting" >&2 - echo " five minutes settles that." >&2 + echo " of this project the two files can come from caches of different ages." >&2 + echo " Waiting five minutes settles that." >&2 exit 1 fi INSTALLER="$TEMP_INSTALLER" diff --git a/mkdocs.yml b/mkdocs.yml index ab6ca2e8..9c7b213c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -98,7 +98,7 @@ plugins: - search # Link rot fails the build: deploy-site.yml runs `mkdocs build --strict`. # omitted_files stays at its default (info) so a stale local docs/ does not -# break a local build; CI regenerates docs/ from scratch anyway. +# break a local build. CI regenerates docs/ from scratch anyway. validation: absolute_links: warn unrecognized_links: warn diff --git a/platforms/_data_dirs.yml b/platforms/_data_dirs.yml index 2d0acd79..5eca2ea0 100644 --- a/platforms/_data_dirs.yml +++ b/platforms/_data_dirs.yml @@ -18,7 +18,7 @@ data_directories: # https://buildbot.libretro.com/assets/system/ # ========================================================================= - # ref: DolphinLibretro/Boot.cpp:72-73 — system/dolphin-emu/Sys/ + # ref: DolphinLibretro/Boot.cpp:72-73 (system/dolphin-emu/Sys/) dolphin-sys: source_url: "https://buildbot.libretro.com/assets/system/Dolphin.zip" source_type: zip @@ -28,7 +28,7 @@ data_directories: exclude: [Themes] description: "Dolphin system data (GameSettings, DSP, fonts, shaders)" - # ref: ppsspp/ext/native/ui/ui_screen.cpp — system/PPSSPP/ + # ref: ppsspp/ext/native/ui/ui_screen.cpp (system/PPSSPP/) ppsspp-assets: source_url: "https://buildbot.libretro.com/assets/system/PPSSPP.zip" source_type: zip @@ -37,7 +37,7 @@ data_directories: strip_components: 1 description: "PPSSPP fonts, backgrounds, shaders, lang files" - # ref: bluemsx-libretro/system/ — system/Databases/ + system/Machines/ + # ref: bluemsx-libretro/system/ (system/Databases/ + system/Machines/) bluemsx: source_url: "https://buildbot.libretro.com/assets/system/blueMSX.zip" source_type: zip @@ -45,7 +45,7 @@ data_directories: local_cache: data/bluemsx description: "blueMSX Databases + Machines configs" - # ref: pcsx2/libretro/main.cpp — system/pcsx2/ + # ref: pcsx2/libretro/main.cpp (system/pcsx2/) lrps2: source_url: "https://buildbot.libretro.com/assets/system/LRPS2.zip" source_type: zip @@ -75,7 +75,7 @@ data_directories: local_cache: data/yaps2-resources description: "yaps2 resources (GameIndex.yaml, RedumpDatabase.yaml, fonts, shaders, icons, sounds)" - # ref: src/Cafe/GameProfile/GameProfile.cpp:181-195 — Cemu/gameProfiles/default/ + # ref: src/Cafe/GameProfile/GameProfile.cpp:181-195 (Cemu/gameProfiles/default/) cemu-gameprofiles: source_url: "https://github.com/cemu-project/Cemu/archive/{version}.tar.gz" source_type: tarball @@ -84,14 +84,14 @@ data_directories: local_cache: data/cemu-gameprofiles description: "Cemu default game profiles (one .ini per title id)" - # ref: src/Cafe/GraphicPack/GraphicPack2.cpp:96-111 — Cemu/graphicPacks/downloadedGraphicPacks/ + # ref: src/Cafe/GraphicPack/GraphicPack2.cpp:96-111 (Cemu/graphicPacks/downloadedGraphicPacks/) cemu-graphic-packs: source_url: "https://github.com/cemu-project/cemu_graphic_packs/releases/download/Github981/graphicPacks981.zip" source_type: zip local_cache: data/cemu-graphic-packs description: "Cemu community graphic packs, release Github981" - # ref: scummvm/backends/platform/libretro — system/scummvm/ + # ref: scummvm/backends/platform/libretro (system/scummvm/) scummvm: source_url: "https://buildbot.libretro.com/assets/system/ScummVM.zip" source_type: zip @@ -99,7 +99,7 @@ data_directories: local_cache: data/scummvm description: "ScummVM extra data files (themes, translations, shaders)" - # ref: nxengine-libretro — system/ + # ref: nxengine-libretro (system/) nxengine: source_url: "https://buildbot.libretro.com/assets/system/NXEngine%20%28Cave%20Story%29.zip" source_type: zip @@ -107,7 +107,7 @@ data_directories: local_cache: data/nxengine description: "NXEngine Cave Story game data" - # ref: ecwolf/src/wl_main.cpp — system/ecwolf.pk3 + # ref: ecwolf/src/wl_main.cpp (system/ecwolf.pk3) ecwolf: source_url: "https://buildbot.libretro.com/assets/system/ECWolf.zip" source_type: zip @@ -115,7 +115,7 @@ data_directories: local_cache: data/ecwolf description: "ECWolf game engine data" - # ref: prboom/src/d_main.c — system/prboom.wad + # ref: prboom/src/d_main.c (system/prboom.wad) prboom: source_url: "https://buildbot.libretro.com/assets/system/PrBoom.zip" source_type: zip @@ -123,7 +123,7 @@ data_directories: local_cache: data/prboom description: "PrBoom Doom engine data" - # ref: xrick/src/data.c — system/xrick/data.zip + # ref: xrick/src/data.c (system/xrick/data.zip) xrick: source_url: "https://buildbot.libretro.com/assets/system/XRick%20%28Rick%20Dangerous%29.zip" source_type: zip @@ -131,7 +131,7 @@ data_directories: local_cache: data/xrick description: "XRick Rick Dangerous game data" - # ref: dinothawr/libretro.cpp — system/dinothawr/ + # ref: dinothawr/libretro.cpp (system/dinothawr/) dinothawr: source_url: "https://buildbot.libretro.com/assets/system/Dinothawr.zip" source_type: zip @@ -139,7 +139,7 @@ data_directories: local_cache: data/dinothawr description: "Dinothawr game data" - # ref: qemu — system firmware + # ref: qemu (system firmware) qemu: source_url: "https://buildbot.libretro.com/assets/system/QEMU.zip" source_type: zip @@ -147,7 +147,7 @@ data_directories: local_cache: data/qemu description: "QEMU firmware (SeaBIOS, VGA BIOS, OpenSBI, etc.)" - # ref: cannonball/src/main.cpp — system/ + # ref: cannonball/src/main.cpp (system/) cannonball: source_url: "https://buildbot.libretro.com/assets/system/Cannonball%20%28ROMs%20Required%29.zip" source_type: zip @@ -155,7 +155,7 @@ data_directories: local_cache: data/cannonball description: "Cannonball OutRun engine config" - # ref: fbneo hiscore.dat — system/fbneo/ + # ref: fbneo hiscore.dat (system/fbneo/) fbneo-hiscore: source_url: "https://buildbot.libretro.com/assets/system/FinalBurn%20Neo%20%28hiscore%29.zip" source_type: zip @@ -163,7 +163,7 @@ data_directories: local_cache: data/fbneo-hiscore description: "FinalBurn Neo hiscore database" - # ref: mame2003/src — system/mame2003/ + # ref: mame2003/src (system/mame2003/) mame2003: source_url: "https://buildbot.libretro.com/assets/system/MAME%202003.zip" source_type: zip @@ -171,7 +171,7 @@ data_directories: local_cache: data/mame2003 description: "MAME 2003 samples + cheat" - # ref: mame2003-plus — system/mame2003-plus/ + # ref: mame2003-plus (system/mame2003-plus/) mame2003-plus: source_url: "https://buildbot.libretro.com/assets/system/MAME%202003-Plus.zip" source_type: zip @@ -179,15 +179,15 @@ data_directories: local_cache: data/mame2003-plus description: "MAME 2003-Plus samples + cheat + history" - # ref: sdlpal/main.c — system/sdlpal/ (Chinese Paladin / 仙剑奇侠传) - # Not on buildbot — sourced from large-files release asset + # ref: sdlpal/main.c (system/sdlpal/, Chinese Paladin / 仙剑奇侠传) + # Not on buildbot, sourced from large-files release asset sdlpal: source_url: "https://github.com/Abdess/retrobios/releases/download/large-files/sdlpal-data.zip" source_type: zip local_cache: data/sdlpal description: "SDLPAL Chinese Paladin game data (.mkf archives)" - # ref: OpenTyrian2000 — system/opentyrian/tyrian/ + # ref: OpenTyrian2000 (system/opentyrian/tyrian/) # Tyrian 2.1 freeware data (buildbot URLs removed, sourced from release asset) opentyrian: source_url: "https://github.com/Abdess/retrobios/releases/download/large-files/opentyrian-data.zip" @@ -196,7 +196,7 @@ data_directories: local_cache: data/opentyrian description: "OpenTyrian Tyrian 2.1 freeware game data" - # ref: syobonaction — system/syobonaction/ + # ref: syobonaction (system/syobonaction/) # Freeware game data from OpenSyobonAction (BGM, res, SE directories) syobonaction: source_url: "https://github.com/akemin-dayo/OpenSyobonAction/archive/refs/heads/{version}.tar.gz" @@ -211,12 +211,12 @@ data_directories: # Upstream repo sources (not on buildbot, available to all platforms) # ========================================================================= - # ref: FreeIntv/src/libretro.c:273 — system/freeintv_overlays/<rom>.png + # ref: FreeIntv/src/libretro.c:273 (system/freeintv_overlays/<rom>.png) # 90 per-game controller overlay PNGs, loaded via stbi_load() # optional: core falls back to embedded default keypad image # freeintv overlays: Assets/Overlays.zip in repo (not a directory) # Already archived in bios/Mattel/Intellivision/freeintv_overlays/ - # No buildbot source — sourced manually from core repo + # No buildbot source, sourced manually from core repo freeintv-overlays: source_url: "https://github.com/libretro/FreeIntv/raw/{version}/Assets/Overlays.zip" source_type: zip @@ -225,8 +225,8 @@ data_directories: strip_components: 1 description: "FreeIntv per-game controller overlay PNGs" - # ref: crawl-ref/source/files.cc:375-458 — datafile_path() dat/ tree - # Not on buildbot — sourced from libretro repo + # ref: crawl-ref/source/files.cc:375-458 (datafile_path() dat/ tree) + # Not on buildbot, sourced from libretro repo # 532 files (tiles, fonts, databases, lua scripts, level descriptions) stonesoup: source_url: "https://github.com/libretro/crawl-ref/archive/refs/heads/{version}.tar.gz" @@ -236,7 +236,7 @@ data_directories: local_cache: data/stonesoup description: "DCSS game data (tiles, fonts, databases, lua, level descriptions)" - # ref: FBNeo src/burner/libretro/libretro.cpp — system/fbneo/cheats/ + # ref: FBNeo src/burner/libretro/libretro.cpp (system/fbneo/cheats/) fbneo-cheats: source_url: "https://github.com/finalburnneo/FBNeo-cheats/archive/refs/heads/{version}.zip" source_type: zip @@ -245,7 +245,7 @@ data_directories: strip_components: 1 description: "FinalBurn Neo per-game cheat definitions" - # ref: FBNeo src/burn/snd/samples.cpp — system/fbneo/samples/ + # ref: FBNeo src/burn/snd/samples.cpp (system/fbneo/samples/) fbneo-samples: source_url: "https://github.com/Abdess/retrobios/releases/download/large-files/fbneo-samples.zip" source_type: zip @@ -253,7 +253,7 @@ data_directories: local_cache: data/fbneo-samples description: "FinalBurn Neo per-game audio samples (49 arcade games)" - # ref: dirksimple — system/ + # ref: dirksimple (system/) dirksimple: source_url: "https://buildbot.libretro.com/assets/system/DirkSimple.zip" source_type: zip diff --git a/platforms/_registry.yml b/platforms/_registry.yml index 5537fa4b..e8bff91f 100644 --- a/platforms/_registry.yml +++ b/platforms/_registry.yml @@ -188,7 +188,7 @@ platforms: method: config_file config: $HOME/.config/retroarch/retroarch.cfg parse_key: system_directory - # configuration.c reads <Application Support>/RetroArch/config; a value + # configuration.c reads <Application Support>/RetroArch/config, and a value # left at default is ~/Documents/RetroArch/system (platform_darwin.m). # Older builds kept the file one level up. - os: darwin @@ -419,7 +419,7 @@ platforms: install: detect: # retrodeck.json since the cfg-to-json migration (global.sh:149-153), - # retrodeck.cfg before it; a home moved to an SD card lives only there. + # retrodeck.cfg before it. A home moved to an SD card lives only there. - os: linux method: config_file config: $HOME/.var/app/net.retrodeck.retrodeck/config/retrodeck/retrodeck.json diff --git a/platforms/_shared.yml b/platforms/_shared.yml index fb024bd7..1d5df3ec 100644 --- a/platforms/_shared.yml +++ b/platforms/_shared.yml @@ -4,9 +4,9 @@ shared_groups: - # NEC PC-9801/9821 — NP2kai core + # NEC PC-9801/9821, NP2kai core # np2kai hardcodes "np2kai/" subfolder for firmware lookups - # ref: NP2kai/sdl/libretro/libretro.c:1804,1806 — milstr_ncat(np2path, "/np2kai") + # ref: NP2kai/sdl/libretro/libretro.c:1804,1806: `milstr_ncat(np2path, "/np2kai")` # font.rom is the lowercase fallback for FONT.ROM, which System.dat declares # (font/font.c:192-195): an alias in the profile, not a second file here. np2kai: @@ -74,9 +74,9 @@ shared_groups: crc32: "638864c1" size: 5288 - # NEC PC-8801 — QUASI88 core + # NEC PC-8801, QUASI88 core # QUASI88 searches "quasi88/" subfolder first - # ref: quasi88-libretro/src/LIBRETRO/libretro.c:463 — snprintf(..., "%s%cquasi88%c%s", ...) + # ref: quasi88-libretro/src/LIBRETRO/libretro.c:463: `snprintf(..., "%s%cquasi88%c%s", ...)` quasi88: # Only what System.dat does not declare for nec-pc-88: the mkII SR # extension ROMs that match N88.ROM (MAME pc8801mk2sr: 710a63ec, c0bd2aa6, diff --git a/platforms/targets/_overrides.yml b/platforms/targets/_overrides.yml index f7ea8622..50f82a4a 100644 --- a/platforms/targets/_overrides.yml +++ b/platforms/targets/_overrides.yml @@ -20,9 +20,9 @@ batocera: targets: _default: # Amiga machine variants (A500, CD32, etc.) are selectors passed to - # fsuae/amiberry, not emulators of their own; batocera-es-system + # fsuae/amiberry, not emulators of their own. batocera-es-system # groups them under the emulator's node in es_systems.yml. - # odcommander is OpenDingux's file manager; flatpak/steam/wine-tkg/sh + # odcommander is OpenDingux's file manager, and flatpak/steam/wine-tkg/sh # are runtime launchers. N64 video plugins (gliden64, glide64mk2, # rice) are backends to mupen64plus, not emulators. remove_cores: @@ -43,7 +43,7 @@ batocera: - gliden64 - glide64mk2 - rice - # Boards are named by SoC; the Raspberry Pi models a user knows map here + # Boards are named by SoC. The Raspberry Pi models a user knows map here # (Batocera's Config.in comments: "rpi2/rpi3", "rpi4 only", "rpi5 only"). bcm2835: aliases: [rpi1, rpi-zero] @@ -96,7 +96,7 @@ retroarch: retrodeck: targets: _default: - # RetroDECK ships RetroArch itself as a component; its target list + # RetroDECK ships RetroArch itself as a component, and its target list # includes the frontend name alongside the actual cores. remove_cores: [retroarch] @@ -104,7 +104,7 @@ emudeck: targets: _default: # EmuDeck's EmuScripts tree carries a template.sh placeholder used - # to scaffold new installers; it is not an emulator. + # to scaffold new installers. It is not an emulator. remove_cores: [template] lakka: @@ -140,7 +140,7 @@ recalbox: targets: _default: # system.ini names a mupen64plus video plugin as the core of the - # mupen64plus emulator; mupenGenerator.py loads it with --gfx + # mupen64plus emulator. mupenGenerator.py loads it with --gfx # mupen64plus-video-<core>.so. Plugins, not emulators. remove_cores: - glide64mk2 # mupen64plus-video-glide64mk2 diff --git a/schemas/emulator.schema.json b/schemas/emulator.schema.json index f908a46b..e6b9f7c7 100644 --- a/schemas/emulator.schema.json +++ b/schemas/emulator.schema.json @@ -133,7 +133,7 @@ "type": "object" } ], - "description": "Revision the profile was read at; an object keys it by build mode when the builds live in different repositories." + "description": "Revision the profile was read at. An object keys it by build mode when the builds live in different repositories." }, "upstream_commit": { "oneOf": [ @@ -144,7 +144,7 @@ "type": "object" } ], - "description": "Revision the profile was read at; an object keys it by build mode when the builds live in different repositories." + "description": "Revision the profile was read at. An object keys it by build mode when the builds live in different repositories." }, "profiled_date": { "description": "Quote it: an unquoted YAML date parses to a date object.", @@ -425,7 +425,7 @@ "type": "boolean" }, "adler32_pairs_with": { - "description": "The file hashed together with this one; adler32_pairs lists the combinations the code accepts.", + "description": "The file hashed together with this one. adler32_pairs lists the combinations the code accepts.", "type": "string" }, "adler32_pairs": { @@ -458,7 +458,7 @@ "type": "boolean" }, "load_from": { - "description": "Where the emulator reads the file when not from the system directory; keyed by build when the libretro and standalone builds read it from different places.", + "description": "Where the emulator reads the file when not from the system directory, keyed by build when the libretro and standalone builds read it from different places.", "oneOf": [ { "type": "string" @@ -479,7 +479,7 @@ ] }, "priority": { - "description": "Preference order among the BIOS a system accepts, lowest first. DuckStation's FindBIOSImageInDirectory keeps the image whose priority is lower; a search list the code walks in order maps onto it as 1, 2, 3.", + "description": "Preference order among the BIOS a system accepts, lowest first. DuckStation's FindBIOSImageInDirectory keeps the image whose priority is lower. A search list the code walks in order maps onto it as 1, 2, 3.", "type": "integer", "minimum": 0 }, @@ -560,7 +560,7 @@ "pattern": "^[a-fA-F0-9]{64}(,[a-fA-F0-9]{64})*$" }, "crc32": { - "description": "CRC32 the code accepts; a list when several dumps pass.", + "description": "CRC32 the code accepts, as a list when several dumps pass.", "oneOf": [ { "type": "string", @@ -577,7 +577,7 @@ ] }, "known_hash_adler32": { - "description": "Adler-32 values the code accepts; a list when several revisions pass.", + "description": "Adler-32 values the code accepts, as a list when several revisions pass.", "oneOf": [ { "type": [ @@ -803,7 +803,7 @@ "prose_written_at": { "type": "string", "pattern": "^[0-9a-f]{40}$", - "description": "The pin a reader confirmed every prose citation against. When the profile's history shows several pins under one text, profile_sync takes this one as the revision the text describes; it never overrides a single candidate." + "description": "The pin a reader confirmed every prose citation against. When the profile's history shows several pins under one text, profile_sync takes this one as the revision the text describes. It never overrides a single candidate." }, "pin_frozen": { "type": "string", @@ -811,7 +811,7 @@ }, "upstream_gone": { "type": "string", - "description": "Why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass; profile_sync reports the contradiction if the forge answers again." + "description": "Why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass. profile_sync reports the contradiction if the forge answers again." }, "source_mirror": { "type": "string", diff --git a/schemas/install-manifest.schema.json b/schemas/install-manifest.schema.json index 6407e84a..a79ed179 100644 --- a/schemas/install-manifest.schema.json +++ b/schemas/install-manifest.schema.json @@ -42,7 +42,7 @@ "target": { "type": "string", "minLength": 1, - "description": "Hardware target this manifest was filtered for; absent when unfiltered" + "description": "Hardware target this manifest was filtered for, absent when unfiltered" }, "platform": { "type": "string", @@ -109,7 +109,7 @@ } }, "system_cores": { - "description": "Each platform system with the cores whose presence keeps it; a system absent here is kept whatever cores are available.", + "description": "Each platform system with the cores whose presence keeps it. A system absent here is kept whatever cores are available.", "type": "object", "additionalProperties": { "type": "array", @@ -268,7 +268,7 @@ "uniqueItems": true }, "alternatives": { - "description": "Cores claiming this destination behind the platform's own declaration, in the order the pack builder tries them; a narrowing that drops every declaring system takes the first whose cores remain.", + "description": "Cores claiming this destination behind the platform's own declaration, in the order the pack builder tries them. A narrowing that drops every declaring system takes the first whose cores remain.", "type": "array", "items": { "type": "object", @@ -298,14 +298,14 @@ } }, "case_variants": { - "description": "Files the folded list serves under another case; installed only where the target directory keeps case.", + "description": "Files the folded list serves under another case, installed only where the target directory keeps case.", "type": "array", "items": { "$ref": "#/$defs/file" } }, "data_directories": { - "description": "Data trees the pack carries, rebuilt by the installer from their source archive; each file is kept only when its sha1 matches.", + "description": "Data trees the pack carries, rebuilt by the installer from their source archive. Each file is kept only when its sha1 matches.", "type": "array", "items": { "type": "object", @@ -521,7 +521,7 @@ "type": "integer" }, "alternatives": { - "description": "Copies other cores read at this destination when they disagree on its content, in the order the pack builder tries them; a narrowing that drops the entry's cores takes the first whose cores remain.", + "description": "Copies other cores read at this destination when they disagree on its content, in the order the pack builder tries them. A narrowing that drops the entry's cores takes the first whose cores remain.", "type": "array", "items": { "type": "object", @@ -571,7 +571,7 @@ } }, "slot_choices": { - "description": "On a platform file a core's own source contradicts while the frontend only checks the path: the copy each core's presence puts there, in the order the pack builder settles the slot. A narrowing serves the first whose cores remain; one naming only cores, or none remaining, leaves `declared_choices`.", + "description": "On a platform file a core's own source contradicts while the frontend only checks the path: the copy each core's presence puts there, in the order the pack builder settles the slot. A narrowing serves the first whose cores remain. One naming only cores, or none remaining, leaves `declared_choices`.", "type": "array", "items": { "type": "object", @@ -617,7 +617,7 @@ } }, "declared_choices": { - "description": "The platform's own answer at the destination by the declaring systems that remain, in the order the pack builder takes the declarations; a narrowing serves the first whose systems remain.", + "description": "The platform's own answer at the destination by the declaring systems that remain, in the order the pack builder takes the declarations. A narrowing serves the first whose systems remain.", "type": "array", "minItems": 1, "items": { @@ -669,7 +669,7 @@ } }, "executable": { - "description": "The repository keeps the file executable; the installer gives it the execute bits the umask allows.", + "description": "The repository keeps the file executable, and the installer gives it the execute bits the umask allows.", "type": "boolean" }, "declared_in": { diff --git a/schemas/platform.schema.json b/schemas/platform.schema.json index 215cfa39..805e8794 100644 --- a/schemas/platform.schema.json +++ b/schemas/platform.schema.json @@ -297,7 +297,7 @@ }, "mirror_of": { "type": "string", - "description": "Native system whose entry this one repeats; the platform's own file does not carry the copy" + "description": "Native system whose entry this one repeats. The platform's own file does not carry the copy" }, "curated": { "type": "boolean", diff --git a/scripts/__init__.py b/scripts/__init__.py index 738bb8ea..0522e3b0 100644 --- a/scripts/__init__.py +++ b/scripts/__init__.py @@ -3,7 +3,7 @@ These modules are run as scripts (``python scripts/verify.py``), as modules (``python -m scripts.scraper.libretro_scraper``), and imported as a package by the tests and the type checker. The first form puts this directory on the path -itself; the other two do not, so importing the package adds it. Without that, +itself. The other two do not, so importing the package adds it. Without that, ``import scripts.common`` fails on the first sibling import it reaches, and every absolute import between siblings would have to be rewritten to be relative -a change that would break running a script directly. diff --git a/scripts/auto_fetch.py b/scripts/auto_fetch.py index 9fd93b9e..93434757 100644 --- a/scripts/auto_fetch.py +++ b/scripts/auto_fetch.py @@ -123,7 +123,7 @@ def _accepted(entry: dict, field: str) -> set[str]: """Every value an entry accepts for a hash field. A profile lists several revisions as a YAML list (daedalusx64's - n64.psh), a platform as a comma-separated string; read as one value, + n64.psh), a platform as a comma-separated string. Read as one value, the list stopped the run with an unhashable-type error. """ value = entry.get(field) @@ -264,7 +264,7 @@ def step4_search_archive_org(entry: dict) -> bytes | None: sha1s = sorted(_accepted(entry, "sha1")) if not sha1s: return None - # Each accepted revision is a query of its own; archive.org matches one. + # Each accepted revision is a query of its own: archive.org matches one. sha1 = " OR ".join(f"sha1:{value}" for value in sha1s) search_url = ( diff --git a/scripts/check_buildbot_system.py b/scripts/check_buildbot_system.py index bcd3b133..9035aeda 100644 --- a/scripts/check_buildbot_system.py +++ b/scripts/check_buildbot_system.py @@ -153,7 +153,7 @@ def print_report(report: dict) -> None: def update_changed(report: dict) -> list[str]: - """Refresh entries that have changed; the keys whose refresh failed.""" + """Refresh entries that have changed and return the keys whose refresh failed.""" failed: list[str] = [] for e in report.get("entries", []): if e["status"] == "UPDATED" and e.get("key"): diff --git a/scripts/check_freshness.py b/scripts/check_freshness.py index cc2d059e..ed7cc519 100644 --- a/scripts/check_freshness.py +++ b/scripts/check_freshness.py @@ -565,7 +565,7 @@ def _unresolved_findings(platform: str, missing: dict[str, list[str]]) -> list[F """One row per platform: the names its targets list that no profile claims. A buildbot name without a profile is a core the target filter cannot - see; a platform's own emulator id without one is an emulator nobody has + see, and a platform's own emulator id without one is an emulator nobody has profiled yet. Both are actionable, so both are listed, but as one row so the backlog does not bury the day's changes. """ @@ -702,7 +702,7 @@ def check_data(offline: bool) -> list[Finding]: def _check_buildbot_system() -> Finding: """The buildbot's system directory against what _data_dirs.yml tracks. - The registry entries are refreshed above; an asset published since, or + The registry entries are refreshed above. An asset published since, or one the buildbot no longer serves, is only seen by reading its .index. """ import check_buildbot_system # noqa: PLC0415 @@ -1030,7 +1030,7 @@ def check_ci(cache_dir: str, offline: bool) -> list[Finding]: def _check_installer_pins() -> Finding: - """The bootstraps pin install.py by SHA-256; a stale pin refuses every install.""" + """The bootstraps pin install.py by SHA-256, so a stale pin refuses every install.""" digest = hashlib.sha256((REPO_ROOT / "install.py").read_bytes()).hexdigest() stale = [] for name in INSTALLERS: @@ -1084,7 +1084,7 @@ def check_profiles(run: bool, offline: bool) -> list[Finding]: def summarize_profile_sync(report: object) -> list[Finding]: """One row per profile with something to look at, from profile_sync's JSON. - The JSON carries the ref verdicts and the pin against the tip; a profile + The JSON carries the ref verdicts and the pin against the tip. A profile whose refs need review is stale, one the forge could not serve is unknown, and one whose upstream moved while every ref still anchors is reported as such without being counted as stale. diff --git a/scripts/check_release.py b/scripts/check_release.py index d43e2283..a3711553 100644 --- a/scripts/check_release.py +++ b/scripts/check_release.py @@ -160,7 +160,7 @@ def main() -> int: ) parser.add_argument( "--sums", metavar="FILE", - help=f"local {SUMS} the packs were listed in; its copy and signature on " + help=f"local {SUMS} the packs were listed in. Its copy and signature on " f"the release must be these files (default: the list attached to the release)", ) parser.add_argument("--json", action="store_true", help="JSON output") @@ -169,7 +169,7 @@ def main() -> int: record = load_record(args.record) tag = args.tag or record.get("tag") if not tag: - print(f"ERROR: {args.record} names no tag; pass --tag", file=sys.stderr) + print(f"ERROR: {args.record} names no tag, pass --tag", file=sys.stderr) return 2 try: assets, draft = fetch_assets(tag) diff --git a/scripts/check_release_assets.py b/scripts/check_release_assets.py index a99dd776..84ef4463 100644 --- a/scripts/check_release_assets.py +++ b/scripts/check_release_assets.py @@ -68,7 +68,7 @@ def compare( against the collection's: a dump rebuilt at its old size and never re-uploaded was invisible to a size comparison. - *registered* is every path .gitignore lists; an asset name depends on + *registered* is every path .gitignore lists. An asset name depends on which other paths share its basename, so it defaults to *expected* only when the caller has nothing wider. A release description that no longer matches what render_notes() would write is a finding of its own: the @@ -182,8 +182,8 @@ def render_notes( """The release page, from what the release actually serves. Every asset gets one row. A file the database indexes carries its - database SHA1; a data-directory bundle carries the hash of its cached - copy when one exists; anything else is listed apart with its size only, + database SHA1, a data-directory bundle carries the hash of its cached + copy when one exists, and anything else is listed apart with its size only, so the page never vouches for bytes nobody indexed. Descriptions and sections already written by hand are kept by name. """ diff --git a/scripts/common.py b/scripts/common.py index 41df23f8..50c1174e 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -147,7 +147,7 @@ def held_adler32_pair(file_entry: dict, db: dict) -> str | None: Dolphin hashes dsp_rom.bin and dsp_coef.bin together and warns on any combination outside its table: two files each accepted alone can still be a pair it refuses. ``adler32_pairs`` lists the accepted pairs, the - entry's own value first, in the code's table order; both members walk + entry's own value first, in the code's table order. Both members walk the same pairs over the same collection, so they settle on one pair. None when the entry declares no pair or none is held whole. """ @@ -195,7 +195,7 @@ def adler32_fits(file_entry: dict, path: str, db: dict | None = None) -> bool: def size_fits(file_entry: dict, candidate_size: int) -> bool: """Whether a size is one the entry declares. - ``size`` is an exact size or the list of sizes the code accepts; it + ``size`` is an exact size or the list of sizes the code accepts, and it outranks a ``min_size``/``max_size`` range. Nothing declared fits all. """ declared = file_entry.get("size") @@ -265,8 +265,8 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") - # Resolve shared group includes shared_path = os.path.join(platforms_dir, "_shared.yml") - # Merge metadata from _registry.yml. The registry is our curated source; - # the scraped YAML may be incomplete (missing cores, metadata fields). + # Merge metadata from _registry.yml. The registry is our curated source, + # while the scraped YAML may be incomplete (missing cores, metadata fields). # Registry fields supplement (not replace) the scraped config. registry_path = os.path.join(platforms_dir, "_registry.yml") if os.path.exists(registry_path): @@ -281,7 +281,7 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") - for depth, name in enumerate(chain): reg_entry = reg.get("platforms", {}).get(name, {}) - # Merge cores (union for lists, override for all_libretro); a + # Merge cores (union for lists, override for all_libretro), a # parent's only where the platform names none. reg_cores = reg_entry.get("cores") if reg_cores is not None and (depth == 0 or "cores" not in config): @@ -452,9 +452,9 @@ def suggest_names(typed: list[str], available: list[str], listing_flag: str) -> def platform_arg(value: str) -> str: """--platform as typed, mapped to the registry's slug when it names one. - The site and the pack names say RetroArch and MiSTer FPGA; verify and + The site and the pack names say RetroArch and MiSTer FPGA, but verify and generate_pack refused both while install.py took them. Letters and - digits decide, as for pack names; anything else reaches require_platform + digits decide, as for pack names. Anything else reaches require_platform unchanged and gets its suggestion. """ key = re.sub(r"[^a-z0-9]", "", value.lower()) @@ -993,7 +993,7 @@ def _member_held(member: dict, crcs: frozenset[str], names: frozenset[str]) -> b def _holding_members(paths: list[str], members: list[dict]) -> list[str]: """The same-named archives holding the most required members, then the most members. - FBNeo reads neocd.bin and 000-lo.lo inside neocdz.zip; the primary copy, + FBNeo reads neocd.bin and 000-lo.lo inside neocdz.zip. The primary copy, a set without 000-lo.lo, won on the name while a variant held both. """ def held(path: str) -> tuple[int, int]: @@ -1034,7 +1034,7 @@ def _by_affinity(paths: list[str], file_entry: dict, dest_hint: str) -> list[str TheXTech coin.ogg for Syobon Action, a Hurrican sound for ARMSX2, the 1 MB CM-32L PCM ROM for ScummVM's 512 KB MT32_PCM.ROM. A size the entry declares orders the candidates first (ordering rejects nothing, so an - unvalidated size keeps its informative status); then the destination's + unvalidated size keeps its informative status). Then the destination's directories and the profile that asks name where its own copy lives. The order is otherwise kept. """ @@ -1210,7 +1210,7 @@ def resolve_local_file( return path, status # 1c. CRC32 lookup, only when no stronger hash is declared. A declared - # size confirms it when available; a handful of emulators validate CRC32 + # size confirms it when available. A handful of emulators validate CRC32 # alone, so those entries retain the same (weaker) evidence as the core. if ( crc_candidates @@ -1287,11 +1287,11 @@ def resolve_local_file( # shortened tail can be claimed by several emulators shipping the same # asset tree, and it then proves nothing: skip it. The full tail can be # claimed twice as well, one storing it at the root of its own - # directory and one nested deeper; there the file whose path carries + # directory and one nested deeper. There the file whose path carries # the least on top of the destination is the one that IS the # destination. # The descent drops at most one leading segment. A destination and the - # tree differ by the wrapper directory at most; beyond that the tail + # tree differ by the wrapper directory at most. Beyond that the tail # stops describing this file and starts describing whichever emulator # happens to store the same asset tree. hint_parts = dest_hint.split("/") @@ -1418,7 +1418,7 @@ def resolve_local_file( # set aside: the name says nothing about this profile's file, # and a data directory it reads may hold it. Dolphin got # Dolphin-MMJR's codehandler.bin while data/dolphin-sys held - # its own; blueMSX got the 16 KB RS232.ROM once msx-emu's + # its own, and blueMSX got the 16 KB RS232.ROM once msx-emu's # 8 KB copy was set aside, while data/bluemsx held its own, # and MSX2P.ROM of another dump once only msx-emu answered # the exact casing. @@ -1649,7 +1649,7 @@ def profiles_for_systems( def entry_serves_systems(entry: dict, profile: dict, system_ids: list[str]) -> bool: """Whether a profile entry belongs to one of the systems, spelled either way. - The entry's own `system:` decides; one without it serves every system + The entry's own `system:` decides. One without it serves every system of its profile, the rule a platform pack applies to core extras. """ own = entry.get("system") @@ -1990,7 +1990,7 @@ def expand_directory_entries( ) -> list[dict]: """Replace each ``type: directory`` entry by the files held under it. - A profile declares the directory its code walks; what a pack can carry + A profile declares the directory its code walks, but what a pack can carry is the files. Each member keeps the entry's fields and is pinned to the content the collection holds at that destination. A directory nothing answers is kept as declared, one gap, and a member the profile also @@ -2277,7 +2277,7 @@ def designated_profiles(profiles: dict[str, dict], names: set[str]) -> set[str]: """The profiles a list of upstream core names designates. The buildbot and es_systems name cores their own way (`mednafen_psx` for - beetle_psx); a profile's `cores:` lists those names. A name no profile + beetle_psx), and a profile's `cores:` lists those names. A name no profile claims stands for itself. """ index = upstream_profile_index(profiles, include_aliases=True) @@ -2385,7 +2385,7 @@ def platform_declarations( A name alone does not say which file a declaration is: RetroArch declares galaksija/ROM1.BIN, a 4 KiB ROM, and DOSBox reads a 32 KiB SC-55 ROM1.BIN. The size, from the platform entry or else from the file its hash names, - tells a declaration of the same file from a same-named one; None stands + tells a declaration of the same file from a same-named one. None stands for a size nobody knows. The slot is the declared destination, sanitized and case-folded, relative to the directory core files go to: RetroDECK writes bios/ in front of every destination, the others put it in diff --git a/scripts/crypto_verify.py b/scripts/crypto_verify.py index 794676a0..a9b5312e 100644 --- a/scripts/crypto_verify.py +++ b/scripts/crypto_verify.py @@ -136,7 +136,7 @@ def _rsa_verify_pkcs1v15_sha256( # AES-128-CBC decryption, standard library only. The build promises stdlib + -# pyyaml; a contributor without cryptography, pycryptodome or openssl on PATH +# pyyaml, and a contributor without cryptography, pycryptodome or openssl on PATH # got a RuntimeError from verify.py on otp.bin. 256 bytes need no speed. diff --git a/scripts/dedup.py b/scripts/dedup.py index 78c2a903..bde06516 100644 --- a/scripts/dedup.py +++ b/scripts/dedup.py @@ -196,7 +196,7 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict: previous = {} except json.JSONDecodeError as e: raise SystemExit( - f"{clone_path} is not valid JSON ({e}); restore it from git " + f"{clone_path} is not valid JSON ({e}). Restore it from git " "before deduplicating again" ) from e diff --git a/scripts/derivations.py b/scripts/derivations.py index e3b5e30d..4a71b91e 100644 --- a/scripts/derivations.py +++ b/scripts/derivations.py @@ -1,11 +1,11 @@ """Catalog entries whose bytes a held dump already contains. -A catalog lists chips as they come off the board; a collection often holds +A catalog lists chips as they come off the board, while a collection often holds the image an emulator reads. The Amiga 3.1 Kickstart pair 391773/391774 is -the high and low 16-bit words of amiga-os-310-a1200.rom, byte-swapped; the +the high and low 16-bit words of amiga-os-310-a1200.rom, byte-swapped, and the TOSEC "Basic V7" is basiclo and basichi end to end. Listed as missing, they send a maintainer after files that are already here. Each transform below is -one the source boards use; a match is by sha1, never by size or name. +one the source boards use. A match is by sha1, never by size or name. """ from __future__ import annotations @@ -172,7 +172,7 @@ def _held_sources(db: dict) -> list[dict]: def derivable(entries: Iterable[dict], db: dict) -> dict[str, dict]: """Missing sha1 to the held file or member and the transform that - produce its bytes; archives stay open for the whole pass.""" + produce its bytes. Archives stay open for the whole pass.""" archives: dict[str, zipfile.ZipFile] = {} try: return _derivable(entries, db, archives) diff --git a/scripts/download.py b/scripts/download.py index 1097e295..8129cd79 100644 --- a/scripts/download.py +++ b/scripts/download.py @@ -226,7 +226,7 @@ def download_file( else: print(f" {label}{downloaded:,} bytes") if expected_size and downloaded != expected_size: - raise ValueError(f"downloaded {downloaded} bytes; expected {expected_size}") + raise ValueError(f"downloaded {downloaded} bytes, expected {expected_size}") def join_volumes(parts: list[Path], dest: Path) -> None: @@ -263,7 +263,7 @@ def _check(archive: Path, checksums: dict[str, str]) -> None: print( f"Error: checksum mismatch for {archive.name}\n" f" expected {expected}\n got {actual}\n" - "Download the parts again; a truncated part gives this.", + "Download the parts again: a truncated part gives this.", file=sys.stderr, ) sys.exit(1) diff --git a/scripts/download.sh b/scripts/download.sh index 3a6b15ee..c6e06e14 100755 --- a/scripts/download.sh +++ b/scripts/download.sh @@ -209,7 +209,7 @@ verify_checksum() { echo "Error: checksum mismatch for ${archive}" >&2 echo " expected ${expected}" >&2 echo " got ${actual}" >&2 - echo "Download the parts again; a truncated part gives this." >&2 + echo "Download the parts again: a truncated part gives this." >&2 exit 1 fi } diff --git a/scripts/dumpcatalog.py b/scripts/dumpcatalog.py index 2a6d469e..9eb76661 100644 --- a/scripts/dumpcatalog.py +++ b/scripts/dumpcatalog.py @@ -35,7 +35,7 @@ def load_provenance_snapshots(provenance_dir: str = DEFAULT_PROVENANCE_DIR) -> d def build_provenance_index(snapshots: dict) -> dict: """Index snapshot entries by sha1 and by (md5, size) per source. - First entry wins on hash collisions within a source; entries are + First entry wins on hash collisions within a source. Entries are pre-sorted at snapshot write time so the outcome is deterministic. """ index = {} @@ -95,7 +95,7 @@ def build_snapshot( def write_snapshot(path: str, snapshot: dict) -> bool: - """Write a snapshot; timestamps alone never count as a change.""" + """Write a snapshot. Timestamps alone never count as a change.""" return write_if_changed(path, json.dumps(snapshot, indent=2) + "\n") diff --git a/scripts/export_native.py b/scripts/export_native.py index 93800bf8..1fb1ce32 100644 --- a/scripts/export_native.py +++ b/scripts/export_native.py @@ -170,7 +170,7 @@ def pinned_base(wanted: dict[str, str], scraped: dict | None) -> str: def _raw_url(url: str) -> str: - """A GitHub blob page names a revision but serves HTML; raw serves bytes.""" + """A GitHub blob page names a revision but serves HTML, raw serves bytes.""" marker = "/blob/" if url.startswith("https://github.com/") and marker in url: owner_repo, _, path = url[len("https://github.com/") :].partition(marker) @@ -203,7 +203,7 @@ _RAW_GITHUB = re.compile(r"^https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/ def _at_revision(url: str, base: str) -> str: - """A file of the pinned repository, read at the pinned revision; empty + """A file of the pinned repository, read at the pinned revision, empty when the URL is not a raw GitHub URL of that repository. ROCKNIX's checker sits in packages/rocknix/, the emulators it names in diff --git a/scripts/exporter/baseline.py b/scripts/exporter/baseline.py index 15305c42..9044afb0 100644 --- a/scripts/exporter/baseline.py +++ b/scripts/exporter/baseline.py @@ -66,7 +66,7 @@ class NativeFile: # An addition filed under our own slug: the platform names no such system. foreign_system: bool = False # For an addition, each core that wants it as (runs standalone, name the - # platform gives it); empty when no core the platform runs is named. + # platform gives it), empty when no core the platform runs is named. runners: list[tuple[bool, str]] = field(default_factory=list) @property @@ -103,7 +103,7 @@ class NativeFile: def hashes(self, field_name: str) -> list[str]: """Accepted values for a hash, truth first when it has an opinion. - The truth is read from the emulator's source; the platform list is a + The truth is read from the emulator's source. The platform list is a secondary source. When both speak and disagree, the truth decides and the divergence is recorded, never silently merged: an emulator that rejects a file will reject it whatever the platform declares. @@ -134,7 +134,7 @@ class NativeFile: with the v2.0 crc (the truth's first) beside the v2.1 md5 and sha1 (System.dat's), a record no file satisfies. When the two sides agree on the dump, the platform's record is kept whole, its value - chosen among those the truth accepts; a field only the truth names + chosen among those the truth accepts. A field only the truth names is written when it names one value, which is then that dump's. """ source = self._identity_source() @@ -526,7 +526,7 @@ def _attach_runners(systems: dict[str, NativeSystem], scraped: dict | None) -> N The platform lists its cores by its own names (Batocera's `mednafen_psx`, Recalbox's `mednafen_psx`), our truth by profile key - (`beetle_psx`); a profile's `cores:` holds the names it answers to. + (`beetle_psx`), and a profile's `cores:` holds the names it answers to. The build a platform runs an emulator as decides the runner. """ if not scraped: diff --git a/scripts/exporter/batocera_exporter.py b/scripts/exporter/batocera_exporter.py index e5e2ad90..a7a2a51c 100644 --- a/scripts/exporter/batocera_exporter.py +++ b/scripts/exporter/batocera_exporter.py @@ -26,7 +26,7 @@ _INDENT = " " * 4 class Exporter(BaseExporter): """Write Batocera's batocera-systems, corrected.""" - # checkBios compares one md5 for a plain file; altmd5 is read only for + # checkBios compares one md5 for a plain file. altmd5 is read only for # a zippedFile: retrodream's boot.bin written with the first of four # md5 refused the three other dumps the core accepts. SINGLE_HASH_FIELD = "md5" @@ -130,7 +130,7 @@ class Exporter(BaseExporter): @staticmethod def needs_original() -> bool: - # The data block is a fraction of the file; the rest is the checker. + # The data block is a fraction of the file, the rest is the checker. return True def _bios_files(self, files: list[NativeFile], before: dict | None = None) -> str: @@ -163,7 +163,7 @@ class Exporter(BaseExporter): return parts def _item_runners(self, fe: NativeFile) -> list[list[str] | None]: - """One item per runner an addition names; None keeps the original's.""" + """One item per runner an addition names. None keeps the original's.""" if fe.platform is not None: return [None] pairs = self._addition_keys(fe) or [] @@ -213,7 +213,7 @@ class Exporter(BaseExporter): Rewriting an entry as one line would drop them, and a note like "ideally - 94bc50..." is the only record of why a hash is blank. - A comment on its own line belongs to the file below it; a comment at + A comment on its own line belongs to the file below it, a comment at the end of a line belongs to the file on it. """ trailing: dict[str, str] = {} diff --git a/scripts/exporter/bizhawk_exporter.py b/scripts/exporter/bizhawk_exporter.py index 22401be3..8806deed 100644 --- a/scripts/exporter/bizhawk_exporter.py +++ b/scripts/exporter/bizhawk_exporter.py @@ -53,7 +53,7 @@ class Exporter(BaseExporter): """No hash or size is written, so no correction is delivered. Every call holding a hash holds one BizHawk declares, the authority - for its cores; the calls without one are SHA1Checksum.Dummy, a + for its cores. The calls without one are SHA1Checksum.Dummy, a per-console dump (DSi firmware, NAND) BizHawk leaves unhashed on purpose. The rewrite this exporter had could only ever fire on a same-named call of another system, giving it the wrong system's hash. diff --git a/scripts/exporter/emudeck_exporter.py b/scripts/exporter/emudeck_exporter.py index 96a07699..83d3258f 100644 --- a/scripts/exporter/emudeck_exporter.py +++ b/scripts/exporter/emudeck_exporter.py @@ -98,7 +98,7 @@ class Exporter(BaseExporter): def _expected_md5s( self, systems: dict[str, NativeSystem], name: str, system_id: str ) -> list[str]: - """What a check must now hold; a refused rewrite keeps EmuDeck's own array.""" + """What a check must now hold. A refused rewrite keeps EmuDeck's own array.""" if name in getattr(self, "_withdrawn", {}): return [] return self._md5s(systems, system_id) @@ -187,7 +187,7 @@ class Exporter(BaseExporter): # it would stop passing the check. A rewrite that withdraws one # is refused and reported instead. # A correction replaces the value it corrects, which is not a - # withdrawal; any other value missing from ours would be. + # withdrawal, but any other value missing from ours would be. withdrawn = theirs - set(md5s) - self._corrected_away(systems, system_id) if withdrawn: self._withdrawn.setdefault(name, set()).update(withdrawn) diff --git a/scripts/exporter/recalbox_exporter.py b/scripts/exporter/recalbox_exporter.py index edb2550e..47d53768 100644 --- a/scripts/exporter/recalbox_exporter.py +++ b/scripts/exporter/recalbox_exporter.py @@ -111,7 +111,7 @@ class Exporter(BaseExporter): @classmethod def writable(cls, fe: NativeFile, require: str = "") -> bool: - """es_bios.xsd makes md5 and core required; without them, no element. + """es_bios.xsd makes md5 and core required: without them, no element. An entry Recalbox already ships has both, so this only ever gates what we would be adding. diff --git a/scripts/exporter/retrodeck_exporter.py b/scripts/exporter/retrodeck_exporter.py index 5af216b6..9794781c 100644 --- a/scripts/exporter/retrodeck_exporter.py +++ b/scripts/exporter/retrodeck_exporter.py @@ -79,7 +79,7 @@ class Exporter(BaseExporter): @staticmethod def needs_original() -> bool: - # A manifest is mostly presets and launch configuration; rebuilding + # A manifest is mostly presets and launch configuration, so rebuilding # one from BIOS data alone would throw the component away. return True @@ -104,7 +104,7 @@ class Exporter(BaseExporter): A component is one emulator's manifest, and only the platform's entries name it. A system whose entries all sit in one component - takes the addition there; one spread over several, or with none of + takes the addition there. One spread over several, or with none of its own, cannot say which manifest is meant, and the addition is left out and counted as such. """ @@ -197,7 +197,7 @@ class Exporter(BaseExporter): additions: list[OrderedDict] | None = None, appended: set[tuple[str, str]] | None = None, ) -> list[OrderedDict]: - """Correct the component's own list; never replace it. + """Correct the component's own list, never replace it. Assigning our entries wholesale dropped every file RetroDECK declares that our model does not carry -- 177 of them across the components. diff --git a/scripts/exporter/retropie_exporter.py b/scripts/exporter/retropie_exporter.py index 120f6fd2..f9486ed0 100644 --- a/scripts/exporter/retropie_exporter.py +++ b/scripts/exporter/retropie_exporter.py @@ -65,7 +65,7 @@ class Exporter(BaseExporter): @staticmethod def carries() -> frozenset[str]: - # The help names files; it states no hash and no requirement flag. + # The help names files. It states no hash and no requirement flag. return frozenset({"name"}) @staticmethod @@ -181,7 +181,7 @@ class Exporter(BaseExporter): Someone reading the sentence copies the files in the order it gives, so the one the emulator prefers is named first. The model - already holds them in that order; this only removes the duplicates + already holds them in that order, so this only removes the duplicates a name can pick up from several cores. """ names: list[str] = [] diff --git a/scripts/exporter/rocknix_exporter.py b/scripts/exporter/rocknix_exporter.py index 95119bf3..a5f61ad4 100644 --- a/scripts/exporter/rocknix_exporter.py +++ b/scripts/exporter/rocknix_exporter.py @@ -37,7 +37,7 @@ class Exporter(BatoceraExporter): def _runner_pair(self, runner: tuple[bool, str]) -> tuple[str, str | None] | None: """ROCKNIX registers libretro cores under `retroarch` and each standalone under its own emulator (`azahar azahar-sa`), in the - emulators package; the `libretro` Batocera writes names nothing + emulators package. The `libretro` Batocera writes names nothing there.""" _standalone, name = runner emulator = self._emulator_of.get(name) diff --git a/scripts/exporter/romm_exporter.py b/scripts/exporter/romm_exporter.py index 8c37f5e8..d6427d7d 100644 --- a/scripts/exporter/romm_exporter.py +++ b/scripts/exporter/romm_exporter.py @@ -69,7 +69,7 @@ class Exporter(BaseExporter): return native_id in SLUG_MAP def writable(self, fe: NativeFile, require: str = "") -> bool: # noqa: ARG002 - """What RomM already ships stays; the conditions gate additions. + """What RomM already ships stays. The conditions gate additions. An entry of theirs that could never verify is still theirs, and the round trip is not the place to decide otherwise. An addition whose @@ -129,10 +129,10 @@ class Exporter(BaseExporter): if not self.writable(fe): continue key = f"{system.native_id}:{fe.name}" - # Their entry keeps its fields and their order; ours fill in. + # Their entry keeps its fields and their order, ours fill in. entry: OrderedDict[str, str] = OrderedDict(output.get(key, {})) # The fixture states every value as a string, size included. - # Where the model settles no size, RomM's own value stands; + # Where the model settles no size, RomM's own value stands. # str(None) wrote "None", and RomM's int() on it raised. size = fe.size() if size is None and fe.platform is not None: diff --git a/scripts/fileless_audit.py b/scripts/fileless_audit.py index 8c181e42..f91e58cd 100644 --- a/scripts/fileless_audit.py +++ b/scripts/fileless_audit.py @@ -9,7 +9,7 @@ required or loaded by this core" while its source had grown eleven filenames read from the system directory. The signal is the request for a directory to read from. A libretro core asks -the frontend with RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY; other shapes ask the +the frontend with RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY. Other shapes ask the environment or build a path from a home directory. Finding one in a file the profile itself cites does not prove a file is loaded, and this reports rather than concludes: it names the profiles worth a reading, so the other hundred and @@ -64,12 +64,12 @@ def audit( return None if str(document.get("exclusion_note") or "").strip(): # Someone read this one and wrote down why nothing is declared. The - # check exists to find the profiles nobody has answered yet; an + # check exists to find the profiles nobody has answered yet, and an # answer that goes stale shows up as a drifting ref instead. return None if document.get("data_directories"): # The load is declared, as a directory rather than a file. dinothawr - # reads system_dir/dinothawr/ and says so there; that is coverage, not + # reads system_dir/dinothawr/ and says so there. That is coverage, not # an assertion waiting to age. return None views = select_views(document, cache_dir, offline) @@ -117,7 +117,7 @@ def main() -> None: ) parser.add_argument( "--offline", action="store_true", - help="read only what the cache holds; no network access", + help="read only what the cache holds, no network access", ) args = parser.parse_args() if args.all == bool(args.emulators): diff --git a/scripts/generate_db.py b/scripts/generate_db.py index 803cc494..828c85ca 100644 --- a/scripts/generate_db.py +++ b/scripts/generate_db.py @@ -273,7 +273,7 @@ def _restore(cached: str, path: str) -> None: """Copy a fetched asset to its registered path, whole or not at all. An interrupted copy at the final name is a truncated file the next scan - hashes and publishes; a scratch beside it is swapped in only once full. + hashes and publishes. A scratch beside it is swapped in only once full. """ directory = os.path.dirname(path) os.makedirs(directory, exist_ok=True) @@ -314,7 +314,7 @@ def _preserve_large_file_entries(files: dict, db_path: str) -> int: # checkout without the release assets would drop every entry they # hold, and the manifests regenerated from it would omit them. raise SystemExit( - f"{db_path} is not valid JSON ({e}); restore it from git " + f"{db_path} is not valid JSON ({e}). Restore it from git " "or regenerate it on a checkout holding the release assets before " "scanning again" ) from e diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index e85d9efe..121544bf 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -261,7 +261,7 @@ def _bounded_join(parts: list[str], keys: list[str]) -> str: """Parts joined while they fit, else the first, a count and a digest. Thirty systems joined made a 261-byte file name and the ZIP could not - be opened; the digest keeps two different selections apart. The joiner + be opened. The digest keeps two different selections apart. The joiner is one no part holds: with "_", sega-dreamcast + arcade and sega-dreamcast-arcade both named Dreamcast_Arcade, and the second build replaced the first. @@ -279,7 +279,7 @@ _UNSAFE_IN_NAME = re.compile(r'[/\\:*?"<>|]') def _name_part(text: str, space: str = "") -> str: """A display name made safe to stand in a file name. - 'FinalBurn Neo (CPS-1/CPS-2)' named a directory that did not exist; a + 'FinalBurn Neo (CPS-1/CPS-2)' named a directory that did not exist, and a Windows user cannot write ':' or '?' either. """ return _UNSAFE_IN_NAME.sub("-", text.replace(" ", space)) @@ -290,8 +290,8 @@ def _platform_pack_stem( ) -> str: """Platform part of a pack name, version included. - A group of identical platforms shares one pack named after all of them; - the builder and --verify-packs both read the name from here. + A group of identical platforms shares one pack named after all of them, + and the builder and --verify-packs both read the name from here. """ rep_cfg = load_platform_config(representative, platforms_dir) version = rep_cfg.get("version", rep_cfg.get("dat_version", "")) @@ -602,7 +602,7 @@ def _matches_an_alternative(fe: dict, local_path: str, profiles: dict) -> bool: """Whether the copy is another version the same profile accepts there. A profile lists every version its code takes under one name (each GRP - of Raze's table, eduke32's demo and retail NWINTER.GRP); the extra + of Raze's table, eduke32's demo and retail NWINTER.GRP). The extra carries the first, and the held copy matching a sibling is no mismatch. """ profile = profiles.get(fe.get("source_profile") or "", {}) @@ -660,7 +660,7 @@ def generate_pack( if zip_contents is None: zip_contents = {} if emu_profiles is None: - # The pipeline always passes them; a caller that does not must get the + # The pipeline always passes them, but a caller that does not must get the # same pack, not one built without validation, slots or agnostic cores. emu_profiles = load_emulator_profiles(emulators_dir) @@ -913,7 +913,7 @@ def generate_pack( if status == "not_found": # A filename-agnostic core takes any image of its system, - # renamed; only an existence frontend accepts that. + # renamed. Only an existence frontend accepts that. files_db = db.get("files", {}) agnostic_path = None agnostic_resolved = False @@ -982,7 +982,7 @@ def generate_pack( existence_discrepancy(file_entry, local_path, platform_display), ) if file_status.get(dedup_key) == "missing": - # An earlier declaration of this path found nothing; this + # An earlier declaration of this path found nothing, and this # one fills it, as verify counts it. del file_status[dedup_key] file_reasons.pop(dedup_key, None) @@ -1105,7 +1105,7 @@ def generate_pack( ): # The core's declared hash comes from its source, the local dump # is what the collection holds. Shipping it keeps the emulator - # working when the code never reads the hash; the divergence is + # working when the code never reads the hash, and the divergence is # reported so it can be resolved at the profile or the dump. # file_status tracks platform declarations only, so the report # goes to its own list and never moves the pack's own count. @@ -1315,7 +1315,7 @@ def _pack_data_tree( ) -> int: """Write one data directory into an emulator pack, under its shared lock. - A refresh swaps the tree by rename; without the lock a walk half done + A refresh swaps the tree by rename. Without the lock a walk half done read the old tree and wrote files of the new one. ``packed_at`` records each member, so a later profile asking for the same bytes there is served rather than reported missing. @@ -1349,8 +1349,8 @@ def _same_bytes(path: str, other: str | None) -> bool: return compute_hashes(path)["sha1"] == compute_hashes(other)["sha1"] -# A file name holds 255 bytes on every filesystem a pack is written to; -# the margin leaves room for the split part suffix and a scratch prefix. +# A file name holds 255 bytes on every filesystem a pack is written to, +# and the margin leaves room for the split part suffix and a scratch prefix. MAX_PACK_NAME_BYTES = 200 @@ -1499,7 +1499,7 @@ def generate_emulator_pack( taken = archive_dest.lower() in seen_lower if taken or _has_path_conflict(archive_dest, seen_destinations, seen_parents): # Another profile's file holds this path. The same archive - # asked for twice is served; anything else leaves this + # asked for twice is served. Anything else leaves this # profile without its archive, which used to pass in # silence: a neocdz.zip lacking 000-lo.lo shipped as the # one the second core needs. @@ -1606,8 +1606,8 @@ def generate_emulator_pack( chosen = (fe, better, None) break if status == "hash_mismatch": - # Not a check the core runs, so the file still serves; - # it is not the dump the profile documents. + # Not a check the core runs, so the file still serves, + # but it is not the dump the profile documents. fallback = fallback or (fe, local_path, "mismatch") continue chosen = (fe, local_path, None) @@ -1870,7 +1870,7 @@ def _group_systems_by_manufacturer( def _extras_for_systems(extras: list[dict], system_ids: list[str]) -> list[dict]: """Core extras owned by one of the given systems. - Extras carry their profile/system identity directly; display labels are + Extras carry their profile/system identity directly. Display labels are presentation only and must never drive routing. """ from common import _norm_system_id @@ -1915,7 +1915,7 @@ def generate_split_packs( source, regions, target_name, one_per_slot, required_only ) ) - # Two groupings write different files; without the tag they accumulate in + # Two groupings write different files. Without the tag they accumulate in # one directory under one SHA256SUMS.txt. group_tag = "" if group_by == "system" else f"_By{group_by.title()}" # The parts carry the version, so the directory does too: a rescrape that @@ -2004,7 +2004,7 @@ def generate_split_packs( def _entry_for_file(candidates: list[dict], held: dict) -> dict: """The declaration a held file answers when several share its name. - BBKEmu declares 8.BIN once per model; the last one won, and the A4980 + BBKEmu declares 8.BIN once per model. The last one won, and the A4980 dump went to the A4988 folder. The declared hash decides, then the destination the collection's own path ends with, then the last one. """ @@ -2547,7 +2547,7 @@ def _run_verify_packs(args: argparse.Namespace) -> None: continue tc = _target_cores_for(platform_name, args.target, args.platforms_dir) # A group pack and a pack built for the platform alone can both be - # present; each one is a pack of this platform. + # present, and each one is a pack of this platform. for pack_name in found: zip_path = os.path.join(args.output_dir, pack_name) result = verify_pack_against_platform( @@ -2612,7 +2612,7 @@ def _skip_empty_truth( tc: set[str] | None, failed: list[str], ) -> bool: - """Leave out a truth pack that would be empty; refuse it when asked for.""" + """Leave out a truth pack that would be empty, refuse it when asked for.""" if source != "truth" or not _truth_layer_is_empty( representative, args.platforms_dir, emu_profiles, tc ): @@ -2778,7 +2778,7 @@ def _run_platform_packs( ) all_ok = all_ok and ok if failed: - # Verification only sees the ZIPs that exist; a pack that was never + # Verification only sees the ZIPs that exist, so a pack that was never # written does not fail it. print(f"ERROR: no pack for {', '.join(sorted(set(failed)))}") sys.exit(1) @@ -2830,7 +2830,7 @@ def _refuse_refresh_data(args: argparse.Namespace, parser: argparse.ArgumentPars def _refuse_include_archived( args: argparse.Namespace, parser: argparse.ArgumentParser ) -> None: - """Only --all chooses among registered platforms; every other mode names + """Only --all chooses among registered platforms. Every other mode names its own platform, emulator, system or hash.""" if args.include_archived and not args.all: parser.error("--include-archived requires --all") @@ -3079,8 +3079,8 @@ def _main(held: contextlib.ExitStack) -> None: # Quick-exit modes: --verify-packs alone = verify existing packs only # Combined with --all-variants, generation runs first then verify if args.verify_packs and not args.all_variants: - # The check resolves core files against data/ like the build did; - # a refresh swapping a tree mid-check would judge another tree. + # The check resolves core files against data/ like the build did, + # and a refresh swapping a tree mid-check would judge another tree. hold_data_dirs(held, load_data_dir_registry(args.platforms_dir)) with _pack_output_lock(args.output_dir, exclusive=False): _run_verify_packs(args) @@ -3295,7 +3295,7 @@ def _registered(repo_root: str) -> frozenset[str]: def _is_release_asset(local_path: str, repo_root: str) -> bool: """Whether the installer fetches this file from the large-files release. - The repository serves every committed file from its raw URL; only the + The repository serves every committed file from its raw URL. Only the files kept out of git live as release assets, and .gitignore is the ledger of those. Size is not the criterion: a committed file over 50 MB is still served by the repository, and announcing it as a release asset @@ -3358,7 +3358,7 @@ def _placed_copies(copies: list[dict], dests: list[str]) -> list[dict]: aes_keys.txt at the root and Batocera prod.keys under switch/, so the installer looked for Citra/sysdata/aes_keys.txt, found nothing and copied nothing. `file` stays as written, since it also lays out a custom - emulator root; `source` says where the installed file is. + emulator root. `source` says where the installed file is. """ by_name: dict[str, list[str]] = {} for dest in dests: @@ -3408,7 +3408,7 @@ def _stable_hashes(local_path: str, db: dict) -> dict: hashes = compute_hashes(local_path, _MANIFEST_HASHES) raise RuntimeError( f"{local_path}: sha1 {hashes['sha1']} contradicts the database scan " - f"({expected}); rehash the file or regenerate database.json" + f"({expected}). Rehash the file or regenerate database.json" ) @@ -3455,7 +3455,7 @@ def _manifest_entry( if is_release_asset: entry["storage"] = "release" entry["release_asset"] = _release_asset_name(local_path, repo_root) - # The installer writes what it downloads with the umask's mode; a program + # The installer writes what it downloads with the umask's mode, but a program # (RetroDECK's pico8, vox) has to stay runnable. The git mode cannot say: # hundreds of MAME archives carry an execute bit nothing reads. if local_path and _is_program(local_path): @@ -3500,7 +3500,7 @@ def _attach_claims( one's copy. A claim joins the copy just before it when the bytes agree and starts an - alternative otherwise; it never joins an earlier copy, which would let it + alternative otherwise. It never joins an earlier copy, which would let it win over a core the builder tries first. Only a core's first claim can win: its later ones are reached only when that one is. A platform entry names no core, so its first claim always starts an alternative. @@ -3703,7 +3703,7 @@ def _manifest_core_entries( source_emu = fe.get("source_profile") or fe.get("source_emulator", "") - # Manifest dests are relative to base_destination; keep the inferred + # Manifest dests are relative to base_destination. Keep the inferred # extras prefix when it is an internal layout dir (RetroDECK bios/). manifest_dest = full_dest if base_dest and manifest_dest.startswith(f"{base_dest}/"): @@ -3755,7 +3755,7 @@ def _claim_platform_omission(held: dict | None, emulator: str) -> bool: """Record a core's claim on a destination the platform already omits. The platform's own omission stands while one of its declaring systems - does; a pack built without them falls to the first core claiming the + does. A pack built without them falls to the first core claiming the path, as for a file present. Overwriting the record lost the platform's claim: a target without that core dropped an omission its pack reports. """ @@ -3936,7 +3936,7 @@ def generate_manifest( # platform file, for the core claims a target build would fall back on. platform_entries: dict[str, tuple[dict, str, str]] = {} # Full destination -> the platform systems declaring it. A file's - # `systems` also names the systems whose cores read it there; a pack built + # `systems` also names the systems whose cores read it there. A pack built # for a target keeps the file only while a declaring system stays. declared_by: dict[str, set[str]] = {} seen_lower: set[str] = set() @@ -4000,11 +4000,11 @@ def generate_manifest( if source != "truth": # The same destination can be declared by more than one system, bare # in one and hash-constrained in another. The builder lets the - # constrained sibling claim it; without the same rule here the + # constrained sibling claim it. Without the same rule here the # manifest named whatever answered to the name, so the pack and the # installer disagreed about which file a destination means. # Decided among the declarations this manifest keeps, as the pack - # does; a manifest carries no data directories. + # does. A manifest carries no data directories. preferred_entries = _preferred_entries( pack_systems, db, bios_dir, base_dest, required_only, zip_contents, offline, @@ -4284,7 +4284,7 @@ def generate_manifest( # RetroArch also runs where case is kept: there Mesen-CE opens # bios.col and np2kai np2kai/2608_bd.wav, which the folded list # serves only as BIOS.col and 2608_BD.WAV. The installer adds these - # where the directory keeps case; the pack, extracted on Windows + # where the directory keeps case, while the pack, extracted on Windows # or macOS too, stays folded. kept = generate_manifest( platform_name, platforms_dir, db, bios_dir, registry_path, @@ -4313,7 +4313,7 @@ def _manifest_data_directories( The source archive and the rule that maps its members onto the tree (strip_components for a ZIP, source_path for a tarball, exclude) come - from _data_dirs.yml, the same refresh_data_dirs applies; every file + from _data_dirs.yml, the same refresh_data_dirs applies. Every file carries the sha1 and size the cache holds, so a member the source changed since is refused rather than installed. """ @@ -4362,7 +4362,7 @@ def _manifest_core_index( buildbot does, and a file names the profile that reads it: `core_names` gives each profile the other names it goes by. `system_cores` gives each platform system the cores whose presence keeps it, as - `filter_systems_by_target` decides; a system absent from it is kept + `filter_systems_by_target` decides. A system absent from it is kept whatever is available. """ reach = system_core_reach( diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py index 82aef685..ab8634d7 100644 --- a/scripts/generate_readme.py +++ b/scripts/generate_readme.py @@ -280,7 +280,7 @@ def _catalog_matched_line(db: dict) -> list[str]: labels = ", ".join(_CATALOG_LABELS.get(s, s) for s in sorted(sources)) return [ f"- **{matched:,} of {system_files:,} system files** matched to" - f" dump-preservation catalogs ({labels}); arcade sets and engine data" + f" dump-preservation catalogs ({labels}). Arcade sets and engine data" f" fall outside what those catalogs index" ] @@ -368,12 +368,12 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "", "## Download BIOS packs", "", - "One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file. At a terminal it asks whether to install everything or to choose systems, cores and regions, and `--system`, `--core`, `--region` and `--target` make the same choice without questions; for a bare minimum, build your own pack below.", + "One pack per platform, and it holds everything the platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. The installer above does the same file by file. At a terminal it asks whether to install everything or to choose systems, cores and regions, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below.", "Files is how many the pack holds once extracted, the figure a file" " manager shows for the folder. It differs from one platform to the" " next because a pack carries only what that platform's emulators" " load." - " The size is what the files occupy once extracted; the ZIP itself" + " The size is what the files occupy once extracted, and the ZIP itself" " downloads smaller.", "", "A pack over 2 GB comes in several parts, and every part is needed." @@ -429,7 +429,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "BIOS, firmware, and system files for consoles from Atari to PlayStation 3.", "These are the files an emulator loads from disk instead of" " carrying inside itself. Some are required to boot a system," - " others improve accuracy or unlock a feature; the packs carry" + " others improve accuracy or unlock a feature, and the packs carry" " both.", "", "Each file is checked the way your platform checks it. Most compare" @@ -445,7 +445,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str: f"- **{acquirable_total} files** the platforms' emulators load" f" are still to be found, and {unsourceable_total} more cannot" f" be sourced at all (per-user keys, user-filled slots, dumps" - f" nobody has made); both are named in the" + f" nobody has made). Both are named in the" f" [gap analysis]({SITE_URL}gaps/)" if missing_total else "- **Nothing missing**: every file the platforms'" @@ -594,11 +594,11 @@ def generate_readme(db: dict, platforms_dir: str) -> str: "", "Documentation and metadata can drift from what emulators actually load.", "To keep packs accurate, platform lists are checked against emulator" - " source code, file by file where a profile exists; when the two" + " source code, file by file where a profile exists. When the two" " disagree, the code wins.", "", "Hashes document what emulator code loads and accepts, not dump" - " provenance; that boundary, and how it relates to preservation" + " provenance. That boundary, and how it relates to preservation" " catalogs such as No-Intro, is drawn in the" f" [FAQ]({SITE_URL}wiki/faq/" "#are-these-files-verified-against-original-hardware-dumps).", @@ -715,8 +715,8 @@ Full walkthrough: [profiling guide]({link("wiki/profiling")}). - `bios/Manufacturer/Console/.variants/filename.sha1prefix` for alternate versions - Files >50 MB go in GitHub release assets (`large-files` release) - RPG Maker and ScummVM directories are excluded from deduplication -- Two paths differing only by case break clones on Windows and macOS; - `tests/test_no_case_collisions.py` enforces this +- Two paths differing only by case break clones on Windows and macOS, + and `tests/test_no_case_collisions.py` enforces this ## Before opening a PR diff --git a/scripts/generate_site.py b/scripts/generate_site.py index 5409ae1d..7a3e43d8 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -152,7 +152,7 @@ def _build_system_page_map_from_data( Uses platform file paths to trace system_id -> bios directory -> manufacturer page. """ # Every console folder a filename sits in. A name in one folder only can - # place a system; a name in several says nothing (MiSTer's boot.rom lives + # place a system, while a name in several says nothing (MiSTer's boot.rom lives # under a dozen consoles, and the last one written used to win). name_consoles: dict[str, set[tuple[str, str]]] = {} for mfr, consoles in manufacturers.items(): @@ -191,7 +191,7 @@ def _build_system_page_map_from_data( if sys_id in _system_page_map: continue # Strategy 1: the folder holding the files the system declares, - # found by content; most votes win. A bare name stands in only + # found by content, and most votes win. A bare name stands in only # where the collection files it in a single console. place = _system_folder(system.get("files", []), db, name_consoles) if place is not None: @@ -321,7 +321,7 @@ def generate_home( [ "", "Checked by is the test each platform runs on its own, replicated " - "from its source code. RetroArch only looks for the filename; " + "from its source code. RetroArch only looks for the filename, while " "Batocera compares MD5 checksums, the fingerprint of a file's " "contents. " "[How each mode works](wiki/verification-modes.md).", @@ -594,7 +594,7 @@ def build_emulator_gap_report( """Files a core loads that no platform declares, per emulator profile. The gap analysis page and the published gaps export must not compute this - twice and drift; both read this one report. + twice and drift. Both read this one report. """ from common import _norm_system_id, merged_platform_declarations from cross_reference import cross_reference as run_cross_reference @@ -810,7 +810,7 @@ def _write_sqlite_export( "schema_version": "1", "generated_at": str(db.get("generated_at") or _timestamp()), "source": REPO_URL, - "scope": "metadata only; no BIOS or firmware payload bytes", + "scope": "metadata only, no BIOS or firmware payload bytes", } connection.executemany( "INSERT INTO metadata(key, value) VALUES (?, ?)", @@ -1091,7 +1091,7 @@ def generate_data_page(exports: list[dict]) -> str: "The DAT is Logiqx XML, the format clrmamepro and RomVault read: one game " "per `bios/<Manufacturer>/<Console>/` folder of the collection, each file a " "rom named by its path below that folder. It audits a copy of the " - "collection's `bios/` tree, or rebuilds that layout from your own dumps; a " + "collection's `bios/` tree, or rebuilds that layout from your own dumps. A " "platform pack has its own layout and is checked with `install.py --check`.", "", "## Stable JSON endpoints", @@ -1113,7 +1113,7 @@ def generate_data_page(exports: list[dict]) -> str: lines.extend([ "", "Every JSON document carries `schema_version`. Breaking changes use a new " - "URL prefix (`/api/v2/`); fields may only be added compatibly within v1.", + "URL prefix (`/api/v2/`), and fields may only be added compatibly within v1.", "", "One emulator profile without the whole list: " "`api/v1/emulators/<id>.json`, the envelope of `emulators.json` holding " @@ -1168,8 +1168,8 @@ def generate_data_page(exports: list[dict]) -> str: "catalog, or emulator compatibility is not a statement about copyright, " "ownership, or redistribution rights.", "", - f"The data can be newer than the [latest published pack]({RELEASE_URL}); " - "pack publication is manual and only occurs after all release gates pass.", + f"The data can be newer than the [latest published pack]({RELEASE_URL}). " + "A pack is published by hand, once every release check has passed.", "", "See the [data model](wiki/data-model.md), [verification modes]" "(wiki/verification-modes.md), and [methodology](wiki/architecture.md) " @@ -1355,7 +1355,7 @@ def platform_structured_data(name: str, coverage: dict) -> dict: The page printed thousands of hashes while its JSON-LD named only the page: a crawler could not learn which md5 Batocera requires for a file. - The software and its version are the subject; each declared file, with + The software and its version are the subject, and each declared file, with the hashes the platform checks, is a part. Past SYSTEM_PARTS_IN_FULL the parts give way to the platform-files table, as system pages do. """ @@ -1530,8 +1530,8 @@ def emulator_structured_data(profile: dict) -> dict: return data -# Working notes kept under docs/ during development, never part of the site; -# no generated page lives in a directory of these names. +# Working notes kept under docs/ during development, never part of the site, +# and no generated page lives in a directory of these names. LOCAL_NOTE_DIRS = ("plans", "specs") @@ -1937,7 +1937,7 @@ def generate_platform_page( def generate_files_page() -> str: """The content address of every held file: files/?sha1=<sha1>. - site.js reads api/v1/file-locations.json and goes to the card; without + site.js reads api/v1/file-locations.json and goes to the card. Without a sha1, or with one the collection does not hold, the page says so. """ return "\n".join([ @@ -2061,7 +2061,7 @@ def _provenance_lines(provenance: dict, prefix: str) -> list[str]: """One visible line per catalog: its badge and the entry's own name. The name was only a title attribute, unreadable on a touch screen and - absent from the search for 793 of 803 provenances; and a TOSEC entry + absent from the search for 793 of 803 provenances, and a TOSEC entry flagged [b] or [o] wore the same green badge as a clean dump. """ lines: list[str] = [] @@ -2311,7 +2311,7 @@ def _system_file_card(f: dict, consumers: FileConsumers) -> list[str]: anchor = f"sha1-{sha1_full[:12]}" if sha1_full != "unknown" else "" id_attr = f' id="{anchor}"' if anchor else "" lines = [f'<div class="rb-sys-file"{id_attr} markdown>', ""] - # The anchor is this page's; the second link is the file's own address, + # The anchor is this page's, the second link is the file's own address, # resolved by content wherever its card moves. permalink = ( f' <a class="rb-permalink" href="#{anchor}" title="Link to this card">#</a>' @@ -2750,7 +2750,7 @@ def _render_emulator_file( if fnote: lines.append(f"- {_escape_tags(str(fnote))}") if not in_repo and f.get("unsourceable"): - # The badge alone sent readers after a dump that cannot exist; the + # The badge alone sent readers after a dump that cannot exist, and the # reason was only on the gaps page, which the card did not link. lines.append( f"- Not collectable: {_escape_tags(str(f['unsourceable']))} " @@ -2844,7 +2844,7 @@ def _plain_value(value: object) -> str: if isinstance(value, bool): return "yes" if value else "no" if value is None: - # A YAML null states that there is none; Python's `None` read as a gap. + # A YAML null states that there is none, but Python's `None` read as a gap. return "none" if isinstance(value, (list, tuple)): return ", ".join(_plain_value(item) for item in value) @@ -3021,7 +3021,7 @@ def generate_emulator_page( source_raw = profile.get("source", "") source = str(source_raw) if not isinstance(source_raw, dict) else "" # A key set to null says there is none (the project is its own upstream, - # it publishes no version); an absent key says nobody wrote it down. The + # it publishes no version), and an absent key says nobody wrote it down. The # page printed `None` for the first, which read as the second. upstream_raw = profile.get("upstream", "") upstream_none = "upstream" in profile and upstream_raw is None @@ -3100,7 +3100,7 @@ def generate_emulator_page( if revision: lines.append(f"| Revision | {revision} |") lines.append(f"| Profiled | {profiled} |") - # The YAML is the reusable document this site renders; the JSON is the + # The YAML is the reusable document this site renders, and the JSON is the # same profile for a program. lines.append( f"| Profile | [YAML]({REPO_URL}/blob/main/emulators/{name}.yml), " @@ -3288,7 +3288,7 @@ def _render_problem_files(platform_problems: list, settled: list | None = None) "", "A platform can declare one path twice with different hashes. The " "path holds the file one declaration accepts, so it is counted once, " - "as held; the other declaration cannot be met at the same time.", + "as held. The other declaration cannot be met at the same time.", "", "| File | Platform | Status | Path held for system |", "|------|----------|--------|--------------|", @@ -3443,7 +3443,7 @@ def generate_gap_analysis( "required and optional files alike since both ship. The first column " "is the BIOS list the platform publishes. The second counts files its " "emulators load that this list never mentions, found by reading their " - "source code, and it is routinely several times larger; a short " + "source code, and it is routinely several times larger. A short " "fraction is flagged and named in the sections below. That second " "number is a floor, not a ceiling: an emulator that accepts any file " "handed to it names none in its code, so nothing there can be counted. " @@ -3520,7 +3520,7 @@ def generate_gap_analysis( "Platform file lists are scraped as-is from each upstream project. " "Emulator profiles are read from source code. The two do not always " "agree, and this table counts the differences. Packs follow the " - "platform contract; these numbers show where that contract diverges " + "platform contract, and these numbers show where that contract diverges " "from what the code loads.", "", "| Platform | Missing from list | Phantom | Hash conflict | Required status |", @@ -4003,7 +4003,7 @@ def generate_wiki_data_model(db: dict, profiles: dict) -> str: "", "`provenance` maps each catalog that lists the file to the DAT and entry " "it was matched against. It is present only when the file matches a " - "snapshot under `provenance/`; the join runs by SHA1 first, then by " + "snapshot under `provenance/`. The join runs by SHA1 first, then by " "MD5 + size. See [dump provenance](../provenance.md).", "", "### Indexes", @@ -4020,20 +4020,20 @@ def generate_wiki_data_model(db: dict, profiles: dict) -> str: "", "`resolve_local_file` tries these steps in order:", "", - "1. SHA1 exact match; every other declared hash must agree with the record", + "1. SHA1 exact match: every other declared hash must agree with the record", "2. SHA256 exact match, with the same all-declarations-must-agree rule", "3. CRC32 plus declared size, only when no stronger hash is present", "4. MD5 direct lookup (including explicitly supported truncated MD5 values)", - "5. Path suffix lookup for regional variants; with hashes it is accepted only if those hashes match", + "5. Path suffix lookup for regional variants. With hashes it is accepted only if those hashes match", "6. Name and alias lookup only when no content hash was declared", - "7. Candidate inspection for composite ZIP MD5 or direct MD5; a named candidate with the wrong content returns `hash_mismatch`", + "7. Candidate inspection for composite ZIP MD5 or direct MD5. A named candidate with the wrong content returns `hash_mismatch`", "8. `zipped_file` content match via the inner-ROM MD5 index", "9. MAME clone fallback, only for declarations without a content hash", - "10. Data-directory scan; declared hashes are computed over the candidate before it is accepted", + "10. Data-directory scan: declared hashes are computed over the candidate before it is accepted", "11. Agnostic size/path fallback, only for declarations without a content hash", "", "A filename or destination can never override a declared hash. The first " - "evidence-compatible match wins; otherwise the resolver reports a mismatch " + "evidence-compatible match wins, otherwise the resolver reports a mismatch " "or absence. Steps and their return codes are described in " "[verification modes](verification-modes.md#file-resolution-chain).", "", @@ -4075,7 +4075,7 @@ def generate_wiki_data_model(db: dict, profiles: dict) -> str: "", "The website publishes versioned JSON, CSV and SQLite metadata generated " "from these same structures. Start with the [Data & API](../data.md) " - "catalog; each downloadable artifact carries a SHA256 in " + "catalog. Each downloadable artifact carries a SHA256 in " "`api/v1/catalog.json`.", "", ] @@ -4247,15 +4247,15 @@ everything or to choose systems, cores and regions, and `--system`, `--core`, [installer reference](wiki/installer.md#choosing-what-to-install)). From a clone of the repository, `python scripts/generate_pack.py --platform retroarch --region us` builds the same narrowing as a pack and `--required-only` the bare -minimum each core needs to start; `--help` lists every way to build your own. +minimum each core needs to start, and `--help` lists every way to build your own. --- ## After extraction Launch a game and use the emulator's firmware status screen where available. -Most supported frontends find files in the documented directory automatically; -standalone emulators may still need their BIOS path configured. +Most supported frontends find files in the documented directory automatically, +but standalone emulators may still need their BIOS path configured. If a game still asks for a missing file, check the [platforms section](platforms/index.md) for the full file list, or the @@ -4385,7 +4385,7 @@ def main() -> None: args = parser.parse_args() try: # Two runs over one docs/ delete each other's pages and scratch - # files in the sweep; the second is refused instead. + # files in the sweep, so the second is refused instead. with artifact_lock(args.docs_dir): _generate(args) except ArtifactLockBusy as exc: @@ -4725,7 +4725,7 @@ plugins: - search # Link rot fails the build: deploy-site.yml runs `mkdocs build --strict`. # omitted_files stays at its default (info) so a stale local docs/ does not -# break a local build; CI regenerates docs/ from scratch anyway. +# break a local build. CI regenerates docs/ from scratch anyway. validation: absolute_links: warn unrecognized_links: warn diff --git a/scripts/generate_truth.py b/scripts/generate_truth.py index f7c4baa3..2c529d47 100644 --- a/scripts/generate_truth.py +++ b/scripts/generate_truth.py @@ -81,7 +81,7 @@ def main(argv: list[str] | None = None) -> None: profiles = load_emulator_profiles(args.emulators_dir) # Load database (optional) - # The default may be absent; a --db that was named must exist. + # The default may be absent, but a --db that was named must exist. db: dict | None = None if args.db != DEFAULT_DB_FILE or os.path.exists(args.db): db = load_database(args.db) diff --git a/scripts/hashing.py b/scripts/hashing.py index 537cd165..3addb3fe 100644 --- a/scripts/hashing.py +++ b/scripts/hashing.py @@ -1,6 +1,6 @@ """Content digests. -SHA-1 is the collection's primary key; the rest are what the various +SHA-1 is the collection's primary key. The rest are what the various frontends check against.""" from __future__ import annotations @@ -15,7 +15,7 @@ from pathlib import Path _ALL_ALGORITHMS = frozenset({"sha1", "md5", "sha256", "crc32", "adler32"}) # (path, inode, size, mtime_ns, ctime_ns) -> the digests read so far. -# verify --all hashed GB_dmg.bin 13 times, once per platform and entry; the +# verify --all hashed GB_dmg.bin 13 times, once per platform and entry. The # bytes are still read from disk, once per file and change. _hash_cache: dict[tuple, dict[str, str]] = {} @@ -118,7 +118,7 @@ def parse_hash_list(raw: str | list | int | None) -> list[str]: """Normalize any hash field into its accepted values, lowercase. A field holds one value, a YAML list, or one comma-joined string - (Recalbox md5, mesence's four sha256 for one entry); a crc32 may carry + (Recalbox md5, mesence's four sha256 for one entry), and a crc32 may carry a 0x prefix. Read one way here, the resolver, the gap report and profile_sync accept the same values. """ diff --git a/scripts/identity.py b/scripts/identity.py index 1400c6ca..d23a0493 100644 --- a/scripts/identity.py +++ b/scripts/identity.py @@ -9,7 +9,7 @@ nothing in the pipeline could see it, because on paper both names resolved. This walks the tree rather than the index, groups by content, and reports a group whose paths sit under different manufacturers. A dump legitimately -shared by two systems of the same maker is common; one shared across makers +shared by two systems of the same maker is common, one shared across makers almost never is. """ diff --git a/scripts/largefiles.py b/scripts/largefiles.py index 02af75f1..dcf2d214 100644 --- a/scripts/largefiles.py +++ b/scripts/largefiles.py @@ -96,8 +96,8 @@ def published_asset_name(name: str) -> str: def asset_candidates(name: str, registered: Iterable[str]) -> list[str]: """Assets that may hold *name*, a registered path or a bare file name. - A bare name shared by several registered paths has one asset per path; - the caller's hash tells them apart. + A bare name shared by several registered paths has one asset per path, + and the caller's hash tells them apart. """ registered = list(registered) if "/" in name: @@ -127,7 +127,7 @@ def fetch_large_file( ) -> str | None: """Return a verified cached large file, downloading it only when allowed. - *name* is a registered bios/ path or a bare file name; asset_names() + *name* is a registered bios/ path or a bare file name. asset_names() turns it into the asset to fetch, and a bare name shared by several registered paths tries each of their assets until one verifies. """ @@ -255,7 +255,7 @@ def _replaced_on_release(name: str, cached: str, offline: bool) -> bool: The release lists a sha256 per asset: a dump rebuilt at the same size (the eight 251658304-byte DSi NANDs) differs only there, and judged by size the stale copy was kept for good. Without a digest the sizes are - compared, as check_release_assets does. No download either way; + compared, as check_release_assets does. No download either way: offline or unreadable, the copy is assumed current. """ if offline: @@ -275,7 +275,7 @@ _digests_cache: dict[str, str] | None = None def _served_digests() -> dict[str, str]: - """sha256 of each asset the release serves, by asset name; empty when + """sha256 of each asset the release serves, by asset name, empty when the API cannot be read.""" global _digests_cache if _digests_cache is not None: diff --git a/scripts/mame_ref_audit.py b/scripts/mame_ref_audit.py index 677148ee..c7c89bdb 100644 --- a/scripts/mame_ref_audit.py +++ b/scripts/mame_ref_audit.py @@ -14,7 +14,7 @@ declaration can sit behind one, as `/* Naomi */ GAME( 1998, naomi, ...)` does. A set no machine macro declares is not an error. Device ROMs take the shortname of their DEFINE_DEVICE_TYPE and some archives are bare ROM_START -blocks; a ref there cites something this check cannot judge, and says so. +blocks. A ref there cites something this check cannot judge, and says so. """ from __future__ import annotations @@ -126,7 +126,7 @@ def main() -> None: ) parser.add_argument( "--offline", action="store_true", - help="read only what the cache holds; no network access", + help="read only what the cache holds, no network access", ) parser.add_argument( "--write", action="store_true", diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py index 9d6bba27..0028a3e1 100644 --- a/scripts/mkdocs_hooks.py +++ b/scripts/mkdocs_hooks.py @@ -3,7 +3,7 @@ The sitemap gave all 664 pages the build date as lastmod, so the field told a crawler nothing. A page whose content carries its own date (an emulator page: the day its profile was last read against the source) states it in -its front matter; the rest get no lastmod rather than an inexact one. +its front matter. The rest get no lastmod rather than an inexact one. """ from __future__ import annotations diff --git a/scripts/nativemode.py b/scripts/nativemode.py index 523f3358..eae8015d 100644 --- a/scripts/nativemode.py +++ b/scripts/nativemode.py @@ -25,7 +25,7 @@ from __future__ import annotations DEFAULT_MODE = "existence" #: Every verification mode a platform YAML may declare. Mirrors the enum in -#: schemas/platform.schema.json; tests/test_audit_regressions.py pins them +#: schemas/platform.schema.json, and tests/test_audit_regressions.py pins them #: together so a new mode cannot be added to one without the other. MODES = ("existence", "md5", "sha1") diff --git a/scripts/packextras.py b/scripts/packextras.py index 9b2d89e6..560f48bf 100644 --- a/scripts/packextras.py +++ b/scripts/packextras.py @@ -228,7 +228,7 @@ def unplaceable_extras(config: dict, undeclared: list[dict], profiles: dict) -> """Keys of the report entries a slug-based platform cannot place. RomM files every BIOS under the slug of its system and knows no slug - for DOS or for the arcade sets MAME 2003 reads; the builder skipped + for DOS or for the arcade sets MAME 2003 reads. The builder skipped those entries and the report counted them in the pack. """ from common import _norm_system_id @@ -283,7 +283,7 @@ def _agnostic_scan_extras( # filename walks into whatever tree that name happens to hit: rom1.bin # is a PS2 ROM and a Roland SC-55 ROM, GameIndex.yaml belongs to four # PS2 profiles and to an Android package. One match is not evidence - # of a directory; two files of the same profile agreeing is. + # of a directory, two files of the same profile agreeing is. resolved_dirs: dict[int, str] = {} named_only: set[int] = set() agnostic_votes: dict[str, int] = {} @@ -467,7 +467,7 @@ def expand_agnostic_entries( in its BIOS folder, which is what the platform pack's scan carries. The emulator pack and verify --emulator looked the placeholder up by name, found nothing and shipped LRPS2 without a PS2 BIOS. The same scan - replaces the placeholders here; with nothing found they stay, a gap. + replaces the placeholders here. With nothing found they stay, a gap. """ if profile.get("bios_mode") != "agnostic" and not any(f.get("agnostic") for f in files): return files @@ -861,7 +861,7 @@ def _collect_emulator_extras( if fname not in covered_names or f.get("unsourceable"): continue # A member of an archive is read inside it, never as a loose - # file; the archive itself is placed by the passes above. + # file. The archive itself is placed by the passes above. if f.get("archive"): continue # No path: the core reads it from nowhere a pack reaches @@ -963,12 +963,12 @@ def _report_extra(u: dict, name: str, dest: str) -> dict: if u.get("members"): extra["members"] = u["members"] # The archive layout the core opens ranks same-named copies by what - # they hold; without it the first copy indexed won. + # they hold. Without it the first copy indexed won. if u.get("contents"): extra["contents"] = u["contents"] # Keep every reproducible identity constraint carried by the source # profile. Some profiles expose CRC32/SHA-256 only through their - # validation block; dropping those fields here would let a same-named + # validation block, and dropping those fields here would let a same-named # but different payload enter a generated pack. expected = u.get("expected") or {} for identity in PROFILE_IDENTITY_FIELDS: @@ -983,7 +983,7 @@ def _report_extra(u: dict, name: str, dest: str) -> dict: def _take( extra: dict, full_dest: str, seen_dests: set[str], taken: dict[str, dict] | None ) -> bool: - """Whether an extra takes its destination; a taken one records the claim.""" + """Whether an extra takes its destination. A taken one records the claim.""" if full_dest in seen_dests: if taken is not None: _another_claim(taken.get(full_dest), extra) @@ -998,7 +998,7 @@ def _another_claim(extra: dict | None, claim: dict) -> None: """Record a core that reads a destination another core's extra took. The pack ships one file per destination, so the first claimant's extra - stands; the others are kept on it so the manifest can name every core + stands. The others are kept on it so the manifest can name every core the file serves. A pack built for a target without the first core packs the next one's copy, and an installer narrowing by core must keep it. """ diff --git a/scripts/packresolve.py b/scripts/packresolve.py index 53d4bc97..be71f409 100644 --- a/scripts/packresolve.py +++ b/scripts/packresolve.py @@ -1,6 +1,6 @@ """Finding the bytes a pack entry names. -Resolution proper lives in common; this layer adds what only a build +Resolution proper lives in common. This layer adds what only a build needs: storage tiers, release assets for files too large to commit, and the offline switch that forbids reaching for the network.""" @@ -51,7 +51,7 @@ def _verified_asset( """The release asset of that name, if it is a copy the entry accepts. The store is asked once per accepted sha1 (or md5), since it keeps one - revision under a name; what it returns is held against every hash the + revision under a name. What it returns is held against every hash the entry declares, sha256 and crc32 included. """ attempts = ( @@ -125,7 +125,7 @@ def lookup_hashes( emulators_dir: str, platforms_dir: str, ) -> int: - """Print diagnostic info for each hash; return how many were not found.""" + """Print diagnostic info for each hash and return how many were not found.""" missing = 0 files_db = db.get("files", {}) by_md5 = db.get("indexes", {}).get("by_md5", {}) @@ -216,8 +216,8 @@ def resolve_file( # missing OR has a hash mismatch (wrong variant on disk) name = file_entry.get("name", "") if file_entry.get("type") == "directory" or name.endswith("/"): - # A tree the collection does not hold is missing, as verify says; - # the asset store holds files, not trees. + # A tree the collection does not hold is missing, as verify says, + # since the asset store holds files, not trees. return (path, status) if path else (None, "not_found") declared = _declared_hashes(file_entry) if file_entry.get("unsourceable") and not any(declared.values()): diff --git a/scripts/pipeline.py b/scripts/pipeline.py index dc532949..35e52604 100644 --- a/scripts/pipeline.py +++ b/scripts/pipeline.py @@ -288,7 +288,7 @@ def _truth_steps(args: argparse.Namespace, results: dict) -> bool: all_ok = True # Step 2c: Generate truth YAMLs # A targeted run writes each platform's model under the target as that - # platform files it; the diff is told the target and reads the same place. + # platform files it, and the diff is told the target and reads the same place. truth_dir = Path(args.output_dir) / "truth" if args.with_truth or args.with_export: @@ -547,7 +547,7 @@ def main() -> None: all_ok = all_ok and ok # Step 3b: Destinations both layers claim, and how each was settled. The - # ones the pack settles by itself must stay at zero cost; the rest name an + # ones the pack settles by itself must stay at zero cost. The rest name an # upstream declaration no build can repair, so this reports and never gates. # A crash is not a report: without --strict slots.py exits 0 on every # conflict, so a non-zero code means it never finished reading. @@ -658,7 +658,7 @@ def main() -> None: print("\n--- 4c/8 generate target manifests: SKIPPED (--skip-packs) ---") results["generate_target_manifests"] = SKIPPED - # Step 5: Consistency check. verify describes the full pack; a run that + # Step 5: Consistency check. verify describes the full pack, and a run that # built only a reduced one (--source platform or truth) has nothing to # compare it with, and says so instead of failing on an empty parse. full_pack_built = args.source == "full" or args.all_variants @@ -675,7 +675,7 @@ def main() -> None: # Step 6: Pack integrity (extract + hash verification) if not args.skip_packs and not full_pack_built: - # The check reads the full pack's name; a reduced pack holds fewer + # The check reads the full pack's name, while a reduced pack holds fewer # files than the platform declares by design. print("\n--- 6/8 pack integrity: SKIPPED (no full pack built) ---") results["pack_integrity"] = SKIPPED diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index c2908b0a..7dcee12b 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -66,7 +66,7 @@ WIDEN_STEPS = (0, 3, 6, 12, 25, 50) # The fallback mapping is a full sequence diff, and it only runs once exact # anchoring has failed, which is rare. openbor.c is the largest file any # profile cites, 55k lines against 57k, and diffing the pair takes nine -# seconds; the ceiling sits above it so that one resolves, and still stops a +# seconds. The ceiling sits above it so that one resolves, and still stops a # pathological pair from stalling a sweep of every profile. MAX_MATCH_LINES = 60000 @@ -217,7 +217,7 @@ def strip_repo_word( if head.lower() in known and tail and "/" not in head and "." not in head: tail = tail.strip() # `ArcadeFlashWeb v1.0.2 flash/flash.html` names the release the file - # was read from; the version is not part of the path either. + # was read from. The version is not part of the path either. version, _, rest = tail.partition(" ") if rest and _VERSION_WORD_RE.fullmatch(version): return rest.strip() @@ -229,7 +229,7 @@ def narrow_by_cited(matches: list[str], cited_dirs: Iterable[str]) -> list[str]: """Keep the candidates under the deepest directory the profile cites. A bare `version.h` matches BasiliskII/src/include/version.h and - SheepShaver/src/include/version.h in cebix/macemu; the profile's own + SheepShaver/src/include/version.h in cebix/macemu. The profile's own source_refs all live under SheepShaver/src, which is the tree the prose meant. Candidates under no cited directory are kept only when none is. """ @@ -271,7 +271,7 @@ def _anchor_tokens(entry: dict) -> list[str]: Both the content values and the set name are searched, because profiles cite two different shapes. FBNeo and Hypseus refs point at the ROM table, - where the CRC32s are; MAME refs point at the machine declaration, which + where the CRC32s are, while MAME refs point at the machine declaration, which carries the set name and no hash at all. """ tokens = collect_tokens(entry) @@ -328,7 +328,7 @@ class Citation: A structured citation lives under a source_ref key and keeps its entry for the values it declares. A prose citation is a path:line run found - inside any other string scalar; its spans locate the path and every + inside any other string scalar. Its spans locate the path and every range token inside the scalar line, so a recale can move the numbers and leave the sentence around them alone. """ @@ -382,7 +382,7 @@ def _walk_document( # What separates one citation from the next in prose. lynx-emu writes -# "...:112; mednafen src/lynx/system.cpp:86-93": without the semicolon the +# `...:112; mednafen src/lynx/system.cpp:86-93`: without the semicolon the # project word read as prose and the citation was charged to the fork. A # sentence end separates them the same way. _PROSE_LIST_DELIMITERS = ",;:(." @@ -421,7 +421,7 @@ def resolve_project_word(path: str, trees: Iterable[list[str] | None]) -> str | device/pif/bootrom_hle.c`: plugins vendored in the declared repository under mupen64plus-video-rice/ and mupen64plus-core/. A citation is in reach when exactly one file ends with the path below a directory naming - the project; the first tree that answers decides. + the project. The first tree that answers decides. """ word, _, rest = path.partition(" ") rest = rest.strip().lstrip("/") @@ -460,7 +460,7 @@ def _prose_runs( # A literal block keeps its line breaks, so a citation wrapped after # `file:` or after a range's comma lost the ranges on the next line # (gearcoleco `libretro.cpp:` then four ranges). The next line is - # read as the run's continuation; a run reaching into it is wrapped. + # read as the run's continuation, and a run reaching into it is wrapped. line = own.rstrip() boundary = len(line) following = lines[number + 1].lstrip() if number + 1 < len(lines) else "" @@ -941,7 +941,7 @@ def anchor_part( pin_lines = fetch(PIN, part.path, part.start, tokens) if pin_lines is None and path != part.path: - # A ref may cite a bare filename the tree search resolved at HEAD; the + # A ref may cite a bare filename the tree search resolved at HEAD. The # same resolved path usually holds at the pin. A genuine rename keeps # the old path at the pin, which is why that one is tried first. pin_lines = fetch(PIN, path, part.start, tokens) @@ -949,7 +949,7 @@ def anchor_part( # Present at HEAD, absent at the pin, and the cited range fits the # HEAD file: the ref was written against HEAD while source_commit # still names an older revision. Saying "missing" sends the reader - # hunting for a move that never happened; the fix is the pin. + # hunting for a move that never happened: the fix is the pin. reason = "pin revision missing" if _written_against_head(part, head_lines): reason = "written against HEAD, pin names an older revision" @@ -1255,7 +1255,7 @@ def branch_in_url(url: str) -> str | None: def branch_candidates(url: str) -> list[str]: """Each prefix of a /tree/ tail, shortest first, that may be the branch. - A branch name can hold a slash, so the tail is not split blindly; the + A branch name can hold a slash, so the tail is not split blindly. The first prefix the forge resolves is the branch, the rest a directory. Taken whole, `master/tests/cruzes` resolved to nothing and the profile was skipped as having no resolvable pin. @@ -1311,7 +1311,7 @@ def verify_at_pin( part, "UNCHECKED", None, None, None, [], "entry declares no value to look for", ) - # An archive ref cites the line declaring the set; its members follow, one + # An archive ref cites the line declaring the set. Its members follow, one # per line, so the window reaches forward as far as the entry has members. reach = SELF_CHECK_CONTEXT + len(tokens) lo = max(0, part.start - 1 - SELF_CHECK_CONTEXT) @@ -1427,7 +1427,7 @@ def _resolve_project_words( ) -> list: """Point `project file` parts at the declared tree that vendors them. - tree_order() yields the trees to search, pin before HEAD; it is only + tree_order() yields the trees to search, pin before HEAD. It is only called for a part that needs it, since reading a HEAD tree costs a request. Parts no tree carries stay external. """ @@ -1587,7 +1587,7 @@ def build_report( The pin comes before HEAD because that is the revision the ref was written against. `mame` cites files that both mamedev/mame and the - libretro fork carry today, but only the upstream pin holds them; the + libretro fork carry today, but only the upstream pin holds them. The fork's pin is an older tree where they lived elsewhere. """ candidates = [path] @@ -1825,7 +1825,7 @@ def build_report( A ref is only broken when it fails everywhere. `mame` cites files that both mamedev/mame and its libretro fork hold, with the same delimited token on the cited line, so no single attribution can be right for all - of them; taking the best outcome across repositories settles it. + of them. Taking the best outcome across repositories settles it. """ owner, _actual = resolve_path(part.path, part.start, tuple(tokens)) carrying = [ @@ -2670,7 +2670,7 @@ def pending_recale( moves = _prose_moves(entry, movable) if not moves: # Either nothing has to move, or the run cannot be written - # without guessing; the second case still blocks the pin. + # without guessing, and the second case still blocks the pin. if any( part.status in movable and part.start is not None @@ -2766,7 +2766,7 @@ def pins_changed(before: dict, after: dict) -> list[str]: def cites_primary(report: ProfileReport) -> bool: """Whether a ref resolved in the repository source_commit pins. - A part attributed to another declared repository carries its slug; one + A part attributed to another declared repository carries its slug, and one read in the primary carries none. A profile citing nothing proves nothing either way and is not held back. """ @@ -2790,7 +2790,7 @@ def _set_pin(text: str, document: dict, field: str, value: str, after: str) -> s def _git_history(path: Path) -> list[str] | None: - """Commits touching the profile, newest first; None when git cannot say. + """Commits touching the profile, newest first, or None when git cannot say. An untracked profile has no history. A git that fails (no repository, dubious ownership, git missing) has not answered, and reading that as @@ -2897,7 +2897,7 @@ def _resolve_at( ) -> tuple[str, object]: """("found", (path, lines)) or ("unclear"|"missing", reason). - Prose often cites a bare filename; the tree at the revision resolves it + Prose often cites a bare filename. The tree at the revision resolves it when exactly one path carries that name. An unreadable or truncated tree, or several paths carrying the name, proves nothing: those come back "unclear", never "missing", because a verdict of absence taken on @@ -2984,7 +2984,7 @@ def _writing_pairs( Each reading lists (repo, writing pin, current pin) per declared repository. A repository whose text lived under several pins gives one - reading per pin; the caller settles them when they all agree. + reading per pin, and the caller settles them when they all agree. `prose_written_at` names the pin a reader confirmed the prose against. Among several candidate pins it is the answer: fixnes's doOpenFDSBIOS @@ -3314,7 +3314,7 @@ def build_parser() -> argparse.ArgumentParser: ) parser.add_argument( "--offline", action="store_true", - help="read only what the cache holds; no network access", + help="read only what the cache holds, no network access", ) parser.add_argument( "--cache-dir", default=DEFAULT_CACHE, @@ -3428,7 +3428,7 @@ def _apply_writes( if not (args.rebase_refs or args.bump_commit) or _stale_prose_blocks(name, path, args): return with tempfile.TemporaryDirectory() as scratch: - # Always work on a copy. A dry run reports what it left there; a real + # Always work on a copy. A dry run reports what it left there, a real # run promotes it. A recale rewrites the refs for HEAD, so the pin # has to follow or neither moves: a profile whose refs describe one # revision and whose pin names another is exactly what the @@ -3445,7 +3445,7 @@ def _apply_writes( if args.rebase_refs and applied and not moved: print( f"{name}: refs recaled but the pin will not follow, so nothing " - "was written; the prose or an annotated ref has to move first", + "was written: the prose or an annotated ref has to move first", file=sys.stderr, ) return @@ -3523,7 +3523,7 @@ def _print_extras( ) -> None: """Optional per-profile sections beyond the ref report. - The ref report mutes a forge that refuses; the extras read the same + The ref report mutes a forge that refuses, but the extras read the same forge again, so a refusal here is reported on the profile's own line instead of ending a pass over every profile. A quota signal still stops everything. @@ -3688,7 +3688,7 @@ def _refuse_flag_combinations(args: argparse.Namespace) -> None: ) if on ] if machine and extras: - # The extra sections only exist in the text report; the other outputs + # The extra sections only exist in the text report. The other outputs # returned before reaching them and printed as if never asked. print( f"{', '.join(machine)} does not carry {', '.join(extras)}", @@ -3775,7 +3775,7 @@ def main() -> None: try: _apply_writes(args, name, profile, report) except YamlWriteError as exc: - # The guard already left the file untouched; keep going. + # The guard already left the file untouched, so keep going. print(f"{name}: write refused: {exc}", file=sys.stderr) failed.add(name) diff --git a/scripts/provenance_report.py b/scripts/provenance_report.py index 16ea6120..42c549f1 100644 --- a/scripts/provenance_report.py +++ b/scripts/provenance_report.py @@ -57,7 +57,7 @@ def archive_members(db: dict) -> dict[tuple[str, int], list[tuple[str, str]]]: def _held_in_archive(entry: dict, members: dict) -> bool: """Whether a catalog entry is a member of one of the collection's ZIPs. - crc32 and size only nominate candidates; a declared sha1 must match the + crc32 and size only nominate candidates. A declared sha1 must match the member's bytes. """ crc = str(entry.get("crc32") or "").lower() @@ -99,7 +99,7 @@ def build_report(db: dict, snapshots: dict, members: dict | None = None) -> dict A DAT counts as covered when the collection holds at least one of its entries. Missing entries from covered DATs are acquisition - targets; missing entries from DATs the collection does not cover at + targets. Missing entries from DATs the collection does not cover at all are out of scope and only counted. No-Intro tags every non-game dump "[BIOS]", including digital title distribution, so without this split the target list is swamped by content the project never ships. @@ -178,7 +178,7 @@ def main() -> int: "--derive", action="store_true", help="Find missing entries a held dump contains (halves, word splits, " - "byte swaps, concatenations); reads the collection, about 35 s", + "byte swaps, concatenations). Reads the collection, about 35 s", ) parser.add_argument("--json", action="store_true", help="Full report as JSON") parser.add_argument( @@ -189,7 +189,7 @@ def main() -> int: ) args = parser.parse_args() if args.write_derivable and not args.derive: - parser.error("--write-derivable records what --derive finds; pass both") + parser.error("--write-derivable records what --derive finds: pass both") db = load_database(args.db) snapshots = load_provenance_snapshots(args.provenance_dir) diff --git a/scripts/refresh_data_dirs.py b/scripts/refresh_data_dirs.py index 97e455e3..89eaa63d 100644 --- a/scripts/refresh_data_dirs.py +++ b/scripts/refresh_data_dirs.py @@ -68,7 +68,7 @@ def hold_data_dirs(stack: contextlib.ExitStack, registry: dict) -> None: """Hold every cached data directory shared for the life of *stack*. A pack resolves names against a tree, then copies the file minutes - later; a refresh swapping the tree in between shipped bytes nobody + later. A refresh swapping the tree in between shipped bytes nobody verified, or died on a file the new tree no longer has. A refresh waits for the holders. Never called before a refresh in the same process: the exclusive lock would wait on this one. @@ -445,8 +445,8 @@ def _refresh_entry( if remote_tag is None: # Read before the download. A release published in between then - # leaves an older tag on newer content, which the next run refreshes; - # read after, it left a newer tag on older content, trusted for good. + # leaves an older tag on newer content, which the next run refreshes. + # Read after, it left a newer tag on older content, trusted for good. if source_type == "zip": remote_tag = _get_remote_etag(source_url) else: diff --git a/scripts/refresh_stale.py b/scripts/refresh_stale.py index c9ebb363..bb90263b 100755 --- a/scripts/refresh_stale.py +++ b/scripts/refresh_stale.py @@ -55,7 +55,7 @@ PLATFORMS_REGISTRY = REPO_ROOT / "platforms" / "_registry.yml" AUTO_AREAS = ("platforms", "native", "targets", "data", "catalogs") MANUAL_AREAS = ("coreinfo", "ci", "profiles") -JOB_TIMEOUT = 1800 # 30 minutes per refresher; scrapers rarely exceed 10 +JOB_TIMEOUT = 1800 # 30 minutes per refresher, scrapers rarely exceed 10 @dataclass(frozen=True) @@ -81,7 +81,7 @@ class JobResult: def _load_platform_registry() -> dict[str, dict]: """Return the platforms map from _registry.yml. - pyyaml is already a project dependency; the registry is small so we read + pyyaml is already a project dependency, and the registry is small so we read it once at startup rather than parsing each dispatch. """ import yaml @@ -122,7 +122,7 @@ def plan_jobs( Surfaced-only entries carry stale state that only a human can resolve (new .info file, manual DAT download, PyPI bump). Ignored entries are - anything not STALE (OK, SKIPPED, UNKNOWN, ERROR); ERROR is also surfaced + anything not STALE (OK, SKIPPED, UNKNOWN, ERROR). ERROR is also surfaced so the final report mentions it. """ jobs: list[Job] = [] @@ -219,7 +219,7 @@ def _command_for( ] if area == "targets": - # "<platform> cores" rows list buildbot names without a profile; no + # "<platform> cores" rows list buildbot names without a profile. No # scraper fixes that, a human writes `cores:` or _overrides.yml. if subject.endswith(" cores"): return None @@ -237,7 +237,7 @@ def _command_for( if area == "data": if subject == "_data_dirs.yml": - # The registry file itself cannot be refreshed; its entries can. + # The registry file itself cannot be refreshed, but its entries can. return None return [ sys.executable, @@ -276,7 +276,7 @@ def _command_for( def _github_token_env() -> dict[str, str]: """Hand `gh auth token` to the subprocess environment. - emudeck and retropie target scrapers hit the GitHub API; without a token + emudeck and retropie target scrapers hit the GitHub API. Without a token the unauthenticated rate limit (60/h) is burnt within a few platforms. """ env = os.environ.copy() @@ -396,7 +396,7 @@ def main() -> int: parser.add_argument( "--dry-run", action="store_true", - help="list what would be refreshed; do not run any command", + help="list what would be refreshed without running any command", ) parser.add_argument( "--jobs", diff --git a/scripts/region.py b/scripts/region.py index 99f79ba0..7c6f9257 100644 --- a/scripts/region.py +++ b/scripts/region.py @@ -1,7 +1,7 @@ """Region vocabulary and ordered-priority selection for pack generation. A file's region: value is the region the emulator code selects it for, not the -region of the dump. Signal standard has no field of its own; it survives only +region of the dump. Signal standard has no field of its own. It survives only inside slugs whose hardware register fuses the two axes (Saturn SMPC areas). """ diff --git a/scripts/region_audit.py b/scripts/region_audit.py index c3eef96f..eb02e2e6 100644 --- a/scripts/region_audit.py +++ b/scripts/region_audit.py @@ -1,6 +1,6 @@ """Cross-check profile region: values against dump-catalog provenance. -Advisory only. The emulator source decides what a region: value should be; this +Advisory only. The emulator source decides what a region: value should be. This reports where an independent catalogue disagrees, so a hand-written value gets a second opinion before it is trusted. diff --git a/scripts/romset_recipes.py b/scripts/romset_recipes.py index 02d40d47..0187f7f3 100644 --- a/scripts/romset_recipes.py +++ b/scripts/romset_recipes.py @@ -391,7 +391,7 @@ def missing_report( "md5": target, "recipes_tried": sorted(usable), "reason": ( - "no recipe reproduces this MD5; the pinned archive is " + "no recipe reproduces this MD5: the pinned archive is " "not TorrentZip or follows a recipe not documented here" if usable else "ROMs for every documented recipe are missing" diff --git a/scripts/safeparse.py b/scripts/safeparse.py index 8411b714..a0f0caa7 100644 --- a/scripts/safeparse.py +++ b/scripts/safeparse.py @@ -102,7 +102,7 @@ def yaml_load(stream: str | TextIO) -> Any: def yaml_load_upstream(stream: str | TextIO) -> Any: """Parse a third party's YAML the way its own PyYAML code reads it. - Our files refuse a repeated key; a platform's file is data we transcribe, + Our files refuse a repeated key, but a platform's file is data we transcribe, and its code keeps the last value. Batocera 43.1's configgen-defaults.yml names rtcw's core twice, and refusing it stopped the rescrape. """ diff --git a/scripts/scraper/_hash_merge.py b/scripts/scraper/_hash_merge.py index d635f4b4..6c9f12ce 100644 --- a/scripts/scraper/_hash_merge.py +++ b/scripts/scraper/_hash_merge.py @@ -76,7 +76,7 @@ def merge_mame_profile( updated_bios.append(entry) matched_names.add(set_name) elif add_new: - # New BIOS set — only added to the main profile + # New BIOS set, only added to the main profile entry = { "name": f"{set_name}.zip", "required": True, @@ -88,7 +88,7 @@ def merge_mame_profile( updated_bios.append(entry) # Entries not matched by the scraper stay untouched - # (computer ROMs, device ROMs, etc. — outside BIOS root set scope) + # (computer ROMs, device ROMs, etc., outside BIOS root set scope) for set_name, entry in existing_by_name.items(): if set_name not in matched_names: updated_bios.append(entry) @@ -296,7 +296,7 @@ def _diff_fbneo( } -# ── Helpers ────────────────────────────────────────────────────────── +# Helpers def _load_yaml(path: str) -> dict[str, Any]: @@ -399,7 +399,7 @@ def _patch_core_version(text: str, version: str) -> str: def _patch_scalar(text: str, key: str, value: str) -> str: - """Replace a top-level scalar in-place, quoted; absent value, no change.""" + """Replace a top-level scalar in-place, quoted. An absent value changes nothing.""" if not value: return text return re.sub( @@ -600,7 +600,7 @@ def _patch_block_values(block: str, entry: dict) -> str: match = _FIELD_LINE.match(line) if match and match["key"] == key: if match["value"].strip().strip('"') != str(value): - # A size comment spells the old value; it goes with it. + # A size comment spells the old value, so it goes with it. lines[i] = f" {key}: {rendered}" break else: @@ -619,7 +619,7 @@ def _backup_and_write_fbneo(path: str, data: dict, hashes: dict) -> None: FBNeo profiles have individual ROM entries with archive: field. Patches core_version, the content values of existing entries that changed, and appends new ROM entries. Advancing core_version alone left - a profile claiming a release whose crc32 it did not carry; comments and + a profile claiming a release whose crc32 it did not carry. Comments and curated source_refs stay as written. """ p = Path(path) diff --git a/scripts/scraper/base_scraper.py b/scripts/scraper/base_scraper.py index 1f86cc69..ac9b2362 100644 --- a/scripts/scraper/base_scraper.py +++ b/scripts/scraper/base_scraper.py @@ -390,7 +390,7 @@ def scraper_cli( config["systems"][sys_id]["files"].append(entry) # Merge into existing YAML: preserve fields the scraper doesn't generate # (data_directories, case_insensitive_fs, manually added metadata). - # The scraper replaces systems + files; everything else is preserved. + # The scraper replaces systems + files, everything else is preserved. output_path = Path(args.output) if output_path.exists(): with open(output_path) as f: diff --git a/scripts/scraper/batocera_scraper.py b/scripts/scraper/batocera_scraper.py index 7e68b898..77f047e0 100644 --- a/scripts/scraper/batocera_scraper.py +++ b/scripts/scraper/batocera_scraper.py @@ -95,7 +95,7 @@ def es_systems_emulators(text: str) -> tuple[set[str], set[str]]: """Every core es_systems.yml offers, and those that run standalone. ES lists, per system, each emulator a user may pick and the cores under - it; configgen-defaults.yml only names the one picked by default, so + it. configgen-defaults.yml only names the one picked by default, so reading it alone left DOSBox Staging, melonDS DS and nine other built cores outside the pack. """ @@ -111,7 +111,7 @@ def es_systems_emulators(text: str) -> tuple[set[str], set[str]]: for emulator, entries in emulators.items(): if not isinstance(entries, dict): continue - # A standalone emulator is its own core; what it lists under it + # A standalone emulator is its own core. What it lists under it # are machines or builds, and the non-cores among them are named # in the overrides. Keys whose value is not a mapping # (archs_include) describe the entry, not a core. diff --git a/scripts/scraper/bizhawk_scraper.py b/scripts/scraper/bizhawk_scraper.py index 4876c26a..f9c6df70 100644 --- a/scripts/scraper/bizhawk_scraper.py +++ b/scripts/scraper/bizhawk_scraper.py @@ -12,8 +12,8 @@ BizHawk declares firmware in FirmwareDatabase.cs using four patterns: FirmwareAndOption(sha1, size, sys, id, ...) - combined one-liner Variable assignments (var x = File(...)) let Option() reference files -by name. Multiple options per firmware slot are ranked by status; -the Ideal non-bad option is selected as canonical. +by name. Multiple options per firmware slot are ranked by status, +and the Ideal non-bad option is selected as canonical. """ from __future__ import annotations @@ -127,7 +127,7 @@ BIZHAWK_CORES = [ "handy", "quicknes", "genesis_plus_gx", - # Ares64 is BizHawk's N64 core only; its firmware (the 64DD IPL) is in + # Ares64 is BizHawk's N64 core only. Its firmware (the 64DD IPL) is in # FirmwareDatabase.cs. The ares profile's thirty systems are not what # BizHawk runs ares for. "mupen64plus_next", @@ -173,7 +173,7 @@ def parse_firmware_database( """ source = _strip_comments(source) - # ── Pass 1: collect File() definitions ──────────────────────── + # Pass 1: collect File() definitions files_by_hash: dict[str, dict] = {} var_to_hash: dict[str, str] = {} @@ -210,7 +210,7 @@ def parse_firmware_database( if var_name: var_to_hash[var_name] = key - # ── Pass 2: collect firmware slots and options ──────────────── + # Pass 2: collect firmware slots and options # FirmwareAndOption one-liner fao_re = re.compile( diff --git a/scripts/scraper/libretro_scraper.py b/scripts/scraper/libretro_scraper.py index bcd74dbb..227b5506 100644 --- a/scripts/scraper/libretro_scraper.py +++ b/scripts/scraper/libretro_scraper.py @@ -27,7 +27,7 @@ SOURCE_URL = ( ) # Libretro cores that expect BIOS files in a subdirectory of system/. -# System.dat lists filenames flat; the scraper prepends the prefix. +# System.dat lists filenames flat, and the scraper prepends the prefix. # ref: each core's libretro.c or equivalent -see platforms/README.md CORE_SUBDIR_MAP = { "nec-pc-98": "np2kai", # libretro-np2kai/sdl/libretro.c diff --git a/scripts/scraper/mame_hash_scraper.py b/scripts/scraper/mame_hash_scraper.py index 076e01ef..9a9ba104 100644 --- a/scripts/scraper/mame_hash_scraper.py +++ b/scripts/scraper/mame_hash_scraper.py @@ -39,7 +39,7 @@ _REPO_URL = "https://github.com/mamedev/mame.git" _STALE_HOURS = 24 -# ── Cache ──────────────────────────────────────────────────────────── +# Cache def _load_cache() -> dict[str, Any] | None: @@ -74,7 +74,7 @@ def _write_cache(data: dict[str, Any]) -> None: log.info("cache written to %s", _CACHE_PATH) -# ── Git operations ─────────────────────────────────────────────────── +# Git operations def _run_git( @@ -92,7 +92,7 @@ def _run_git( def _sparse_clone(tag: str) -> None: """Clone the release the data will be labelled with, not master. - The version comes from the latest release; cloning master gave line + The version comes from the latest release. Cloning master gave line numbers and hashes of a later revision under that release's label, and the profiles cited lines no declared revision holds. """ @@ -183,7 +183,7 @@ def _cleanup() -> None: shutil.rmtree(_CLONE_DIR) -# ── Profile discovery ──────────────────────────────────────────────── +# Profile discovery _MAME_TREES = frozenset({ @@ -223,7 +223,7 @@ def _find_mame_profiles() -> list[Path]: return profiles -# ── Diff formatting ────────────────────────────────────────────────── +# Diff formatting def _format_diff( @@ -268,7 +268,7 @@ def _format_diff( return lines -# ── Main ───────────────────────────────────────────────────────────── +# Main def _fetch_hashes(force: bool) -> dict[str, Any]: @@ -355,10 +355,10 @@ def release_profile( ) -> dict[str, Any]: """A profile for one MAME release a platform builds, from its own source. - Recalbox ships libretro/mame twice, built at 0.258 and at 0.278; the + Recalbox ships libretro/mame twice, built at 0.258 and at 0.278. The BIOS root sets and their ROMs change between releases, so the current MAME profile does not describe them. Each set keeps the system and the - required flag the current profile gives it; the contents and the line + required flag the current profile gives it, while the contents and the line are the release's own. """ version = release.removeprefix("mame") diff --git a/scripts/scraper/misterfpga_scraper.py b/scripts/scraper/misterfpga_scraper.py index 5f265665..3553c339 100644 --- a/scripts/scraper/misterfpga_scraper.py +++ b/scripts/scraper/misterfpga_scraper.py @@ -9,8 +9,8 @@ MiSTer verification logic (MiSTer-devel/Downloader_MiSTer): - file_system.py:705-712, hash_file() is a plain MD5 of the file bytes - jobs/process_db_index_worker.py:216, an installed file is up to date when its MD5 equals the description hash -- jobs/process_db_index_worker.py:242, integrity checks compare MD5 only; - the declared size is logged on failure but never gates the result +- jobs/process_db_index_worker.py:242, integrity checks compare MD5 only, + and the declared size is logged on failure but never gates the result - jobs/fetch_file_worker.py:61-65, a freshly downloaded file is rejected on MD5 mismatch @@ -51,7 +51,7 @@ SOURCE_URL = ( DB_MEMBER = "bios_db.json" -# Files live under games/ on the SD card; base_destination carries that prefix +# Files live under games/ on the SD card, and base_destination carries that prefix DB_ROOT = "games/" # MiSTer core folder -> (retrobios system ID, display name, core repository) diff --git a/scripts/scraper/recalbox_scraper.py b/scripts/scraper/recalbox_scraper.py index c37a912f..30dd4fb9 100644 --- a/scripts/scraper/recalbox_scraper.py +++ b/scripts/scraper/recalbox_scraper.py @@ -108,7 +108,7 @@ SYSTEMS_TREE_URL = ( ) SYSTEMS_DIR = "package/recalbox-romfs2/systems" # One raw read per system.ini made about 150 requests and GitLab throttled -# the scrape past half an hour; GraphQL returns a batch of blobs at once. +# the scrape past half an hour. GraphQL returns a batch of blobs at once. GRAPHQL_URL = "https://gitlab.com/api/graphql" BLOBS_QUERY = ( "query($paths: [String!]!, $ref: String!) { project(fullPath: \"recalbox/recalbox\") " diff --git a/scripts/scraper/retrodeck_scraper.py b/scripts/scraper/retrodeck_scraper.py index f34054a8..97e28f40 100644 --- a/scripts/scraper/retrodeck_scraper.py +++ b/scripts/scraper/retrodeck_scraper.py @@ -456,7 +456,7 @@ class Scraper(BaseScraper): "verification_mode": "md5", "cores": cores, # Each component is one emulator RetroDECK ships and launches on - # its own; retroarch is the one that runs cores. + # its own, and retroarch is the one that runs cores. "standalone_cores": [c for c in cores if c != "retroarch"], "systems": systems, } diff --git a/scripts/scraper/rocknix_scraper.py b/scripts/scraper/rocknix_scraper.py index 4fc23911..8c4c8431 100644 --- a/scripts/scraper/rocknix_scraper.py +++ b/scripts/scraper/rocknix_scraper.py @@ -40,7 +40,7 @@ SOURCE_TEMPLATE = ( "https://raw.githubusercontent.com/ROCKNIX/distribution/{ref}/" "projects/ROCKNIX/packages/rocknix/sources/scripts/rocknix-systems" ) -# The branch a test or a manual run can still name; a scrape reads the tag +# The branch a test or a manual run can still name. A scrape reads the tag # of the release its YAML is labelled with. SOURCE_URL = SOURCE_TEMPLATE.format(ref="next") STANDALONE_TREE_URL = ( @@ -53,7 +53,7 @@ def standalone_emulators(package_names: list[str]) -> list[str]: """The standalone emulators ROCKNIX packages, by the names profiles use. A package is named after its emulator with an ``-sa`` suffix - (``duckstation-sa``), once without its hyphen (``hatarisa``); both + (``duckstation-sa``), once without its hyphen (``hatarisa``), and both spellings are kept so a profile listing either is found. """ names: set[str] = set() diff --git a/scripts/scraper/romm_scraper.py b/scripts/scraper/romm_scraper.py index eb1ef6de..e1f555a6 100644 --- a/scripts/scraper/romm_scraper.py +++ b/scripts/scraper/romm_scraper.py @@ -120,7 +120,7 @@ SLUG_MAP: dict[str, str] = { # Mirrors are per file, not per core: a slug sharing a core with another reads # only the firmware that core needs for its own system. The Neo Geo slugs run # fbneo, as arcade does (index.ts:410-418), and fbneo boots every Neo Geo -# game from neogeo.zip; the fixture gives it to arcade alone. None mirrors +# game from neogeo.zip, but the fixture gives it to arcade alone. None mirrors # every file of the slug. FIRMWARE_MIRRORS: dict[str, dict[str, tuple[str, ...] | None]] = { "tg16": {"turbografx-cd": None}, diff --git a/scripts/scraper/romset_dat_importer.py b/scripts/scraper/romset_dat_importer.py index 584123aa..a75bd470 100644 --- a/scripts/scraper/romset_dat_importer.py +++ b/scripts/scraper/romset_dat_importer.py @@ -2,7 +2,7 @@ A DAT states, per set, the members an emulator version expects: name, size and CRC32. That is a recipe, and TorrentZip turns a recipe plus the ROM bytes -into the exact archive. Profiles document a few hundred sets by hand; a DAT +into the exact archive. Profiles document a few hundred sets by hand, while a DAT documents every set of one version at once. MAME ships its ``-listxml`` output as a release asset and FBNeo keeps its DATs @@ -463,7 +463,7 @@ def main() -> int: nargs="?", const="latest", help="download upstream instead of using --pack " - "(a MAME tag such as mame0289; bare, the newest release)", + "(a MAME tag such as mame0289, or bare for the newest release)", ) parser.add_argument( "--cache-dir", default=".cache/dats", diff --git a/scripts/scraper/targets/lakka_targets_scraper.py b/scripts/scraper/targets/lakka_targets_scraper.py index cdbf8c54..07350613 100644 --- a/scripts/scraper/targets/lakka_targets_scraper.py +++ b/scripts/scraper/targets/lakka_targets_scraper.py @@ -45,7 +45,7 @@ class ShellSubsetError(RuntimeError): def _condition(text: str, env: dict[str, str]) -> bool | None: - """`[ "${A}" = "x" -o "${B}" != "y" ]`, `-n`, `-z`; None when a clause + """`[ "${A}" = "x" -o "${B}" != "y" ]`, `-n`, `-z`. None when a clause tests a variable nothing has set and no other clause is true.""" results: list[bool | None] = [] for clause in re.split(r"\s+-o\s+", text): @@ -72,12 +72,12 @@ def _condition(text: str, env: dict[str, str]) -> bool | None: # The variables this scraper reads. Set inside a case statement, which the -# evaluator does not follow, they stop the scrape; anything else is skipped. +# evaluator does not follow, they stop the scrape. Anything else is skipped. WATCHED = frozenset({"OPENGLES", "LIBRETRO_CORES", "EXCLUDE_LIBRETRO_CORES"}) def _expand(value: str, env: dict[str, str]) -> str: - """${NAME} and $NAME from what is set so far; unset expands to nothing.""" + """${NAME} and $NAME from what is set so far. Unset expands to nothing.""" return re.sub( r"\$\{(\w+)\}|\$(\w+)", lambda m: env.get(m.group(1) or m.group(2), ""), @@ -182,7 +182,7 @@ def device_cores(cores_mk: str, env: dict[str, str]) -> list[str]: def device_arch(project: str, options: str) -> str: """The architecture Lakka builds a device for: aarch64 where its options - list it, else arm; the Generic images are x86_64.""" + list it, else arm. The Generic images are x86_64.""" if project == "Generic": return "x86_64" return "aarch64" if re.search(r"^\s*aarch64\)", options, re.MULTILINE) else "arm" diff --git a/scripts/scraper/targets/retropie_targets_scraper.py b/scripts/scraper/targets/retropie_targets_scraper.py index a87d2838..64d4e3a8 100644 --- a/scripts/scraper/targets/retropie_targets_scraper.py +++ b/scripts/scraper/targets/retropie_targets_scraper.py @@ -148,7 +148,7 @@ class Scraper(BaseTargetScraper): print(f" warning: no rp_module_id in {filename}", file=sys.stderr) continue # A libretro package is lr-<core> with the buildbot name hyphenated - # (lr-beetle-psx -> beetle_psx); a standalone package keeps the id + # (lr-beetle-psx -> beetle_psx), and a standalone package keeps the id # the platform list carries (dosbox-staging). core_name = module_id if core_name.startswith("lr-"): diff --git a/scripts/scraper/targets/rocknix_targets_scraper.py b/scripts/scraper/targets/rocknix_targets_scraper.py index 7f99ef0a..78129f78 100644 --- a/scripts/scraper/targets/rocknix_targets_scraper.py +++ b/scripts/scraper/targets/rocknix_targets_scraper.py @@ -91,7 +91,7 @@ def core_names(libretro: list[str], standalone: list[str]) -> list[str]: """Package names as the profiles' cores: lists spell them. A libretro package is the core's name with `-lr` (`beetle-psx-lr`, - `neocd_lr`), spelled with underscores as the buildbot names it; a + `neocd_lr`), spelled with underscores as the buildbot names it, and a standalone package drops its `-sa` (`duckstation-sa`, `hatarisa`). """ names = {re.sub(r"[-_]lr$", "", package).replace("-", "_") for package in libretro} @@ -101,7 +101,7 @@ def core_names(libretro: list[str], standalone: list[str]) -> list[str]: # A package that builds nothing itself and pulls other cores in. idtech-lr # installs ecwolf, prboom, tyrquake and vitaquake2 (vitaquake3 and boom3 on -# x86_64); no profile could name it. +# x86_64). No profile could name it. METAPACKAGES = {"idtech-lr": "projects/ROCKNIX/packages/emulators/libretro/idtech-lr/package.mk"} _IF_RE = re.compile(r'^if \[ "\$\{(\w+)\}" = "?([\w-]+)"? \]; then\n(.*?)^fi$', re.MULTILINE | re.DOTALL) @@ -111,7 +111,7 @@ def metapackage_cores(package_mk: str, arch: str) -> list[str]: """The -lr packages a metapackage depends on for one architecture. OPENGLES_SUPPORT is yes on every ROCKNIX device (config/graphic, from - OPENGLES="mesa" in projects/ROCKNIX/options); TARGET_ARCH is the device's. + OPENGLES="mesa" in projects/ROCKNIX/options), and TARGET_ARCH is the device's. """ found: list[str] = [] for variable, value, body in _IF_RE.findall(package_mk): diff --git a/scripts/siterender.py b/scripts/siterender.py index 6a10fb3f..58393157 100644 --- a/scripts/siterender.py +++ b/scripts/siterender.py @@ -13,7 +13,7 @@ SYSTEM_ICON_BASE = "https://raw.githubusercontent.com/libretro/retroarch-assets/ ICON_CACHE_PATH = Path(".cache") / "system_icons.json" # Icon names confirmed to exist upstream. A name absent from this map has not -# been checked yet; a name mapped to False has no icon and gets none rendered, +# been checked yet. A name mapped to False has no icon and gets none rendered, # because a heading with a broken image reads worse than a heading without one. _icon_available: dict[str, bool] = {} @@ -136,6 +136,12 @@ def _system_link(sys_id: str, prefix: str = "") -> str: return f"[{sys_id}]({prefix}systems/{slug}.md#{anchor})" return sys_id +def _field_text(key: object, value: object) -> str: + """A scalar of a structured block. A source reference reads as code.""" + text = str(value) + return f"`{text}`" if key == "source_ref" else text + + def _render_yaml_value(lines: list[str], val: object, indent: int = 4) -> None: """Render any YAML value as indented markdown.""" pad = " " * indent @@ -151,7 +157,7 @@ def _render_yaml_value(lines: list[str], val: object, indent: int = 4) -> None: for item in v: if isinstance(item, dict): parts = [ - f"{ik}: {iv}" + f"{ik}: {_field_text(ik, iv)}" for ik, iv in item.items() if not isinstance(iv, (dict, list)) ] @@ -164,12 +170,12 @@ def _render_yaml_value(lines: list[str], val: object, indent: int = 4) -> None: sv = str(v) if len(sv) > 200: sv = sv[:200] + "..." - lines.append(f"{pad}- **{k}:** {sv}") + lines.append(f"{pad}- **{k}:** {_field_text(k, sv)}") elif isinstance(val, list): for item in val: if isinstance(item, dict): parts = [ - f"{ik}: {iv}" + f"{ik}: {_field_text(ik, iv)}" for ik, iv in item.items() if not isinstance(iv, (dict, list)) ] diff --git a/scripts/slot.py b/scripts/slot.py index e1fdda8f..c6cb06d3 100644 --- a/scripts/slot.py +++ b/scripts/slot.py @@ -1,7 +1,7 @@ """One file per slot: keep the BIOS a core would actually load. A slot is a (system, region) pair holding several interchangeable BIOS. Region -filtering narrows a pack to one territory; a system can still ship three US +filtering narrows a pack to one territory, but a system can still ship three US PlayStation BIOS that differ only by revision, which is what leaves the choice open in the frontend. @@ -112,7 +112,7 @@ def resolve_slot_drops( """Destinations to skip, and the groups no declared order can decide. Returns (drops, undecidable). A group is decided only when every candidate - declares a priority and exactly one holds the lowest; anything else keeps + declares a priority and exactly one holds the lowest. Anything else keeps every candidate. ``held`` names the destinations the collection holds: a candidate it lacks ships nothing, so it neither wins nor displaces one. """ diff --git a/scripts/slots.py b/scripts/slots.py index 1d506258..a810b2a6 100644 --- a/scripts/slots.py +++ b/scripts/slots.py @@ -9,7 +9,7 @@ that names the right file for a slot could never win and never even be heard. The index is keyed by destination AND by name, the name carrying the union of what every same-named entry claims. Dolphin declares three IPL.bin separated -only by their path, so a name-only key merges them; a path-only key answers +only by their path, so a name-only key merges them, and a path-only key answers nothing when a candidate is known by name alone. Ambiguity resolves to the union and is never discarded, the same rule region.py already applies. """ @@ -476,7 +476,7 @@ def pack_overrides( """Full pack destination -> the file a platform pack serves there instead. Where a source-verified profile contradicts the scraped baseline on one - destination, the pack answers to the platform it is built for; in + destination, the pack answers to the platform it is built for. In existence mode the frontend never reads the bytes, so serving the emulator's file satisfies both. The ZIP builder, the install manifest and verify all read this: two of them deciding alone gave the one-line @@ -508,7 +508,7 @@ def slot_choices( """Destination -> (core, the file it has served there) in decision order. A pack built for a set of cores serves the first choice whose core is in - it, None standing for the platform's own answer; no core in it leaves + it, None standing for the platform's own answer. No core in it leaves the platform's answer too. The order is arbitrate's: a core agreeing with the platform settles the slot whatever else is present, then the strongest proof decides. Read for one core set by pack_overrides and @@ -562,7 +562,7 @@ def apply_override( def _strongest(claims: list[Claim]) -> Claim: - """The profile claim with the strongest proof; the first emulator breaks ties. + """The profile claim with the strongest proof, the first emulator breaking ties. yaps2 pins its GameIndex.yaml by sha1 while armsx2 and lrps2 only match a path: alphabetical order served armsx2's copy to all three. @@ -575,13 +575,13 @@ def arbitrate(conflict: Conflict, mode: str, addressee: str = "platform") -> Dec A pack answers to whoever asked for it. A platform pack must leave the frontend's own check green, because a user reading red concludes the pack - is broken; a pack built for one emulator answers to that emulator. The + is broken. A pack built for one emulator answers to that emulator. The other layer is served as well whenever the destination allows it. In ``existence`` mode the frontend only looks for a path, so the emulator's file satisfies both sides at once and there is nothing to trade away. In a content-checking mode the two answers cannot share one path, and the pack's - addressee decides; the loss is reported rather than absorbed, because the + addressee decides. The loss is reported rather than absorbed, because the cause is an upstream declaration that needs fixing at its source. """ profile = _strongest(conflict.profile_claims) @@ -606,7 +606,7 @@ def format_decision(decision: Decision) -> str: if decision.serves_both: winner = decision.winner.local_path # A claim that only matched a path is answered by whatever file sits - # there; only one that pins content can be left wanting. + # there. Only one that pins content can be left wanting. pinned_elsewhere = _pinned_elsewhere(conflict.profile_claims, winner) served = sorted({ c.emulator for c in conflict.profile_claims if c.emulator @@ -614,7 +614,7 @@ def format_decision(decision: Decision) -> str: others = sorted(pinned_elsewhere) line = ( f"{conflict.destination}: serve {winner} " - f"({', '.join(served) or 'profile'}); the frontend only " + f"({', '.join(served) or 'profile'}): the frontend only " "checks the path, so both are satisfied" ) if others: @@ -659,7 +659,7 @@ def find_collisions( One path holds one file, so whichever declaration the builder reaches first decides in silence. Declaring an archive several times to name its inner ROMs is the documented zipped_file pattern and resolves to one - archive; two declarations landing on two files is a contradiction the + archive. Two declarations landing on two files is a contradiction the upstream list carries. RetroDECK aims a PC-88 disk subsystem ROM and a CoCo disk ROM at one bios/disk.rom. """ diff --git a/scripts/split_pack.py b/scripts/split_pack.py index 0a9ebc84..af6ec7e9 100644 --- a/scripts/split_pack.py +++ b/scripts/split_pack.py @@ -225,7 +225,7 @@ def main() -> int: parser.add_argument("target", type=Path, help="a pack, or a directory of packs") parser.add_argument( "--max-size", type=_size, default=ASSET_LIMIT, metavar="SIZE", - help="a part stays under this many bytes (K, M, G suffixes; default 2G)", + help="a part stays under this many bytes (K, M, G suffixes, default 2G)", ) args = parser.parse_args() # The packs are rewritten in place by generate_pack under this lock: a diff --git a/scripts/torrentzip.py b/scripts/torrentzip.py index e695c2c4..d7ae054d 100644 --- a/scripts/torrentzip.py +++ b/scripts/torrentzip.py @@ -100,7 +100,7 @@ def identify_romset( """Find which recipe rebuilds to a target archive MD5. recipes maps a label (e.g. a MAME version) to a list of - (member name, CRC32 hex) pairs; atoms maps CRC32 hex to ROM bytes. + (member name, CRC32 hex) pairs, and atoms maps CRC32 hex to ROM bytes. Returns the matching label, or None when no recipe reproduces the hash. """ target = target_md5.lower() diff --git a/scripts/upstream.py b/scripts/upstream.py index 96bfd29d..325ec571 100644 --- a/scripts/upstream.py +++ b/scripts/upstream.py @@ -51,7 +51,7 @@ _HOSTS: dict[str, tuple[str, str, str]] = { "https://codeberg.org/api/v1", "https://codeberg.org", ), - # The Ryujinx repository left GitHub in October 2024; this Gitea pull + # The Ryujinx repository left GitHub in October 2024. This Gitea pull # mirror kept its history up to 1.1.1402. "git.ngram.ca": ( "forgejo", @@ -192,7 +192,7 @@ def content_url(repo: Repo, sha: str, path: str) -> str: Forgejo and Gitea hosts put their web routes, /raw/commit included, behind a proof-of-work page (git.ngram.ca answers 200 with an HTML - challenge); the API raw route is not challenged. raw_url stays the + challenge), while the API raw route is not challenged. raw_url stays the link a reader opens. """ if repo.family != "forgejo": @@ -236,7 +236,7 @@ def _host_is_unresolvable(exc: BaseException) -> bool: """Whether a connection failure is the name itself, not the network. URLError carries the cause in `reason`, and a wrapped one carries it in - `__cause__`; the walk is bounded because either chain can be cyclic. + `__cause__`. The walk is bounded because either chain can be cyclic. """ seen: BaseException | None = exc for _ in range(8): @@ -271,7 +271,7 @@ def _fetch(url: str, accept_json: bool = False) -> bytes | None: A pass over every profile issues thousands of requests, so a dropped connection or a transient 5xx is a certainty rather than an accident. - Those are retried; a definitive answer from the forge is not. + Those are retried, a definitive answer from the forge is not. """ failure: UpstreamError | None = None for attempt in range(RETRIES): @@ -376,7 +376,7 @@ def _api( ) -> object | None: """Cached API call. The cache stores absence as well as payloads. - ``max_age`` bounds the trust in a cached answer, in seconds; a stale + ``max_age`` bounds the trust in a cached answer, in seconds. A stale answer is refreshed unless the run is offline, when it still serves. ``absent_max_age`` bounds a cached absence alone, for a resource that can appear but, once there, does not change. @@ -668,7 +668,7 @@ MAX_TREE_PAGES = 50 def _gitlab_tree( repo: Repo, sha: str, cache_dir: str, offline: bool ) -> tuple[list[str], bool]: - """GitLab serves its tree in pages; each page is cached on its own URL. + """GitLab serves its tree in pages, each page cached on its own URL. A page that cannot be read mid-walk reports the listing as truncated: the paths already collected are real, but their absence proves nothing. diff --git a/scripts/validate_pr.py b/scripts/validate_pr.py index 65976a17..e25e8b83 100644 --- a/scripts/validate_pr.py +++ b/scripts/validate_pr.py @@ -86,7 +86,7 @@ class ValidationResult: return all(s != "FAIL" for s, _ in self.checks) def to_markdown(self) -> str: - status = "✅" if self.passed else "❌" + status = "PASS" if self.passed else "FAIL" lines = [f"### {status} `{self.filename}`"] lines.append("") lines.append(f"- **Path**: `{self.filepath}`") @@ -98,13 +98,13 @@ class ValidationResult: for status_str, message in self.checks: if status_str == "PASS": - lines.append(f"- ✅ {message}") + lines.append(f"- Pass: {message}") elif status_str == "FAIL": - lines.append(f"- ❌ {message}") + lines.append(f"- Fail: {message}") elif status_str == "WARN": - lines.append(f"- ⚠️ {message}") + lines.append(f"- Warning: {message}") else: - lines.append(f"- ℹ️ {message}") + lines.append(f"- Info: {message}") return "\n".join(lines) @@ -306,7 +306,7 @@ def validate_file( if expected and (len(parts) < 4 or parts[1] not in makers): # Depth alone passed a PS1 BIOS filed under bios/Nintendo/Game Boy/. result.add_warning( - "Placed under " + (here or "the bios/ root") + "; the other files of " + "Placed under " + (here or "the bios/ root") + ", while the other files of " "its system are in " + " or ".join(f"`{f}`" for f in sorted(expected)) ) elif len(parts) >= 4: @@ -316,12 +316,12 @@ def validate_file( elif expected_folders: # The contributor asks before forking: say where it goes. result.add_warning( - "File is not under bios/ yet; its system's files are in " + "File is not under bios/ yet. Its system's files are in " + " or ".join(f"`{f}`" for f in expected_folders) ) else: result.add_warning( - "File is not under bios/ yet; place it in bios/Manufacturer/Console/" + "File is not under bios/ yet. Place it in bios/Manufacturer/Console/" ) if name_known and not sha1_known and not md5_known: @@ -371,7 +371,7 @@ def get_changed_files() -> list[str]: changed.extend(found or []) if not compared: print( - "no upstream/ or origin/ main line to compare against; reading the " + "no upstream/ or origin/ main line to compare against, reading the " "staged, modified and untracked files only", file=sys.stderr, ) @@ -389,7 +389,7 @@ def _files_to_validate( if args.changed and args.files: # Named files were dropped for the git diff, and the run reported # "No changed BIOS files detected" about files it never looked at. - parser.error("--changed reads the git diff; name files or pass --changed, not both") + parser.error("--changed reads the git diff: name files or pass --changed, not both") if not args.changed: if not args.files: parser.error("No files specified. Use --changed or provide file paths.") @@ -408,7 +408,7 @@ def _load_database_if_any(path: str) -> dict | None: """The database, optional only where the default is meant. A mistyped --db read as "no database" and every file passed its - duplicate and placement checks unchecked; a damaged one did the same + duplicate and placement checks unchecked. A damaged one did the same after a warning. """ if path == DEFAULT_DB and not os.path.exists(path): @@ -473,7 +473,7 @@ def main() -> None: print(json.dumps(output, indent=2)) elif args.markdown: lines = ["## BIOS Validation Report", ""] - status = "✅ All checks passed" if all_passed else "❌ Some checks failed" + status = "all checks passed" if all_passed else "some checks failed" lines.append(f"**Status**: {status}") lines.append("") @@ -491,13 +491,13 @@ def main() -> None: print(f" Size: {r.size:,}") for s, m in r.checks: marker = ( - "✓" + "ok" if s == "PASS" - else "✗" + else "fail" if s == "FAIL" - else "!" + else "warn" if s == "WARN" - else "i" + else "info" ) print(f" [{marker}] {m}") diff --git a/scripts/validate_schemas.py b/scripts/validate_schemas.py index 26e2ad8d..2f9c3d52 100644 --- a/scripts/validate_schemas.py +++ b/scripts/validate_schemas.py @@ -134,7 +134,7 @@ def _validate_pack_manifests(dist: Path) -> list[str]: return _scan_pack_manifests(dist) except ArtifactLockBusy: print( - f"note: {dist.name} is being written; skipping pack manifests", + f"note: {dist.name} is being written, skipping pack manifests", file=sys.stderr, ) return [] @@ -340,7 +340,7 @@ def _semantic_install_checks(path: Path, manifest: dict) -> list[str]: def unchecked_formats() -> list[str]: """Formats the schemas declare that this jsonschema install cannot check. - date-time and uri need the format extras; without them the ten format + date-time and uri need the format extras. Without them the ten format constraints of the published schemas were accepted unread. """ used = { diff --git a/scripts/validation.py b/scripts/validation.py index 73174897..34fc6ec6 100644 --- a/scripts/validation.py +++ b/scripts/validation.py @@ -89,7 +89,7 @@ def _entry_rule(emu_name: str, f: dict, checks: set[str]) -> dict: def warned_checks(f: dict, checks: set[str]) -> set[str]: """The checks of an entry the code warns about instead of refusing. - `on_mismatch: warn` covers every check; a map names them one by one, as + `on_mismatch: warn` covers every check, while a map names them one by one, as Azahar refuses a SecureInfo_A of the wrong size and only logs a bad signature. """ @@ -340,7 +340,7 @@ def check_file_validation( them must accept it through one of its own entries for the name, the way each runs its own check. Without, the checks of every core naming the file are merged. A check declared `on_mismatch: warn` rejects - nothing, since the core runs with the file; ``strict`` counts it, to + nothing, since the core runs with the file, while ``strict`` counts it, to prefer a file that passes it too. Returns None if all checks pass or no validation applies. @@ -786,7 +786,7 @@ def validated_choice( """The file a platform destination ships, and the disagreement if any. A frontend's own check can pass while an emulator it runs rejects the - file; a held variant both accept replaces it. The pack and the install + file. A held variant both accept replaces it. The pack and the install manifest both read this, so they name the same file. A destination another emulator declares more precisely is that emulator's: ZEsarUX's 48 KB cpc6128.rom check has no say over ep128emu/roms/cpc6128.rom. @@ -816,8 +816,8 @@ def validated_choice( if not check(local_path, True): return local_path, None - # A held file every check passes, warn-level ones included, comes first; - # then the file itself when only a warning fails (the core runs it); + # A held file every check passes, warn-level ones included, comes first, + # then the file itself when only a warning fails (the core runs it), # then a held file the core at least runs. better = variant(True) if better: @@ -839,6 +839,6 @@ def existence_discrepancy(file_entry: dict, local_path: str, platform_display: s declared = file_entry.get("md5", "") or file_entry.get("sha1", "") actual = compute_hashes(local_path) return ( - f"packed per {platform_display} existence check; declared hash {declared}, " + f"packed per {platform_display} existence check: declared hash {declared}, " f"file md5 {actual['md5']} sha1 {actual['sha1']}" ) diff --git a/scripts/verify.py b/scripts/verify.py index d5968e96..ac180d8b 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -153,7 +153,7 @@ def verify_entry_existence( return {"name": name, "status": Status.MISSING, "required": required} result = {"name": name, "status": Status.OK, "required": required} if resolve_status == "hash_mismatch": - # The frontend reads no bytes, so the file stays; the declared hash + # The frontend reads no bytes, so the file stays, and the declared hash # it contradicts is reported, as the pack does. result["discrepancy"] = existence_discrepancy( file_entry, local_path, platform_display @@ -267,7 +267,7 @@ def verify_entry_md5( **base, "status": Status.UNTESTED, "path": local_path, - "reason": f"expected {md5_list[0][:12]}… got {actual_md5[:12]}…", + "reason": f"expected {md5_list[0][:12]}... got {actual_md5[:12]}...", } @@ -296,7 +296,7 @@ def verify_entry_sha1( **base, "status": Status.UNTESTED, "path": local_path, - "reason": f"expected {expected_sha1[:12]}… got {actual_sha1[:12]}…", + "reason": f"expected {expected_sha1[:12]}... got {actual_sha1[:12]}...", } @@ -628,7 +628,7 @@ def find_undeclared_files( # A copy contradicting the declared hash counts as held # only where the builder would ship it. Under existence # the frontend never opens the file, so the pack carries - # it and reports the divergence; under a digest mode the + # it and reports the divergence. Under a digest mode the # frontend would reject it, the builder leaves it out, and # calling it available here would describe a pack that # does not contain it. @@ -794,7 +794,7 @@ def _mark_hidden( Returns the full destinations the builder fills with a core's file. ``report`` is the gap report the caller already computed with the - builder's arguments; without it the builder's pass computes its own. + builder's arguments. Without it the builder's pass computes its own. """ from packextras import hidden_extras @@ -868,8 +868,8 @@ def _resolve_declaration( def _twin_unmet(result: dict, held_by: str | None) -> bool: """Mark a declaration unmet at a path another declaration holds. - The path is answered by the winner's file, which the pack counts once; - this declaration's failure is reported, never folded into the + The path is answered by the winner's file, which the pack counts once. + This declaration's failure is reported, never folded into the destination's status. """ if held_by is None or result["status"] == Status.OK: @@ -895,7 +895,7 @@ def _resolve_for_platform( ) -> tuple[str | None, str]: """Resolve one platform entry the way the pack builder does. - A slot the arbitration decided wins over the resolver; a frontend that + A slot the arbitration decided wins over the resolver, and a frontend that never reads the bytes takes the filename-free core's own image. """ override = slot_overrides.get( @@ -932,7 +932,7 @@ def verify_platform( mode = normalize_mode(config.get("verification_mode")) platform = config.get("platform", "unknown") - # The builder settles a destination claimed by both layers; this must read + # The builder settles a destination claimed by both layers, and this must read # the same decision, or the two tools describe different packs. has_zipped = any( fe.get("zipped_file") @@ -1588,7 +1588,7 @@ def verify_emulator( dest_to_name: dict[str, str] = {} data_dir_notices: list[str] = [] - # The emulator pack withdraws these; the report withdraws the same. + # The emulator pack withdraws these, and the report withdraws the same. region_drops: set[str] = set() if regions: from packextras import emulator_region_drops @@ -2114,7 +2114,7 @@ def print_emulator_result(result: dict, verbose: bool = False) -> None: def _refuse_listing_narrowings( args: argparse.Namespace, parser: argparse.ArgumentParser ) -> None: - """A listing mode reads --platform at most; anything else is refused. + """A listing mode reads --platform at most, anything else is refused. Printing past a narrowing flag lets the user believe it applied (generate_pack applies the same table). @@ -2378,7 +2378,7 @@ def _main(held: contextlib.ExitStack) -> None: def _json_details(details: list[dict], verbose: bool) -> list[dict]: """The entries a JSON report lists: what needs attention, or every one. - --verbose shows each entry with its ground truth in the text report; it + --verbose shows each entry with its ground truth in the text report. It used to be accepted beside --json and dropped, the output byte for byte the same, so a script asking for the passing entries got nothing. """ diff --git a/scripts/ziptools.py b/scripts/ziptools.py index 9a8cabe4..7e8ab3f1 100644 --- a/scripts/ziptools.py +++ b/scripts/ziptools.py @@ -223,7 +223,7 @@ MAX_ZIP_MEMBERS = 100_000 MAX_ZIP_MEMBER_SIZE = 8 * 1024 * 1024 * 1024 # The largest generated pack is already ~5 GB uncompressed and the collection -# only grows; this bounds a malicious archive without capping a real one. +# only grows. This bounds a malicious archive without capping a real one. MAX_ZIP_TOTAL_SIZE = 64 * 1024 * 1024 * 1024 # DEFLATE cannot exceed roughly 1,032:1, so this rejects a declared ratio no @@ -249,14 +249,14 @@ def safe_extract_zip( """ dest = os.path.realpath(dest_dir) os.makedirs(dest, exist_ok=True) - # Reading the umask sets it; it is put back at once. + # Reading the umask sets it, so it is put back at once. umask = os.umask(0) os.umask(umask) with zipfile.ZipFile(zip_path, "r") as zf: members = zf.infolist() if len(members) > max_members: raise ValueError( - f"ZIP has {len(members)} members; limit is {max_members}" + f"ZIP has {len(members)} members, limit is {max_members}" ) declared_total = 0 @@ -292,7 +292,7 @@ def safe_extract_zip( declared_total += member.file_size if declared_total > max_total_size: raise ValueError( - f"ZIP expands to {declared_total} bytes; limit is {max_total_size}" + f"ZIP expands to {declared_total} bytes, limit is {max_total_size}" ) if member.file_size and member.compress_type in _BOUNDED_RATIO_METHODS: if member.compress_size == 0: @@ -331,7 +331,7 @@ def safe_extract_zip( f"ZIP member size mismatch for {name}: " f"{actual_size} != {member.file_size}" ) - # The member's own mode, else what a plain open() gives; the + # The member's own mode, else what a plain open() gives. The # temporary file is private and would keep 0600 otherwise. os.chmod(tmp_path, ((mode & 0o777) or 0o666) & ~umask) os.replace(tmp_path, target) diff --git a/tests/__init__.py b/tests/__init__.py index 9edbc0fa..e18270d4 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,6 +1,6 @@ """No test downloads a release asset unless it says so. -The CI job sets RETROBIOS_OFFLINE; a local run of the documented command +The CI job sets RETROBIOS_OFFLINE, but a local run of the documented command did not, and e2e fixtures queried the large-files release and wrote its answers into the shared .cache/large. A test that serves its own assets clears the variable for itself. diff --git a/tests/test_agnostic_scope.py b/tests/test_agnostic_scope.py index 06e1d891..a99635be 100644 --- a/tests/test_agnostic_scope.py +++ b/tests/test_agnostic_scope.py @@ -56,7 +56,7 @@ class AgnosticScan(unittest.TestCase): class BundledHashIsProof(unittest.TestCase): """A bundled file with a declared hash is served by those bytes or flagged. - Four NetherSX2-Turnip entries named their own sha1; the collection held + Four NetherSX2-Turnip entries named their own sha1, but the collection held NetherSX2's copies, which the builder shipped in their place. """ diff --git a/tests/test_agnostic_substitute.py b/tests/test_agnostic_substitute.py index 3c6cb00a..8ba581e2 100644 --- a/tests/test_agnostic_substitute.py +++ b/tests/test_agnostic_substitute.py @@ -1,7 +1,7 @@ """Pack, verify and manifest answer the same way for a filename-agnostic core. The pack alone renamed any PS2 image into a missing slot, even on an md5 -platform whose frontend then rejects it, and counted it OK; verify called +platform whose frontend then rejects it, and counted it OK, while verify called the slot missing and the manifest omitted it. """ diff --git a/tests/test_archive_choice.py b/tests/test_archive_choice.py index 860f6dbd..d961a48b 100644 --- a/tests/test_archive_choice.py +++ b/tests/test_archive_choice.py @@ -127,7 +127,7 @@ class IntegrityChecksEveryMember(unittest.TestCase): class TheArchiveHoldingTheCoreMembers(unittest.TestCase): """FBNeo reads neocd.bin and 000-lo.lo inside neocdz.zip. The primary - copy has no 000-lo.lo; a variant holds both. Resolved by name, every + copy has no 000-lo.lo, and a variant holds both. Resolved by name, every pack shipped the primary at fbneo/neocdz.zip and the core could not start a Neo Geo CD game.""" @@ -182,7 +182,7 @@ class TheArchiveHoldingTheCoreMembers(unittest.TestCase): self.assertEqual(extra["members"], members) def test_the_collection_holds_each_archive_a_core_requires(self): - """FBNeo's nmk004.zip wants nmk004.bin crc 8ae61a09; both copies held + """FBNeo's nmk004.zip wants nmk004.bin crc 8ae61a09, but both copies held MAME's 83b6f611 dump while the FBNeo dump sat loose in bios/.""" import json diff --git a/tests/test_artifact_lock.py b/tests/test_artifact_lock.py index c77c8b2f..905db767 100644 --- a/tests/test_artifact_lock.py +++ b/tests/test_artifact_lock.py @@ -111,7 +111,7 @@ class PackLockCliTest(unittest.TestCase): self.assertIn("is in use by another run", proc.stdout) def test_every_writing_mode_refuses_a_locked_output(self): - """Two of seven modes took the lock; five wrote straight into it. + """Two of seven modes took the lock, and five wrote straight into it. A mode that writes packs or manifests into a directory another run holds produces the half-written artifact the lock exists to prevent. @@ -225,7 +225,7 @@ class PipelineHoldsTheDataTrees(unittest.TestCase): class SiteGenerationHoldsDocs(unittest.TestCase): """generate_site swept from docs/ every file its own run had not written, including the scratch file and new pages of a second run on - the same tree; that run then died on os.replace or lost pages.""" + the same tree. That run then died on os.replace or lost pages.""" def test_a_second_run_is_refused_before_it_writes(self): docs = _tempdir(self) diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index f813c88b..86ef1ffd 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -45,7 +45,7 @@ from scripts.generate_pack import ( class ReadmeRegressions(unittest.TestCase): - """The README advertises commands; these must stay executable. + """The README advertises commands, and these must stay executable. Wording is the maintainer's, so nothing here asserts prose. What is asserted is that every flag and URL the README hands a reader is one the @@ -114,7 +114,7 @@ class ReadmeRegressions(unittest.TestCase): class ReleaseSigningRegressions(unittest.TestCase): """A checksum list published beside its own artifacts proves nothing. - SHA256SUMS.txt answers corruption; whoever can rewrite a release rewrites + SHA256SUMS.txt answers corruption, but whoever can rewrite a release rewrites the list with it. The signature is what a third party checks, and it is only checkable while allowed_signers, the signing step and the upload list stay in agreement. @@ -227,7 +227,7 @@ class WorkflowRegressions(unittest.TestCase): self.assertIsNotNone(job, "no job runs the test suite") self.assertIsNone( workflow["jobs"][job].get("if"), - f"{job} carries a condition; the suite must run on push and on PR", + f"{job} carries a condition, but the suite must run on push and on PR", ) def test_added_profiles_meet_their_upstream_on_both_roads(self): @@ -250,7 +250,7 @@ class WorkflowRegressions(unittest.TestCase): self.assertEqual( triggers["pull_request"]["paths"], triggers["push"]["paths"], - "the two path lists have drifted; a push would skip what a PR checks", + "the two path lists have drifted, so a push would skip what a PR checks", ) def test_pull_request_only_jobs_are_guarded(self): @@ -265,7 +265,7 @@ class WorkflowRegressions(unittest.TestCase): ) def test_no_workflow_relies_on_a_yaml_anchor(self): - """The workflow parser reads no anchor; PyYAML would hide the break.""" + """The workflow parser reads no anchor, and PyYAML would hide the break.""" for path in sorted((ROOT / ".github" / "workflows").glob("*.yml")): for number, line in enumerate( path.read_text(encoding="utf-8").splitlines(), 1 @@ -513,8 +513,8 @@ class PatchesTargetWhatRuns(unittest.TestCase): class StandaloneCopiesNameTheirSource(unittest.TestCase): - """The registry's anchor names one path per file for every platform; - each manifest places the file its own way, and the installer copied + """The registry's anchor names one path per file for every platform, + while each manifest places the file its own way, and the installer copied nothing where the two differed (EmuDeck's aes_keys.txt, Batocera's switch/prod.keys).""" @@ -551,7 +551,7 @@ class StandaloneCopiesNameTheirSource(unittest.TestCase): class ADamagedArchiveIsNotPacked(unittest.TestCase): """The deterministic rebuild raises on a member whose bytes fail their - CRC; the builder caught it and copied the damaged archive into the pack + CRC. The builder caught it and copied the damaged archive into the pack "for verify to flag", which nothing did.""" def test_the_rebuild_refusal_reaches_the_run(self): @@ -577,7 +577,7 @@ class ADamagedArchiveIsNotPacked(unittest.TestCase): class PackReadmesSayWhatTheInstallerDoes(unittest.TestCase): """The EmuDeck README promised keys set up automatically (they need - --standalone-copies) and gave a Citra path the installer never uses; the + --standalone-copies) and gave a Citra path the installer never uses, and the RetroArch README offered only `| sh`, which Windows cannot run.""" def _guide(self, platform: str) -> str: @@ -654,7 +654,7 @@ class AutoFetchReadsListsAndPlacesWithoutClobbering(unittest.TestCase): class NoParserAcceptsAnAbbreviation(unittest.TestCase): """argparse completes a prefix: `slots.py --emulator dolphin` became - --emulators-dir dolphin and reported 0 contested destinations, exit 0; + --emulators-dir dolphin and reported 0 contested destinations, exit 0, and `pipeline.py --all` became --all-variants and built six packs per platform. The flags read like other scripts' and were never refused.""" @@ -680,7 +680,7 @@ class NoParserAcceptsAnAbbreviation(unittest.TestCase): class FaqRegressions(unittest.TestCase): - """The FAQ states facts the code owns; these tie it back to the source. + """The FAQ states facts the code owns, and these tie it back to the source. Three of its claims had drifted: a pinned MAME version, Adler-32 attributed to Dolphin's IPL instead of its DSP ROMs, and a verbose @@ -730,7 +730,7 @@ class FaqRegressions(unittest.TestCase): self.assertIn(name, sentence, f"FAQ omits the Adler-32 file {name}") self.assertNotIn( "IPL.bin", carriers, - "IPL.bin gained an Adler-32 hash; the docs say it has none", + "IPL.bin gained an Adler-32 hash, but the docs say it has none", ) for page in ("faq.md", "profiling.md"): text = (ROOT / "wiki" / page).read_text(encoding="utf-8") @@ -905,7 +905,7 @@ class PipelineRegressions(unittest.TestCase): def test_nothing_parsed_is_not_consistent(self): """A changed output format must not pass with no platform compared.""" with contextlib.redirect_stdout(io.StringIO()): - self.assertFalse(pipeline.check_consistency("RetroArch — 2/2 OK", "")) + self.assertFalse(pipeline.check_consistency("RetroArch = 2/2 OK", "")) self.assertFalse(pipeline.check_consistency("", "")) def test_pack_without_verify_result_is_a_failure(self): @@ -922,7 +922,7 @@ class PipelineRegressions(unittest.TestCase): self.assertFalse(pipeline.check_consistency(verify, pack)) def test_only_the_full_variant_feeds_the_comparison(self): - """--all-variants printed six packs under one label; the last won.""" + """--all-variants printed six packs under one label, and the last won.""" output = "\n".join([ "Generating pack for RetroArch [source=full]...", " a.zip: 5 files packed (5 baseline + 0 from cores), 535/535 files OK", @@ -932,7 +932,7 @@ class PipelineRegressions(unittest.TestCase): self.assertEqual(pipeline.parse_pack_counts(output), {"RetroArch": (535, 535)}) def test_exclusions_read_only_the_full_variant(self): - """--all-variants printed six packs under one label; the last won.""" + """--all-variants printed six packs under one label, and the last won.""" output = "\n".join([ "Generating pack for Batocera [source=full]...", " a.zip: 5 files packed (5 baseline + 0 from cores), 5/5 files OK, 3 unsafe excluded", @@ -967,7 +967,7 @@ class PipelineRegressions(unittest.TestCase): def test_a_targeted_export_reads_a_full_model(self): - """--target wrote truth/<target>/ only; the export read truth/.""" + """--target wrote truth/<target>/ only, but the export read truth/.""" commands: list[list[str]] = [] def fake_run(command, _label): @@ -991,7 +991,7 @@ class PipelineRegressions(unittest.TestCase): class SchemaFormatsAreChecked(unittest.TestCase): - """date-time and uri need jsonschema's format extras; without them the + """date-time and uri need jsonschema's format extras. Without them the published format constraints were accepted unread.""" @unittest.skipUnless(HAS_JSONSCHEMA, "validating a schema needs jsonschema") @@ -1082,7 +1082,7 @@ class OneBaselineVerdict(unittest.TestCase): """The builder and the manifest each wrote the platform baseline. The builder looked inside a zipped_file archive whatever the outer - resolution said; the manifest only after a hash_mismatch. An archive + resolution said, the manifest only after a hash_mismatch. An archive found by name without the member Batocera checks left the pack and stayed in the manifest. A slot override replaced a release asset in the manifest and not in the pack. @@ -1130,7 +1130,7 @@ class OneBaselineVerdict(unittest.TestCase): def test_the_builder_accepts_what_verify_accepts(self): """verify took a 29-character md5 by prefix and a ZIP by its - composite; the builder compared exact md5s and refused both when + composite, but the builder compared exact md5s and refused both when another declared hash disagreed.""" import hashlib @@ -1695,7 +1695,7 @@ class InstallerBoundaryRegressions(unittest.TestCase): def test_target_schema_accepts_the_null_the_generator_emits(self): """The schema and generate_target_manifests must agree on null. - A target with no core list is written as null; a schema that rejects + A target with no core list is written as null, and a schema that rejects it turns a valid manifest into a CI failure. """ from jsonschema import Draft202012Validator @@ -1742,7 +1742,7 @@ class InstallerBoundaryRegressions(unittest.TestCase): """A target without a core inventory must not void the manifest. generate_target_manifests emits null for a target that publishes no - core list; rejecting the document would silently disable --target for + core list. Rejecting the document would silently disable --target for every target on that platform. """ normalized = install._validate_targets({"windows": None, "switch": ["a5200"]}) @@ -1934,7 +1934,7 @@ class EveryManifestEntryIsFetchable(unittest.TestCase): def test_repo_paths_name_the_file_the_database_holds(self): """A manifest written before a file moved sends the installer to 404. - database.json is regenerated whenever a file is refiled; the manifests + database.json is regenerated whenever a file is refiled, but the manifests are a separate artefact and were left behind once (the two DS firmware dumps of the 7 September refile). The installer fetches repo_path from raw.githubusercontent.com, so a stale one is a @@ -1958,7 +1958,7 @@ class EveryManifestEntryIsFetchable(unittest.TestCase): def test_release_entries_are_exactly_the_files_git_does_not_hold(self): """The installer has two sources, and the manifest must pick the right one. - A committed file is served by the repository; a gitignored one by + A committed file is served by the repository, a gitignored one by the large-files release. Marking a committed file as a release asset sends the installer to an asset nobody uploaded (sdlpal/5.avi, 83 MB in git, was announced as release asset `5.avi`). Marking a gitignored @@ -2016,7 +2016,7 @@ class ReleaseAssetCriterion(unittest.TestCase): generate_pack._registered.cache_clear() def test_the_manifest_names_the_asset_as_github_serves_it(self): - # GitHub publishes a space as a dot; the site linked the dotted + # GitHub publishes a space as a dot. The site linked the dotted # name while the manifest gave install.py the spaced one, a 404. from scripts import generate_pack @@ -2056,7 +2056,7 @@ class ReleaseAssetsMatchTheCollection(unittest.TestCase): downloads, and the manifest size is that of the local copy. Both FBNeo sample archives were rebuilt locally after their upload and never re-uploaded: same members, different container, every install of them - failed. The comparison is offline here on a fixture; the script runs it + failed. The comparison is offline here on a fixture, while the script runs it against the live release. """ @@ -2098,12 +2098,12 @@ class ReleaseAssetsMatchTheCollection(unittest.TestCase): ) def test_release_notes_are_rendered_from_the_collection(self): - """The release page is written by hand and drifts; it is rendered instead. + """The release page is written by hand and drifts, so it is rendered instead. Three assets had no row, three rows carried the SHA1 of an asset that had since been replaced, and the footer counted 41 files for 44. - Hand-written descriptions survive by name; a new row takes its - description from the profile that declares the file; an asset the + Hand-written descriptions survive by name. A new row takes its + description from the profile that declares the file, and an asset the collection does not index is listed apart, with its size only. """ from scripts import check_release_assets @@ -2263,7 +2263,7 @@ class FreshnessGuardMechanics(unittest.TestCase): deploy-site.yml regenerates README.md and CONTRIBUTING.md and then fails if git sees a change. That is only a staleness check because a run which - moves nothing but the clock leaves the file untouched; if the comparison + moves nothing but the clock leaves the file untouched. If the comparison missed a timestamp form, the guard would fail on every run and stop meaning anything. """ @@ -2663,7 +2663,7 @@ class APackNameFitsAFileName(unittest.TestCase): def test_two_systems_never_name_one_system(self): """sega-dreamcast,arcade and sega-dreamcast-arcade both wrote - RetroArch_..._Dreamcast_Arcade.zip; the second replaced the first.""" + RetroArch_..._Dreamcast_Arcade.zip, and the second replaced the first.""" from scripts.generate_pack import _system_tag pairs = [ @@ -2699,8 +2699,8 @@ class AGroupPackIsWrittenUnderItsOwnName(unittest.TestCase): class ARegionDroppedExtraBlocksNothing(unittest.TestCase): - """The builder skips a region-dropped core extra before placing it; - the report placed it anyway, so on a case-folding platform it hid the + """The builder skips a region-dropped core extra before placing it, + but the report placed it anyway, so on a case-folding platform it hid the next core's FOO.ROM that the pack does carry.""" def test_the_report_skips_what_the_region_pass_drops(self): @@ -2731,7 +2731,7 @@ class ARegionDroppedExtraBlocksNothing(unittest.TestCase): class AnotherEmulatorsTreeProvesNothing(unittest.TestCase): - """lrps2 names no hash for pcsx2/resources/GameIndex.yaml; the only + """lrps2 names no hash for pcsx2/resources/GameIndex.yaml, and the only full-tail copy was ARMSX2's, which counted as path proof and replaced the GameIndex RetroArch pins on desktop targets, where ARMSX2 does not exist. Upstream PCSX2 took ARMSX2's patches.zip by name the same way.""" @@ -2920,7 +2920,7 @@ class TheZipIndexCacheKnowsItsInputs(unittest.TestCase): class GeneratedModelsAreWrittenWhole(unittest.TestCase): """The truth model and the cumulative MAME clone map were written by - truncate-then-write; a corrupt clone map also read as empty and was + truncate-then-write, and a corrupt clone map also read as empty and was then overwritten, losing what earlier runs recorded.""" def test_both_writers_replace_their_file_atomically(self): @@ -2953,7 +2953,7 @@ class GeneratedModelsAreWrittenWhole(unittest.TestCase): class APackNoteBesideItsSlotIsANote(unittest.TestCase): """The builder writes INSTRUCTIONS_<name>.txt beside the slot it - explains; verify_pack recognised notes at the ZIP root only and failed + explains, but verify_pack recognised notes at the ZIP root only and failed a pack holding games/keen6/INSTRUCTIONS_egagraph.ck6.txt.""" def test_a_nested_note_is_not_hashed_against_the_collection(self): @@ -2973,7 +2973,7 @@ class APackNoteBesideItsSlotIsANote(unittest.TestCase): class NoHandlerSwallowsEverything(unittest.TestCase): - """CLAUDE.md forbids `except Exception: pass`; the edit hook missed the + """CLAUDE.md forbids `except Exception: pass`, but the edit hook missed the two-line form and nothing in CI checked it.""" def test_no_catch_all_handler_only_passes(self): @@ -3093,7 +3093,7 @@ class ModuleConstantsDeclaredOnce(unittest.TestCase): class OnlyTheSchemaValidatorNeedsJsonschema(unittest.TestCase): - """Build scripts and install.py run on stdlib plus pyyaml; jsonschema is + """Build scripts and install.py run on stdlib plus pyyaml, and jsonschema is tooling for validate_schemas and CI. An import anywhere else turns a contributor's pipeline run into an ImportError.""" @@ -3337,7 +3337,7 @@ class AnAcceptedVersionIsNoCoreDiscrepancy(unittest.TestCase): class ADataDirectoryCopyPassesTheNameChecks(unittest.TestCase): """The name steps over bios/ refuse a candidate outside the size or the - Adler-32 the entry's code checks; a cache copy found by the same name + Adler-32 the entry's code checks, but a cache copy found by the same name was returned without either check.""" def setUp(self): @@ -3543,7 +3543,7 @@ class VerifyStrictAppliesInEveryMode(unittest.TestCase): class OpenMsxRomsSitInItsSystemroms(unittest.TestCase): """openMSX entries had no path and landed at the BIOS root, where no frontend points FilePool. RetroBat declares its ROMs under - openMSX/share/systemroms; the profile's paths must agree.""" + openMSX/share/systemroms, and the profile's paths must agree.""" def test_every_entry_is_under_share_systemroms(self): profile = yaml.safe_load((ROOT / "emulators" / "openmsx.yml").read_text()) @@ -3565,8 +3565,8 @@ class OpenMsxRomsSitInItsSystemroms(unittest.TestCase): class ASameNamedMemberIsNotTheFile(unittest.TestCase): """The gap report counted touchhle's LiberationMono-Regular.ttf as held - because idtech4a++'s extras.zip has a member of that name, another font; - verify --emulator said missing.""" + because idtech4a++'s extras.zip has a member of that name, another font, + while verify --emulator said missing.""" def test_a_declared_hash_decides_a_member_or_data_hit(self): from scripts import cross_reference as xr @@ -3897,7 +3897,7 @@ class MessagesSeparateWithAColon(unittest.TestCase): class AReaderThatLeavesEarlyIsNoCrash(unittest.TestCase): """`verify.py --list-emulators | head -1` ended on a BrokenPipeError - traceback; every listing and report did.""" + traceback, and so did every listing and report.""" def test_a_closed_pipe_ends_quietly(self): proc = subprocess.Popen( @@ -3977,7 +3977,7 @@ class TheIssueFormListsEveryPlatform(unittest.TestCase): class TheTestJobHasTheDataTrees(unittest.TestCase): - """Packs built without data directories exit non-zero; the CI test job + """Packs built without data directories exit non-zero, but the CI test job had none, and two pack parity tests failed there only.""" def test_the_trees_are_fetched_before_the_suite(self): @@ -4214,7 +4214,7 @@ class SignaturesCarryTheirTypes(unittest.TestCase): shared API among them (artifact locks, the data-dir resolver, the region priority list of _select_variants).""" - # Lowered as modules are annotated; never raised. + # Lowered as modules are annotated, never raised. CEILING = 0 COMPLETE = ("artifacts.py", "common.py", "validation.py", "generate_pack.py") @@ -4321,7 +4321,7 @@ class DocumentedHashLookupsFindTheirFile(unittest.TestCase): class ToolReferenceListsEveryModule(unittest.TestCase): """The exporter table described retropie_exporter as a System.dat writer - and left out bizhawk, misterfpga and rocknix; the target table missed + and left out bizhawk, misterfpga and rocknix, and the target table missed recalbox and rocknix. A contributor reads these tables as the map.""" def _rows(self, heading: str) -> set[str]: @@ -4395,7 +4395,7 @@ class EveryOptionIsDocumented(unittest.TestCase): """profile_sync's --system, --stale-before and --ref, auto_fetch --create-issues, download.py --info and forty more were in no page: a maintainer ran --all and spent the API quota that --system would have - saved. --help lists a flag; only a page says when to reach for it.""" + saved. --help lists a flag, but only a page says when to reach for it.""" def test_every_long_option_of_a_tracked_script_is_in_the_docs(self): tracked = subprocess.run( @@ -4582,7 +4582,7 @@ class GapsPageCountsOneWay(unittest.TestCase): class UnsourceableCardSaysWhy(unittest.TestCase): """DraStic's nds_firmware_modified.bin carried an 'unsourceable' badge - and nothing else; the reason was only on the gaps page.""" + and nothing else. The reason was only on the gaps page.""" def test_reason_and_link(self): from scripts.generate_site import _render_emulator_file @@ -4859,7 +4859,7 @@ class ZippedFileMd5IsParsedOnce(unittest.TestCase): class AHashListIsReadOneWay(unittest.TestCase): """mesence declares four sha256 for BS-X.bin as one comma-joined string. - The resolver split it and shipped the file; the gap report and + The resolver split it and shipped the file, but the gap report and profile_sync looked the whole string up and called it missing.""" def test_every_reader_splits_the_list(self): @@ -4878,7 +4878,7 @@ class AHashListIsReadOneWay(unittest.TestCase): class RommNeoGeoFoldersGetTheirBios(unittest.TestCase): """RomM runs fbneo for neogeoaes and neogeomvs as for arcade and reads - firmware per platform folder; the fixture gives neogeo.zip to arcade + firmware per platform folder, but the fixture gives neogeo.zip to arcade alone, so a Neo Geo game in its own folder started without it.""" def test_the_mirror_is_per_file(self): @@ -4971,7 +4971,7 @@ class DocumentedExamplesHoldTogether(unittest.TestCase): class TheReadmeCountsSystemsAsListSystemsDoes(unittest.TestCase): """The README counted every raw spelling (nes and nintendo-nes as two) - and announced 550 systems; the tool it points to listed 513.""" + and announced 550 systems while the tool it points to listed 513.""" def test_one_count(self): import io @@ -5070,7 +5070,7 @@ class AFailedVerificationIsAnError(unittest.TestCase): class TheGroundTruthFooterSaysWhatItCounts(unittest.TestCase): """"417 platform-only (no emulator profile)" where 369 of 526 files had - a profile; 20% here for 21% on the site; and "0/81 (0%)" for MiSTer, + a profile, 20% here for 21% on the site, and "0/81 (0%)" for MiSTer, which declares no core by design.""" def _footer(self, coverage): @@ -5121,8 +5121,8 @@ class ThePipelineSummaryTimesEachStep(unittest.TestCase): class StrictFailsOnMissingOnly(unittest.TestCase): - """The docstring promised exit 1 on a required file missing or rejected; - a rejected file is UNTESTED, a warning, and --strict never saw it.""" + """The docstring promised exit 1 on a required file missing or rejected, + but a rejected file is UNTESTED, a warning, and --strict never saw it.""" def test_the_contract(self): from scripts import verify as verify_mod diff --git a/tests/test_batocera_cores.py b/tests/test_batocera_cores.py index 118604d1..1746ab4e 100644 --- a/tests/test_batocera_cores.py +++ b/tests/test_batocera_cores.py @@ -112,8 +112,8 @@ class AnEmulatorLaunchedBothWaysGetsBothLayouts(unittest.TestCase): self.assertEqual(system_ini_libretro(ini) & standalone, {"dolphin"}) def test_upstream_yaml_is_read_as_its_code_reads_it(self): - """configgen-defaults.yml names rtcw's core twice; the strict loader - stopped the rescrape, Batocera's PyYAML keeps the last value.""" + """configgen-defaults.yml names rtcw's core twice. The strict loader + stopped the rescrape, while Batocera's PyYAML keeps the last value.""" from safeparse import yaml_load_upstream self.assertEqual( diff --git a/tests/test_bios_companions.py b/tests/test_bios_companions.py index fa063771..2786dd53 100644 --- a/tests/test_bios_companions.py +++ b/tests/test_bios_companions.py @@ -2,7 +2,7 @@ PCSX2 opens <bios>.rom1 or <stem>.rom1, and nvm and mec the same way. Its profile named them rom1.bin, ROM2.BIN and EROM.BIN, names the code never -opens; ROM2.BIN found a misfiled Galaksija ROM inside the PS2 folder, and a +opens. ROM2.BIN found a misfiled Galaksija ROM inside the PS2 folder, and a 4 MB size bound then swept GameIndex.yaml and cheat archives to the root of the Batocera BIOS folder. """ diff --git a/tests/test_casefold_cache.py b/tests/test_casefold_cache.py index 41250986..9105f9ca 100644 --- a/tests/test_casefold_cache.py +++ b/tests/test_casefold_cache.py @@ -27,7 +27,7 @@ class CasefoldIndexFollowsItsSource(unittest.TestCase): class APrimaryUnderAnotherCasing(unittest.TestCase): - """x1 asked for IPLROM.X1; only Recalbox's second md5 sat under that + """x1 asked for IPLROM.X1, and only Recalbox's second md5 sat under that casing, in .variants/, and it won over iplrom.x1, the dump every platform pins, in the same directory.""" diff --git a/tests/test_check_freshness.py b/tests/test_check_freshness.py index 16d89744..619867c6 100644 --- a/tests/test_check_freshness.py +++ b/tests/test_check_freshness.py @@ -317,7 +317,7 @@ class RepositoryWiringTests(unittest.TestCase): def test_a_target_of_every_declared_core_does_not_age(self): """RetroBat, RetroDECK and RomM name one target that runs every core - they declare; with nothing hand-kept, there is no date to watch.""" + they declare. With nothing hand-kept, there is no date to watch.""" import tempfile # noqa: PLC0415 from pathlib import Path as _Path # noqa: PLC0415 @@ -370,7 +370,7 @@ class PinsWithExtras(unittest.TestCase): class AStaticTargetStillNamesItsCores(unittest.TestCase): - """RetroBat's single target is `cores: null`; the check returned OK + """RetroBat's single target is `cores: null`, and the check returned OK before reading the names, and its 50 unprofiled emulators never showed.""" def test_declared_names_are_checked(self): diff --git a/tests/test_core_file_fills_declaration.py b/tests/test_core_file_fills_declaration.py index c107a2fd..b62e8350 100644 --- a/tests/test_core_file_fills_declaration.py +++ b/tests/test_core_file_fills_declaration.py @@ -97,7 +97,7 @@ class ACoreFileFillsAFreeDeclaration(unittest.TestCase): class AFileDeclaredUnderAnotherName(unittest.TestCase): """The platform declares ROM1 with the md5 of the core's ROM. The - builder packs ROM at the core's path; verify read the enriched + builder packs ROM at the core's path, but verify read the enriched declarations, took ROM as declared and never counted it.""" def test_the_report_lists_what_the_builder_packs(self): @@ -145,7 +145,7 @@ class AFileDeclaredUnderAnotherName(unittest.TestCase): class AMissingDataDirectoryFailsTheRun(unittest.TestCase): """A refresh refused by a quota left the PPSSPP pack with 2 files and - the run exited 0; nothing downstream checks data directories.""" + the run exited 0: nothing downstream checks data directories.""" def test_the_pack_records_it_and_main_exits_non_zero(self): import generate_pack as gp @@ -225,7 +225,7 @@ class AFileNobodyHoldsIsAnOmission(unittest.TestCase): class AMemberNameIsNotALooseFile(unittest.TestCase): """verify counted a core file "in pack" when its name existed only as a - member of some ZIP (naomi2.zip's 315-6146.bin); the builder, which reads + member of some ZIP (naomi2.zip's 315-6146.bin), but the builder, which reads no archive member names, shipped nothing.""" def test_verify_reads_undeclared_files_as_the_builder_does(self): @@ -261,7 +261,7 @@ class AMemberNameIsNotALooseFile(unittest.TestCase): class TwoDeclarationsOfOnePath(unittest.TestCase): """Two systems declare one destination under two names, no hash, one held. The builder packed the held file and kept the first verdict it - read; verify kept the worst, on the raw destination. Read either way + read, while verify kept the worst, on the raw destination. Read either way round, both must count the path once and met.""" def _run(self, first: str, second: str, spelling: str): diff --git a/tests/test_cross_reference_sources.py b/tests/test_cross_reference_sources.py index 6371f832..d3596012 100644 --- a/tests/test_cross_reference_sources.py +++ b/tests/test_cross_reference_sources.py @@ -55,7 +55,7 @@ class GapReportSources(unittest.TestCase): self.assertEqual(report["gpgx"]["gaps"], 0) def test_any_accepted_version_fills_the_slot(self): - """raze accepts ten DUKE3D.GRP; the report judged the first alone and + """raze accepts ten DUKE3D.GRP, but the report judged the first alone and listed the file to acquire while the collection holds the tenth.""" profiles = {"raze": {"emulator": "Raze", "systems": ["dos"], "files": [ {"name": "DUKE3D.GRP", "path": "DUKE3D.GRP", "size": 1, "sha1": "a" * 40}, diff --git a/tests/test_declared_names.py b/tests/test_declared_names.py index eb3a5607..b233ed91 100644 --- a/tests/test_declared_names.py +++ b/tests/test_declared_names.py @@ -54,7 +54,7 @@ class FlatDeclaredSet(unittest.TestCase): class AnAliasIsADeclaration(unittest.TestCase): """RetroArch lists amiberry's cd32.rom as kick40060.CD32, an alias the - profile declares; the gap report still called cd32.rom undeclared.""" + profile declares, yet the gap report still called cd32.rom undeclared.""" def test_a_file_declared_under_its_alias_is_covered(self): profiles = {"amiberry": { diff --git a/tests/test_dedup.py b/tests/test_dedup.py index cc81de58..5bab6a64 100644 --- a/tests/test_dedup.py +++ b/tests/test_dedup.py @@ -108,7 +108,7 @@ class TrueDuplicates(_Bios): def test_two_variants_of_one_content_keep_one(self): # msx.rom.a317e6b4 and MSX.ROM.e998f0c4 differ only by casing and - # suffix; nothing outside .variants/ holds the bytes in this tree. + # suffix, and nothing outside .variants/ holds the bytes in this tree. self.write("Microsoft/MSX/.variants/msx.rom.a317e6b4") self.write("Microsoft/MSX/.variants/MSX.ROM.e998f0c4") self.run_dedup() @@ -295,7 +295,7 @@ class PathPriority(unittest.TestCase): class TheNoDedupListIsPinned(unittest.TestCase): """Every directory the dedup must leave alone, with the reason written - beside it in dedup.py. Only RPG Maker and ScummVM were tested; a merge + beside it in dedup.py. Only RPG Maker and ScummVM were tested, so a merge that dropped c64-emu would have the name step serve the C128 keymap to three machines again, with the suite green.""" diff --git a/tests/test_derivations.py b/tests/test_derivations.py index 38be8f5a..a346224e 100644 --- a/tests/test_derivations.py +++ b/tests/test_derivations.py @@ -1,7 +1,7 @@ """Catalog entries the collection already holds in another layout. 391773/391774, the two Kickstart 3.1 chips of the A1200, are the high and low -16-bit words of the image the collection keeps, byte-swapped; TOSEC's Basic V7 +16-bit words of the image the collection keeps, byte-swapped, and TOSEC's Basic V7 is two held ROMs end to end. The gap report listed them as acquisition targets. """ @@ -104,7 +104,7 @@ class ARomsetMemberIsASource(unittest.TestCase): class CombineMatchesZlib(unittest.TestCase): - """The operator is composed once per length; it must stay zlib's.""" + """The operator is composed once per length, and it must stay zlib's.""" def test_against_zlib(self): import os diff --git a/tests/test_deterministic_zip.py b/tests/test_deterministic_zip.py index 78653f49..2d5659fa 100644 --- a/tests/test_deterministic_zip.py +++ b/tests/test_deterministic_zip.py @@ -325,7 +325,7 @@ class TestPackDeterminism(unittest.TestCase): def test_an_executable_source_stays_executable(self): """Pinning the mode stripped the bit the RetroDECK pack needs. - It ships the two Voxatron engine binaries; extracted at 644 they + It ships the two Voxatron engine binaries, and extracted at 644 they cannot be run. Git records the bit, so reading it from the source leaves the pack the same from any clone. """ diff --git a/tests/test_download.py b/tests/test_download.py index 0702b2c2..dfd8da08 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -219,7 +219,7 @@ class TestPackGrouping(unittest.TestCase): self.assertIsNone(download.find_pack(_release(RELEASE_ASSETS), "nintendo")) def test_find_pack_resolves_a_platform_id_that_drops_separators(self): - # The platform is `misterfpga` everywhere else; the asset is MiSTer_FPGA. + # The platform is `misterfpga` everywhere else, but the asset is MiSTer_FPGA. pack = download.find_pack( _release(RELEASE_ASSETS + ["MiSTer_FPGA_2026-08-29_BIOS_Pack.zip"]), "misterfpga", diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 228fd170..0003f3c2 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -1129,7 +1129,7 @@ class TestE2E(unittest.TestCase): self.assertEqual(result, {"fceumm", "gambatte"}) def test_a_build_a_platform_compiles_is_reached_by_name(self): - """Recalbox compiles libretro/mame at 0.258 and 0.278; the buildbot + """Recalbox compiles libretro/mame at 0.258 and 0.278, but the buildbot RetroArch installs from does not, so all_libretro must not reach them while a platform naming them does.""" profiles = { @@ -2888,7 +2888,7 @@ class TestE2E(unittest.TestCase): # --platform + --system is a valid combination self.assertTrue(has_platform and has_system) - # ── BizHawk scraper tests ────────────────────────────────────── + # BizHawk scraper tests def test_150_bizhawk_scraper_parse_firmware_and_option(self): """Parse FirmwareAndOption() one-liner pattern.""" @@ -3087,7 +3087,7 @@ class TestE2E(unittest.TestCase): # --------------------------------------------------------------- def test_159_cross_ref_archive_in_repo(self): - """Archived files group by archive; in_repo=True when archive exists.""" + """Archived files group by archive, in_repo=True when archive exists.""" config = load_platform_config("test_existence", self.platforms_dir) profiles = load_emulator_profiles(self.emulators_dir) undeclared = find_undeclared_files( @@ -3438,7 +3438,7 @@ class TestE2E(unittest.TestCase): self.assertNotIn("lr_file.bin", names) def test_171_generate_truth_dedup_required_wins(self): - """Dedup merges cores; required=True wins over required=False.""" + """Dedup merges cores and required=True wins over required=False.""" import yaml as _yaml from common import _emulator_profiles_cache @@ -3521,7 +3521,7 @@ class TestE2E(unittest.TestCase): "unprofiled_core", [name for name in profiles if name == "unprofiled_core"] ) # unprofiled_core has no profile YAML so resolve_platform_cores - # won't include it; cores_resolved reflects only matched profiles + # won't include it, so cores_resolved reflects only matched profiles self.assertEqual(cov["cores_resolved"], 1) self.assertNotIn("unprofiled_core", cov["cores_unprofiled"]) @@ -4297,7 +4297,7 @@ class TestE2E(unittest.TestCase): cov = truth["_coverage"] self.assertEqual(cov["cores_profiled"], 1) # core_b has no profile YAML, so resolve_platform_cores never - # includes it; cores_resolved reflects only matched profiles + # includes it, so cores_resolved reflects only matched profiles self.assertEqual(cov["cores_resolved"], 1) # Inject unprofiled info into system-level coverage for diff. @@ -6002,7 +6002,7 @@ struct BurnDriver BurnDrvneogeo = { # --all took the same filter and wrote twelve complete manifests. (["--all", "--manifest"], ["--system", "sony-playstation"], "refuse"), (["--all", "--split"], ["--system", "sony-playstation"], "refuse"), - # A pack built with --system is named after its systems; the check + # A pack built with --system is named after its systems, but the check # looked for the full pack instead. (["--platform", "retroarch", "--verify-packs"], ["--system", "sony-playstation"], "refuse"), @@ -6089,7 +6089,7 @@ struct BurnDriver BurnDrvneogeo = { --target narrowed the build and nothing else: the conformance stage held every targeted pack to the platform's whole system list and core set, so a correct build exited non-zero on hundreds of files it - was never asked to carry. Region was already passed to the check; + was never asked to carry. Region was already passed to the check, and target has to travel the same way, which is why the pack is not in the skip list. """ @@ -6124,7 +6124,7 @@ struct BurnDriver BurnDrvneogeo = { ) def test_standalone_mode_names_itself(self): - """--emulator --standalone ships a different file set; without a tag it + """--emulator --standalone ships a different file set, and without a tag it overwrote the pack built without it.""" from generate_pack import _narrowings diff --git a/tests/test_emulator_pack_counts.py b/tests/test_emulator_pack_counts.py index 3b43f7cf..10faa915 100644 --- a/tests/test_emulator_pack_counts.py +++ b/tests/test_emulator_pack_counts.py @@ -65,7 +65,7 @@ class PackAndReportAgree(unittest.TestCase): class APlaceholderIsAnsweredByEvidence(unittest.TestCase): """LRPS2 declares only <bios>.bin: no name to look up, so its emulator pack shipped no PS2 BIOS and verify said missing. Another profile of the - system proves the folder by hash; the images there of the declared + system proves the folder by hash, and the images there of the declared size are what the core reads.""" def test_pack_and_report_carry_the_images(self): diff --git a/tests/test_export_counts.py b/tests/test_export_counts.py index 37f95182..bf3bc04b 100644 --- a/tests/test_export_counts.py +++ b/tests/test_export_counts.py @@ -80,7 +80,7 @@ class RetroDeckWritesWhatItCounts(unittest.TestCase): self.assertEqual(changes.applied, []) def test_an_addition_at_another_path_is_written(self): - """melonDS: RetroDECK declares firmware.bin at the root; the truth adds + """melonDS: RetroDECK declares firmware.bin at the root and the truth adds SkyEmu/firmware.bin. Keyed by name and system, the addition vanished and the report still counted it.""" existing = [{"filename": "firmware.bin", "system": "nds", "md5": A}] @@ -265,7 +265,7 @@ class PureDataExportsKeepWhatWeDoNotModel(unittest.TestCase): def test_two_additions_differing_by_directory_are_two_lines(self): """PCSX2's vulkan and opengl convert.glsl were both written under the - bare name; the second was dropped and still counted as added.""" + bare name, so the second was dropped and still counted as added.""" from exporter.baseline import Report shaders = [ @@ -424,7 +424,7 @@ class SystemDatKeepsItsQuoting(unittest.TestCase): class ModelKeepsOneFileOneEntry(unittest.TestCase): def test_a_list_of_sizes_is_not_one_size(self): - """A profile may accept several revisions; int() on the list crashed.""" + """A profile may accept several revisions, and int() on the list crashed.""" several = NativeFile("a.bin", "a.bin", "s", truth={"size": [1024, 2048], "crc32": "aaaaaaaa"}) single = NativeFile("b.bin", "b.bin", "s", truth={"size": [1024], "crc32": "aaaaaaaa"}) self.assertIsNone(several.size()) @@ -521,7 +521,7 @@ class RommKeepsItsOwnKeys(unittest.TestCase): self.assertEqual(changes.applied, ["doom/PLUTONIA.WAD sha1"]) def test_the_shared_helper_reads_every_exporter_the_same_way(self): - """RomM's writable is per instance; the base helper bound fe as self.""" + """RomM's writable is per instance, but the base helper bound fe as self.""" from exporter import discover_exporters # noqa: PLC0415 theirs = NativeFile("boot.bin", "dc/boot.bin", "dc", @@ -688,8 +688,8 @@ class RetroDeckCorrectsOnlyWhatItCarries(unittest.TestCase): class BatoceraKeepsTheRunnerKeys(unittest.TestCase): def test_emulator_and_core_travel_with_a_rewritten_entry(self): - """checkBios skips a BIOS whose emulator or core is not installed; - rewritten without the keys, vectrex's MAME BIOS was wanted by every + """checkBios skips a BIOS whose emulator or core is not installed. + Rewritten without the keys, vectrex's MAME BIOS was wanted by every build.""" from exporter.batocera_exporter import Exporter as Batocera # noqa: PLC0415 @@ -788,8 +788,8 @@ class ACorruptOriginalIsRefused(unittest.TestCase): class TheSummaryCountsWhatTheFileCarries(unittest.TestCase): """RomM kept the sha1 and crc the truth contradicts beside the corrected - md5, and RomM accepts any one hash; RetroDECK kept a cleared md5 and - Recalbox an element it could not rewrite, both counted cleared; RomM and + md5, and RomM accepts any one hash. RetroDECK kept a cleared md5 and + Recalbox an element it could not rewrite, both counted cleared. RomM and System.dat counted a sha1 filled that no record could hold.""" def _contradicted(self): diff --git a/tests/test_exporters.py b/tests/test_exporters.py index f8064b4c..a49de4cc 100644 --- a/tests/test_exporters.py +++ b/tests/test_exporters.py @@ -130,7 +130,7 @@ class Reconciliation(unittest.TestCase): """The platform's file corrected, not replaced by ours.""" def test_a_bare_truth_name_is_not_a_path_suffix(self): - """fbneo's boot.bin has no path; libretro's dc/boot.bin ends in + """fbneo's boot.bin has no path, while libretro's dc/boot.bin ends in /boot.bin. The suffix paired them past the size guard and wrote the 480-byte file's size and hashes over the 2 MB Dreamcast BIOS.""" truth = {"systems": {"sega-dreamcast": {"files": [ @@ -161,7 +161,7 @@ class Reconciliation(unittest.TestCase): self.assertEqual(agreeing.size(), 955352) def test_a_size_list_keeps_the_platform_size_it_accepts(self): - """geargrafx accepts syscard3.pce headerless or headered; System.dat + """geargrafx accepts syscard3.pce headerless or headered, and System.dat states 262144 for the same dump. The list came first, stated no single size, and the rom line went out with none.""" both = NativeFile( @@ -323,7 +323,7 @@ class ExporterRegistry(unittest.TestCase): ) def test_only_a_format_with_the_field_claims_to_carry_it(self): - """Recalbox writes mandatory; RetroBat's entries are md5 and file.""" + """Recalbox writes mandatory, while RetroBat's entries are md5 and file.""" exporters = discover_exporters() self.assertIn("required", exporters["recalbox"].carries()) self.assertNotIn("required", exporters["retrobat"].carries()) @@ -384,7 +384,7 @@ class SearchOrder(unittest.TestCase): def test_a_region_the_help_already_fills_gets_no_alternative(self): """PicoDrive loads the first file of each region's list. RetroPie - names one per region; the export appended three more, which the + names one per region, but the export appended three more, which the sentence reads as three more required files.""" from exporter.baseline import NativeSystem # noqa: PLC0415 @@ -415,7 +415,7 @@ class SearchOrder(unittest.TestCase): """Nothing is dropped on the rank here, so the best one wins. slot.py voids the choice when cores disagree because it keeps one - file; ordering keeps them all, and a file that is some core's first + file, while ordering keeps them all, and a file that is some core's first choice belongs early. """ merged = {"name": "scph5501.bin", "priority": 2, "priority_conflict": True} @@ -521,7 +521,7 @@ class PinnedRevision(unittest.TestCase): self.assertEqual(pinned_base(wanted, scraped), "") def test_every_platform_that_records_its_source_pins_the_export(self): - """A scraped platform states the revision; the export follows it.""" + """A scraped platform states the revision, and the export follows it.""" exporters = discover_exporters() for name in ("batocera", "recalbox", "bizhawk", "romm", "retroarch"): with self.subTest(platform=name): @@ -674,7 +674,7 @@ class RecalboxExport(unittest.TestCase): self.assertEqual(exporter.validate(systems, produced), []) def test_an_addition_goes_where_the_core_reads_it(self): - """DuckStation reads scph5000.bin at the BIOS root; the export wrote + """DuckStation reads scph5000.bin at the BIOS root, but the export wrote psx/scph5000.bin, a path no core opens.""" import copy # noqa: PLC0415 @@ -693,7 +693,7 @@ class RecalboxExport(unittest.TestCase): """Recalbox files Pentagon and Scorpion under zxspectrum, apart. Merged, the Scorpion ROMs sat under the Pentagon name and the BIOS - manager lost a section; the line the maintainer commented out went + manager lost a section, and the line the maintainer commented out went with the rewrite. """ old, new = "1" * 32, "2" * 32 @@ -755,7 +755,7 @@ class RommExport(unittest.TestCase): return exporter, systems, exporter.render(systems, report, {}, None) def test_every_entry_can_actually_verify(self): - """RomM matches on size and then on one hash; without both, never. + """RomM matches on size and then on one hash: without both, never. An entry no source gives a size to carries none and validate() names it: this test passed for one only because it held the string "None".""" @@ -885,7 +885,7 @@ class SystemDatKeepsSpaceIndentedLines(unittest.TestCase): class RommSizeIsNeverNone(unittest.TestCase): """size() is None where the truth contradicts RomM's hash without a size - or names several sizes; str(None) went out as "None", validate() passed + or names several sizes. str(None) went out as "None", validate() passed it as truthy, and RomM's int("None") raised.""" def _export(self, platform_size): @@ -1223,7 +1223,7 @@ class UpstreamFidelity(unittest.TestCase): def setUpClass(cls): if not UPSTREAM_CACHE.is_dir(): raise unittest.SkipTest( - "no upstream cache; run scripts/export_native.py --all --fetch" + "no upstream cache, run scripts/export_native.py --all --fetch" ) def _export(self, platform: str, truth: dict | None = None) -> dict[str, str]: @@ -1498,7 +1498,7 @@ class UpstreamFidelity(unittest.TestCase): } def test_retropie_keeps_every_name_its_packages_already_list(self): - """RetroPie's BIOS list is prose; a name it writes is never removed.""" + """RetroPie's BIOS list is prose, and a name it writes is never removed.""" produced, originals = self._export("retropie", self.RETROPIE_TRUTH) exporter = discover_exporters()["retropie"]() help_of = re.compile(r'rp_module_help="((?:[^"\\]|\\.)*)"') @@ -1590,7 +1590,7 @@ class ARecordDescribesOneDump(unittest.TestCase): class AnAdditionCarriesItsRunner(unittest.TestCase): - """Batocera's apple2 entry is gated on libretro/mame; Clock Signal's + """Batocera's apple2 entry is gated on libretro/mame, so Clock Signal's apple2.rom written inside it was asked of mame users and never of clk users. Recalbox got core="libretro/duckstation", a core it never runs.""" diff --git a/tests/test_extra_identity.py b/tests/test_extra_identity.py index 508fa56d..a0761e39 100644 --- a/tests/test_extra_identity.py +++ b/tests/test_extra_identity.py @@ -65,7 +65,7 @@ class IdentityTravels(unittest.TestCase): class UnsourceableIsNoCopy(unittest.TestCase): """The second pass copies a covered file to another core's path by name. - zc210 ships its own default.sf2; dosbox-staging reads a default.sf2 that + zc210 ships its own default.sf2, while dosbox-staging reads a default.sf2 that the operating system links to its SoundFont, which no collection holds. The name was enough to give dosbox-staging a slot, recorded as missing while zc210 was in the pack and absent once it was not, so a pack built @@ -98,8 +98,8 @@ class UnsourceableIsNoCopy(unittest.TestCase): class BareNameIsADestination(unittest.TestCase): - """geargrafx reads syscard1.pce at the root of the system directory; - Recalbox declares it only under pcenginecd/. The declaration settles the + """geargrafx reads syscard1.pce at the root of the system directory, + but Recalbox declares it only under pcenginecd/. The declaration settles the core's need on the promise that the builder copies the file to the core's path, and the second pass skipped every entry with no path.""" diff --git a/tests/test_extract_targets.py b/tests/test_extract_targets.py index ac08f36c..bd8c2248 100644 --- a/tests/test_extract_targets.py +++ b/tests/test_extract_targets.py @@ -48,7 +48,7 @@ class ExtractTargets(unittest.TestCase): self.assertEqual(explained, rooted) def test_no_generator_keeps_its_own_table(self): - """The which-pack page describes setups per OS; these two were the + """The which-pack page describes setups per OS, and these two were the per-platform copies of the registry.""" readme = (REPO_ROOT / "scripts" / "generate_readme.py").read_text(encoding="utf-8") site = (REPO_ROOT / "scripts" / "generate_site.py").read_text(encoding="utf-8") diff --git a/tests/test_file_consumers.py b/tests/test_file_consumers.py index 837a9c7d..3ef7a56c 100644 --- a/tests/test_file_consumers.py +++ b/tests/test_file_consumers.py @@ -1,7 +1,7 @@ """A file's readers are the entries that resolve to it, not those sharing its name. The site joined database files to emulators and platforms by bare name. The -collection holds the pak0.pk3 of Quake III and of Enemy Territory; each page +collection holds the pak0.pk3 of Quake III and of Enemy Territory, and each page named every engine that reads a pak0.pk3 as a reader of both, which is the homonym tests/test_game_data_homonyms.py forbids the resolver to serve. """ diff --git a/tests/test_fileless_audit.py b/tests/test_fileless_audit.py index 74196326..d8e179a9 100644 --- a/tests/test_fileless_audit.py +++ b/tests/test_fileless_audit.py @@ -95,7 +95,7 @@ class TestFilelessAudit(unittest.TestCase): self.assertIsNone(self._run()) def test_an_alias_has_no_files_of_its_own(self): - """eden-nightly is eden under another name; it was swept and its + """eden-nightly is eden under another name, yet it was swept and its forge's 403 failed the run.""" self._write(BASE + "type: alias\nalias_of: other\n") self.assertIsNone(self._run()) @@ -107,7 +107,7 @@ class TestFilelessAudit(unittest.TestCase): class TestCommandLine(unittest.TestCase): """Named profiles were the only mode, so the documented example printed - nothing; a misspelt name ended in a traceback and an unreachable source + nothing. A misspelt name ended in a traceback and an unreachable source left the run green.""" def setUp(self): @@ -155,7 +155,7 @@ class TestCommandLine(unittest.TestCase): class TestCorpusIsAnswered(unittest.TestCase): """Every fileless profile is covered, answered, or flagged. - Offline, so it reads the fetch cache; skipped where that is cold rather + Offline, so it reads the fetch cache, and is skipped where that is cold rather than turning a network absence into a failure. """ diff --git a/tests/test_find_pinned_revision.py b/tests/test_find_pinned_revision.py index 4651b29f..473633fd 100644 --- a/tests/test_find_pinned_revision.py +++ b/tests/test_find_pinned_revision.py @@ -1,7 +1,7 @@ """A platform's pinned revision found in its upstream history. RetroArch pins ScummVM's queen.tbl and FBNeo's hiscore.dat at revisions -today's upstream no longer carries; the bytes are in the project's history. +today's upstream no longer carries, but the bytes are in the project's history. """ from __future__ import annotations diff --git a/tests/test_game_data_homonyms.py b/tests/test_game_data_homonyms.py index 9ea68c41..d28ccfcc 100644 --- a/tests/test_game_data_homonyms.py +++ b/tests/test_game_data_homonyms.py @@ -5,7 +5,7 @@ under `baseq2/` and Half-Life's under `valve/`. The name step of the resolver ignores directories, so once one of them is collected every other entry of that name resolves to it and a pack ships the wrong game's bytes under the right path. The collection stores such a file under the tail the engine -reads (`.../baseq2/pak0.pak`), which lets its own entry resolve by path; an +reads (`.../baseq2/pak0.pak`), which lets its own entry resolve by path. An entry that only reaches the same file by its bare name is a homonym, and carries `unsourceable:` until its own bytes are held. """ @@ -192,7 +192,7 @@ class SecondPassKeepsIdentity(unittest.TestCase): class ReleaseAssetIsNotANameMatch(unittest.TestCase): """The release fallback keeps the flag the local resolver honours. - ioquake3's baseq3/pak0.pk3 is flagged unsourceable; the local resolver + ioquake3's baseq3/pak0.pk3 is flagged unsourceable. The local resolver returned not_found, then the release fallback looked the asset up by its bare name and handed Return to Castle Wolfenstein's demo pak to three platform manifests. @@ -256,7 +256,7 @@ class ReleaseAssetAnswersEveryDeclaredHash(unittest.TestCase): class ForeignCopyYieldsToADataDirectory(unittest.TestCase): """codehandler.bin is held by three Dolphin forks under bios/Other/, all - different; Dolphin, PrimeHack and Triforce got MMJR's by index order + different. Dolphin, PrimeHack and Triforce got MMJR's by index order while data/dolphin-sys, which Dolphin reads, held the upstream file.""" def test_the_data_directory_answers_before_another_emulators_copy(self): @@ -412,7 +412,7 @@ class SwitchKeysAreTheNewestSet(unittest.TestCase): class Pc98ScsiBiosIsNotTheAppleCard(unittest.TestCase): - """np2kai declared an exact 16 KB its loader never requires; the Apple II + """np2kai declared an exact 16 KB its loader never requires, so the Apple II SCSI card ROM of that size won the name tie over the PC-98 BIOS.""" def test_np2kai_resolves_the_pc98_rom(self): @@ -455,7 +455,7 @@ class BundledFilesComeFromTheirOwnTree(unittest.TestCase): class HeldFilesAreNotUnsourceable(unittest.TestCase): - """`unsourceable:` says the collection cannot hold a file; once its bytes + """`unsourceable:` says the collection cannot hold a file, so once its bytes sit at the path the entry names, the flag hides them. The RTCW demo paks and the Spearhead 2.11 pak3 were collected the night @@ -487,7 +487,7 @@ class HeldFilesAreNotUnsourceable(unittest.TestCase): class BundledFilesAreTheBuildTheyDescribe(unittest.TestCase): """A bundled file is documented from one build. msx-emu's cbios.txt is the - C-BIOS 0.29 notes (10469 bytes); the collection held the 0.23 notes and + C-BIOS 0.29 notes (10469 bytes), but the collection held the 0.23 notes and served them by name. future-pinball-fploader documents BAM 1.5-408 and received the 1.5-360 BAM.dll. A namesake of another size is another build: the entry needs a hash, its own bytes, or `unsourceable:`.""" diff --git a/tests/test_hash_merge.py b/tests/test_hash_merge.py index c7a79a62..7ebae883 100644 --- a/tests/test_hash_merge.py +++ b/tests/test_hash_merge.py @@ -199,7 +199,7 @@ class TestMameMerge(unittest.TestCase): def test_numeric_looking_rom_name_survives_the_write(self) -> None: """MAME ships ROMs named 01 and 23. Bare YAML turns them into numbers. - The manager set loads "01"; written unquoted it re-parses as the + The manager set loads "01", but written unquoted it re-parses as the integer 1 and the profile stops naming the file the driver opens. """ from scripts.scraper._hash_merge import ( @@ -370,7 +370,7 @@ class TheScraperClonesTheReleaseItLabels(unittest.TestCase): class AReleaseProfileDescribesItsOwnRelease(unittest.TestCase): - """Recalbox builds libretro/mame at 0.258 and at 0.278; the current + """Recalbox builds libretro/mame at 0.258 and at 0.278, but the current MAME profile described neither. A release profile carries that release's sets and pins, and keeps the system the current profile gives a set.""" @@ -571,7 +571,7 @@ class TestDiff(unittest.TestCase): self.assertEqual(len(diff["updated"]), 0) def test_diff_fbneo_keeps_a_per_rom_ref(self) -> None: - """The scraper knows the driver line; a curated ref knows its ROM.""" + """The scraper knows the driver line, while a curated ref knows its ROM.""" profile = _make_fbneo_profile() profile["files"][0]["crc32"] = "9036d879" profile["files"][0]["size"] = 131072 diff --git a/tests/test_hidden_extras.py b/tests/test_hidden_extras.py index 14eb8dd3..a97b1fdf 100644 --- a/tests/test_hidden_extras.py +++ b/tests/test_hidden_extras.py @@ -51,7 +51,7 @@ class OneRule(unittest.TestCase): def test_a_refused_declaration_occupies_nothing(self): """verify counted a declaration whose hash the frontend refuses as - occupying its path; the builder leaves it out, and the core file + occupying its path, but the builder leaves it out, and the core file that then takes the path was reported missing from the pack.""" source = (REPO_ROOT / "scripts" / "verify.py").read_text(encoding="utf-8") compact = " ".join(source.split()) @@ -92,7 +92,7 @@ class TheReportSaysSo(unittest.TestCase): db = load_database("database.json") profiles = load_emulator_profiles("emulators") - # Platforms whose filesystem folds case; RetroPie and Lakka run on + # Platforms whose filesystem folds case. RetroPie and Lakka run on # Linux and keep both names. cls.results = { name: verify_platform( @@ -115,7 +115,7 @@ class TheReportSaysSo(unittest.TestCase): self.assertIn("another case", entry.get("omitted", "")) def test_a_twin_with_the_same_bytes_serves_the_core(self): - # MesenCE opens bios.col; RetroArch's pack folds it onto BIOS.col, + # MesenCE opens bios.col, and RetroArch's pack folds it onto BIOS.col, # the same bytes, which serves the core on a folding filesystem. entry = self._entry("MesenCE", "bios.col") self.assertIsNot(entry.get("in_pack"), False) diff --git a/tests/test_identity.py b/tests/test_identity.py index 79e73b5d..a90f9796 100644 --- a/tests/test_identity.py +++ b/tests/test_identity.py @@ -69,7 +69,7 @@ class TestCrossVendorDuplicates(unittest.TestCase): def test_an_exemption_does_not_cover_a_third_maker(self): # The four Roland ROMs were exempt by content alone, under a reason - # naming a DOSBox tree; the second copies sat in the Amiga tree and + # naming a DOSBox tree, but the second copies sat in the Amiga tree and # nothing could tell. self._write("Magnavox/Odyssey2/o2rom.bin", b"odyssey") self._write("Philips/Videopac/O2.bin", b"odyssey") diff --git a/tests/test_install.py b/tests/test_install.py index 5672ca15..0f133643 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -389,7 +389,7 @@ class TestFreeSpaceGuard(unittest.TestCase): class AFolderThatRefusesWritesIsNamed(unittest.TestCase): """A read-only BIOS folder ended the run on a traceback (a subfolder to - create), or on three retries per file and "once that is resolved"; a + create), or on three retries per file and "once that is resolved", and a platform named but not detected was told to use sudo, which on another machine creates /userdata/bios on the wrong disk.""" @@ -893,8 +893,8 @@ class TestStandaloneCopiesExtraDirs(unittest.TestCase): class StandaloneCopiesReadWhereThePackPutTheFile(unittest.TestCase): - """The registry names Citra/sysdata/aes_keys.txt for every platform; - EmuDeck's manifest installs it at the root. The installer looked under + """The registry names Citra/sysdata/aes_keys.txt for every platform, + but EmuDeck's manifest installs it at the root. The installer looked under the registry's path, found nothing and copied nothing to Azahar.""" def _copy(self, entry: dict) -> tuple[Path, tuple[int, int, int]]: @@ -971,7 +971,7 @@ class DetectionFollowsTheRegistry(unittest.TestCase): def test_every_config_file_read_is_published(self): """The registry published five RetroArch config files and the fixed - RetroDECK folder; the installer also read Snap, the older macOS file, + RetroDECK folder, but the installer also read Snap, the older macOS file, C:\\RetroArch, Program Files, ES-DE, Steam and RetroDECK's own config. A manifest reader saw a subset of what the installer does.""" import yaml # noqa: PLC0415 @@ -1196,7 +1196,7 @@ class InstallerStaysOnPython38AndTheStdlib(unittest.TestCase): python38 = shutil.which("python3.8") if python38 is None: - self.skipTest("no python3.8 on PATH; the static checks below still run") + self.skipTest("no python3.8 on PATH, the static checks below still run") code = ( "import importlib.util; " "spec = importlib.util.spec_from_file_location('install', 'install.py'); " @@ -1224,7 +1224,7 @@ class InstallerStaysOnPython38AndTheStdlib(unittest.TestCase): if python38 is None: if os.environ.get("CI"): self.fail("CI must provide python3.8 for the installer's floor") - self.skipTest("no python3.8 on PATH; the static checks below still run") + self.skipTest("no python3.8 on PATH, the static checks below still run") handler = functools.partial( http.server.SimpleHTTPRequestHandler, directory=str(REPO_ROOT) ) @@ -1334,7 +1334,7 @@ class InstallerStaysOnPython38AndTheStdlib(unittest.TestCase): def test_no_local_is_assigned_and_never_read(self): - """ruff --select F in py38 mode is the installer's lint gate; an + """ruff --select F in py38 mode is the installer's lint gate, and an unread `appdata` in _os_default_dests made it exit 1. The suite has no ruff, so the rule is read from the syntax tree.""" import ast # noqa: PLC0415 @@ -1472,7 +1472,7 @@ class TargetFlagIsAppliedOrRefused(unittest.TestCase): class TestBaseUrlScheme(unittest.TestCase): - """The bootstraps insist on HTTPS; the installer must not be laxer.""" + """The bootstraps insist on HTTPS, so the installer must not be laxer.""" def test_https_is_accepted(self): self.assertEqual( @@ -1989,7 +1989,7 @@ class TestAvailablePlatforms(unittest.TestCase): with tempfile.TemporaryDirectory(dir=scratch) as directory: root = Path(directory) # A piped script must not trust a same-named file in the caller's - # working directory; only a real local install.sh may use its peer. + # working directory. Only a real local install.sh may use its peer. (root / "install.py").write_text( "raise SystemExit('untrusted cwd installer ran')\n", encoding="utf-8", @@ -2190,7 +2190,7 @@ class TargetListFailureIsNotAnAnswer(unittest.TestCase): class RetroArchWhereItReallyLives(unittest.TestCase): """Windows: retroarch.cfg sits beside retroarch.exe and system defaults - to <exe folder>\\system; only %APPDATA% was read, and the fallback was a + to <exe folder>\\system. Only %APPDATA% was read, and the fallback was a folder RetroArch never reads. macOS: the config is under Application Support/RetroArch/config, the system folder in Documents.""" @@ -2385,7 +2385,7 @@ class AnUnreadableRetroDeckConfigIsSaid(unittest.TestCase): class TheBoardTheSystemNamesIsTheTarget(unittest.TestCase): """Batocera, Recalbox and ROCKNIX each write the board they were built - for; the installer read none of them, so a Batocera RPi4 installed + for, but the installer read none of them, so a Batocera RPi4 installed every board's files (8.6 GiB where bcm2711 needs 5.5).""" def test_each_source_is_read(self): @@ -2509,7 +2509,7 @@ class BizHawkIsFoundWhereItReads(unittest.TestCase): class RetroArchUwpIsFound(unittest.TestCase): """The UWP/MSIX RetroArch keeps retroarch.cfg and system/ in its - package's LocalState; no rule looked under %LOCALAPPDATA%\\Packages.""" + package's LocalState, but no rule looked under %LOCALAPPDATA%\\Packages.""" def _state(self) -> Path: local = Path(_tempdir(self)) @@ -2536,7 +2536,7 @@ class RetroArchUwpIsFound(unittest.TestCase): class QuitMeansNoAtTheLastQuestion(unittest.TestCase): - """Every menu taught q as quit; at "Download 3.2 GB ...? [Y/n]" a q + """Every menu taught q as quit, yet at "Download 3.2 GB ...? [Y/n]" a q started the download.""" def test_quit_words_refuse(self): @@ -2591,7 +2591,7 @@ class ACutFileListIsRetried(unittest.TestCase): class DataDirectoriesAreInstalled(unittest.TestCase): - """The README said the installer does what the pack does; for RetroArch + """The README said the installer does what the pack does, but for RetroArch it left out 2,640 data files (Dolphin's Sys, PPSSPP's assets) and --check still said "All files up to date".""" @@ -2846,7 +2846,7 @@ class SteamRetroArchOnMacIsPortable(unittest.TestCase): class AMissingFileListNamesTheRef(unittest.TestCase): """A 404 on the manifest said three attempts were made and to check the - connection and proxy; it was asked once, and the cause is the ref.""" + connection and proxy, but it was asked once, and the cause is the ref.""" def _run(self, ref: str) -> str: error = install.urllib.error.HTTPError("u", 404, "Not Found", None, None) diff --git a/tests/test_install_cores.py b/tests/test_install_cores.py index 7fe61090..3d104654 100644 --- a/tests/test_install_cores.py +++ b/tests/test_install_cores.py @@ -114,7 +114,7 @@ class NarrowToCores(unittest.TestCase): class TheBuildersOrder(unittest.TestCase): """RetroPie reads megaplay.zip as advancemame (copy A), mame (copy B), then mame2003 (copy A). Without advancemame the builder ships mame's - copy; merging mame2003 into the first copy gave it A.""" + copy, and merging mame2003 into the first copy gave it A.""" ENTRY = { "dest": "megaplay.zip", "sha1": "a" * 40, "size": 1, @@ -245,7 +245,7 @@ class APlatformOmissionKeepsItsClaim(unittest.TestCase): class APlatformFileSettledByCoresAndSystems(unittest.TestCase): - """RetroArch's dsi_bios9.bin ships melonds' copy where melonds runs; on + """RetroArch's dsi_bios9.bin ships melonds' copy where melonds runs. On a target without it the pack serves the platform's answer, and the pinned nintendo-dsi declaration gives way to the bare nintendo-ds one once its system drops. The installer kept melonds' copy on rpi4.""" diff --git a/tests/test_install_experience.py b/tests/test_install_experience.py index 71d71111..9eb27c3d 100644 --- a/tests/test_install_experience.py +++ b/tests/test_install_experience.py @@ -32,7 +32,7 @@ PAYLOAD = bytes(range(256)) * 400 # 102400 bytes class _RangeHandler(http.server.BaseHTTPRequestHandler): - """Serves PAYLOAD with Range support; fails first when asked to.""" + """Serves PAYLOAD with Range support and fails first when asked to.""" ranges: list[str] = [] fail_first: list[int] = [] @@ -312,8 +312,8 @@ class CommandLine(unittest.TestCase): class ReviewCases(unittest.TestCase): - """Saying no to the large-download question ended on Done; --quiet hid - fatal messages and swallowed --check; a resumed copy inflated the speed.""" + """Saying no to the large-download question ended on Done, --quiet hid + fatal messages and swallowed --check, and a resumed copy inflated the speed.""" def test_declining_is_not_done(self): buf = io.StringIO() diff --git a/tests/test_install_selection.py b/tests/test_install_selection.py index dc1d2819..3fa514b8 100644 --- a/tests/test_install_selection.py +++ b/tests/test_install_selection.py @@ -376,7 +376,7 @@ class TheOneLinerNarrows(unittest.TestCase): def test_a_pinned_ref_is_named_as_the_way_out(self): """RETROBIOS_REF=<tag>, which the docs suggest for reproducibility, - selects lists from before narrowing existed; the error said only + selects lists from before narrowing existed, and the error said only "narrowing needs a newer one".""" with FakeRepository(selection=False) as repo: proc = subprocess.run( @@ -648,7 +648,7 @@ class InstallMatchesATargetManifest(unittest.TestCase): class ACoreWithNothingHeldIsAnOmission(unittest.TestCase): """DOSBox serves SC-55/WAVEROM3.BIN, DOSBox Pure wants it and nothing is held for it. A pack built for a target without DOSBox lists it as left - out; narrowed from the full manifest, it had vanished.""" + out. Narrowed from the full manifest, it had vanished.""" MANIFEST = {"files": [{ "dest": "SC-55/WAVEROM3.BIN", "cores": ["dosbox"], "sha1": "1" * 40, diff --git a/tests/test_mame_ref_audit.py b/tests/test_mame_ref_audit.py index 6f560dc2..07f4f3b3 100644 --- a/tests/test_mame_ref_audit.py +++ b/tests/test_mame_ref_audit.py @@ -48,7 +48,7 @@ class TestDeclares(unittest.TestCase): self.assertTrue(declares(DRIVER[1], "ekara")) def test_a_clone_naming_it_as_parent_is_not_a_declaration(self): - """ekara is the parent field of ekarag; most of a driver looks so.""" + """ekara is the parent field of ekarag, and most of a driver looks so.""" self.assertFalse(declares(DRIVER[2], "ekara")) self.assertTrue(declares(DRIVER[2], "ekarag")) diff --git a/tests/test_md5_pack_context.py b/tests/test_md5_pack_context.py index 3207e304..d3b57220 100644 --- a/tests/test_md5_pack_context.py +++ b/tests/test_md5_pack_context.py @@ -51,7 +51,7 @@ class TheEmulatorContextIsChecked(unittest.TestCase): def test_the_standalone_layout_reaches_a_profile_without_structure(self): - """BBKEmu has no pack_structure; its A4980 8.BIN goes to + """BBKEmu has no pack_structure, and its A4980 8.BIN goes to system/BBKEmu/A4980/ standalone. The hash pack kept the bare name, then, once laid out, sent it to the A4988 folder whose entry shares the name.""" diff --git a/tests/test_name_tiebreak.py b/tests/test_name_tiebreak.py index 21a2f782..29cd9566 100644 --- a/tests/test_name_tiebreak.py +++ b/tests/test_name_tiebreak.py @@ -1,6 +1,6 @@ """Same-named candidates are ordered by the size the entry declares. -ScummVM declares MT32_PCM.ROM at 524288 bytes; the name step took the 1 MB +ScummVM declares MT32_PCM.ROM at 524288 bytes, but the name step took the 1 MB CM-32L PCM ROM that sorted first. Ordering rejects nothing, so a size without `validation: [size]` keeps its informative status. """ diff --git a/tests/test_native_mode.py b/tests/test_native_mode.py index 0a2406b2..657ea1b5 100644 --- a/tests/test_native_mode.py +++ b/tests/test_native_mode.py @@ -117,7 +117,7 @@ class BothConsumersAgree(unittest.TestCase): class ThePolicyIsSpeltInOnePlace(unittest.TestCase): - """Consumers ask the module; they do not re-spell the rule. + """Consumers ask the module and do not re-spell the rule. Four sites still compared the mode to a literal after this module existed, and one of them dispatched an unknown mode to MD5 verification while diff --git a/tests/test_optional_dependencies.py b/tests/test_optional_dependencies.py index 610f7a0d..9eb0ff6f 100644 --- a/tests/test_optional_dependencies.py +++ b/tests/test_optional_dependencies.py @@ -53,7 +53,7 @@ class SuiteWithoutJsonschema(unittest.TestCase): class ScriptsNeedOnlyPyyaml(unittest.TestCase): - """The build scripts need the standard library and pyyaml; jsonschema is + """The build scripts need the standard library and pyyaml. jsonschema is validate_schemas.py's alone. CI installs jsonschema with its whole tree (attrs, referencing, rpds-py), so an import of any of them would pass there and fail for a contributor following the documented setup.""" diff --git a/tests/test_owner_resolution.py b/tests/test_owner_resolution.py index bf0e4cc9..621a6500 100644 --- a/tests/test_owner_resolution.py +++ b/tests/test_owner_resolution.py @@ -1,7 +1,7 @@ """Every reader of a profile entry names its owner, as the builder does. The resolver prefers the owning profile's copy when a name has several. The -builder passes `source_profile`; the site's consumer index, the slot claims +builder passes `source_profile`. The site's consumer index, the slot claims and the agnostic scan did not, and resolved 95 entries to other files: the site credited aethersx2's game_controller_db.txt to armsx2 and left the copy armsx2's pack ships without a reader, and MAME's neogeo.zip without MAME. diff --git a/tests/test_pack_grouping.py b/tests/test_pack_grouping.py index 3b6bfcac..e60125fd 100644 --- a/tests/test_pack_grouping.py +++ b/tests/test_pack_grouping.py @@ -1,7 +1,7 @@ """--one-per-slot and --region read one grouping of a pack. The slot pass put each core extra under every system of its profile. PicoDrive -ranks its Mega CD BIOSes within sega-megacd; spread across sega-megadrive, +ranks its Mega CD BIOSes within sega-megacd. Spread across sega-megadrive, sega-32x and the rest, they shared a tier with unranked files, the tier was ruled undecidable, and the keep overrode the drop. """ diff --git a/tests/test_path_conflict_status.py b/tests/test_path_conflict_status.py index 2390994f..4f10aacc 100644 --- a/tests/test_path_conflict_status.py +++ b/tests/test_path_conflict_status.py @@ -2,7 +2,7 @@ RetroArch declares SGB1.sfc as a file and SGB1.sfc/<rom> as files inside it. The builder ships one shape and counted every conflicting declaration OK, -resolved or not; verify.py resolves each on its own. A required file absent +resolved or not, while verify.py resolves each on its own. A required file absent from the collection read as covered in the pack report and as missing in verify. """ @@ -227,7 +227,7 @@ class TheEmulatorPackShipsWhatTheCoreAccepts(unittest.TestCase): class AlternativesAgreeWithThePack(unittest.TestCase): """Two versions declared at one path: the held one has a contradicted md5, the other is not held. The pack ships the held copy with a - discrepancy; verify took the worst status and said missing.""" + discrepancy, but verify took the worst status and said missing.""" def setUp(self): self._tmp = tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") @@ -280,7 +280,7 @@ class AlternativesAgreeWithThePack(unittest.TestCase): class AMaskedArchiveIsMissing(unittest.TestCase): - """Profile a ships a loose pack.zip; profile b needs pack.zip as an + """Profile a ships a loose pack.zip while profile b needs pack.zip as an archive holding a member a's copy lacks. The pack skipped b's archive in silence and verify counted it OK on b's own copy.""" diff --git a/tests/test_path_suffix.py b/tests/test_path_suffix.py index d549c64d..59548b09 100644 --- a/tests/test_path_suffix.py +++ b/tests/test_path_suffix.py @@ -30,7 +30,7 @@ class TestPathSuffixes(unittest.TestCase): ) def test_a_deep_tree_keeps_every_level(self): - # Seven 3DS system archives differ only past the sixth segment; a + # Seven 3DS system archives differ only past the sixth segment, so a # single key per file merged all seven onto one. suffixes = _path_suffixes( "bios/Nintendo/3DS/Citra/nand/0000/title/0004009b/00014002/" @@ -100,7 +100,7 @@ class TestResolutionAmbiguity(unittest.TestCase): return resolve_local_file({"name": name}, self.db, dest_hint=hint) def test_a_full_tail_claimed_twice_goes_to_the_closest_owner(self): - # emu_one stores it right at its destination; emu_two nests it one + # emu_one stores it right at its destination while emu_two nests it one # directory deeper. The one that IS the destination wins. path, status = self._resolve( "convert.glsl", "resources/shaders/convert.glsl" @@ -174,7 +174,7 @@ class TestSizeGateOnTheNameStep(unittest.TestCase): self.assertEqual(status, "hash_mismatch") def test_a_list_of_accepted_sizes_gates_the_name_step(self): - # SC-55/ROM2.BIN accepts two sizes; a PlayStation 2 ROM2.BIN of a + # SC-55/ROM2.BIN accepts two sizes. A PlayStation 2 ROM2.BIN of a # third size answered to the name because the list was ignored. entry = {"name": "ROM", "size": [8, 999], "validation": ["size"]} path, status = resolve_local_file(entry, self.db) diff --git a/tests/test_profile_checks.py b/tests/test_profile_checks.py index e3897b2f..2e528be2 100644 --- a/tests/test_profile_checks.py +++ b/tests/test_profile_checks.py @@ -58,7 +58,7 @@ class BeebEmTeletextFont(_Probe): class BeebEmSystemRoms(_Probe): """The OS, Tube, Z80 and Master 512 ROMs are read with one fread of the slot's size. A short read reports an error and BeebEm runs with what it - read; bytes past the slot are never read (Src/BeebMem.cpp:1291-1308, + read. Bytes past the slot are never read (Src/BeebMem.cpp:1291-1308, Src/Tube.cpp:1540-1553, Src/Z80Support.cpp:247-261, Src/Master512CoPro.cpp:3777-3790 at a982ba6).""" @@ -90,7 +90,7 @@ class BeebEmSidewaysRoms(_Probe): class BeetleLynxBootRom(_Probe): """CRom drops a boot ROM under 512 bytes and keeps the 0x88 fill, so no - game boots; a longer one is read for its first 512 bytes + game boots, and a longer one is read for its first 512 bytes (mednafen/lynx/rom.cpp:61-75 at fcdefcf).""" def test_short_is_refused_and_longer_is_read(self): @@ -135,7 +135,7 @@ class Atari800SystemRoms(_Probe): class AresAtari5200Bios(unittest.TestCase): """ares registers an Atari 5200 firmware by sha256 and refuses to load a game without it (desktop-ui/emulator/atari-5200.cpp:12-16, 82-88 at - 4cb8d92); the profile left the system out, so no pack carried the BIOS.""" + 4cb8d92). The profile left the system out, so no pack carried the BIOS.""" def test_the_profile_declares_it(self): profile = _profile("ares") @@ -150,7 +150,7 @@ class AresAtari5200Bios(unittest.TestCase): class A5200Bios(_Probe): """The core reads 0x800 bytes and falls back to the Altirra OS on a short - read; bytes past them are never read (libretro/libretro.c:456-468 at + read. Bytes past them are never read (libretro/libretro.c:456-468 at 40c6f2f).""" def test_short_falls_back_and_longer_is_read(self): @@ -177,7 +177,7 @@ class BeetlePceSystemCards(_Probe): class EightyOneRoms(_Probe): """memory_load reads the ROM and CRC32Block's value only picks the tape - patches in rompatch.c; a ROM the table does not know loads without them + patches in rompatch.c: a ROM the table does not know loads without them (81/zx81/zx81.c:102-103, 81/Ace/ace.c:77-78, 81/zx81/rompatch.c at fa70949). The profile declared a crc32 check with no value.""" @@ -191,7 +191,7 @@ class EightyOneRoms(_Probe): class AdvanceMameArchives(_Probe): - """verify_length_and_hash checks each member and only adds a warning; the + """verify_length_and_hash checks each member and only adds a warning. The archive itself has no size or hash anyone checks (src/romload.c:327-363 at 21f8f6f). The 26 BIOS archives declared archive-level checks with no archive values.""" @@ -210,7 +210,7 @@ class AdvanceMameArchives(_Probe): class MameMemberChecksOnlyWarn(unittest.TestCase): """libretro MAME and mame2015 warn on a member's wrong length or checksums and run (src/emu/romload.cpp:602-625 at 9069f39, src/emu/romload.c:501-519 - at 7adbf44); an archive-level check with no archive value ran nothing.""" + at 7adbf44). An archive-level check with no archive value ran nothing.""" def test_no_valueless_archive_check(self): for emulator, names in ( @@ -225,7 +225,7 @@ class MameMemberChecksOnlyWarn(unittest.TestCase): class HypseusArchives(unittest.TestCase): """Hypseus checks each member's size and CRC32, never the archive - (game.cpp:636-906 at cda8796); its 71 archives declared archive-level + (game.cpp:636-906 at cda8796). Its 71 archives declared archive-level checks with no archive value.""" def test_no_archive_level_check(self): @@ -252,7 +252,7 @@ class DolphinForksIplDumps(_Probe): class GambatteBootRoms(_Probe): """get_bootloader_from_file reads 0x100 or 0x900 bytes and gives up on a - short read; it never reads past them (libgambatte/libretro/libretro.cpp + short read, and never reads past them (libgambatte/libretro/libretro.cpp 1426-1486 at d9d6cd0). The upstream crc32 check the profile claimed has no code behind it: sinamas/gambatte was reset to a README in 2021.""" @@ -264,7 +264,7 @@ class GambatteBootRoms(_Probe): class GeargrafxCards(_Probe): - """LoadBiosData strips a 512-byte header and refuses any other size; the + """LoadBiosData strips a 512-byte header and refuses any other size. The CRC32 only names the card in the log, and an unknown LaserActive CRC32 is logged and loaded (src/media.cpp:570-632, 662-705, 1028-1063 at d0307bf). The profiles declared crc32 checks with no value.""" @@ -318,7 +318,7 @@ class AppleIIgsRomSizes(_Probe): class AltirraHappy810(_Probe): """ATFirmwareDetection recognises the pre-v7 Happy 810 ROM by its size (3K, 4K or a doubled overdump) and a CRC32 that skips the hidden 1K and - the serial; the whole-file CRC32 the profile checked is never computed, + the serial. The whole-file CRC32 the profile checked is never computed, so a dump with another serial was refused (firmwaredetect.cpp:186-231 in the 4.40 source).""" diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index 9d319522..f8c415e2 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -330,7 +330,7 @@ class TestWorstStatus(unittest.TestCase): class TestAnchorBlock(unittest.TestCase): def test_a_range_ending_past_the_file_is_gone(self): - """dolphin cited NANDImporter.cpp:239-323 in a 317-line file; the + """dolphin cited NANDImporter.cpp:239-323 in a 317-line file. The part inside the file anchored, and the ref read as sound.""" lines = [f"line {n}" for n in range(1, 11)] self.assertEqual(anchor_block(lines, list(lines), 8, 14).status, "GONE") @@ -465,7 +465,7 @@ class TestVerifyAtPin(unittest.TestCase): self.assertIsNone(profile_sync.cites_another_version(same, {"libretro": "v0.16.0"})) def test_a_name_stem_elsewhere_does_not_move_a_ref(self): - """linapple cites the PRAVETS82 option; the stem also names an install line.""" + """linapple cites the PRAVETS82 option, and the stem also names an install line.""" lines = ['option(ENABLE_ROM_CLONE_PRAVETS "" OFF)', "", "", "", "", "", "", "", "", "", "", "", "res/roms/pravets82.rom"] part = RefPart("CMakeLists.txt", 1, 1, "CMakeLists.txt:1") @@ -560,7 +560,7 @@ class TestVerifyAtPin(unittest.TestCase): ) def test_an_entry_declaring_nothing_is_accepted_but_not_called_anchored(self): - # Nothing to re-read, so no review is demanded; but the verdict says + # Nothing to re-read, so no review is demanded, but the verdict says # that nothing was checked rather than claiming the ref anchors. part = RefPart("a.c", 1, 1, "a.c:1") result = profile_sync.verify_at_pin(part, self.LINES, []) @@ -790,7 +790,7 @@ class TestNudgeToDeclared(unittest.TestCase): ) def test_a_range_over_code_cites_that_code(self): - """ymir's 598-618 cited load_rom_cartridge(); nudged onto the file + """ymir's 598-618 cited load_rom_cartridge(). Nudged onto the file table beside it, a rewritten function read SHIFTED, not CHANGED.""" lines = ["void load_rom_cartridge() {"] + [" code();"] * 19 + ["}", "kKOF95Files"] self.assertIsNone(profile_sync.nudge_to_declared(lines, 1, 21, ["kkof95files"])) @@ -1414,7 +1414,7 @@ class TestBuildReport(unittest.TestCase): self.assertEqual(report.entries[0].status, "MOVED") def test_a_value_absent_from_the_whole_file_is_not_held_against_the_ref(self): - # A ref citing loading logic never spells the value out; its absence + # A ref citing loading logic never spells the value out, so its absence # is not evidence that the ref is stale. self.files[("headsha", "a.c")] = ["x", "load_bios(path);"] profile = self._profile(["a.c:2"]) @@ -1432,7 +1432,7 @@ class TestBuildReport(unittest.TestCase): self.assertEqual(report.entries[0].status, "ANCHORED") def test_the_repository_with_a_subject_owns_a_shared_path(self): - # A port and its upstream can both carry a path; only one holds the + # A port and its upstream can both carry a path, but only one holds the # cited subject, and a blank line is never a citation. self.files[("portpin", "src/a.cpp")] = ["x", "", "y"] self.files[("uppin", "src/a.cpp")] = ["x", "GAME(1985, bubsys", "y"] @@ -1450,7 +1450,7 @@ class TestBuildReport(unittest.TestCase): def test_a_blank_first_line_does_not_hand_the_ref_to_the_upstream(self): """lrps2's VMManager.cpp:418-431 opens on a blank line in the fork it - was written for; scored 0, the upstream (418 unrelated, not blank) + was written for. Scored 0, the upstream (418 unrelated, not blank) took the ref and its code decided the rebase target.""" self.files[("portpin", "src/a.cpp")] = ["x", "", "load_patches();", "y"] self.files[("porthead", "src/a.cpp")] = ["", "load_patches();", "y", "w"] @@ -1470,7 +1470,7 @@ class TestBuildReport(unittest.TestCase): } report = profile_sync.report_to_dict(build_report("lrps2", profile, self.dir)) part = report["entries"][0]["parts"][0] - # Moved by -1 in the fork, the block's real target; the upstream's + # Moved by -1 in the fork, the block's real target. The upstream's # +2 shift of unrelated code is not it. self.assertIsNone(part["repo"]) self.assertEqual((part["status"], part["start"]), ("SHIFTED", 1)) @@ -1487,13 +1487,13 @@ class TestBuildReport(unittest.TestCase): profile["upstream"] = "https://github.com/o/up" profile["source_branch"] = "libretro" build_report("test", profile, self.dir) - # Only the port carries the branch; the upstream keeps its own tip. + # Only the port carries the branch. The upstream keeps its own tip. self.assertEqual(seen["o/n"], "libretro") self.assertIsNone(seen["o/up"]) def test_the_subject_beats_a_merely_non_blank_line(self): # A fork whose tree is offset holds a real but unrelated statement at - # the cited line; the repository carrying the subject wins. + # the cited line. The repository carrying the subject wins. self.files[("portpin", "src/a.cpp")] = ["x", "GAME(1997, drgw2100c", "y"] self.files[("uppin", "src/a.cpp")] = ["x", "GAME(1997, pgm,", "y"] self.files[("headsha", "src/a.cpp")] = ["x", "GAME(1997, pgm,", "y"] @@ -1510,7 +1510,7 @@ class TestBuildReport(unittest.TestCase): def test_a_ref_is_broken_only_when_it_fails_everywhere(self): # Both repositories carry the path with the same delimited token on the - # cited line, so no single attribution is right; the ref anchors in one + # cited line, so no single attribution is right. The ref anchors in one # of them and that settles it. self.files[("portpin", "src/a.cpp")] = ["x", "GAME(1997, drgw, pgm,", "y"] self.files[("porthead", "src/a.cpp")] = ["x", "", "y"] @@ -1682,7 +1682,7 @@ class TestDeclaredDeadUpstream(TestBuildReport): yuzu and suyu were withdrawn, citron's domain was taken by a squatter. Leaving those profiles to fail every pass reports an open problem where - there is a settled fact. Declaring it records the death; the guard is + there is a settled fact. Declaring it records the death, and the guard is that a declaration must stop being true the moment the forge answers. """ @@ -1745,7 +1745,7 @@ class TestRefsAheadOfTheirPin(TestBuildReport): """nestopia's shape: the file is there, the line is not yet. Palette and database loads sat at 2041 and 2063, which is where HEAD - carries them; the pinned revision was four hundred lines shorter. + carries them. The pinned revision was four hundred lines shorter. """ self.files[("pinsha", "a.c")] = ["x"] * 10 self.files[("headsha", "a.c")] = ["x"] * 40 + ["the cited line"] + ["y"] @@ -1757,7 +1757,7 @@ class TestRefsAheadOfTheirPin(TestBuildReport): ) def test_a_range_beyond_head_is_still_just_missing(self): - """Not every pin miss is a stale pin; only one that fits HEAD.""" + """Not every pin miss is a stale pin, only one that fits HEAD.""" self.files[("headsha", "a.c")] = ["x"] report = build_report("test", self._profile(["a.c:40"]), self.dir) part = report.entries[0].parts[0] @@ -2401,7 +2401,7 @@ class TestWriteDryRun(unittest.TestCase): def test_two_writing_pins_give_two_readings(self): """vitaquake2: written at one pin, re-pinned under the same text. Each - pin is a reading; a run settles when every reading agrees.""" + pin is a reading, and a run settles when every reading agrees.""" revisions = [ ("c2", {"source_commit": "pin2", "notes": "x"}), ("c1", {"source_commit": "pin1", "notes": "x"}), @@ -2415,7 +2415,7 @@ class TestWriteDryRun(unittest.TestCase): def test_a_confirmed_pin_settles_the_readings(self): """fixnes: doOpenFDSBIOS lived under four pins and was exact at the - last; with nothing to record that reading, the bump was refused for + last. With nothing to record that reading, the bump was refused for good. prose_written_at names the pin and the readings collapse.""" revisions = [ ("c2", {"source_commit": "pin2", "notes": "x"}), @@ -2613,7 +2613,7 @@ class TestDeliberatelyFrozenPin(TestBuildReport): def test_the_builds_platforms_hold_say_so(self): # reicast is the commit Recalbox's reicast.mk builds, 789 commits - # behind master; compared to HEAD it showed eight refs to review that + # behind master. Compared to HEAD it showed eight refs to review that # nobody could act on. from common import load_emulator_profiles # noqa: PLC0415 @@ -2631,7 +2631,7 @@ class TestDeliberatelyFrozenPin(TestBuildReport): class TestProseSpacingIsNotADifference(unittest.TestCase): - """A recale keeps the author's spacing; the check has to allow for it. + """A recale keeps the author's spacing, so the check has to allow for it. _run_after_moves renders `a.c:228,1439-1443` while the writer leaves the sentence as written, `a.c:228, 1439-1443`. Comparing the two literally @@ -3136,7 +3136,7 @@ class TestCollectCitations(unittest.TestCase): ) def test_a_semicolon_separates_citations_like_a_comma(self): - # lynx-emu: "...:112; mednafen src/lynx/system.cpp:86-93" cites the + # lynx-emu: `...:112; mednafen src/lynx/system.cpp:86-93` cites the # mednafen upstream, not the fork the profile was read from. for line in ( "see Lynx.emu/src/lynx/system.cpp:112; mednafen src/lynx/system.cpp:86-93", @@ -3318,7 +3318,7 @@ class TestCitationSurfaceGuard(unittest.TestCase): A consumer keying on the field name reopens the gap this closes: citations outside its list rot while the pin advances. The walker - matches the key once; everything else goes through the collector. + matches the key once. Everything else goes through the collector. """ source = Path(profile_sync.__file__).read_text(encoding="utf-8") self.assertNotIn('.get("source_ref")', source) @@ -3683,7 +3683,7 @@ class TestRealignProse(unittest.TestCase): def test_run_realigns_from_the_writing_pin(self): self._repo_with_advanced_pin() - # At the writing pin line 10 is the subject; at the current pin the + # At the writing pin line 10 is the subject. At the current pin the # same content sits on line 14. Anchoring from the current pin would # track whatever occupies line 10 there instead. self.files[("oldpin", "a.c")] = ["x"] * 9 + ["subject"] @@ -3703,7 +3703,7 @@ class TestRealignProse(unittest.TestCase): """A committed pin change under the same text may be a correction. vitaquake2 kept its notes while 38fc9331 re-pinned it onto the - revision those notes described; realigning from the first pin moved + revision those notes described. Realigning from the first pin moved correct citations onto unrelated code. """ self._repo_with_advanced_pin() @@ -3867,7 +3867,7 @@ class TestRealignProse(unittest.TestCase): class TestOutputModesApplyTheirFlags(unittest.TestCase): - """--changed-only narrows --json too; extras are refused off the text report.""" + """--changed-only narrows --json too. Extras are refused off the text report.""" def _main(self, *argv): from unittest import mock @@ -4104,7 +4104,7 @@ class OfflineCacheMissIsNotGone(TestBuildReport): class TestSelectionNamesWhatMatchedNothing(unittest.TestCase): """`--all --system atari-lynxx` printed nothing and exited 0, which read - as "no Lynx profile needs a re-read"; `--emulator handyy` offered no + as "no Lynx profile needs a re-read", and `--emulator handyy` offered no suggestion.""" PROFILES = { @@ -4135,7 +4135,7 @@ class TestSelectionNamesWhatMatchedNothing(unittest.TestCase): class TestTreeUrlIntoADirectory(unittest.TestCase): """`.../libretro-samples/tree/master/tests/cruzes` took the whole tail as - the branch; nothing resolved and cruzes was skipped as having no pin.""" + the branch. Nothing resolved and cruzes was skipped as having no pin.""" def test_candidates_are_prefixes_shortest_first(self): self.assertEqual( diff --git a/tests/test_prose_style.py b/tests/test_prose_style.py new file mode 100644 index 00000000..7b2450fa --- /dev/null +++ b/tests/test_prose_style.py @@ -0,0 +1,177 @@ +"""Prose in the repository is written the way its maintainer writes. + +Em-dashes, clause-joining semicolons, unicode arrows, the ellipsis character, +box-drawing banners and check-mark emoji had spread through profiles, docs, +comments and command output. None of them is wrong, but together they gave the +project a generated look its maintainer did not want. This module names every +place one comes back. +""" + +from __future__ import annotations + +import io +import re +import subprocess +import tokenize +import unittest +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parent.parent + +GLYPHS = re.compile( + "[–—…←-⇿─-╿✓-✘⚠✅❌]" +) +# A semicolon between two words of prose. Code quoted in prose sits in +# backticks, which are blanked before the search. +CLAUSE_SEMICOLON = re.compile(r"[A-Za-z0-9)\]\"']; [A-Za-z(]") +BACKTICKS = re.compile(r"`[^`\n]*`") +FENCED = re.compile(r"^```.*?^```", re.S | re.M) + +SKIPPED_TREES = ("bios/", "data/", "recipes/", "provenance/", "install/") +TEXT_SUFFIXES = { + ".py", ".sh", ".ps1", ".js", ".css", ".md", ".yml", ".yaml", ".html", + ".txt", ".cfg", ".toml", "", +} +PROSE_KEYS = { + "notes", "note", "description", "exclusion_note", "size_note", + "region_note", "hle_note", "comment", "reason", +} + + +def _tracked() -> list[Path]: + listed = subprocess.run( + ["git", "ls-files"], cwd=ROOT, capture_output=True, text=True, check=True + ).stdout.splitlines() + return [ + ROOT / name + for name in listed + if not name.startswith(SKIPPED_TREES) + and Path(name).suffix in TEXT_SUFFIXES + and (ROOT / name).is_file() + ] + + +def _semicolons(text: str) -> list[str]: + return [ + line.strip() + for line in BACKTICKS.sub("``", text).splitlines() + if CLAUSE_SEMICOLON.search(line) + ] + + +def _python_prose(source: str) -> str: + """Comments and docstrings of a module, one per line.""" + parts: list[str] = [] + previous = tokenize.INDENT + for token in tokenize.generate_tokens(io.StringIO(source).readline): + if token.type == tokenize.COMMENT: + parts.append(token.string) + elif token.type == tokenize.STRING and previous in ( + tokenize.INDENT, tokenize.NEWLINE, tokenize.NL, tokenize.DEDENT, + ): + parts.append(token.string) + if token.type not in (tokenize.COMMENT, tokenize.NL): + previous = token.type + return "\n".join(parts) + + +class _TagTolerantLoader(yaml.SafeLoader): + """mkdocs.yml names Python callables with !!python/name tags.""" + + +_TagTolerantLoader.add_multi_constructor( + "tag:yaml.org,2002:python/", lambda loader, suffix, node: None +) + + +def _yaml_prose(text: str) -> str: + """Prose scalars and comments of a YAML document.""" + parts = [ + line.split("#", 1)[1] + for line in text.splitlines() + if line.lstrip().startswith("#") + ] + + def walk(node: object) -> None: + if isinstance(node, dict): + for key, value in node.items(): + if key in PROSE_KEYS and isinstance(value, str): + parts.append(value) + else: + walk(value) + elif isinstance(node, list): + for item in node: + walk(item) + + walk(yaml.load(text, Loader=_TagTolerantLoader)) + return "\n".join(parts) + + +class NoGeneratedTypography(unittest.TestCase): + def test_no_dash_arrow_ellipsis_or_banner_glyphs(self): + offenders = [] + for path in _tracked(): + text = path.read_text(encoding="utf-8", errors="replace") + for number, line in enumerate(text.splitlines(), 1): + if GLYPHS.search(line): + offenders.append(f"{path.relative_to(ROOT)}:{number}: {line.strip()[:100]}") + self.assertEqual(offenders, [], "\n".join(offenders[:40])) + + +class NoClauseSemicolons(unittest.TestCase): + def _check(self, files: list[Path], extract) -> None: + offenders = [] + for path in files: + text = path.read_text(encoding="utf-8") + for line in _semicolons(extract(text)): + offenders.append(f"{path.relative_to(ROOT)}: {line[:100]}") + self.assertEqual(offenders, [], "\n".join(offenders[:40])) + + def test_markdown(self): + files = [p for p in _tracked() if p.suffix == ".md"] + self._check(files, lambda text: FENCED.sub("", text)) + + def test_yaml_prose_and_comments(self): + files = [p for p in _tracked() if p.suffix in (".yml", ".yaml")] + self._check(files, _yaml_prose) + + def test_python_comments_and_docstrings(self): + files = [p for p in _tracked() if p.suffix == ".py"] + self._check(files, _python_prose) + + + def test_schema_descriptions(self): + offenders = [] + for path in sorted((ROOT / "schemas").glob("*.json")): + text = path.read_text(encoding="utf-8") + for line in _semicolons(text) + GLYPHS.findall(text): + offenders.append(f"{path.relative_to(ROOT)}: {line[:100]}") + self.assertEqual(offenders, [], "\n".join(offenders)) + + +class GeneratedSiteProse(unittest.TestCase): + """The site pages carry strings no tracked file shows verbatim.""" + + def test_generated_pages(self): + docs = ROOT / "docs" + pages = [ + p for p in docs.rglob("*.md") + if "superpowers" not in p.parts and "plans" not in p.parts + and "specs" not in p.parts + ] if docs.is_dir() else [] + if not pages: + self.skipTest("docs/ not generated (python scripts/generate_site.py)") + offenders = [] + for page in pages: + text = re.sub(r"<script.*?</script>", "", page.read_text(encoding="utf-8"), flags=re.S) + text = FENCED.sub("", text) + for number, line in enumerate(text.splitlines(), 1): + if GLYPHS.search(line) or _semicolons(line): + offenders.append(f"{page.relative_to(ROOT)}:{number}: {line.strip()[:100]}") + self.assertEqual(offenders, [], "\n".join(offenders[:40])) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_provenance.py b/tests/test_provenance.py index cbdad92d..8b33b6c6 100644 --- a/tests/test_provenance.py +++ b/tests/test_provenance.py @@ -354,7 +354,7 @@ class TestProvenanceReport(unittest.TestCase): ) def test_a_loose_file_matches_by_crc32_and_size(self): - """Redump lists DTL-H10100's image by crc32 alone; collected as a + """Redump lists DTL-H10100's image by crc32 alone. Collected as a loose file it stayed MISSING for good.""" db = {"files": {"f" * 40: {"name": "ps2-0101jd.bin", "size": 4194304, "md5": "e" * 32, "crc32": "E9836A0C"}}} diff --git a/tests/test_region.py b/tests/test_region.py index e2e03d29..943fe854 100644 --- a/tests/test_region.py +++ b/tests/test_region.py @@ -720,7 +720,7 @@ class TestReportAndBuilderNarrowTogether(unittest.TestCase): tmp.cleanup() def test_a_missing_regional_core_file_is_withdrawn_too(self): - """A missing platform file is grouped and withdrawn under --region; a + """A missing platform file is grouped and withdrawn under --region, but a missing core file was never grouped and stayed "required missing" for a region the request excludes.""" sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts")) @@ -752,7 +752,7 @@ class TestReportAndBuilderNarrowTogether(unittest.TestCase): def test_the_report_names_the_fallback_groups(self): """The pack README lists the systems kept whole because nothing - answers the request; verify said all OK and named none.""" + answers the request. verify said all OK and named none.""" sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts")) import common import verify as reporter @@ -850,7 +850,7 @@ class TestReportAndBuilderNarrowTogether(unittest.TestCase): DuckStation's ConsoleRegion::PAL, Beetle PSX, SwanStation, PCSX ReARMed's EU slot and Rustation all serve Australian and New Zealand discs from the - same images; annotated [europe] only, --region australia dropped them. + same images. Annotated [europe] only, --region australia dropped them. """ import yaml @@ -921,7 +921,7 @@ class FontRomsCarryNoTerritory(unittest.TestCase): self.assertEqual(tagged, []) class EmulatorModeKeepsAHeldFile(unittest.TestCase): - """Platform mode never lets a missing file displace a held one; emulator + """Platform mode never lets a missing file displace a held one. Emulator mode did. A held scph5501.bin (north-america) was withdrawn under --region jp for a Japanese image the collection lacks, and the pack shipped no PlayStation BIOS.""" diff --git a/tests/test_region_platform_index.py b/tests/test_region_platform_index.py index 4d2be7cb..fbb1a59e 100644 --- a/tests/test_region_platform_index.py +++ b/tests/test_region_platform_index.py @@ -43,7 +43,7 @@ class OnlyThePlatformsCores(unittest.TestCase): class OnlyThePlatformsCoresRankASlot(unittest.TestCase): """RomM runs beetle_psx and pcsx_rearmed, which rank no PlayStation - BIOS; DuckStation's ranks dropped four images RomM declares.""" + BIOS, yet DuckStation's ranks dropped four images RomM declares.""" PROFILES = { "beetle_psx": {"emulator": "Beetle", "type": "libretro", diff --git a/tests/test_romset_recipes.py b/tests/test_romset_recipes.py index 7813031c..37d2d3a7 100644 --- a/tests/test_romset_recipes.py +++ b/tests/test_romset_recipes.py @@ -533,7 +533,7 @@ class RepositoryRun(unittest.TestCase): class TheMissingReportNamesItsTargets(unittest.TestCase): - """--missing printed three counters; the archives to go and find were + """--missing printed three counters. The archives to go and find were only in --json.""" def test_every_target_is_named(self): diff --git a/tests/test_scraper_contract.py b/tests/test_scraper_contract.py index 4b1dec35..e4fc31c0 100644 --- a/tests/test_scraper_contract.py +++ b/tests/test_scraper_contract.py @@ -4,7 +4,7 @@ wiki/adding-a-scraper.md and wiki/adding-a-platform.md document compare_with_config, ChangeSet.has_changes and test_connection as the interface a new scraper plugs into. No scraper in the repository calls them, -so nothing proved they still worked; a documented contract that is never +so nothing proved they still worked. A documented contract that is never exercised is a promise to contributors backed by nothing. """ @@ -119,7 +119,7 @@ class TestConnection(unittest.TestCase): self.assertFalse(_StubScraper(error=ValueError("bad format")).test_connection()) def test_an_unexpected_error_is_not_swallowed(self): - """Only reachability failures are absorbed; a bug must surface.""" + """Only reachability failures are absorbed. A bug must surface.""" with self.assertRaises(KeyError): _StubScraper(error=KeyError("bug")).test_connection() @@ -434,7 +434,7 @@ class RetroDeckCoresAreItsComponents(unittest.TestCase): class BizHawkRunsAresForN64Only(unittest.TestCase): - """BizHawk embeds ares as Ares64, its N64 core; mapping it to the ares + """BizHawk embeds ares as Ares64, its N64 core. Mapping it to the ares profile claimed thirty systems and accused FirmwareDatabase.cs of a wrong MSX.rom it never declared for ares.""" @@ -449,7 +449,7 @@ class BizHawkRunsAresForN64Only(unittest.TestCase): class EveryTargetCoreReachesAProfile(unittest.TestCase): - """A target lists cores by their buildbot or package name; a name no + """A target lists cores by their buildbot or package name. A name no profile's cores: claims makes --target drop that core and its systems without a word. Only check_freshness compared them, on a fresh scrape.""" @@ -639,7 +639,7 @@ for path in sorted((root / package.replace(".", "/")).rglob("*.py")): class ImportingAScraperFetchesNothing(unittest.TestCase): """A tag resolved at module load made a refused API call fall back to - master before any scraper ran; the rule since is no network at import. + master before any scraper ran. The rule since is no network at import. Each module is imported in a fresh interpreter with sockets refused, so nothing already cached hides an import-time fetch.""" diff --git a/tests/test_shared_groups.py b/tests/test_shared_groups.py index 93d8a842..94c0219e 100644 --- a/tests/test_shared_groups.py +++ b/tests/test_shared_groups.py @@ -3,7 +3,7 @@ The np2kai group declared itf.rom required, a file the core never opens (bios.c:579 sits behind the #else of BIOS_SIMULATE, always defined), and bios.rom, sound.rom and the rhythm WAVs required where the code falls back. -System.dat masked the group; a rescrape dropping itf.rom would have brought +System.dat masked the group: a rescrape dropping itf.rom would have brought it back as a required file of RetroArch, Lakka and RetroPie. """ diff --git a/tests/test_shipped_content.py b/tests/test_shipped_content.py index e4913da9..99927ab4 100644 --- a/tests/test_shipped_content.py +++ b/tests/test_shipped_content.py @@ -76,7 +76,7 @@ class ShippedFilesSatisfyTheirDeclaration(unittest.TestCase): if not reads_file_contents(config.get("verification_mode")): continue # A destination may be declared by more than one system, bare in - # one and hash-constrained in another; the builder lets whichever + # one and hash-constrained in another. The builder lets whichever # resolves claim it, so any of them satisfying the bytes is enough. declared: dict[str, list[dict]] = {} for system in config.get("systems", {}).values(): diff --git a/tests/test_site_exports.py b/tests/test_site_exports.py index 412b6145..3d014742 100644 --- a/tests/test_site_exports.py +++ b/tests/test_site_exports.py @@ -296,7 +296,7 @@ class PerModeSourcePins(unittest.TestCase): class AnEmulatorPageNamesItsRevision(unittest.TestCase): - """The page linked the repositories unpinned; the commit every citation + """The page linked the repositories unpinned. The commit every citation refers to sat in the YAML alone, for 178 profiles.""" def test_each_repository_links_its_pinned_commit(self): @@ -367,7 +367,7 @@ class AVariantShowsWhoPinsIt(unittest.TestCase): class AFlaggedDumpIsNotVerified(unittest.TestCase): """scph5000.bin, which TOSEC names "...(JP)[b].bin", wore a green - "Verified dump: TOSEC" badge; the catalog name lived only in a title + "Verified dump: TOSEC" badge. The catalog name lived only in a title attribute, outside the search and invisible on a touch screen.""" def test_flags_and_name(self): @@ -447,7 +447,7 @@ class AGoneSourceIsSaid(unittest.TestCase): class ASystemCardLandsOnThePlatformsSection(unittest.TestCase): """From scph5000.bin's card, [retrodeck] opened the top of a 2,000-file - page; the emulator card already landed on #sony-playstation.""" + page, while the emulator card already landed on #sony-playstation.""" def test_section_and_destination(self): import types diff --git a/tests/test_site_validation.py b/tests/test_site_validation.py index f9c9820f..aab67b3c 100644 --- a/tests/test_site_validation.py +++ b/tests/test_site_validation.py @@ -73,7 +73,7 @@ class WikiSourceHeadings(unittest.TestCase): offenders.append(f"{page.name}:{number}") elif not fenced and line[:1].isspace() and line.lstrip().startswith("#"): # Inside a list item or an admonition an indented hash is - # a heading too; code that needs one goes in a fence. + # a heading too. Code that needs one goes in a fence. offenders.append(f"{page.name}:{number}") self.assertEqual(offenders, []) @@ -245,7 +245,7 @@ class TheHomeTitleSaysWhatTheSiteIs(unittest.TestCase): class PlatformPagesPrintTheDeclaredCrc32(unittest.TestCase): - """System.dat pins aes.zip by crc32 91e93107; the RetroArch page printed + """System.dat pins aes.zip by crc32 91e93107. The RetroArch page printed only its sha1 and md5, so the crc a clrmamepro user pastes found nothing.""" def test_the_rendered_page(self): diff --git a/tests/test_site_write.py b/tests/test_site_write.py index c65f96a8..125b57b8 100644 --- a/tests/test_site_write.py +++ b/tests/test_site_write.py @@ -144,7 +144,7 @@ class Sweep(unittest.TestCase): """It is never reset, so a second run can only sweep less, never more. Deleting a page a previous run produced would be the dangerous - direction; sparing one is merely stale, and the next fresh process + direction. Sparing one is merely stale, and the next fresh process removes it. """ self._produce("emulators/kept.md") diff --git a/tests/test_slot.py b/tests/test_slot.py index 0d5a70ee..b61b0748 100644 --- a/tests/test_slot.py +++ b/tests/test_slot.py @@ -197,7 +197,7 @@ class TestRepoProfiles(unittest.TestCase): self.assertEqual(kept, {"scph5501.bin"}) def test_conflicting_cross_profile_orders_decide_nothing(self): - """pcsx1 walks scph1001 first; DuckStation prefers scph5501. The pack + """pcsx1 walks scph1001 first while DuckStation prefers scph5501. The pack serves both cores, so neither order may drop the other's first pick.""" index = slot.build_slot_index(self.profiles) for name in ("scph1001.bin", "scph5501.bin"): diff --git a/tests/test_slots.py b/tests/test_slots.py index d320be21..9604a254 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -127,7 +127,7 @@ class TestConflicts(unittest.TestCase): def test_a_core_claim_sits_where_the_pack_puts_it(self): """RetroDECK writes bios/ into every destination and leaves its base - empty; core files go under bios/ too. Claimed at the root, they never + empty, so core files go under bios/ too. Claimed at the root, they never met the platform's and four contradictions went unreported.""" config = {"base_destination": "", "systems": {"console": {"files": [ {"name": "IPL.bin", "destination": "bios/GC/JAP/IPL.bin", "md5": "m" * 32}, @@ -169,7 +169,7 @@ class TestConflicts(unittest.TestCase): self.assertEqual(conflicts, []) def test_a_platform_list_naming_the_profile_file_is_agreement(self): - """Recalbox names both scph1001.bin revisions; the resolver stops on + """Recalbox names both scph1001.bin revisions. The resolver stops on the first, the profile pins the other, and --strict reported a contradiction nobody has to correct.""" conflicts = slots.find_conflicts( @@ -223,7 +223,7 @@ class TestConflicts(unittest.TestCase): def test_a_bare_sibling_met_first_does_not_hide_the_contradiction(self): """RetroArch declares dsi_bios7.bin bare under one system and with a - hash under another; the pack ships the hashed one, so the slot is + hash under another. The pack ships the hashed one, so the slot is judged on it, whichever system is read first.""" config = { "systems": { @@ -403,7 +403,7 @@ class TestBuilderAndVerifierAgree(unittest.TestCase): def test_neither_reimplements_the_mode_test(self): # A local "if mode == md5" beside the override would drift from the # arbitration rule the moment either side is edited. The anchor is the - # override lookup both sides must perform; the old anchor was a string + # override lookup both sides must perform. The old anchor was a string # the test above forbids, so the window was the whole file. mode_test = re.compile(r"""[=!]=\s*["'](?:md5|sha1|existence)["']""") for name in ("generate_pack.py", "verify.py"): @@ -443,7 +443,7 @@ class TestSelfContradictingDestinations(unittest.TestCase): def test_a_file_both_declarations_accept_settles_the_path(self): """RetroDECK: ATARIOSB.ROM under one system with one md5, under - another with a list naming that same md5; the shipped file passes + another with a list naming that same md5. The shipped file passes both, so --strict has nothing to correct there.""" config = self._config( {"name": "IPL.bin", "destination": "disk.rom", "md5": "m" * 32}, @@ -599,7 +599,7 @@ class TestProvenEvidence(unittest.TestCase): def test_path_evidence_is_proof(self): # Dolphin declares no checksum for the GameCube boot ROM because its - # source declares none; the path is then the whole assertion. + # source declares none, so the path is then the whole assertion. self.assertTrue(slots.Claim("profile", "d", "n", status="path_exact").is_proven) def test_a_name_is_not_proof(self): @@ -612,7 +612,7 @@ class TestProvenEvidence(unittest.TestCase): class AnExactSizeContestsAnotherSize(unittest.TestCase): """System.dat pinned the 2 KiB X1 font as xmil/IPLROM.X1T, where xmil - reads a 32 KiB Turbo IPL; the profile's name-only claim could not + reads a 32 KiB Turbo IPL. The profile's name-only claim could not contest it, and RetroArch packs shipped the font as the IPL.""" def setUp(self): @@ -688,7 +688,7 @@ class ManifestFollowsTheArbitration(unittest.TestCase): class StrongestProfileClaimWins(unittest.TestCase): - """yaps2 pins GameIndex.yaml by sha1; armsx2 matched a path only.""" + """yaps2 pins GameIndex.yaml by sha1 while armsx2 matched a path only.""" def test_hash_proof_beats_path_proof(self): def claim(emu, path, status): diff --git a/tests/test_system_pack_extras.py b/tests/test_system_pack_extras.py index 6a580c11..2d8d9b4c 100644 --- a/tests/test_system_pack_extras.py +++ b/tests/test_system_pack_extras.py @@ -2,7 +2,7 @@ With --platform and --system, the full source emptied the core extras, so `--source full` and `--source platform` built the same pack under two -names; the split packs, built per system, carried them. +names, while the split packs, built per system, carried them. """ from __future__ import annotations diff --git a/tests/test_system_pack_parity.py b/tests/test_system_pack_parity.py index f6a22df1..4cf8edc5 100644 --- a/tests/test_system_pack_parity.py +++ b/tests/test_system_pack_parity.py @@ -50,7 +50,7 @@ class SystemPackMatchesVerify(unittest.TestCase): ) report = json.loads(_run("scripts/verify.py", "--system", system, "--json")) pack_missing = sorted(re.findall(r"^ MISSING: (\S+)", packed, re.M)) - # One per destination, as the pack reports them; an entry the + # One per destination, as the pack reports them. An entry the # collection cannot hold is counted apart on both sides. verify_missing = sorted({ (d["destination"], d["name"]) for d in report["details"] diff --git a/tests/test_system_selection.py b/tests/test_system_selection.py index 5c09325b..6452a10d 100644 --- a/tests/test_system_selection.py +++ b/tests/test_system_selection.py @@ -92,7 +92,7 @@ class ADeclinedBuildIsAFailure(unittest.TestCase): class AMistypedPlatformIsNamed(unittest.TestCase): - """verify and cross_reference ended a typo on a traceback; generate_pack + """verify and cross_reference ended a typo on a traceback, and generate_pack ran its whole build first and then said "no pack for batocra".""" # Every script taking --platform: slots ended on a traceback, and diff --git a/tests/test_target_scrapers.py b/tests/test_target_scrapers.py index 5ec4c0a6..a5478d7e 100644 --- a/tests/test_target_scrapers.py +++ b/tests/test_target_scrapers.py @@ -323,7 +323,7 @@ class RetroPieModuleFlags(unittest.TestCase): class HashScrapersRefuseAnUnknownVersion(unittest.TestCase): """mame_hash_scraper wrote core_version "unknown" after a failed API call - and cached it for a day; the pipeline step still read OK.""" + and cached it for a day, while the pipeline step still read OK.""" def test_mame_raises(self): from scripts.scraper import mame_hash_scraper # noqa: PLC0415 diff --git a/tests/test_target_systems.py b/tests/test_target_systems.py index fb6ebcb9..c4896a12 100644 --- a/tests/test_target_systems.py +++ b/tests/test_target_systems.py @@ -2,7 +2,7 @@ Batocera files the Enterprise under enterprise-64-128. ep128emu, the core that reads ep128emu/roms/exos21.rom, declares enterprise-64 and -enterprise-128; only CLK carries the joined id. With a target that has +enterprise-128. Only CLK carries the joined id. With a target that has ep128emu and not CLK, the system was dropped from the report while the builder still shipped its ROMs as ep128emu extras. """ @@ -57,7 +57,7 @@ class TargetSystems(unittest.TestCase): self.assertEqual(self.kept(systems("Enterprise/exos10.bin")), []) def test_a_path_an_off_target_core_reads_excludes_nothing(self): - """Batocera's bbc runs on MAME, which no profile ties to bbcb.zip; CLK + """Batocera's bbc runs on MAME, which no profile ties to bbcb.zip, but CLK reads two of its ROMs. With CLK off the target the system stayed unknown before and must stay kept.""" declared = {"bbc": {"files": [ diff --git a/tests/test_truth_diff.py b/tests/test_truth_diff.py index c8661f5e..b2ffe176 100644 --- a/tests/test_truth_diff.py +++ b/tests/test_truth_diff.py @@ -77,7 +77,7 @@ class ADiffThatComparedNothingFails(unittest.TestCase): class OneNameSeveralFiles(unittest.TestCase): - """Dolphin's three IPL.bin differ only by path; the model kept one.""" + """Dolphin's three IPL.bin differ only by path, and the model kept one.""" REGIONS = {"USA": "a" * 32, "EUR": "b" * 32, "JAP": "c" * 32} diff --git a/tests/test_twin_declarations.py b/tests/test_twin_declarations.py index 7a2ab26b..4acbddf7 100644 --- a/tests/test_twin_declarations.py +++ b/tests/test_twin_declarations.py @@ -2,7 +2,7 @@ RetroDECK declares bios/disk.rom for pc88 (the N88SUB ROM) and for coco (the CoCo disk ROM), and bios/cdibios.zip for two components with two md5. The -pack holds one file per path; verify resolved each declaration to its own +pack holds one file per path, but verify resolved each declaration to its own file and counted both OK, so three green tools described a pack whose frontend hashes bios/disk.rom for xroar and finds the PC-88 ROM. """ @@ -75,7 +75,7 @@ class TwinDeclarations(unittest.TestCase): self.assertEqual(statuses.count("ok"), 1, by_system) loser = next(d for d in by_system.values() if d["status"] != "ok") self.assertIn("is not met at the path", loser.get("discrepancy", "")) - # The path counts once, for the file it ships; the loser is a detail. + # The path counts once, for the file it ships. The loser is a detail. self.assertEqual(report["status_counts"], {"ok": 1}) diff --git a/tests/test_unplaced_extras.py b/tests/test_unplaced_extras.py index e3d1df41..90ba40bf 100644 --- a/tests/test_unplaced_extras.py +++ b/tests/test_unplaced_extras.py @@ -2,7 +2,7 @@ RomM files every BIOS under the slug of its system and knows no slug for DOS or for the arcade sets MAME 2003 reads. The builder skipped those -entries without a word; the report counted them "in pack" and the manifest +entries without a word: the report counted them "in pack" and the manifest listed them neither in files nor in omitted_files. """ diff --git a/tests/test_upstream.py b/tests/test_upstream.py index c27720e4..282cd57b 100644 --- a/tests/test_upstream.py +++ b/tests/test_upstream.py @@ -436,7 +436,7 @@ class TestCache(unittest.TestCase): class TestCacheCollision(unittest.TestCase): def test_a_file_where_a_directory_is_needed_skips_the_write(self): # A profile citing both a directory and files inside it caches the - # directory as a file first; that must not break the files. + # directory as a file first, and that must not break the files. with tempfile.TemporaryDirectory() as root: base = Path(root) (base / "C64DTV").write_text("", encoding="utf-8") @@ -689,7 +689,7 @@ class TestCompare(unittest.TestCase): def test_a_missing_tag_is_asked_again_once_stale(self): """A profile written on release day asked for v2.0 before it was - pushed; the 404 was cached for good and the profile was never seen + pushed. The 404 was cached for good and the profile was never seen as frozen on its tag.""" import os as _os diff --git a/tests/test_validate_pr.py b/tests/test_validate_pr.py index ab2b06aa..9910e897 100644 --- a/tests/test_validate_pr.py +++ b/tests/test_validate_pr.py @@ -264,11 +264,11 @@ class Reporting(_Fixture): markdown = result.to_markdown() for value in (result.sha1, result.md5, result.crc32): self.assertIn(value, markdown) - self.assertIn("✅", markdown) + self.assertIn("### PASS", markdown) def test_a_failure_is_marked_in_the_heading(self): rel = self._bios_file("bios/Sega/Saturn/bad.exe") - self.assertIn("❌", validate_pr.validate_file(rel, None, EMPTY_HASHES).to_markdown()) + self.assertIn("### FAIL", validate_pr.validate_file(rel, None, EMPTY_HASHES).to_markdown()) class PlatformHashLoading(_Fixture): @@ -324,7 +324,7 @@ class FlagsAreAppliedOrRefused(unittest.TestCase): class AFileOutsideBiosIsToldWhereToGo(unittest.TestCase): """validate_pr knew bios/Sony/PlayStation/ for scph5501.bin and only said - "not under bios/"; given an absolute path, a placed file was reported a + "not under bios/". Given an absolute path, a placed file was reported a duplicate of itself.""" def test_both(self): diff --git a/tests/test_validated_choice.py b/tests/test_validated_choice.py index d509abd1..241622ec 100644 --- a/tests/test_validated_choice.py +++ b/tests/test_validated_choice.py @@ -1,7 +1,7 @@ """The pack and the install manifest place the same bytes at a destination. The builder replaced a file an emulator rejects by a held variant both -accept; the manifest kept the first resolution. install.py then placed the +accept, but the manifest kept the first resolution. install.py then placed the PS2 ROM2.BIN at galaksija/ROM2.BIN where the pack carried the Galaksija ROM, across 14 destinations on six platforms. """ @@ -102,7 +102,7 @@ class ValidatedChoice(unittest.TestCase): ) def test_core_extras_are_judged_too(self): - """The baseline loop judged a platform's own files; the core-extras loop + """The baseline loop judged a platform's own files while the core-extras loop shipped whatever the name found. Both loops live in generate_pack.""" tree = ast.parse((REPO_ROOT / "scripts" / "generate_pack.py").read_text(encoding="utf-8")) builder = next( @@ -217,7 +217,7 @@ class DolphinForksJudgeTheirOwnDspTable(unittest.TestCase): class AWarningRejectsNothing(unittest.TestCase): - """BeebEm warns about a short ROM and runs it; Azahar warns about a bad + """BeebEm warns about a short ROM and runs it. Azahar warns about a bad signature and runs the file. A warn-level check never refuses a file, yet a held file that passes it is preferred.""" diff --git a/tests/test_validation_scope.py b/tests/test_validation_scope.py index b631e19c..87399f97 100644 --- a/tests/test_validation_scope.py +++ b/tests/test_validation_scope.py @@ -2,7 +2,7 @@ Built over every profile, ZEsarUX (standalone, a 48K cpc6128.rom) and ePSXe judged RetroArch packs and the gaps page listed five hash mismatches with no -object. verify and the builder pass resolve_platform_cores' selection; this +object. verify and the builder pass resolve_platform_cores' selection, and this test fails if either hands the index the whole profile set again. """ diff --git a/tests/test_verify_emulator_evidence.py b/tests/test_verify_emulator_evidence.py index e70dc7a9..c8a20e9e 100644 --- a/tests/test_verify_emulator_evidence.py +++ b/tests/test_verify_emulator_evidence.py @@ -356,8 +356,8 @@ class RepositoryWideEvidence(unittest.TestCase): ) if local and status == "hash_mismatch": offenders.append(f"{key}:{entry.get('name', '')}") - # These exist; what must not happen is verify calling them covered. - # The unit tests above pin the reporting -- this one records the size + # These exist. What must not happen is verify calling them covered. + # The unit tests above pin the reporting, and this one records the size # of the surface so a regression in resolution shows up here. self.assertIsInstance(offenders, list) print(f"\n entries resolving to hash_mismatch: {len(offenders)}") diff --git a/tests/test_verify_pack_choice.py b/tests/test_verify_pack_choice.py index f19f1765..1898de8a 100644 --- a/tests/test_verify_pack_choice.py +++ b/tests/test_verify_pack_choice.py @@ -3,7 +3,7 @@ The check took the first sorted *_BIOS_Pack.zip whose name contained the platform name. With a full and a regional pack side by side, --region us judged the full pack against the regional expectation and never opened the -regional one; a pack built with --source truth answered SKIP and exit 0. +regional one. A pack built with --source truth answered SKIP and exit 0. """ from __future__ import annotations diff --git a/tests/test_workflow_paths.py b/tests/test_workflow_paths.py index d0661884..c831e372 100644 --- a/tests/test_workflow_paths.py +++ b/tests/test_workflow_paths.py @@ -80,7 +80,7 @@ class DeploySiteTriggers(unittest.TestCase): ) self.assertIn("generate_site.py", entry_points) # mkdocs build runs the hooks mkdocs.yml names: a script of the build. - # The file carries Python tags safe_load refuses; the list is plain. + # The file carries Python tags safe_load refuses, but the list is plain. mkdocs = (REPO_ROOT / "mkdocs.yml").read_text(encoding="utf-8") hooks = re.search(r"^hooks:\n((?: - .+\n)+)", mkdocs, re.M) entry_points += [ @@ -140,7 +140,7 @@ class DocumentedSteps(unittest.TestCase): self.assertEqual(silent, []) def test_the_scraper_recipe_names_every_abstract_method(self): - """tools.md said implement fetch_requirements(); validate_format() is + """tools.md said implement fetch_requirements(), but validate_format() is abstract too, and a scraper written from the page could not be built.""" source = (SCRIPTS / "scraper" / "base_scraper.py").read_text(encoding="utf-8") abstract = re.findall(r"@abstractmethod\s+def (\w+)", source) diff --git a/wiki/adding-a-platform.md b/wiki/adding-a-platform.md index aeb15813..301bf639 100644 --- a/wiki/adding-a-platform.md +++ b/wiki/adding-a-platform.md @@ -377,7 +377,7 @@ This executes in sequence: A new platform is archived-by-default nowhere: `status: active` puts it in `list_platforms.py`, the CI matrix, and the scrapers. Set -`status: archived` to keep the configuration without the automation; archived +`status: archived` to keep the configuration without the automation. Archived platforms are excluded unless `--all` or `--include-archived` is passed. Check the output for: diff --git a/wiki/adding-a-scraper.md b/wiki/adding-a-scraper.md index d0888470..d35aae19 100644 --- a/wiki/adding-a-scraper.md +++ b/wiki/adding-a-scraper.md @@ -330,7 +330,7 @@ Parses Logiqx XML DATs, the format the dump-preservation catalogs publish: Used by `redump_dat_scraper` (fetches the four Redump BIOS DATs directly) and by `dat_pack_importer` (reads a locally downloaded No-Intro or TOSEC pack, since neither can be fetched without a browser). Both write a snapshot to -`provenance/`; they do not touch platform YAMLs. +`provenance/`, and they do not touch platform YAMLs. ### mame_parser @@ -436,8 +436,8 @@ exporter then had to invent: add it to the requirement instead, through | Unmapped slug warnings | New system added upstream | Add mapping to `SLUG_MAP` | | Empty requirements list | Upstream format changed | Check `validate_format()`, update parser | | Hash mismatch in verify | Upstream updated hashes | Re-scrape and regenerate platform YAML | -| Scraper hangs | URL unreachable, no timeout | `_fetch_raw()` has 30s timeout; check URL | -| `Response exceeds 50 MB` | Upstream file grew | Investigate; may need chunked parsing | +| Scraper hangs | URL unreachable, no timeout | `_fetch_raw()` has 30s timeout, check URL | +| `Response exceeds 50 MB` | Upstream file grew | Investigate, may need chunked parsing | | `validate_format` fails | Upstream restructured | Update both `validate_format` and `fetch_requirements` | ### E2E tests diff --git a/wiki/advanced-usage.md b/wiki/advanced-usage.md index cfc66b5d..4c134824 100644 --- a/wiki/advanced-usage.md +++ b/wiki/advanced-usage.md @@ -17,7 +17,7 @@ and exits 1 when a hash is not in the database, so a script can tell. Build a pack containing only files matching hashes from a list. Each line carries one hash (MD5, SHA-1 or CRC32), alone or beside a file name as -`md5sum` writes it; `#` starts a comment: +`md5sum` writes it. A `#` starts a comment: ```bash python scripts/generate_pack.py --platform batocera --from-md5-file missing.txt @@ -87,7 +87,7 @@ Three rules keep a filtered pack usable: `--region us` still ships `disksys.rom`, because the Famicom Disk System has no American BIOS. - **Region-free files always survive.** `psxonpsp660.bin`, `ps1_rom.bin` and - `openbios.bin` are declared `[world]`; they add a capability rather than + `openbios.bin` are declared `[world]`: they add a capability rather than competing regionally. - **Untagged files always survive.** Most BIOS are not regional and carry no `region:` at all. @@ -144,7 +144,7 @@ Where no such list is declared, the group is left untouched and counted: Two rules keep a declared order from overreaching: - **Cores that disagree cancel out.** pcsx1 walks `scph1001` first while - DuckStation prefers `scph5501`; the pack serves both cores, so neither order + DuckStation prefers `scph5501`. The pack serves both cores, so neither order wins and both files stay. - **A slot mixing unrelated roles stays open.** px68k's IPL ROMs are ranked, but its character ROM shares the same system and carries no rank, so the diff --git a/wiki/architecture.md b/wiki/architecture.md index f882f5cb..ff62e513 100644 --- a/wiki/architecture.md +++ b/wiki/architecture.md @@ -13,7 +13,7 @@ platforms/ one YAML config per platform (scraped from upstream) _data_dirs.yml data directory definitions (Dolphin Sys, PPSSPP...) targets/ hardware target configs + _overrides.yml provenance/ dump-catalog snapshots (redump, no-intro, tosec) -scripts/ all tooling (Python, pyyaml; jsonschema for schema checks) +scripts/ all tooling (Python and pyyaml, jsonschema for schema checks) scraper/ upstream scrapers (libretro, batocera, recalbox...) scraper/targets/ hardware target scrapers (retroarch, batocera, emudeck, retropie) exporter/ native format exporters (batocera, recalbox, emudeck...) @@ -96,7 +96,7 @@ graph LR The pack combines platform baseline (layer 1) with core requirements (layer 3). Neither too much (no files from unused cores) nor too few (no missing files for active cores). A same-named local file that contradicts an explicit hash is recorded as an -unsafe omission on hash-verifying platforms; existence platforms ship it and +unsafe omission on hash-verifying platforms, while existence platforms ship it and report the divergence, because their code never reads the bytes. The emulator's source code serves as ground truth for what files are needed, @@ -139,7 +139,7 @@ follow the emulator source code. `provenance_report.py` reports the reverse direction: catalog entries absent from the collection, which become acquisition targets. A DAT counts as covered -when the collection holds at least one of its entries; entries from DATs the +when the collection holds at least one of its entries. Entries from DATs the collection does not cover are counted but not listed, since No-Intro tags every non-game dump as `[BIOS]`, including tens of thousands of digital-distribution entries that are out of scope here. @@ -150,13 +150,13 @@ Platforms that produce identical packs are grouped automatically. Two platforms share a pack when they declare the same files, run the same emulators and see file names the same way. Lakka declares RetroArch's files and cores but runs on Linux, where `bios.col` and `BIOS.col` are two files -that different cores open; RetroArch's pack folds them for Windows and macOS. +that different cores open, while RetroArch's pack folds them for Windows and macOS. So Lakka gets its own pack. RetroPie inherits RetroArch's systems but ships its own package list, standalone emulators included, and is case-sensitive too, so it gets a separate pack and a separate install manifest. With `--target`, the fingerprint includes target cores so platforms with different hardware filters get separate packs. Emulator and system packs -also retain system identity, `variant_group` and requested region; same-named +also retain system identity, `variant_group` and requested region. Same-named regional files are never collapsed merely because their display label matches. ## Pack reproducibility @@ -209,19 +209,19 @@ emulator-level validation (wrong CRC32, wrong size), a DISCREPANCY is reported. The pack generator searches the repo for a variant that satisfies both. If none exists, the platform version is kept and the discrepancy stays reported. A filename or destination never overrides a declared content hash -during resolution; whether a mismatch is packed is then decided by the +during resolution. Whether a mismatch is packed is then decided by the platform's own verification mode. ## Security - install metadata is fetched from the same revision as the installer that - reads it, and validated before use; -- destinations are normalized and contained below the selected BIOS root; + reads it, and validated before use. +- destinations are normalized and contained below the selected BIOS root. - downloads are bounded by declared and global size limits, verified with - SHA256/SHA1, written to unique temporary siblings and atomically replaced; + SHA256/SHA1, written to unique temporary siblings and atomically replaced. - ZIP extraction rejects traversal, absolute paths, duplicates, links, special - files, encryption, excessive expansion and suspicious compression ratios; -- standalone-emulator copies require explicit `--standalone-copies` consent; + files, encryption, excessive expansion and suspicious compression ratios. +- standalone-emulator copies require explicit `--standalone-copies` consent. - CI writes only what its job needs: `validate.yml` holds `pull-requests: write` for the validation comment and labels, `deploy-site.yml` holds the Pages deploy identity, and the release job holds `contents: write` but runs only @@ -355,7 +355,7 @@ pattern and how to add a test. | Workflow | File | Trigger | Role | |----------|------|---------|------| | Deploy Site | `deploy-site.yml` | push to main (platforms, emulators, wiki, scripts) + manual | validate contracts, generate site, build with MkDocs, validate rendered HTML, deploy to Pages | -| Validation | `validate.yml` | pull request and push to main on bios/, platforms/, emulators/, schemas/, scripts/, tests/ | schema check and full test suite on both; BIOS hash validation and auto-label on pull requests | +| Validation | `validate.yml` | pull request and push to main on bios/, platforms/, emulators/, schemas/, scripts/, tests/ | schema check and full test suite on both, BIOS hash validation and auto-label on pull requests | Releases are not built in CI: the packs are generated and checked on the maintainer's machine and uploaded with `gh`, see the diff --git a/wiki/faq.md b/wiki/faq.md index 00b41cb8..00f44e53 100644 --- a/wiki/faq.md +++ b/wiki/faq.md @@ -39,8 +39,8 @@ Platforms that verify by MD5 accept specific hashes. If yours doesn't match any A filename is never allowed to stand in for a declared hash. When a file entry carries a hash, resolution matches on content and reports `hash_mismatch` if the only same-named copy disagrees. What happens next depends on the platform: an -MD5 or SHA1 platform would reject the file, so the pack omits it and says why; -an existence platform only checks presence, so the file ships and the divergence +MD5 or SHA1 platform would reject the file, so the pack omits it and says why, +while an existence platform only checks presence, so the file ships and the divergence is reported instead. ## Why are there files that aren't BIOS? @@ -80,7 +80,7 @@ version's own source tree, because the BIOS root sets differ between versions. Derivatives and ports carry their own profiles on top of those generations: `mamearcade`, `mamemess`, `mame2003_midway`, the three `mame4droid` drops, `advancemame`, `groovymame` and `hbmame`. The pack -ships the sets matching the core you run; a generic unversioned arcade +ships the sets matching the core you run, and a generic unversioned arcade pack cannot do that. ## How do I know which BIOS I need? @@ -138,7 +138,7 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \ ``` On Windows the arguments need a script block, since `iex` would read them as -its own; the form is on the [Installer](installer.md#passing-options) page. +its own. The form is on the [Installer](installer.md#passing-options) page. ## Is this legal? @@ -148,7 +148,7 @@ Redistributing firmware is not settled law, and this page does not pretend other - **Writing an emulator is lawful.** *Sony v. Connectix* (2000) and *Sega v. Accolade* (1992) held that copying a work during reverse engineering, to reach the functional elements needed for interoperability, is fair use. Both concern the act of copying while developing, and *Connectix* specifically involved copying Sony's BIOS in the course of that work. Neither decision addresses distributing firmware to third parties, so they support the legality of emulation itself rather than of this collection. - **Fair use (US, 17 USC 107) is a defence, argued case by case.** The project's position is that non-commercial redistribution for personal backup and archival weighs favourably on purpose and on market effect, since these files are not sold separately. It weighs poorly on the amount used: each file is copied whole. Manufacturers do still monetise some of this firmware indirectly, through re-releases, subscription services and mini consoles, so the market factor is contestable rather than clear. -- **Interoperability in the EU.** The Software Directive (2009/24/EC, Art. 5-6) permits decompilation and use to achieve interoperability, subject to conditions, and Art. 6 restricts passing the resulting information to others. It supports the emulation use case; it is not a general redistribution permission. +- **Interoperability in the EU.** The Software Directive (2009/24/EC, Art. 5-6) permits decompilation and use to achieve interoperability, subject to conditions, and Art. 6 restricts passing the resulting information to others. It supports the emulation use case, but it is not a general redistribution permission. - **Discontinued hardware.** Most firmware here is for hardware no longer sold or supported. This bears on the fair-use market factor and on the practical likelihood of complaint. "Abandonware" is not a legal doctrine in any jurisdiction, and nothing here rests on it. ### Encryption keys (Switch prod.keys, 3DS AES keys, Wii U keys) @@ -158,13 +158,13 @@ This is the most contested area, and the weakest part of the project's position. - **Keys are unlikely to be copyrightable.** A bare numeric value has no author's creative expression, so copyright is a poor fit. This says nothing about the DMCA, which is the provision that actually applies. - **DMCA 1201(f) is narrow.** Section 1201(f) allows a person who has lawfully obtained the right to use a copy to circumvent for the sole purpose of achieving interoperability with an independently created program, and 1201(f)(3) allows the means to be made available to others only for that same purpose. Publishing keys openly is not obviously within that allowance, and the trafficking prohibitions in 1201(a)(2) and 1201(b) remain in play. This is the clearest legal risk the project carries. - **Library of Congress exemptions do not cover this repository.** The triennial exemptions at 37 CFR 201.40 let an eligible library, archive or museum circumvent access controls to preserve a lawfully acquired video game whose server support has ended, with access limited to the institution's premises. The Ninth Triennial Proceeding (2024 cycle) renewed them and declined to extend them to off-premises remote access. A public repository is neither an eligible institution nor an on-premises reading room, so these exemptions show which way preservation policy is moving without authorising what is done here. -- **Keys come from consumer hardware.** They are extracted from retail devices their owners bought. *Chamberlain v. Skylink* (2004) held that a 1201 claim requires some nexus to copyright infringement, in a dispute over a garage-door opener; later cases have narrowed its reach, and it is a weak foundation for a general post-sale right. +- **Keys come from consumer hardware.** They are extracted from retail devices their owners bought. *Chamberlain v. Skylink* (2004) held that a 1201 claim requires some nexus to copyright infringement, in a dispute over a garage-door opener. Later cases have narrowed its reach, and it is a weak foundation for a general post-sale right. - **Trade secret is not a live issue.** Keys embedded in millions of shipped devices and widely republished are not kept secret by reasonable measures. ### Recent firmware (Switch 19.0.0, PS3UPDAT, PSVUPDAT) -- **Free download is not a licence.** Manufacturers publish these updates on open CDNs without authentication, which makes them easy to obtain but does not grant a right to redistribute them; PlayStation firmware ships under an end-user licence agreement. The practical argument is that mirroring a file the manufacturer already gives away for free causes no identifiable loss, not that doing so is expressly permitted. -- **Functional necessity.** Emulators cannot run the software these systems were built for without this firmware. That is why the files are collected; it is a statement of purpose, not a legal defence in itself. +- **Free download is not a licence.** Manufacturers publish these updates on open CDNs without authentication, which makes them easy to obtain but does not grant a right to redistribute them, and PlayStation firmware ships under an end-user licence agreement. The practical argument is that mirroring a file the manufacturer already gives away for free causes no identifiable loss, not that doing so is expressly permitted. +- **Functional necessity.** Emulators cannot run the software these systems were built for without this firmware. That is why the files are collected. It is a statement of purpose, not a legal defence in itself. - **Yuzu context.** The Yuzu settlement (2024) concerned the emulator and its alleged facilitation of piracy. Yuzu settled without admitting liability, so it set no precedent either way on firmware or key redistribution. It does show that rights holders in this space litigate. ### Summary @@ -175,11 +175,11 @@ This reflects the project's good-faith understanding, not legal advice. ### Asking for a file to be removed -A rights holder, or anyone acting for one, can [open an issue](https://github.com/Abdess/retrobios/issues) identifying the file by path or hash. A file whose removal is requested by its rights holder is removed from the repository and from the next release; no formal notice is required and none will be demanded. State the file and the basis of the claim. The same channel is open to anyone else with a concern about a specific file. +A rights holder, or anyone acting for one, can [open an issue](https://github.com/Abdess/retrobios/issues) identifying the file by path or hash. A file whose removal is requested by its rights holder is removed from the repository and from the next release. No formal notice is required and none will be demanded. State the file and the basis of the claim. The same channel is open to anyone else with a concern about a specific file. ## Isn't the Switch or PS3 too recent for a retro project? -Age is not what decides inclusion here; availability is. Firmware distribution depends on manufacturer servers, and those disappear: Nintendo closed the 3DS and Wii U eShops in March 2023, Sony shut the PSP store in 2021. Once a CDN goes offline, the files only survive where someone archived them. +Age is not what decides inclusion here: availability is. Firmware distribution depends on manufacturer servers, and those disappear: Nintendo closed the 3DS and Wii U eShops in March 2023, Sony shut the PSP store in 2021. Once a CDN goes offline, the files only survive where someone archived them. The project tries to archive files while they are still available rather than after they have become rare. "Retro" is a moving window: the PlayStation 2 was current hardware when its BIOS was first preserved, and today's consoles will be tomorrow's retro systems. A file is included for the same reason at any age: an emulator needs it, and nothing guarantees it stays available. @@ -211,7 +211,7 @@ On existence-mode platforms (RetroArch, Lakka, RetroPie), files are never `untes Running `verify.py --emulator <core> --verbose` shows the emulator-level ground truth, which can confirm whether the file's hash matches what the source code expects. The platform report applies the same check on its own: `verify.py --platform retroarch` prints a `DISCREPANCY` line for every file the platform accepts and a profiled emulator rejects. -It reaches only as far as the profiles do. Files no profile states a value for are platform-only, and nothing can be said about their content; the footer of the platform report gives that ratio as `Ground truth: N/M files have emulator validation`. +It reaches only as far as the profiles do. Files no profile states a value for are platform-only, and nothing can be said about their content. The footer of the platform report gives that ratio as `Ground truth: N/M files have emulator validation`. ## Can I use BIOS from one platform on another? diff --git a/wiki/first-install.md b/wiki/first-install.md index c0ca27e1..f3781b7b 100644 --- a/wiki/first-install.md +++ b/wiki/first-install.md @@ -12,7 +12,7 @@ the cases that come up. Three things, and a few minutes: - The BIOS folder the emulator reads. The installer finds it by itself on most - systems; on a handheld, that usually means plugging the SD card into a + systems. On a handheld, that usually means plugging the SD card into a computer. - `curl` or `wget`, and Python 3.8 or newer. The command below checks for both and stops with a message if either is absent. @@ -155,7 +155,7 @@ its BIOS folder, see [Getting started](getting-started.md). ### Error: Python 3.8 or newer is required. Python is missing from the machine. The message names the command that installs -it, `sudo apt install python3` on Debian and Ubuntu; on a handheld running Batocera or Recalbox it is already there, so +it, `sudo apt install python3` on Debian and Ubuntu. On a handheld running Batocera or Recalbox it is already there, so this message usually means the command ran on the computer rather than on the console. diff --git a/wiki/getting-started.md b/wiki/getting-started.md index bfd6d53f..a18bdd44 100644 --- a/wiki/getting-started.md +++ b/wiki/getting-started.md @@ -6,8 +6,8 @@ BIOS files are firmware dumps from original console hardware. Emulators need the ## Installation -Three ways to get BIOS files in place. The installer is the one to use; -the two sections after it are for when it cannot run. For a walkthrough of a +Three ways to get BIOS files in place. The installer is the one to use, +and the two sections after it are for when it cannot run. For a walkthrough of a first install with what each step prints, see [First install](first-install.md). @@ -56,7 +56,7 @@ python install.py --standalone-copies # opt in to extra standalone-emulator pat The default flow writes inside the detected platform tree only. Copies into separate standalone-emulator directories are opt-in, so discovery cannot cause unexpected writes elsewhere on the machine. Entries the collection cannot -satisfy are reported as safely omitted and the run continues; the installer +satisfy are reported as safely omitted and the run continues. The installer never substitutes a same-named file for one a hash-verifying platform would reject. diff --git a/wiki/index.md b/wiki/index.md index 919556c1..fc3e4ded 100644 --- a/wiki/index.md +++ b/wiki/index.md @@ -45,9 +45,9 @@ See [contributing](../contributing.md) for submission guidelines. ## Glossary - **BIOS** - firmware burned into console hardware, needed by emulators that rely on original boot code -- **firmware** - system software loaded by a console at boot; used interchangeably with BIOS in this project -- **HLE** - High-Level Emulation; software reimplementation of BIOS functions, avoids needing the original file -- **hash** - fixed-length fingerprint of a file's contents; this project uses MD5, SHA1, SHA256, CRC32, and Adler-32 +- **firmware** - system software loaded by a console at boot, used interchangeably with BIOS in this project +- **HLE** - High-Level Emulation: software reimplementation of BIOS functions, avoids needing the original file +- **hash** - fixed-length fingerprint of a file's contents. This project uses MD5, SHA1, SHA256, CRC32, and Adler-32 - **platform** - a distribution that packages emulators (RetroArch, Batocera, Recalbox, EmuDeck, etc.) - **core** - an emulator packaged as a libretro plugin, loaded by RetroArch or compatible frontends - **profile** - a YAML file in `emulators/` documenting one core's BIOS requirements, verified against source code @@ -58,11 +58,11 @@ See [contributing](../contributing.md) for submission guidelines. - **scraper** - a script that fetches BIOS requirement data from an upstream source (System.dat, es_bios.xml, etc.) - **exporter** - a script that converts ground truth data back into a platform's native format - **target** - a hardware architecture that a platform runs on (e.g. switch, rpi4, x86_64, steamos) -- **region** - the territory an emulator's code branches on to select a file; `--region` builds a pack from an ordered priority list, `--one-per-slot` keeps one file per system and region +- **region** - the territory an emulator's code branches on to select a file. `--region` builds a pack from an ordered priority list, `--one-per-slot` keeps one file per system and region - **variant** - an alternative version of a BIOS file (different revision, region, or dump), stored in `.variants/` -- **required** - a file the core needs to function; determined by source code behavior +- **required** - a file the core needs to function, determined by source code behavior - **optional** - a file the core functions without, possibly with reduced accuracy or missing features -- **hle_fallback** - flag on a file indicating the core has an HLE path; absence is downgraded to INFO severity +- **hle_fallback** - flag on a file indicating the core has an HLE path, and absence is downgraded to INFO severity - **severity** - the urgency of a verification result: OK (verified), INFO (negligible), WARNING (degraded), CRITICAL (broken) - **status** - the outcome of a single file check: `ok`, `untested` (present, hash not the expected one), or `missing` - **discrepancy** - a file that passes the platform check but fails the emulator's own size or hash validation @@ -71,5 +71,5 @@ See [contributing](../contributing.md) for submission guidelines. - **storage tier** - where a file comes from: `embedded` (in `bios/`), `external` (downloaded at build), `user_provided` - **truth** - platform-shaped data generated from emulator profiles, used to diff against what the platform declares - **dump catalog** - a preservation project (Redump, No-Intro, TOSEC) publishing DATs of verified hardware dumps -- **provenance** - the catalogs that list a file, joined into the database by hash; an annotation, never an authority +- **provenance** - the catalogs that list a file, joined into the database by hash. An annotation, never an authority - **manifest** - the JSON file list per platform in `install/`, consumed by `install.py` diff --git a/wiki/installer.md b/wiki/installer.md index 4fe7eb0d..b4c437f2 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -63,11 +63,11 @@ POSIX, `py -3` then `python3` then `python` on Windows) and refuse to continue without one. `install.sh` needs `curl` or `wget` and `sha256sum` or `shasum`. Windows PowerShell 5.1 still negotiates SSL 3.0 and TLS 1.0 by default and GitHub refuses both, so `install.ps1` raises the floor to TLS 1.2 before -downloading; `install.sh` pins the same floor with `curl --tlsv1.2`. +downloading, and `install.sh` pins the same floor with `curl --tlsv1.2`. They delete the temporary installer on the way out, including on interrupt. Run from a clone, `install.sh` and `install.ps1` reuse the `install.py` sitting -next to them and skip the download entirely; piped from stdin, `install.sh` +next to them and skip the download entirely. Piped from stdin, `install.sh` never treats the working directory as a trusted location for it. Piped from `curl`, the shell's standard input is the script itself, so @@ -88,7 +88,7 @@ macOS. 4. Hashes what is already in the destination and reports how many entries are present, verified, or present with the wrong contents. 5. Downloads what is missing or wrong, up to 8 files at a time. At a - terminal one line shows the progress, the speed and the time left; in a + terminal one line shows the progress, the speed and the time left, while in a log each finished file gets its own line. In an interactive run, a download of 1 GB or more is confirmed first (`--yes` skips the question). 6. Verifies each download against the declared size, SHA-256 and SHA-1 before @@ -127,8 +127,8 @@ Retroarch: 5865 files, 5.7 GB. q) quit ``` -`i` appears for RetroArch, Lakka and RetroPie when cores are found installed; -the line above is a RetroArch with Beetle PSX HW, Snes9x, mGBA, Genesis Plus GX +`i` appears for RetroArch, Lakka and RetroPie when cores are found installed, +and the line above is a RetroArch with Beetle PSX HW, Snes9x, mGBA, Genesis Plus GX and FCEUmm. It keeps what those cores read and drops the systems none of them emulates, the rule `--installed-cores` applies. @@ -141,7 +141,7 @@ the rule `--installed-cores` applies. list, such as game engines and extra computers. Choosing systems leaves it out unless it is chosen too, as `generate_pack.py --system` does. - **Cores.** The platform's own BIOS list for the chosen systems is always - kept; this narrows only the extra files each emulator core loads beyond it. + kept. This narrows only the extra files each emulator core loads beyond it. Asked only when the chosen systems have such files. - **Regions.** Asked only when a chosen system has one BIOS per region. The numbers give an order of preference: `2,1` keeps the second region where a @@ -169,12 +169,12 @@ they need. The cores are the `<name>_libretro.so` (`.dll`, `.dylib`, unset, a `retroarch.cfg` next to the system directory for a portable install given with `--dest`, and the folders RetroPie (`/opt/retropie/libretrocores`) and Lakka (`/usr/lib/libretro`, `/storage/cores`) install into. A core file -is named the buildbot's way (`mednafen_psx`); the manifest maps each name to +is named the buildbot's way (`mednafen_psx`), and the manifest maps each name to the profile its files are filed under (`beetle_psx`). What stays is what a pack built for exactly those cores carries, the rule `--target` follows too: a platform system stays when an installed core -emulates it or reads its files, or when no core of the platform does; a +emulates it or reads its files, or when no core of the platform does. A file a core loads stays when that core is installed. Where two cores read one path and want different bytes, the copy of the first installed core in the builder's order is the one installed. The same holds for a file of the @@ -195,12 +195,12 @@ than what was asked. A system name that itself contains commas, as Recalbox's The region rule is the one `generate_pack.py --region` applies, and a test holds the two to the same file list. In each group of regional alternatives -the best-ranked match stays; a file declared for every region beats regional -files that match nothing asked; when nothing matches, every regional file +the best-ranked match stays. A file declared for every region beats regional +files that match nothing asked. When nothing matches, every regional file stays, so no system is left without its BIOS. A file the emulator does not select by region always stays. The manifest records, for each file, the systems that declare it, and for a regional file, its regions and the groups -it competes in; the installer reads nothing else. +it competes in. The installer reads nothing else. The questions are asked only when standard input is a terminal. Piped, scripted or run with `--no-input`, the installer asks nothing and installs @@ -214,9 +214,9 @@ what the options name, everything by default. | `--dest PATH` | Destination directory, overriding detection. With `--dest` alone the file list is RetroArch's | | `--target NAME` | Keep only the files the cores of that hardware target need, and the systems they emulate. An unknown target is refused rather than ignored, since carrying on would install everything. On Batocera, Recalbox and ROCKNIX the board is read from the system (`batocera.arch`, `recalbox.arch`, `HW_DEVICE`) and applied when no `--target` is given | | `--every-board` | Install the files of every board instead of the one the system names, for a card that moves between devices | -| `--installed-cores` | Keep only what the cores already installed read (RetroArch, Lakka, RetroPie); see [Installed cores](#installed-cores) | -| `--system NAMES` | Install only these systems. Comma-separated or repeated; `--list-systems` prints the names, `other` included | -| `--core NAMES` | Keep the platform's own list and only the extra files these cores load; `--list-cores` prints the names | +| `--installed-cores` | Keep only what the cores already installed read (RetroArch, Lakka, RetroPie). See [Installed cores](#installed-cores) | +| `--system NAMES` | Install only these systems. Comma-separated or repeated. `--list-systems` prints the names, `other` included | +| `--core NAMES` | Keep the platform's own list and only the extra files these cores load. `--list-cores` prints the names | | `--region LIST` | Preferred regions, best first (`us,eu,jp`): keep one BIOS per region where a system has several. Accepts the names and aliases of `generate_pack.py --region` | | `--list-systems` | Print a platform's systems with the files and size each holds | | `--list-cores` | Print the cores whose extra files a platform installs | @@ -224,7 +224,7 @@ what the options name, everything by default. | `--check` | Report and exit without writing | | `--dry-run` | Show what would be downloaded, by system and with sizes, without writing anything | | `--yes`, `-y` | Do not ask before a download of 1 GB or more | -| `--quiet`, `-q` | Print only failures and the final summary; implies `--no-input` | +| `--quiet`, `-q` | Print only failures and the final summary. Implies `--no-input` | | `--version` | Print the installer's identity, the first 12 hex digits of the SHA-256 the bootstraps pin | | `--list-platforms` | Print the supported platforms and what was detected here | | `--list-targets` | Print the hardware targets a platform publishes, with the core count each carries | @@ -243,7 +243,7 @@ Files the list does not name are never read, moved or deleted. | Variable | Effect | |----------|--------| -| `RETROBIOS_REF` | Branch or tag the file list and the payloads are read from. Defaults to `main`; a release tag pins a reproducible file set | +| `RETROBIOS_REF` | Branch or tag the file list and the payloads are read from. Defaults to `main`, and a release tag pins a reproducible file set | | `RETROBIOS_BASE_URL` | Base URL for the manifest and the files it declares. HTTPS only, plain HTTP allowed to loopback for end-to-end tests. Whoever controls this base controls the expected hashes, hence the check | | `RETROBIOS_OS` | Names the host outright (`linux`, `wsl`, `windows`, `darwin`, `android`) instead of detecting it | | `EXTERNAL_STORAGE` | Android only, the shared storage root RetroArch builds its default directories from. Defaults to `/storage/emulated/0` | @@ -306,11 +306,11 @@ WSL does not pass them. A forced `--platform retrobat` falls back to | `~/.var/app/org.libretro.RetroArch/config/retroarch/retroarch.cfg` | RetroArch (Flatpak) | `system_directory` | | `~/snap/retroarch/current/.config/retroarch/retroarch.cfg` | RetroArch (Snap) | `system_directory` | | `~/.config/retroarch/retroarch.cfg` | RetroArch (native) | `system_directory` | -| `~/Library/Application Support/RetroArch/config/retroarch.cfg` | RetroArch (macOS) | `system_directory`; at default, `~/Documents/RetroArch/system` (portable, Steam build included: `Application Support/RetroArch/system`) | -| `retroarch.cfg` beside `retroarch.exe` (`C:\RetroArch-Win64`, `C:\RetroArch`, `Program Files\RetroArch`) | RetroArch (Windows) | `system_directory`; at default or without a config, `system` beside the exe | +| `~/Library/Application Support/RetroArch/config/retroarch.cfg` | RetroArch (macOS) | `system_directory`. At default, `~/Documents/RetroArch/system` (portable, Steam build included: `Application Support/RetroArch/system`) | +| `retroarch.cfg` beside `retroarch.exe` (`C:\RetroArch-Win64`, `C:\RetroArch`, `Program Files\RetroArch`) | RetroArch (Windows) | `system_directory`. At default or without a config, `system` beside the exe | | `%APPDATA%\RetroArch\retroarch.cfg` | RetroArch (Windows) | `system_directory`, read when the exe folder has no config | | `%ProgramFiles(x86)%\Steam\steamapps\common\RetroArch\retroarch.cfg` | RetroArch (Steam) | `system_directory` | -| `%LOCALAPPDATA%\Packages\1e4cf179-f3c2-404f-b9f3-cb2070a5aad8_*\LocalState` | RetroArch (UWP/MSIX package) | `system_directory` of the `retroarch.cfg` there, `~` meaning that folder; by default `LocalState\system` | +| `%LOCALAPPDATA%\Packages\1e4cf179-f3c2-404f-b9f3-cb2070a5aad8_*\LocalState` | RetroArch (UWP/MSIX package) | `system_directory` of the `retroarch.cfg` there, `~` meaning that folder. By default `LocalState\system` | | LaunchBox `Data\Emulators.xml` | RetroArch (portable) | the system directory that entry points at | | LaunchBox `Data\Emulators.xml` naming `EmuHawk.exe` | BizHawk (portable) | `Firmware` beside `EmuHawk.exe` | | `$BIZHAWK_DATA_HOME`, or `$XDG_DATA_HOME/emuhawk-monort-<version>` (Nix package) | BizHawk (Unix) | `Firmware` under it | @@ -469,7 +469,7 @@ followed. | `0` | everything asked for is installed or already up to date | | `1` | a failure: the one-liner could not download or verify `install.py`, or found no Python 3.8 (nothing was run), an unusable base URL, an unknown platform or target, `--installed-cores` with no core found, a manifest that fails validation, a fetch that never succeeded, no platform to install for in a non-interactive run, some files failed while others installed, or `--check` found files to fetch | | `2` | nothing was installed: every file the run tried failed (a BIOS folder that cannot be written, for one) | -| `130` | stopped with Ctrl+C; run the same command again to carry on | +| `130` | stopped with Ctrl+C. Run the same command again to carry on | | `141` | the output was piped to a reader that closed early (`--list \| head`) | `install.ps1` passes the installer's code on unchanged: run as a file it exits diff --git a/wiki/profiling.md b/wiki/profiling.md index c75d8473..616eb8dc 100644 --- a/wiki/profiling.md +++ b/wiki/profiling.md @@ -29,7 +29,7 @@ level. The emulator's own codebase is the single source of truth. No A note on libretro port differences: the most common change is path resolution. The upstream emulator loads files from the current working -directory; the libretro wrapper redirects to `retro_system_directory`. +directory, and the libretro wrapper redirects to `retro_system_directory`. This is normal adaptation, not a divergence worth documenting. Similarly, filename changes like `naomi2_eeprom.bin` becoming `n2_eeprom.bin` are often deliberate. RetroArch uses a single shared system directory for @@ -59,7 +59,7 @@ If the source is hosted outside GitHub, it's worth exploring further. Emulator source on GitLab, Codeberg, SourceForge, Bitbucket, archive.org snapshots, and community mirror tarballs. Inspecting copyright headers or license strings in the libretro fork often points to the original -author's site. The upstream code exists somewhere; it's worth continuing the search before concluding the source is unavailable. +author's site. The upstream code exists somewhere, so it's worth continuing the search before concluding the source is unavailable. One thing worth noting: even when the same repository was analyzed for a related profile (e.g., fbneo for arcade systems), it helps to do a @@ -148,7 +148,7 @@ What does not, and why each trap is easy to fall into: The exception is hardware that fuses both axes in one register, such as the Saturn SMPC area codes behind `asia-ntsc` and `asia-pal`. - **A single-region system.** When every file of a system shares one region, - the pack filter keeps them all anyway; annotating adds nothing. + the pack filter keeps them all anyway, so annotating adds nothing. - **A language without a territory.** Arabic MSX variants, CJK fonts. The vocabulary is territorial by design and inventing a slug would break it. @@ -222,7 +222,7 @@ files: Record `source_commit` when profiling: upstream code moves, and a `source_ref` line number only stays checkable against the commit it was read at. Profiles written before this field existed carry `profiled_date` -and `core_version` instead; they gain `source_commit` as they are +and `core_version` instead. They gain `source_commit` as they are re-verified. ### Writing style @@ -305,7 +305,7 @@ familiar codebase, avoids carrying over blind spots. **Path adaptation vs real divergence.** The libretro wrapper changing `fopen("./rom.bin")` to load from `system_dir` is the standard -porting pattern. The file is the same; only the directory resolution +porting pattern. The file is the same, only the directory resolution changed. True divergences (added/removed files, different embedded data) are the ones worth documenting. @@ -335,21 +335,21 @@ which CI validates every profile against. | `upstream` | no | original emulator repository URL | | `profiled_date` | yes | date of source analysis. Quote it, or YAML parses it as a date object | | `core_version` | yes | version analyzed | -| `source_commit` | no | commit SHA of `source` the code was read at; anchors every `source_ref` line number | +| `source_commit` | no | commit SHA of `source` the code was read at. Anchors every `source_ref` line number | | `upstream_commit` | no | same, for `upstream` | -| `source_branch` | no | branch `source` was read from when it is not the default one (a port living on a pull request branch); profile_sync follows it | +| `source_branch` | no | branch `source` was read from when it is not the default one (a port living on a pull request branch). profile_sync follows it | | `built_by` | no | platforms that compile this libretro build themselves (Recalbox's `mame0278`). Such a profile is reached only by a platform naming it in `cores:`, never by `all_libretro`: the buildbot does not publish it | | `bios_mode` | no | `agnostic` when the core takes any file of the right shape in its BIOS folder instead of a fixed name (PCSX2). Packs then carry every matching dump, and a `<bios>.bin` placeholder stands for them | -| `bios_directory` | no | the folder an agnostic core scans, relative to the system directory (`pcsx2/bios/`); a scan never seeds from files outside it | +| `bios_directory` | no | the folder an agnostic core scans, relative to the system directory (`pcsx2/bios/`). A scan never seeds from files outside it | | `display_name` | no | full display name (e.g. "Sega - Mega Drive (BlastEm)") | | `logo` | no | image URL used on the emulator page | | `systems` | yes | list of system IDs this core handles | | `cores` | no | every upstream name the core is known by, for buildbot/target matching | -| `alias_of` | for `type: alias` | profile key this one aliases; the alias carries no `files` | +| `alias_of` | for `type: alias` | profile key this one aliases. The alias carries no `files` | | `mode` | no | default mode: `standalone`, `libretro`, or `both` | | `verification` | no | how the core verifies BIOS: `existence`, `md5`, `sha1`, `crc32` | | `files` | yes, unless `type: alias` | list of file entries | -| `data_directories` | no | whole directory trees the core needs, referencing `_data_dirs.yml` keys; an entry may carry `mode:` when only one build reads the tree | +| `data_directories` | no | whole directory trees the core needs, referencing `_data_dirs.yml` keys. An entry may carry `mode:` when only one build reads the tree | | `notes` | no | free-form technical notes | | `note` | no | single-paragraph variant of `notes` | | `exclusion_note` | no | why the profile has no files despite .info declaring firmware | @@ -377,14 +377,14 @@ partitions), and `game_count`. | `required` | true if the core needs this file to function | | `system` | system ID this file belongs to (for multi-system profiles) | | `archive` | ROM set the file lives inside, for arcade entries (e.g. `neogeo.zip`) | -| `size` | expected size in bytes; a list when the code accepts several exact sizes | +| `size` | expected size in bytes, or a list when the code accepts several exact sizes | | `min_size`, `max_size` | size range when the code accepts a range | | `md5`, `sha1`, `crc32`, `sha256` | expected hashes from source code | -| `known_hash_adler32` | expected Adler-32 hash (Dolphin's DSP ROMs); pair with `adler32_byteswap` when the code hashes 16-bit byte-swapped data | +| `known_hash_adler32` | expected Adler-32 hash (Dolphin's DSP ROMs). Pair with `adler32_byteswap` when the code hashes 16-bit byte-swapped data | | `adler32_pairs_with`, `adler32_pairs` | the file hashed together with this one and the combinations the code accepts, this file's value first, in table order: Dolphin warns on a DSP ROM pair outside its `known_roms` even when each file passes alone | | `pin_frozen` | why `source_commit` is held on purpose rather than followed. The profile is then judged against its own revision, like one pinned to a superseded tag | | `prose_written_at` | the pin a reader confirmed the prose citations against. When the profile's history shows a text living under several pins, profile_sync takes this one as the revision the text describes, so a bump is no longer refused for a citation already reread. It never overrides a history with a single candidate | -| `upstream_gone` | why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass; profile_sync reports it as declared, and reports the contradiction if the forge answers again | +| `upstream_gone` | why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass. profile_sync reports it as declared, and reports the contradiction if the forge answers again | | `source_mirror` | a repository carrying the same tree, consulted after `source` and `upstream`. What keeps a profile checkable once its own forge stops answering | | `validation` | checks the code performs: `size`, `crc32`, `md5`, `sha1`, `adler32`, `signature`, `crypto`. Can be a list or dict `{core: [...], upstream: [...]}` for divergent checks | | `aliases` | alternate filenames for the same file | @@ -394,7 +394,7 @@ partitions), and `game_count`. | `region` | always a list of territory slugs from the schema enum (`[north-america]`, `[japan, asia-ntsc]`). The region the code selects the file **for**, never the region of the dump. See step 3b | | `region_check` | true if the core refuses to boot a game whose region does not match the BIOS | | `fast_boot` | BIOS generation label the core uses to decide whether fast boot is available | -| `priority` | preference order when several BIOS satisfy the same slot, **lowest wins**. DuckStation's `FindBIOSImageInDirectory` keeps the image whose priority is lower, and its table de-prioritizes by raising the number: the buggy launch console sits at 50 and PS2 images at 100, while `scph5501` sits at 5. A core that walks an ordered search list, as PicoDrive does with `biosfiles_us/eu/jp`, maps onto the same field as 1, 2, 3. Only set it from the source; `--one-per-slot` reads it | +| `priority` | preference order when several BIOS satisfy the same slot, **lowest wins**. DuckStation's `FindBIOSImageInDirectory` keeps the image whose priority is lower, and its table de-prioritizes by raising the number: the buggy launch console sits at 50 and PS2 images at 100, while `scph5501` sits at 5. A core that walks an ordered search list, as PicoDrive does with `biosfiles_us/eu/jp`, maps onto the same field as 1, 2, 3. Only set it from the source. `--one-per-slot` reads it | | `embedded` | true if the data is compiled into the binary and the external file is optional | | `bundled` | true if the file ships with the emulator rather than being user-provided | | `has_builtin` | true if the core falls back to a built-in copy when the file is absent | diff --git a/wiki/release-process.md b/wiki/release-process.md index 92dff32a..11e13b8a 100644 --- a/wiki/release-process.md +++ b/wiki/release-process.md @@ -33,7 +33,7 @@ dispatch. The list is the set of inputs the site is generated from. A script that `generate_site.py`, `generate_readme.py` or another build step starts to import -must be added to it, or the site silently goes stale; +must be added to it, or the site silently goes stale. `tests/test_workflow_paths.py` computes the import closure and fails when one is missing. @@ -107,7 +107,7 @@ of being silently ignored. each profile the change adds (the files `git diff --diff-filter=A` names against the pull request base, or against the commit a push moved main from). A profile written from a clone can cite lines that do not hold the value it -declares while schemas and tests pass it; this job confronts it with its +declares while schemas and tests pass it. This job confronts it with its upstream. An edited profile is not held to it. **run-tests.** Runs `python -m unittest discover -s tests -t . -v`. Must pass before a @@ -135,13 +135,13 @@ the arcade sets over 100 MB. `.gitignore` is the authoritative list: every **Storage.** Listed in `.gitignore` so they stay out of git history. Old version-tagged releases are deleted by hand when a new one is published -(see [cutting a release](#cutting-a-release)); `large-files` is never one of +(see [cutting a release](#cutting-a-release)), and `large-files` is never one of them. **Restore.** No workflow builds a pack. `generate_pack.py` fetches an asset into `.cache/large/` when a pack needs it (`fetch_large_file()`), and `scripts/restore_large_files.py` puts every registered asset back at its -`bios/` path by the SHA-1 of its content; `deploy-site.yml` runs it before +`bios/` path by the SHA-1 of its content, and `deploy-site.yml` runs it before generating anything, since the site's coverage reads the disk. **Asset name.** A gitignored path whose file name no other gitignored path @@ -149,7 +149,7 @@ shares is published under that file name. When two paths share one, each is published under its location below `bios/`, segments joined by `--` and any character outside `A-Za-z0-9._-` replaced by `_` (`Id_Software--Wolfenstein_Enemy_Territory--etmain--pak0.pk3`). -`asset_names()` in `scripts/largefiles.py` is the only place that rule lives; +`asset_names()` in `scripts/largefiles.py` is the only place that rule lives: the manifests, the fetcher and `check_release_assets.py` all read it. **Upload.** To add or update a large file: @@ -169,8 +169,8 @@ from the release and caches in `.cache/large/` for subsequent runs. from the manifest size, and the manifest size is that of the local file. A file rebuilt locally after its upload therefore fails every install until it is uploaded again (`--clobber`). `python scripts/check_release_assets.py` -compares every gitignored `bios/` path in the database with its asset, and the release page with the one it renders from the collection; -the online pipeline runs it as step 2b2. To refresh the page: +compares every gitignored `bios/` path in the database with its asset, and the release page with the one it renders from the collection. +The online pipeline runs it as step 2b2. To refresh the page: ```bash python scripts/check_release_assets.py --notes tmp/notes.md @@ -200,7 +200,7 @@ python scripts/generate_pack.py --platform retropie --verify-packs --output-dir python scripts/split_pack.py dist/ # 4. Checksums of the files as published, then sign the list. The checksums -# answer corruption; the signature answers a rewritten release, which is +# answer corruption, and the signature answers a rewritten release, which is # the one thing a checksum published beside its own artifacts cannot # answer. (cd dist && sha256sum *.zip > SHA256SUMS.txt) @@ -227,7 +227,7 @@ done # re-uploaded from an older build. The check holds every asset against # release.json and the local checksum list, by the sha256 GitHub computes, # and the parts of each pack against the download size the README prints. -# Publish only on a clean exit; rerun the upload for what it names. +# Publish only on a clean exit, otherwise rerun the upload for what it names. python scripts/check_release.py --tag "v${DATE}" --sums dist/SHA256SUMS.txt \ && gh release edit "v${DATE}" --draft=false --latest @@ -307,7 +307,7 @@ Until v2026.09.04 the parts were byte ranges cut by `split`, named opened alone is not an archive and no tool says a part is missing, so five reports in six months took one for a broken download (issues 45, 51, 66, 77 and 79). The README, the download page and the troubleshooting page describe -both layouts for as long as a release cut that way is still published; once +both layouts for as long as a release cut that way is still published. Once step 7 has deleted it, the `.zip.001` paragraph leaves those three pages. The table carries a Files column, the count step 5 prints, and the diff --git a/wiki/testing-guide.md b/wiki/testing-guide.md index e4bb61b3..c860325b 100644 --- a/wiki/testing-guide.md +++ b/wiki/testing-guide.md @@ -5,7 +5,7 @@ This page covers how to run, understand, and extend the test suite. The suite is discovered dynamically across focused modules, so its exact count is reported by the test runner instead of being hand-maintained here. Tests do not require network access. Most build synthetic fixtures under the repository's -`tmp/`; modules that read real artifacts skip cleanly when those inputs are absent. +`tmp/`. Modules that read real artifacts skip cleanly when those inputs are absent. ## Running tests @@ -46,14 +46,14 @@ Every module in `tests/`, by the area it guards. | Installer and downloads | loopback server | `test_check_release`, `test_download`, `test_install`, `test_install_cores`, `test_install_experience`, `test_install_selection` | | Truth and native export | synthetic + cached originals | `test_export_counts`, `test_export_native_layer`, `test_exporters`, `test_truth_diff`, `test_truth_layout` | | Scrapers, upstream and provenance | inline sources, synthetic | `test_check_freshness`, `test_dedup`, `test_fbneo_parser`, `test_find_pinned_revision`, `test_hash_merge`, `test_mame_parser`, `test_mame_ref_audit`, `test_profile_sync`, `test_provenance`, `test_refresh_data_dirs`, `test_refresh_failures`, `test_refresh_stale`, `test_retrodeck_scraper_errors`, `test_romset_recipes`, `test_scraper_contract`, `test_upstream`, `test_upstream_index` | -| Site, docs and repository contracts | rendered pages, sources | `test_contributing_text`, `test_data_dir_refs`, `test_dataclass_defaults`, `test_optional_dependencies`, `test_site_availability`, `test_site_cores`, `test_site_exports`, `test_site_platform_hashes`, `test_site_system_links`, `test_site_validation`, `test_site_write`, `test_validate_pr`, `test_validate_pr_hashes`, `test_workflow_paths` | +| Site, docs and repository contracts | rendered pages, sources | `test_contributing_text`, `test_data_dir_refs`, `test_dataclass_defaults`, `test_optional_dependencies`, `test_prose_style`, `test_site_availability`, `test_site_cores`, `test_site_exports`, `test_site_platform_hashes`, `test_site_system_links`, `test_site_validation`, `test_site_write`, `test_validate_pr`, `test_validate_pr_hashes`, `test_workflow_paths` | ## Test architecture ### test_e2e.py The main regression suite. `TestE2E` exercises the resolution, verification, -pack generation and cross-reference logic; `StandaloneModeRequiresAStandaloneBuild` +pack generation and cross-reference logic, and `StandaloneModeRequiresAStandaloneBuild` sits beside it for the per-emulator build mode. **Fixture pattern.** `setUp` creates a temporary directory tree with: @@ -148,7 +148,7 @@ only by case. On Windows and macOS, git can only check out one of them, which silently corrupts the clone. `.variants/` is exempt: those names are disambiguated by a hash suffix on purpose. -**test_pack_integrity.** Described below; needs packs in `dist/`. +**test_pack_integrity.** Described below. Needs packs in `dist/`. ## How to add a test @@ -211,7 +211,7 @@ python scripts/generate_pack.py --all --verify-packs --output-dir dist/ ``` Integrated as pipeline step 6/8 (runs after consistency check, before -README generation). Requires packs in `dist/`; skip with `--skip-packs`. +README generation). Requires packs in `dist/`, skip with `--skip-packs`. ## Verification discipline @@ -236,7 +236,7 @@ roads into main: every pull request, and every direct push, that touches `install.py`. Work reaches main by push as often as by pull request, so a suite wired to pull requests alone would guard the road nobody takes. The test job (`run-tests`) runs in parallel with schema validation, and on a pull request -with BIOS validation and auto-labeling too; those two read pull request context +with BIOS validation and auto-labeling too. Those two read pull request context and stay behind an event guard. A push series collapses to the tip, so what a green run states is that the head diff --git a/wiki/tools.md b/wiki/tools.md index b7c87a18..79e923f6 100644 --- a/wiki/tools.md +++ b/wiki/tools.md @@ -1,7 +1,7 @@ # Tools -All tools are Python scripts in `scripts/`. They need Python 3.12 and `pyyaml`; -only `validate_schemas.py` also needs `jsonschema[format-nongpl]`. `install.py` +All tools are Python scripts in `scripts/`. They need Python 3.12 and `pyyaml`, +and only `validate_schemas.py` also needs `jsonschema[format-nongpl]`. `install.py` alone runs on Python 3.8. ## Pipeline @@ -54,9 +54,9 @@ Pipeline flags: | `--skip-docs` | skip steps 7 and 8 | | `--include-archived` | include archived platforms in verify, packs, truth and export | | `--target TARGET` | filter verify, packs and truth by hardware target | -| `--source {platform,truth,full}` | pack file source, passed through to `generate_pack.py`; refused with `--skip-packs` | -| `--all-variants` | build the 6 source x required combinations; refused with `--skip-packs` and with `--source` | -| `--check-buildbot` | run step 2b; additive, and ignored under `--offline` | +| `--source {platform,truth,full}` | pack file source, passed through to `generate_pack.py`. Refused with `--skip-packs` | +| `--all-variants` | build the 6 source x required combinations. Refused with `--skip-packs` and with `--source` | +| `--check-buildbot` | run step 2b. Additive, and ignored under `--offline` | | `--with-truth` | run steps 2c and 2d | | `--with-export` | run steps 2c, 2d and 2e | | `--output-dir DIR` | pack output directory (default `dist/`) | @@ -165,7 +165,7 @@ python scripts/generate_pack.py --all --verify-packs --output-dir dist/ # extra # Data refresh python scripts/generate_pack.py --all --refresh-data # force re-download data dirs -python scripts/generate_pack.py --all --offline # cache-only; never open the network +python scripts/generate_pack.py --all --offline # cache-only, never open the network # Install manifests (consumed by install.py) python scripts/generate_pack.py --all --manifest --output-dir install/ @@ -254,7 +254,7 @@ of patching the previous one. A branch URL keeps its name while its content moves, and no URL comparison can see that. `--refresh-cache` downloads every file again and writes no -export; it is what follows a rescrape, so the original and the platform +export. It is what follows a rescrape, so the original and the platform YAML describe the same moment. ```bash @@ -353,7 +353,7 @@ Selection narrows `--all` before any request is spent: `--system sega-saturn`, and `--limit 20`. Output takes `--markdown` (a report written under `--report-dir`, `reports/` by default), and `--full-diff` takes `--ref PATH` to show one cited file and `--context N` lines around each hunk. `--strict` -exits 1 when a profile has refs to review; CI runs it on every profile a change +exits 1 when a profile has refs to review, and CI runs it on every profile a change adds. `--offline` answers from `--cache-dir` alone. ```bash @@ -371,7 +371,7 @@ not declare, so no revision can confirm it), `UNCHECKED` (a pin equal to HEAD is judged on self-consistency, and an entry with neither a hash nor a name gives that check nothing to look for). An entry carries the worst status of its parts. Only `CHANGED`, `GONE` and `AMBIGUOUS` count as -needing a re-read; a zero next to a row of `unchecked` is not a proof. +needing a re-read. A zero next to a row of `unchecked` is not a proof. A single cited line is often not distinctive, so the anchor widens by steps of ±3, ±6, ±12, ±25 and ±50 lines until it is unique. Three further @@ -403,7 +403,7 @@ python scripts/profile_sync.py --all --rebase-refs --bump-commit ``` Asking for both makes the pass atomic. The work happens on a copy, and the -copy is promoted only when the pin follows the refs; a profile whose refs +copy is promoted only when the pin follows the refs. A profile whose refs describe one revision while its pin names another is the state the all-or-nothing rule exists to prevent, and recaling alone produces it. What holds a pin back is an annotated ref, one under a mode key, or a prose run the @@ -414,7 +414,7 @@ The first prints the plan and changes nothing: `would recale` per ref and `would set source_commit` (and `upstream_commit`, when that one moves too) per pin the write changes. It reaches that plan by running the real write path over a throwaway copy, so the planned bump reads the text -the recale would have left rather than the one on disk; a pin held back by +the recale would have left rather than the one on disk, and a pin held back by prose that the same pass would have moved is not reported as blocked. Drop `--dry-run` and the same pass writes, recale before bump on each profile. @@ -475,8 +475,8 @@ and every write is verified by reparsing the document. Uses `GITHUB_TOKEN` when set, which `--all` requires. Responses are cached under `.cache/upstream/`, addressed by commit sha, so `--offline` replays a -previous run. GitHub, GitLab and Forgejo upstreams; other hosts are -reported as skipped. +previous run. GitHub, GitLab and Forgejo upstreams are supported, other +hosts are reported as skipped. The forge side lives in `upstream.py`: it resolves a revision, fetches a file at a given sha, and compares trees, for the forge families the @@ -563,9 +563,9 @@ python scripts/refresh_stale.py --only platforms,targets --jobs 6 | Script | Purpose | |--------|---------| | `common.py` | Shared library: hash computation, file resolution, platform config loading, emulator profiles, target filtering | -| `dedup.py` | Deduplicate `bios/` (`--dry-run`, `--bios-dir`): byte-identical copies are deleted and one kept; identical MAME sets under other names stay one file, named in `_mame_clones.json`. Trees addressed by path are left alone (`NODEDUP_DIRS`): BBK, C-Dogs SDL, Ikemen GO, PinMAME, RPG Maker, ScummVM, Softdisk, TheXTech, Theme Hospital, c64-emu, tzdata | +| `dedup.py` | Deduplicate `bios/` (`--dry-run`, `--bios-dir`): byte-identical copies are deleted and one kept. Identical MAME sets under other names stay one file, named in `_mame_clones.json`. Trees addressed by path are left alone (`NODEDUP_DIRS`): BBK, C-Dogs SDL, Ikemen GO, PinMAME, RPG Maker, ScummVM, Softdisk, TheXTech, Theme Hospital, c64-emu, tzdata | | `identity.py` | One content filed under two identities: groups `bios/` by content and reports a group that crosses manufacturers outside `KNOWN_SHARED` (`--strict` exits 1, pipeline step 3a) | -| `slots.py` | Destinations the platform and a core both claim, and how the pack settles each (`--platform`, `--include-archived`, `--target`, `--json`, `--strict`; pipeline step 3b passes the run's own `--include-archived` and `--target`) | +| `slots.py` | Destinations the platform and a core both claim, and how the pack settles each (`--platform`, `--include-archived`, `--target`, `--json`, `--strict`, and pipeline step 3b passes the run's own `--include-archived` and `--target`) | | `region_audit.py` | Confront every profile `region:` with the regions No-Intro names for the same dump (`--json`, `--db`, `--emulators-dir`). An opinion, never an authority: the code decides, and a disagreement is a line to read in the emulator's source | | `validate_pr.py` | Validate BIOS files in pull requests, post markdown report | | `validate_schemas.py` | Validate the data contracts: schemas and semantic invariants. `--source-only` checks `emulators/` and `platforms/` alone, which is what PR validation runs | @@ -580,7 +580,7 @@ python scripts/refresh_stale.py --only platforms,targets --jobs 6 | `generate_site.py` | Generate all MkDocs site pages (this documentation) | | `validate_site.py` | Validate rendered metadata, headings, image alternatives, JSON-LD, local resources, links and fragments | | `romset_recipes.py` | Identify which emulator version an arcade archive matches, and rebuild a pinned archive from ROMs already held | -| `scraper/romset_dat_importer.py` | Fetch and import per-set recipes from MAME `-listxml` or FBNeo DATs into `recipes/`; `--fetch` alone takes the newest MAME release, and FBNeo DATs are refreshed by git blob sha | +| `scraper/romset_dat_importer.py` | Fetch and import per-set recipes from MAME `-listxml` or FBNeo DATs into `recipes/`. `--fetch` alone takes the newest MAME release, and FBNeo DATs are refreshed by git blob sha | | `deterministic_zip.py` | Rebuild MAME BIOS ZIPs deterministically (same ROMs = same hash) | | `torrentzip.py` | Build TorrentZip archives for MAME/FBNeo ROM sets (archive bytes depend only on contents) | | `crypto_verify.py` | 3DS RSA signature and AES crypto verification | @@ -594,12 +594,12 @@ Further options, by script: | Script | Options | |--------|---------| -| `auto_fetch.py` | `--create-issues` prints a GitHub issue body per file still missing; it posts nothing | +| `auto_fetch.py` | `--create-issues` prints a GitHub issue body per file still missing. It posts nothing | | `check_buildbot_system.py` | `--update` refreshes the entries found stale, `--json`, `--registry` | | `check_freshness.py` | `--cache-dir`, `--native-cache-dir` (originals of the native export) and `--truth-dir` move the caches it reads | | `check_release.py` | `--tag`, `--sums dist/SHA256SUMS.txt`, `--record` (default `release.json`), `--json` | | `check_release_assets.py` | `--gitignore` (the asset registry), `--db`, `--notes FILE`, `--json` | -| `diff_truth.py` | `--format markdown` (or `--markdown`), `--json`, one of them; `--truth-dir`, `--target` | +| `diff_truth.py` | `--format markdown` (or `--markdown`), `--json` (one of them), `--truth-dir`, `--target` | | `download.py` | `--list`, `--info <platform>` shows a pack's file name, size and parts without downloading | | `export_native.py` | `--truth-dir`, `--upstream-dir` (where the platforms' own files are cached) | | `find_pinned_revision.py` | `--repo URL --path FILE --md5 HASH`, `--write PATH`, `--cache-dir` | @@ -607,12 +607,12 @@ Further options, by script: | `generate_site.py` | `--docs-dir` (output, `docs/` by default) | | `mame_ref_audit.py` | `--write` points each stale ref at the line declaring its set, `--offline`, `--cache-dir` | | `migrate.py` | `--dry-run`, `--include-branches` also reads BIOS files from every remote branch | -| `provenance_report.py` | `--provenance-dir`, `--write-derivable PATH` (with `--derive`; the pipeline writes `derivable.json`) | +| `provenance_report.py` | `--provenance-dir`, `--write-derivable PATH` (with `--derive`, and the pipeline writes `derivable.json`) | | `refresh_stale.py` | `--freshness-arg FLAG` passes a flag through to `check_freshness.py`, repeatable | | `release_record.py` | `--install-dir` (manifests the archives are held against), `--output` | | `restore_large_files.py` | `--cache` (downloaded assets), `--gitignore`, `--db` | | `romset_recipes.py` | `--dat-recipes PATH`, a snapshot or a directory of them (default `recipes/`) | -| `split_pack.py` | `--max-size 1900M`, the ceiling per part (K, M, G; default 2G) | +| `split_pack.py` | `--max-size 1900M`, the ceiling per part (K, M, G, default 2G) | | `torrentzip.py` | `--check ZIP` reports conformance, `--rebuild ZIP -o OUT` normalizes an archive | | `validate_pr.py` | `--changed` takes the BIOS files the branch changes, `--markdown`, `--json` | | `validate_site.py` | `--site-dir` (rendered site), `--config` (mkdocs.yml), `--max-errors N` | @@ -641,18 +641,18 @@ SHA-256 and SHA-1, and replaces each destination atomically. Both one-liners, shell and PowerShell, verify the downloaded Python installer against the SHA-256 embedded in their bootstrap before running it. Copies into standalone-emulator directories are opt-in through `--standalone-copies`. Manifest entries with no -available payload are reported as safely omitted; they are never replaced by a +available payload are reported as safely omitted, and they are never replaced by a same-named file. `scripts/download.sh` remains available for downloading a prebuilt platform -ZIP when a manually reviewed pack release contains it; it is separate from the +ZIP when a manually reviewed pack release contains it. It is separate from the per-file automatic installer above. A pack over 2 GB is published in several parts: both downloaders group them under one platform name, download each one and check it against the release's `SHA256SUMS.txt`. Parts that are each -a ZIP are extracted one after the other; the `.zip.001` slices of releases up +a ZIP are extracted one after the other, and the `.zip.001` slices of releases up to v2026.09.04 are joined first. That list carries a detached signature, `SHA256SUMS.txt.sig`, verifiable -against `allowed_signers` at the repository root; the +against `allowed_signers` at the repository root, and the [release process](release-process.md#verifying-a-release) gives the commands. Volumes are staged inside the destination directory rather than the system temp directory, which is a RAM disk on Batocera, ROCKNIX and RetroDECK. @@ -704,7 +704,7 @@ collection does not have, and tries every recipe whose ROMs are present. Reconstruction only works when the pinned archive is itself TorrentZip. An archive whose bytes carry metadata unrelated to its contents cannot be derived -from ROMs by anyone; those are reported as unreproducible rather than guessed +from ROMs by anyone, so those are reported as unreproducible rather than guessed at. Writing is explicit: the pipeline only ever reports. ## Large files @@ -719,7 +719,7 @@ using `fetch_large_file()` from `common.py`. The same function is used by Located in `scripts/scraper/`. Each platform scraper inherits `BaseScraper` and implements its two abstract methods, `fetch_requirements()` and -`validate_format()`; the MAME and FBNeo hash scrapers read a source tree and +`validate_format()`. The MAME and FBNeo hash scrapers read a source tree and stand alone. | Scraper | Source | Format | @@ -736,7 +736,7 @@ stand alone. | `misterfpga_scraper` | BiosDB_MiSTer bios_db.json.zip | JSON in ZIP | | `coreinfo_scraper` | .info files from libretro-core-info | INI-like | | `bizhawk_scraper` | FirmwareDatabase.cs | C# source | -| `mame_hash_scraper` | mamedev/mame source tree; `--release mameNNNN` writes the profile of one release a platform builds | C source (sparse clone) | +| `mame_hash_scraper` | mamedev/mame source tree. `--release mameNNNN` writes the profile of one release a platform builds | C source (sparse clone) | | `fbneo_hash_scraper` | FBNeo source tree | C source (sparse clone) | Internal modules: `base_scraper.py` (abstract base with `_fetch_raw()` caching @@ -754,8 +754,8 @@ Adding a scraper: inherit `BaseScraper`, implement `fetch_requirements()` and ## Dump-catalog provenance Snapshots of the preservation catalogs are committed to `provenance/` and -refreshed manually. `generate_db.py` joins them into `database.json`; -`provenance_report.py` reports the gaps. +refreshed manually. `generate_db.py` joins them into `database.json`, +and `provenance_report.py` reports the gaps. ```bash python -m scripts.scraper.redump_dat_scraper --dry-run @@ -780,7 +780,7 @@ by pipeline step 1b. | Catalog | Acquisition | Notes | |---------|------------|-------| | Redump | direct fetch from redump.info `/static/bios` | 4 BIOS DATs. redump.org serves stale DATs | -| No-Intro | local pack, imported with `dat_pack_importer` | Dat-o-Matic blocks automation; the `hugo19941994/auto-datfile-generator` mirror rebuilds daily | +| No-Intro | local pack, imported with `dat_pack_importer` | Dat-o-Matic blocks automation, and the `hugo19941994/auto-datfile-generator` mirror rebuilds daily | | TOSEC | local pack, imported with `dat_pack_importer` | annual pack from tosecdev.org, 138 Firmware DATs | The join is by SHA1, then by MD5 + size. A match sets the `provenance` field diff --git a/wiki/troubleshooting.md b/wiki/troubleshooting.md index b6ada15a..ed7fcb0a 100644 --- a/wiki/troubleshooting.md +++ b/wiki/troubleshooting.md @@ -186,7 +186,7 @@ How to read and interpret `verify.py` output. | `missing` | File not found in the repository | Hash and size mismatches are reported as `untested` with a reason field -showing expected vs actual values (e.g., `expected abc123… got def456…`). +showing expected vs actual values (e.g., `expected abc123... got def456...`). **Reading the output:** @@ -265,7 +265,7 @@ python install.py --platform batocera --dest /userdata/bios/ ``` `python install.py --list-platforms` lists the platforms the installer knows -and the ones it detects here; `--help` lists the options. +and the ones it detects here, and `--help` lists the options. **Manifest or file not found:** @@ -289,7 +289,7 @@ bash scripts/download.sh --list ``` A pack's name lists every platform it serves. Releases up to v2026.10.10 -ship RetroArch and Lakka as one `RetroArch_Lakka` pack; the next ones give +ship RetroArch and Lakka as one `RetroArch_Lakka` pack, and the next ones give Lakka its own, since Lakka runs on Linux where two names that differ by case are two files. The installer and the download scripts find the right pack either way. diff --git a/wiki/verification-modes.md b/wiki/verification-modes.md index 61bb9a91..451445ce 100644 --- a/wiki/verification-modes.md +++ b/wiki/verification-modes.md @@ -101,7 +101,7 @@ size must equal the declared size, then any one of MD5, SHA1 and CRC32 must match. An entry without a size never verifies, since RomM reads it as 0. A wrong hash beside a right one does not withhold the file. `verify.py`, the pack builder and the install manifest apply that rule. ZIP files are not -opened; only the container is checked. +opened, only the container is checked. ### ROCKNIX verification @@ -229,16 +229,16 @@ evidence-compatible match: | Step | Method | Returns | When it applies | |------|--------|---------|-----------------| -| 1 | SHA1 | `sha1_exact` | A declared SHA1 identifies a database record; every other declared hash must agree with that same record | +| 1 | SHA1 | `sha1_exact` | A declared SHA1 identifies a database record, and every other declared hash must agree with that same record | | 2 | SHA256 | `sha256_exact` | A declared SHA256 identifies a record, again requiring all declarations to agree | -| 3 | CRC32 plus size | `crc32_exact` | Used only when no stronger hash is declared; size confirms the weaker checksum when available | -| 4 | MD5 | `md5_exact` | Direct lookup; an explicitly supported truncated MD5 also needs a compatible name | +| 3 | CRC32 plus size | `crc32_exact` | Used only when no stronger hash is declared. Size confirms the weaker checksum when available | +| 4 | MD5 | `md5_exact` | Direct lookup. An explicitly supported truncated MD5 also needs a compatible name | | 5 | Path suffix | `path_exact` or a hash-exact status | Disambiguates regional paths. With any declared hash, the path is accepted only when the content matches it | -| 6 | Name or alias | `name_exact` | Existence/size resolution only when no content hash is declared; prefers primary files and supports casefold matching | +| 6 | Name or alias | `name_exact` | Existence/size resolution only when no content hash is declared. Prefers primary files and supports casefold matching | | 7 | Named candidate inspection | `md5_composite_exact`, `md5_exact`, or `hash_mismatch` | Checks composite ZIP MD5 or direct MD5. A matching name with wrong content is surfaced, never treated as exact | -| 8 | ZIP contents index | `zip_exact` | `zipped_file` with MD5; searches the inner-ROM index only after name-based resolution fails | +| 8 | ZIP contents index | `zip_exact` | `zipped_file` with MD5. Searches the inner-ROM index only after name-based resolution fails | | 9 | MAME clone | `mame_clone` | Resolves a deduplicated clone to its canonical set only when no content hash was declared | -| 10 | Data directory | `data_dir` or `data_dir_hash_exact` | Searches exact path then case-insensitive basename; computes every declared hash before accepting an unindexed candidate | +| 10 | Data directory | `data_dir` or `data_dir_hash_exact` | Searches exact path then case-insensitive basename, then computes every declared hash before accepting an unindexed candidate | | 11 | Agnostic fallback | `agnostic_fallback` | Size/path constrained lookup only when no content hash was declared | If no step matches, the result is `(None, "not_found")`. @@ -293,7 +293,7 @@ A `scph5501.bin` file passes Batocera MD5 verification (hash matches upstream declaration) but fails an emulator profile's size check because the profile was verified against a different revision. The search looks for a held file carrying a Batocera-accepted md5 that also passes the size check, under that -name or any name the emulator's hashes reach. If found, it ships; if not, the +name or any name the emulator's hashes reach. If found, it ships. If not, the Batocera-verified file ships and the discrepancy stays visible in verification and gap reporting.