70 Commits

Author SHA1 Message Date
Abdessamad Derraz
e90095abd9 fix: resolve bios case collisions
Delete duplicate lowercase variants (identical MD5) of 12 files
that prevented clean checkout on case-insensitive filesystems
(Windows, macOS).

Canonical chosen per upstream source code:
- Atari 2600 KV*.WAV: uppercase (stella2023 hardcode)
- Vectrex VEC_Minestorm.vec: lowercase (BizHawk hardcode)
- MSX MSX{,2,2EXT}.ROM: uppercase (fMSX hardcode, 6/7 platforms)
- Doom DOOM2.WAD: uppercase (matches dir convention)

Add aliases to stella2014 and clk profiles so resolution still
finds the canonical source. Correct retrodeck Vectrex casing to
match upstream. Merge Commodore/Vic-20 into VIC-20.

Add tests/test_no_case_collisions.py as a CI guard.

Closes #49
2026-04-18 10:01:29 +02:00
Abdessamad Derraz
c8b27cac5e docs: rename which-pack nav to download 2026-04-18 09:01:11 +02:00
Abdessamad Derraz
1d191ff190 chore: drop empty hash placeholders 2026-04-18 09:01:04 +02:00
Abdessamad Derraz
5a6b54c195 refactor: extract sizes to structured fields 2026-04-18 09:01:01 +02:00
Abdessamad Derraz
e5ef253892 feat: add vice rom hashes from source 2026-04-18 09:00:58 +02:00
Abdessamad Derraz
4ba8648ec2 feat: enrich bsnes with system and hashes 2026-04-18 09:00:55 +02:00
Abdessamad Derraz
617f5cc364 refactor: hash-anchor truth enrichment 2026-04-18 09:00:31 +02:00
Abdessamad Derraz
d4ce6df911 fix: remaining releases variable reference 2026-04-03 22:34:45 +02:00
Abdessamad Derraz
d0846ed78f fix: which-pack link text, paths, and table clarity 2026-04-03 22:29:16 +02:00
Abdessamad Derraz
07b4e55053 docs: rewrite which-pack as complete download guide 2026-04-03 22:27:00 +02:00
Abdessamad Derraz
690e897ca7 docs: rewrite which-pack page with real guidance 2026-04-03 22:23:06 +02:00
Abdessamad Derraz
7471c176c3 fix: generate which-pack page via generate_site.py 2026-04-03 22:20:23 +02:00
Abdessamad Derraz
e72773e46d fix: restore community tools section in readme generator 2026-04-03 15:00:38 +02:00
Abdessamad Derraz
3c0c1cec02 fix: generate banner header in readme and site scripts 2026-04-03 14:22:22 +02:00
Abdessamad Derraz
faf4236463 docs: add project logo and branding assets 2026-04-03 14:17:53 +02:00
Abdessamad Derraz
1c0c502258 docs: add community tools section
Reference BIOS Preservation Tool by monster-penguin in README,
wiki, and site nav.
2026-04-03 13:33:21 +02:00
Abdessamad Derraz
06c48e071a test: update grouping test for flat zip behavior 2026-04-03 12:06:38 +02:00
Abdessamad Derraz
8f93ee2239 feat: flatten zips, standalone copies, retropie grouping 2026-04-03 12:04:55 +02:00
Abdessamad Derraz
9ba8b02ff1 fix: verify functions handle flat zip extraction 2026-04-03 11:50:26 +02:00
Abdessamad Derraz
6fc2753f3e feat: add standalone copies for 9 emulators 2026-04-03 11:20:21 +02:00
Abdessamad Derraz
486b359c22 feat: extend do_standalone_copies with pattern, note, wsl fallback 2026-04-03 11:16:34 +02:00
Abdessamad Derraz
76a3543672 feat: verify functions handle flat and nested ZIPs 2026-04-03 11:15:32 +02:00
Abdessamad Derraz
48d185dd7d feat: flatten ZIP structure, strip base_dest prefix 2026-04-03 11:12:14 +02:00
Abdessamad Derraz
6dbc3f510b fix: retrodeck bios_path double prefix 2026-04-03 11:07:46 +02:00
Abdessamad Derraz
97e26103f5 fix: include source/req tags in grouped pack rename 2026-04-03 11:07:34 +02:00
Abdessamad Derraz
59d777a33d fix: restore wiki links for mkdocs context 2026-04-02 20:54:14 +02:00
Abdessamad Derraz
9ce4724fc4 fix: sha1-based large file restore, fix broken data dir urls
Replace grep-based restore with SHA1 matching via database.json.
The old grep heuristic failed for assets with renamed basenames
(dsi_nand_batocera42.bin) or special characters (MAME dots vs
spaces), and only restored to the first .gitignore match when
multiple paths shared a basename.

Fix 3 broken data directory sources:
- opentyrian: buildbot URL 404, use release asset
- syobonaction: invalid git_subtree URL, use GitHub archive
- stonesoup: same fix, adds 532 game data files
2026-04-02 18:46:44 +02:00
Abdessamad Derraz
7e46c23f3a feat: restore large files and data dirs in site deploy
generate_site.py resolves files on disk for gap analysis.
Without large files and data directories, the deployed site
showed 148 missing platform files and 207 unsourced core
complement files.
2026-04-02 18:25:02 +02:00
Abdessamad Derraz
6f22dd7738 docs: fix --skip-packs comment in tools wiki 2026-04-02 17:55:23 +02:00
Abdessamad Derraz
c0e42ee4eb docs: fix factual errors in wiki pages 2026-04-02 17:13:59 +02:00
Abdessamad Derraz
92b270c054 Update docs, site generator & verification
Add and reorder BIOS path entries in the site generator (BizHawk, EmuDeck, RetroPie, RomM). Update the add-platform pipeline steps and CI workflow notes. Document verification behavior changes: FirmwareDatabase index now includes sha256; RomM uses MD5 verification (verify.py checks MD5 only); BizHawk uses SHA1; severity label for GREEN adjusted to WARNING. Clarify troubleshooting/verify output semantics (UNTESTED and mismatch reporting), add profiling fields (core_classification option and adler32), fix several path and link typos (RetroDECK path, README/CONTRIBUTING links), and other small docs polishing.
2026-04-02 16:26:12 +02:00
Abdessamad Derraz
2f11542ed3 chore: regenerate manifests, site, and docs after new BIOS files 2026-04-02 15:56:24 +02:00
Abdessamad Derraz
f9a612db4a refactor: simplify readme contributor section to avatars only 2026-04-02 15:39:34 +02:00
Abdessamad Derraz
812775f6b4 Add platform contribution steps and nav
Add an "Add a new platform" section to CONTRIBUTING.md (instructions to write a scraper in scripts/scraper/, create platform YAML in platforms/, register in platforms/_registry.yml, and submit a PR) and note contributor crediting. Update README: bump verified files from 7,296 to 7,302, add RomM and RetroDECK contributor credits with PR links, and refresh the auto-generated timestamp. Add sdlpal to the mkdocs.yml navigation.
2026-04-02 15:36:27 +02:00
Abdessamad Derraz
73ccb216f5 feat: align gap analysis coherence, add 7 BIOS files, unsourceable field
cross_reference.py: add bios_mode/agnostic/load_from filters, archive
grouping, unsourceable field support. verify.py: case-insensitive
by_name lookup, storage:release in_repo, unsourceable skip, trailing
slash fix. generate_site.py: enriched all_declared, platform-relevant
profile filtering, proper in_repo resolution on emulator pages,
acknowledged gaps section.

New BIOS: delta2.rom (XRoar), tilekey.dat + sprites.sif (NXEngine),
Gram Kracker.ctg + cf7+.ctg + ti-pcard.ctg (ti99sim), desc.dat
(SDLPAL). Profiles: hle_fallback on tilekey.dat/key.txt, unsourceable
on 7 files with source-verified reasons.
2026-04-02 15:35:24 +02:00
Abdessamad Derraz
5ee81b30c6 feat: add contributor credits to pack readme 2026-04-02 11:43:06 +02:00
Abdessamad Derraz
b5eae226cd feat: enrich readme contributors with platform attribution 2026-04-02 11:42:40 +02:00
Abdessamad Derraz
fd4606885e feat: add contributor credit to site platform pages 2026-04-02 11:42:31 +02:00
Abdessamad Derraz
ded903ed7a feat: add contributed_by field to retrodeck and romm 2026-04-02 11:41:19 +02:00
Abdessamad Derraz
077392bcd9 docs: add contributor attribution to romm and retrodeck scrapers 2026-04-02 11:41:15 +02:00
Abdessamad Derraz
f4626ce3bd Add MSX2J ROM and update manifests
Add MSX2J.rom (sha1: 0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd, size: 32768) to multiple install manifests and the RetroDECK bios list. Update generated timestamps and adjust total_files/total_size counts in batocera, lakka, recalbox, retroarch, retrobat, and retrodeck manifests. Also bump README verified file count and regenerate the auto-generated timestamp to reflect the new entry.
2026-04-02 10:44:25 +02:00
Abdessamad Derraz
9e184f76fc fix: swanstation ps1_rom.bin accepts multiple sizes
SwanStation accepts PS1 (512KB), PS2 (4MB), and PS3 (0x3E66F0)
BIOS sizes but only uses the first 512KB. MD5 validates the
extracted content, not the full file. List all accepted sizes
to eliminate the false size mismatch discrepancy.

validation.py: support size as list in emulator profiles.
generate_site.py: handle list sizes in emulator page display.

All 18 original hash mismatches are now resolved: 0 discrepancies.
2026-04-02 07:39:30 +02:00
Abdessamad Derraz
fa0ed63718 fix: add psx variant mappings, fix emulator verify path
scph3000.bin v2.1J and scph3500.bin v2.2J already existed under
different primary names (scph3500.bin and scph5000.bin respectively).
Add .variants/ entries so by_name resolves both filenames.

verify_single_emulator now calls _find_best_variant on hash mismatch,
matching the platform-level verification path.
2026-04-02 01:24:24 +02:00
Abdessamad Derraz
c3fa55bd46 feat: add msx2 japanese bios variant for ares
Source: Subtixx/RetroStation MSX2J.rom
SHA256 0c672d86 matches ares desktop-ui/emulator/msx2.cpp:15.
Resolves last MSX2.ROM discrepancy across all platforms.
2026-04-02 01:12:36 +02:00
Abdessamad Derraz
0401d058a1 feat: add by_sha256 index, fix reporting attribution
generate_db: add by_sha256 index for O(1) variant lookup.
verify: _find_best_variant uses indexed sha256 instead of O(n) scan.
validation: check_file_validation returns (reason, emulators) tuple,
attributing mismatch only to emulators whose check actually failed.
beetle_psx: remove incorrect size field for ps1_rom.bin (code does
not validate size, swanstation is sole size authority).
2026-04-02 00:59:01 +02:00
Abdessamad Derraz
95b7a9813c feat: add custom site stylesheet with theme and components 2026-04-02 00:48:02 +02:00
Abdessamad Derraz
22829cfab9 feat: improve site ux with cards, badges and hash truncation 2026-04-02 00:46:21 +02:00
Abdessamad Derraz
2326306f2b fix: adler32 byteswap for dolphin dsp validation
Dolphin computes adler32 on byte-swapped (16-bit) data, not raw
file bytes. Add adler32_byteswap flag to dolphin/primehack/ishiiruka
profiles and support it in validation.py.

Reduces hash mismatch discrepancies from 18 to 2.
2026-04-01 22:51:39 +02:00
Abdessamad Derraz
28ecf19f2b fix: variant resolution suppresses false discrepancies
_find_best_variant now searches by hash (md5, sha1, crc32, sha256)
across the entire database instead of only by filename. Finds
variants stored under different names (e.g. eu_mcd2_9306.bin for
bios_CD_E.bin, scph1001_v20.bin for scph1001.bin).

verify_entry_existence now also calls _find_best_variant to
suppress discrepancies when a matching variant exists in the repo.

Reduces false discrepancies from 22 to 11 (4 unique files where
the variant genuinely does not exist in the repo).
2026-04-01 22:45:43 +02:00
Abdessamad Derraz
91925120c9 feat: unify gap analysis with verify results and source provenance
Single source of truth for gap page: verification status from
verify.py (verified/untested/missing/mismatch), file provenance
from cross_reference (bios/data/large_file/missing).

cross_reference.py: _find_in_repo -> _resolve_source returning
source category, stop skipping storage: release/large_file,
add by_path_suffix lookup, all_declared param for global check.

generate_site.py: gap page now shows verification by platform,
18 hash mismatches, and core complement with provenance breakdown.
2026-04-01 22:33:37 +02:00
Abdessamad Derraz
cbb86c7746 docs: add missing CLI flags to wiki tools page 2026-04-01 18:51:44 +02:00
Abdessamad Derraz
9bbd39369d fix: alias-only files missing from full packs
find_undeclared_files was enriching declared_names with DB aliases,
filtering core extras that were never packed by Phase 1 under that
name. Pass strict YAML names to _collect_emulator_extras so alias-
only files (dc_bios.bin, amiga-os-310-a1200.rom, scph102.bin, etc.)
get packed at the emulator's expected path. Also fix truth mode
output message and --all-variants --verify-packs quick-exit bypass.
2026-04-01 18:39:36 +02:00
Abdessamad Derraz
a1333137a0 fix: truth mode skipping phases 2-3 due to indent 2026-04-01 15:12:45 +02:00
Abdessamad Derraz
1efe95228f feat: propagate source flags to pipeline 2026-04-01 14:52:39 +02:00
Abdessamad Derraz
074e3371f2 feat: source mode text in pack readme 2026-04-01 14:52:25 +02:00
Abdessamad Derraz
85cc23398a feat: source-aware pack verification 2026-04-01 14:52:02 +02:00
Abdessamad Derraz
47a68c1a11 feat: add --source and --all-variants flags 2026-04-01 14:50:33 +02:00
Abdessamad Derraz
5f579d1851 feat: add source param to manifest and split packs 2026-04-01 14:44:39 +02:00
Abdessamad Derraz
2c1c2a7bfe feat: add combined source+required variant tests 2026-04-01 14:42:52 +02:00
Abdessamad Derraz
423a1b201e feat: add source param to generate_pack 2026-04-01 14:39:04 +02:00
Abdessamad Derraz
9c6b3dfe96 feat: add include_all to _collect_emulator_extras 2026-04-01 14:33:54 +02:00
Abdessamad Derraz
b070fa41de feat: add include_all param to find_undeclared_files 2026-04-01 14:29:31 +02:00
Abdessamad Derraz
0a272dc4e9 chore: lint and format entire codebase
Run ruff check --fix: remove unused imports (F401), fix f-strings
without placeholders (F541), remove unused variables (F841), fix
duplicate dict key (F601).

Run isort --profile black: normalize import ordering across all files.

Run ruff format: apply consistent formatting (black-compatible) to
all 58 Python files.

3 intentional E402 remain (imports after require_yaml() must execute
after yaml is available).
2026-04-01 13:17:55 +02:00
Abdessamad Derraz
a2d30557e4 chore: remove unused imports from generate_site.py 2026-04-01 13:13:06 +02:00
Abdessamad Derraz
0e6db8abdf docs: sync wiki sources with pipeline changes
Update wiki source files (the single source of truth for the site):
- tools.md: renumber pipeline steps 1-8, add step 6 (pack integrity),
  add missing CLI flags for cross_reference.py and refresh_data_dirs.py
- architecture.md: update mermaid diagram with pack integrity step,
  fix test file count (5 files, 249 tests)
- testing-guide.md: add test_pack_integrity section, add step 5 to
  verification discipline checklist
2026-04-01 13:08:19 +02:00
Abdessamad Derraz
6eca4c416a chore: remove dead wiki generator functions, update docs
Remove 4 unused functions from generate_site.py (generate_wiki_index,
generate_wiki_architecture, generate_wiki_tools, generate_wiki_profiling)
that contained stale data. Wiki pages are sourced from wiki/ directory.

Update generate_site.py contributing section with correct test counts
(249 total, 186 E2E, 8 pack integrity) and pack integrity documentation.
2026-04-01 13:05:34 +02:00
Abdessamad Derraz
e5859eb761 refactor: dry pack integrity into cli and update docs
Move verification logic to generate_pack.py --verify-packs (single
source of truth). test_pack_integrity.py is now a thin wrapper that
calls the CLI. Pipeline step 6/8 uses the same CLI entry point.

Renumber all pipeline steps 1-8 (was skipping from 5 to 8/9).

Update generate_site.py with pack integrity test documentation.
2026-04-01 12:31:10 +02:00
Abdessamad Derraz
754e829b35 feat: add pack integrity test and integrate into pipeline
Extract each platform ZIP to tmp/ (real filesystem, not /tmp tmpfs)
and verify every declared file exists at the correct path with the
correct hash per the platform's native verification mode.

Handles ZIP inner content verification (checkInsideZip, md5_composite,
inner ROM MD5) and path collision deduplication.

Integrated as pipeline step 6/8. Renumber all pipeline steps to be
sequential (was skipping from 5 to 8).
2026-04-01 12:22:50 +02:00
Abdessamad Derraz
7beb651049 fix: correct core extras placement for retrodeck and romm packs
RetroDECK: core extras with subdirectory paths (e.g. vice/C64/,
fbneo/, dc/) were placed outside bios/ because the prefix was only
inferred for bare filenames. Add _detect_extras_prefix() to infer
the dominant BIOS prefix from YAML destinations.

RomM: core extras landed flat at bios/{file} instead of the required
bios/{platform_slug}/{file}. Add _detect_slug_structure() to detect
per-system slug layouts and _map_emulator_to_slug() to route each
extra to the correct slug subfolder.

Also skip manifest writes when only the generated timestamp changed,
preventing unnecessary diffs in install/*.json.
2026-04-01 11:08:01 +02:00
Abdessamad Derraz
5eeaf87a3a fix: resolve all untested and missing bios across platforms
Batocera: fix sc3000.rom md5 (no dump matches upstream hash),
remove erroneous bk0010.zip mame entries (upstream confirmed
mame needs no bios for bk), add PSP2UPDAT.PUP correct version.
Recalbox: add MSX2R2.ROM from blueMSX v2.82.
RetroDECK: fix stale peribox_ev/gen.zip md5 hashes.

Regenerate database, manifests, readme.
2026-04-01 01:42:39 +02:00
146 changed files with 20656 additions and 7323 deletions

BIN
.github/assets/banner-light.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
.github/assets/banner.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
.github/assets/favicon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
.github/assets/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
.github/assets/social-preview.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@@ -58,16 +58,32 @@ jobs:
run: | run: |
mkdir -p .cache/large mkdir -p .cache/large
gh release download large-files -D .cache/large/ 2>/dev/null || true gh release download large-files -D .cache/large/ 2>/dev/null || true
for f in .cache/large/*; do python3 -c "
[ -f "$f" ] || continue import hashlib, json, os, shutil
name=$(basename "$f") db = json.load(open('database.json'))
target=$(grep "$name" .gitignore | head -1) with open('.gitignore') as f:
if [ -n "$target" ] && [ ! -f "$target" ]; then ignored = {l.strip() for l in f if l.strip().startswith('bios/')}
mkdir -p "$(dirname "$target")" cache = '.cache/large'
cp "$f" "$target" if not os.path.isdir(cache):
echo "Restored: $target" exit(0)
fi idx = {}
done for fn in os.listdir(cache):
fp = os.path.join(cache, fn)
if os.path.isfile(fp):
h = hashlib.sha1(open(fp, 'rb').read()).hexdigest()
idx[h] = fp
restored = 0
for sha1, entry in db['files'].items():
path = entry['path']
if path in ignored and not os.path.exists(path):
src = idx.get(sha1)
if src:
os.makedirs(os.path.dirname(path), exist_ok=True)
shutil.copy2(src, path)
print(f'Restored: {path}')
restored += 1
print(f'Total: {restored} files restored')
"
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -36,6 +36,43 @@ jobs:
- run: pip install pyyaml mkdocs-material pymdown-extensions - run: pip install pyyaml mkdocs-material pymdown-extensions
- name: Restore large files from release
run: |
mkdir -p .cache/large
gh release download large-files -D .cache/large/ 2>/dev/null || true
python3 -c "
import hashlib, json, os, shutil
db = json.load(open('database.json'))
with open('.gitignore') as f:
ignored = {l.strip() for l in f if l.strip().startswith('bios/')}
cache = '.cache/large'
if not os.path.isdir(cache):
exit(0)
idx = {}
for fn in os.listdir(cache):
fp = os.path.join(cache, fn)
if os.path.isfile(fp):
h = hashlib.sha1(open(fp, 'rb').read()).hexdigest()
idx[h] = fp
restored = 0
for sha1, entry in db['files'].items():
path = entry['path']
if path in ignored and not os.path.exists(path):
src = idx.get(sha1)
if src:
os.makedirs(os.path.dirname(path), exist_ok=True)
shutil.copy2(src, path)
print(f'Restored: {path}')
restored += 1
print(f'Total: {restored} files restored')
"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Refresh data directories
run: python scripts/refresh_data_dirs.py
continue-on-error: true
- name: Generate site - name: Generate site
run: | run: |
python scripts/generate_site.py python scripts/generate_site.py

2
.gitignore vendored
View File

@@ -29,7 +29,7 @@ data/
# Large files stored as GitHub Release assets (additional) # Large files stored as GitHub Release assets (additional)
bios/Arcade/MAME/artwork/snspell.zip bios/Arcade/MAME/artwork/snspell.zip
bios/Arcade/MAME/MAME 0.174 Arcade XML.dat bios/Arcade/MAME/MAME 0.174 Arcade XML.dat
bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP.3ae832c9
bios/Nintendo/DS/DSi_Nand_JPN.bin bios/Nintendo/DS/DSi_Nand_JPN.bin
bios/Nintendo/DS/DSi_Nand_EUR.bin bios/Nintendo/DS/DSi_Nand_EUR.bin
bios/Nintendo/DS/DSi_Nand_USA.bin bios/Nintendo/DS/DSi_Nand_USA.bin

View File

@@ -7,6 +7,16 @@
3. Variants (alternate hashes): `bios/Manufacturer/Console/.variants/` 3. Variants (alternate hashes): `bios/Manufacturer/Console/.variants/`
4. Create a Pull Request - checksums are verified automatically 4. Create a Pull Request - checksums are verified automatically
## Add a new platform
1. Write a scraper in `scripts/scraper/`
2. Create the platform YAML in `platforms/`
3. Register in `platforms/_registry.yml`
4. Submit a Pull Request
Contributors who add platform support are credited in the README,
on the documentation site, and in the BIOS packs.
## File conventions ## File conventions
- Files >50 MB go in GitHub release assets (`large-files` release) - Files >50 MB go in GitHub release assets (`large-files` release)

View File

@@ -1,8 +1,10 @@
# RetroBIOS <p align="center">
<img src=".github/assets/banner.png" alt="RetroBIOS" width="400">
</p>
Complete BIOS and firmware packs for Batocera, BizHawk, EmuDeck, Lakka, Recalbox, RetroArch, RetroBat, RetroDECK, RetroPie, and RomM. Complete BIOS and firmware packs for Batocera, BizHawk, EmuDeck, Lakka, Recalbox, RetroArch, RetroBat, RetroDECK, RetroPie, and RomM.
**7,293** verified files across **396** systems, ready to extract into your emulator's BIOS directory. **7,302** verified files across **396** systems, ready to extract into your emulator's BIOS directory.
## Quick Install ## Quick Install
@@ -27,7 +29,7 @@ Pick your platform, download the ZIP, extract to the BIOS path.
| Platform | BIOS files | Extract to | Download | | Platform | BIOS files | Extract to | Download |
|----------|-----------|-----------|----------| |----------|-----------|-----------|----------|
| Batocera | 362 | `/userdata/bios/` | [Download](../../releases/latest) | | Batocera | 361 | `/userdata/bios/` | [Download](../../releases/latest) |
| BizHawk | 118 | `Firmware/` | [Download](../../releases/latest) | | BizHawk | 118 | `Firmware/` | [Download](../../releases/latest) |
| EmuDeck | 161 | `Emulation/bios/` | [Download](../../releases/latest) | | EmuDeck | 161 | `Emulation/bios/` | [Download](../../releases/latest) |
| Lakka | 448 | `system/` | [Download](../../releases/latest) | | Lakka | 448 | `system/` | [Download](../../releases/latest) |
@@ -46,8 +48,8 @@ Each file is checked against the emulator's source code to match what the code a
- **10 platforms** supported with platform-specific verification - **10 platforms** supported with platform-specific verification
- **329 emulators** profiled from source (RetroArch cores + standalone) - **329 emulators** profiled from source (RetroArch cores + standalone)
- **396 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...) - **396 systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)
- **7,293 files** verified with MD5, SHA1, CRC32 checksums - **7,302 files** verified with MD5, SHA1, CRC32 checksums
- **8710 MB** total collection size - **8765 MB** total collection size
## Supported systems ## Supported systems
@@ -59,14 +61,14 @@ Full list with per-file details: **[https://abdess.github.io/retrobios/](https:/
| Platform | Coverage | Verified | Untested | Missing | | Platform | Coverage | Verified | Untested | Missing |
|----------|----------|----------|----------|---------| |----------|----------|----------|----------|---------|
| Batocera | 361/362 (99.7%) | 359 | 2 | 1 | | Batocera | 361/361 (100.0%) | 361 | 0 | 0 |
| BizHawk | 118/118 (100.0%) | 118 | 0 | 0 | | BizHawk | 118/118 (100.0%) | 118 | 0 | 0 |
| EmuDeck | 161/161 (100.0%) | 161 | 0 | 0 | | EmuDeck | 161/161 (100.0%) | 161 | 0 | 0 |
| Lakka | 448/448 (100.0%) | 448 | 0 | 0 | | Lakka | 448/448 (100.0%) | 448 | 0 | 0 |
| Recalbox | 346/346 (100.0%) | 345 | 1 | 0 | | Recalbox | 346/346 (100.0%) | 346 | 0 | 0 |
| RetroArch | 448/448 (100.0%) | 448 | 0 | 0 | | RetroArch | 448/448 (100.0%) | 448 | 0 | 0 |
| RetroBat | 339/339 (100.0%) | 339 | 0 | 0 | | RetroBat | 339/339 (100.0%) | 339 | 0 | 0 |
| RetroDECK | 2006/2006 (100.0%) | 2004 | 2 | 0 | | RetroDECK | 2006/2006 (100.0%) | 2006 | 0 | 0 |
| RetroPie | 448/448 (100.0%) | 448 | 0 | 0 | | RetroPie | 448/448 (100.0%) | 448 | 0 | 0 |
| RomM | 374/374 (100.0%) | 374 | 0 | 0 | | RomM | 374/374 (100.0%) | 374 | 0 | 0 |
@@ -122,6 +124,10 @@ To keep packs accurate, each file is checked against the emulator's source code.
<a href="https://github.com/monster-penguin"><img src="https://avatars.githubusercontent.com/u/266009589?v=4" width="50" title="monster-penguin"></a> <a href="https://github.com/monster-penguin"><img src="https://avatars.githubusercontent.com/u/266009589?v=4" width="50" title="monster-penguin"></a>
## Community tools
- [BIOS Preservation Tool](https://github.com/monster-penguin/BIOS-Preservation-Tool) by [monster-penguin](https://github.com/monster-penguin) - scan, verify, and stage your own BIOS collection using RetroBIOS hash metadata
## Contributing ## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
@@ -130,4 +136,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
This repository provides BIOS files for personal backup and archival purposes. This repository provides BIOS files for personal backup and archival purposes.
*Auto-generated on 2026-03-31T12:15:43Z* *Auto-generated on 2026-04-03T12:59:52Z*

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

301
bios/sdlpal/desc.dat Normal file
View File

@@ -0,0 +1,301 @@
本說明檔由 Eric-Chen 整理
http://hi.baidu.com/eric_chensoft
適用於 SDLPAL (http://sdlpal.codeplex.com)
3d(觀音符)=以觀音聖水書寫的靈符。*HP+150
3e(聖靈符)=具有女媧神強大靈力的符咒。*全體HP+300
3f(金剛符)=使用後如有金鐘鐵罩護身。*增加防禦七回合。
40(淨衣符)=具有祛病、驅邪的法力,*可解赤毒、屍毒、瘴毒。
41(靈心符)=具有寧神、驅邪的靈效,*可解瘋魔、妖縛、昏睡、封咒。
42(天師符)=茅山道士用來對付妖怪的符咒。
43(風靈符)=產生風系法術的符咒。
44(雷靈符)=產生雷系法術的符咒。
45(水靈符)=產生冰系法術的符咒。
46(火靈符)=產生火系法術的符咒。
47(土靈符)=產生土系法術的符咒。
48(舍利子)=得道高僧佛身火化後,*結成如珠狀的東西。*最大真氣值+3
49(玉菩提)=墨玉菩提樹的種籽。*最大真氣值+5
4a(銀杏子)=銀杏樹所結的白色核果。*最大體力值+3
4b(糯米)=糯稻的米,富於黏性,*可解屍毒。
4c(糯米糕)=糯米加麥芽、甜豆所煮的米糕,*可解屍毒。HP+25
4d(鹽巴)=取海水煎熬或曝曬而成,用來調*味,有時可解毒。
4e(茶葉蛋)=雞蛋水煮後,以茶葉入味。*便宜而好吃的食物。*HPMP+15
4f(雞蛋)=便宜而常見的食物。*HPMP+10
50(糖葫蘆)=以竹簽串李子,裹上麥芽糖,*形如葫蘆,故稱「糖葫蘆」。*HPMP+22
51(蠟燭)=用蠟製的點火照明的東西。
52(符紙)=泛黃的空白符紙。
53(檀香)=含有檀香料的一種香,點燃用以*薰衣、薰室內,驅逐惡氣。
54(大蒜)=具有除穢、祛病、護身等功能,*可以入藥。*戰鬥中服食避毒率+30%
56(酒)=以米加酒麴釀製而成,*可解赤毒。HPMP+15
57(雄黃)=天然產的礦物,塊狀、色黃,*可解赤毒。
58(雄黃酒)=一點點的雄黃,撒在酒中,*習俗在端午節喝這種酒;*可解赤毒、瘴毒。
59(九節菖蒲)=一種水草,葉子狹長如劍,*可解赤毒、屍毒、瘴毒、毒絲。
5a(驅魔香)=以大蒜、雄黃、艾草、檀香等混合*煉製而成,點燃後發出魔物厭惡*的氣味,使魔物不敢接近。
5b(十里香)=以生血、內藏、肉桂等煉製,*點燃後散發出吸引魔物的香味。
5c(水果)=養顏美容、幫助消化。*HPMP+20
5d(燒肉)=以炭火熏烤的醬汁豬肉。*HPMP+30
5e(醃肉)=用鹽巴醃漬的豬肉。*HP+85
5f(還魂香)=點燃後會散發奇異的香氣,*能牽引離體魂魄回歸軀體。*HP恢復10%
60(贖魂燈)=以蓮燈作法與鬼差交涉,*贖回死者魂魄。*HP恢復30%
61(孟婆湯)=消除死者罪孽業障,*使死者復活。*HP恢復50%
62(天香續命露)=以大量珍貴秘藥精煉而成,*具有肉白骨、藥死人之奇效。*HP恢復100%
63(止血草)=嚼碎後敷在傷口上,可迅速止血。*HP+50
64(行軍丹)=活血順氣的藥丸。*HP+100
65(金創藥)=上等刀傷藥,去腐生肌。*HP+200
66(蟠果)=西王母蟠桃園遺種,*籽小肉厚汁液香甜。*HP+450
67(紫菁玉蓉膏)=依宮廷秘方,采珍貴藥材煉製,*是療傷藥的極品。*HP+1000
68(鼠兒果)=產於山間野地,多為鼠類所食,*經人發現移種平地。*MP+36
69(還神丹)=寧神醒腦的藥丸。*MP+50
6a(龍涎草)=經蛟龍唾涎灌溉而生,*具有補中益氣之療效。*MP+110
6b(靈山仙芝)=寄生於枯木上的菌類,俗稱瑞草,*具有養氣培元之神效。*MP+260
6c(雪蓮子)=白玉雪蓮之蓮子,其形珠圓玉潤,*服食者真氣充盈,經脈通暢。*MP+400
6d(天仙玉露)=觀音菩薩淨瓶甘露水,*人間難求的仙界聖藥。*MP+700
6e(神仙茶)=神仙廣成子養生延壽之秘方。*HPMP+440
6f(靈葫仙丹)=修道隱士所煉丹藥。*HPMP+250
70(試煉果)=藥王神農氏嘗百草時,*最早發現的珍藥。*靈力最大值+3
71(女媧石)=女神媧皇煉石補天後,*所遺之五色石。*防禦最大值+3
72(八仙石)=八仙石洞中所采集之丹礦。*防禦最大值+2
73(蜂巢)=蜜蜂的窩,可以拿來丟敵人。
74(屍腐肉)=沾染屍毒的腐敗肉塊。*毒性: 屍毒
75(毒蛇卵)=煉蠱的材料。*毒性: 赤毒
76(毒蠍卵)=煉蠱的材料。*毒性: 赤毒
77(毒蟾卵)=煉蠱的材料。*毒性: 赤毒
78(蜘蛛卵)=煉蠱的材料。*毒性: 赤毒
79(蜈蚣卵)=煉蠱的材料。*毒性: 赤毒
7a(鶴頂紅)=七大毒蠱,中毒後每回合損血,*至死方休。*解藥: 血海棠 致命藥引: 孔雀膽
7b(孔雀膽)=七大毒蠱,中毒後每回合損血,*至死方休。*解藥: 金蠶蠱 致命藥引: 鶴頂紅
7c(血海棠)=七大毒蠱,中毒後每回合損血,*至死方休。*解藥: 斷腸草 致命藥引: 三屍蠱
7d(斷腸草)=七大毒蠱,中毒後每回合損血,*至死方休。*解藥: 三屍蠱 致命藥引: 金蠶蠱
7e(醍醐香)=紫葉小白花,散發濃鬱香氣,*聞到香氣,便如酒醉一般。*妖縛四回合。
7f(忘魂花)=青藍色小花,散發淡淡香氣,*聞到香氣,便會渾然忘我、*昏睡三回合。
80(紫罌粟)=服食者會產生幻覺,敵我不分。*瘋魔四回合。
81(鬼枯藤)=具毒性的黑褐色野生藤蔓,*可解赤毒、屍毒、瘴毒、毒絲。*HP-30
82(腹蛇涎)=腹蛇的毒涎。*毒性: 瘴毒
83(蜂王蜜)=蜜蜂所釀最好的蜜。*HPMP+150
84(雪蛤蟆)=生長於天山極寒之地,僅銅錢般大*小。武術最大值+2 防禦最大值+2*靈力最大值+2
85(赤蠍粉)=以整只赤尾蠍研磨成的粉末,*可使敵方全體中赤毒。
86(化屍水)=碰到傷口血水,便腐蝕潰爛,*受傷者沾染立斃。
87(迷魂香)=點燃蒙汗藥散發迷香,*可使敵人昏睡五回合。
88(九陰散)=服食前若已中毒,可補滿體力,*但無法解毒;*服食前若沒中毒,即刻斃命。
89(無影毒)=七大毒蠱,中毒後立即發作,*耗損一半體力。
8a(三屍蠱)=七大毒蠱;中毒後,潛伏片刻即*會發作,毒性非常猛烈。*解藥: 孔雀膽 致命藥引: 血海棠
8b(金蠶蠱)=七大毒蠱,中毒後每回合損血,*至死方休。*解藥: 鶴頂紅 致命藥引: 斷腸草
8c(幻蠱)=分泌的毒液會影響人的腦部,*使人敵我不分,*瘋魔五回合。
8d(隱蠱)=如帶刺甲蟲,將其身體捏破,*散發之煙霧可助我方隱匿形跡。*全體隱形三回合。
8e(冰蠶蠱)=以雪山冰洞內所產所冰蠶培養的*蠱蟲,可做為攻擊道具。
8f(火蠶蠱)=以麒麟炎洞內所產火蠶所培養的*蠱蟲,可做為攻擊道具。
90(食妖蟲)=寄生宿主吸取靈氣,九回合後,*可煉成靈蠱。
91(靈蠱)=以稀有藥物豢養的雌蠱。*全體MP+250
92(爆烈蠱)=預先將法力灌輸在蠱蟲體內,*投擲敵人產生強烈爆炸。
93(碧血蠶)=寄生宿主吸取血液,九回合後,*可煉成赤血蠶。
94(蠱)=巫師施法所需的材料。
95(赤血蠶)=吸血維生的毒蠱,*服食後體力完全恢復。
96(金蠶王)=蠱中之王,月夜散發金色磷光,*服食後可提升修行。
97(引路蜂)=跟隨引路蜂而行,*可回到迷宮起點。
98(傀儡蟲)=湘西雲貴巫師用以控制屍體,*可使死者繼續攻擊九回合。
99(梅花鏢)=形如梅花的暗器。*敵人HP-90
9a(袖裏劍)=暗藏在衣袖中的飛劍。*敵人HP-170
9b(透骨釘)=精鐵打造、三寸長的鐵針是*很鋒利的暗器。*敵人HP-250
9c(雷火珠)=填充火藥的鐵珠,投擲撞擊*後會爆裂傷人。*敵人HP-135
9d(毒龍砂)=以腹蛇毒煉製成的細砂,*可使敵方全體中瘴毒。*HP-55
9e(吸星鎖)=鐵製鋼抓,尾端系以靈蠱蠶絲,*可吸取敵人HP180
9f(纏魂絲)=千年蜘蛛的毒絲。*毒性: 毒絲
a0(捆仙繩)=施有咒術的粗麻繩,*可令妖怪動彈不得,*妖縛五回合。
a1(無影神針)=細如牛毛,傷人於無形。*敵人HP-400
a2(血玲瓏)=紅色鐵球,四周裝有鋒利刀片。*敵方全體HP-300
a3(長鞭)=生牛皮製的七尺軟鞭。*武術+20 身法+20
a4(九截鞭)=以鐵節鐵環組成的九節軟鞭。*武術+66 身法+33
a5(金蛇鞭)=以蛇皮絞以金絲編織成九尺軟鞭。*武術+99 身法+60
a6(木劍)=用木材雕刻的劍,小孩玩具。*武術+2 身法+3
a7(短刀)=一尺半長的鈍刀,可用來劈*砍木材。*武術+6 身法-5
a8(鐵劍)=一般鐵匠大量生產的劍,打造*得頗為粗劣。*武術+10 防禦+3
a9(大刀)=刀身寬而長,刃部鋒利,*背部厚重。*武術+16 防禦+1
aa(仙女劍)=一尺長的雙手劍,適合女子*使用,可發出兩次攻擊。*武術+8 防禦+5
ab(長劍)=一般鐵匠接受訂造的劍,*比鐵劍精致鋒利。*武術+25
ac(紅纓刀)=精鋼打造,背厚刃薄,*刀柄飾以紅色長穗。*武術+38
ad(越女劍)=劍身寬僅兩指,*專為女子打造。*武術+22 身法+8
ae(戒刀)=佛門中人練武所用之刀,*嚴禁傷生染血。*武術+55 防禦+5 靈力+10
af(玄鐵劍)=以珍貴的黑色鐵礦打造而成,*堅韌鋒利但極笨重。*武術+70 身法-20 靈力-15 防禦+9
b0(芙蓉刀)=百花派獨門兵器雙手彎刀,*可發出兩次攻擊。*武術+16 身法+8
b1(柳月刀)=細長鐵製雙刀,形如柳葉新月,*可發出兩次攻擊。*武術+28 身法+12 防禦+3
b2(青鋒劍)=名家精心打造的劍,輕薄鋒利。*武術+75 身法+15
b3(苗刀)=苗族戰士所慣用的佩刀。*武術+70 身法+32
b4(鳳鳴刀)=出鞘之聲有如鳳鳴,*故稱「鳳鳴刀」。武術+124*防禦+9 身法+32 靈力+16
b5(雙龍劍)=與一般劍長度相同的雙手劍,*可發出兩次攻擊。*武術+62 防禦+9 身法+9
b6(玉女劍)=鴛鴦雙劍中的雌劍,與金童劍為*一對。武術+100 靈力+15*身法+20 吉運+30
b7(金童劍)=鴛鴦雙劍中的雄劍,與玉女劍為*一對。武術+100 吉運+30*身法+20 靈力+15 防禦+3
b8(龍泉劍)=龍泉的水質非常適合造劍,*當地生產的劍叫龍泉劍。*武術+88 身法+20 吉運+22
b9(鬼牙刀)=苗刀的一種,刀尖倒鉤,*又稱「勾魂刀」。*武術+90 身法+26 吉運-9
ba(七星劍)=劍身鑲嵌七顆金黃寶石,可吸取北*斗七星之精氣。武術+120 靈力+50*身法+32 吉運+33 防禦+7
bb(玄冥寶刀)=可連續攻擊敵方全體兩次,*傳說是魔族的邪異兵器。*武術+98 身法+98 吉運+98
bc(巫月神刀)=苗族拜月教鎮教之寶。*武術+132 靈力+55 防禦+29*身法+45 吉運+36
bd(盤龍劍)=鑄劍宗師歐冶子所煉寶劍,劍身鑄*有青龍盤柱。武術+134 靈力+37*防禦+8 身法+40 吉運+32
be(太極劍)=道祖張陵之隨身配劍,天師仗以降*妖伏魔。武術+158 靈力+90*防禦+35 身法+50 吉運+33
bf(無塵劍)=上古神劍,指天天崩、劃地地裂。*武術+200 防禦+20 身法+77*吉運+33
c0(青蛇杖)=雕刻雙蛇纏繞的綠玉杖。*武術+50 靈力+62 防禦+6
c1(鬼頭杖)=苗族巫師役鬼煉蠱之法器,*頭顱中囚禁四十九條生魂。*武術+70 靈力+88 防禦+11
c2(冥蛇杖)=來自冥界之魔杖,號令群邪,*杖頭鑲嵌千年蛇王內丹。*武術+88 靈力+120 防禦+22
c3(天蛇杖)=女神媧皇煉化五色石所用法杖。*武術+100 靈力+150 防禦+33*吉運+36
c4(頭巾)=以剩餘布料縫製的頭巾。*防禦+1
c5(青絲巾)=青色的絲織髮帶。*防禦+2
c6(髮飾)=錫製的女子頭飾。*防禦+3
c7(銀釵)=純銀的髮釵。*防禦+5
c8(翠玉金釵)=鑲有綠翡翠的黃金髮釵。*防禦+9
c9(皮帽)=羊皮縫製的帽子,非常保暖。*防禦+4
ca(珍珠冠)=以珍珠縫綴的紅色錦冠。*防禦+13
cb(天師帽)=道士做法時所戴的帽子。*防禦+11 靈力+3
cc(紫金冠)=紫金冠以薄銅片鑄成,*外殼以紫飾金而成。*防禦+18
cd(天蠶絲帶)=以極珍貴的天蠶絲織成,*輕薄柔韌。*防禦+25 身法+8
ce(鳳凰羽毛)=金翅鳳凰腹部的銀色羽毛。*防禦+7 身法+24 吉運+9
cf(沖天冠)=天兵神將遺留的護頭金盔,*頂插雙雉尾羽。*防禦+28法+5 靈力+3 吉運+3
d0(布袍)=粗布縫製的交領長袖白袍。*防禦+3
d1(藤甲)=以荊藤編製的護甲。*防禦+7
d2(絲衣)=以蠶絲紡織而成,輕柔透氣。*防禦+3 身法+4
d3(鐵鎖衣)=以鐵環扣鎖製成的護甲。*防禦+13 身法-10
d4(夜行衣)=暗黑色的緊身衣靠,*便於隱匿夜色之中。*防禦+18 身法+12 吉運+12
d5(青銅甲)=青銅製的獸面紋胸護甲。*防禦+22 身法-13
d6(羅漢袍)=修行得道的和尚所穿的衣袍。*防禦+10 吉運+10 靈力+10
d7(鐵鱗甲)=以魚鱗形甲片編綴而成的鎧甲。*防禦+28 身法-4
d8(天師道袍)=天師道祖修行時所穿的法衣。*防禦+33 靈力+28
d9(精鐵戰甲)=以橢圓形的精鐵片編綴而成,*光亮照人,*又稱「光明鎧」。防禦+40 身法-7
da(金縷衣)=以金線穿玉片編製而成*又稱「金縷玉衣」。*防禦+7 身法-10
db(鬼針冑)=長滿倒刺的銅製盔甲。*防禦+55 武術+9
dc(天蠶寶衣)=以極珍貴的天蠶絲織成,*輕薄柔韌。*防禦+66
dd(青龍寶甲)=龍鱗編綴而成,世間絕頂*戰甲。*防禦+90
de(白虎之鎧)=以罕見的白虎皮製成的皮甲。*防禦+80
df(玄武戰袍)=以玄武的殼甲鍛造而成,*材質堅韌色黑而無光澤。*防禦+80
e0(朱雀戰衣)= 以南方火鳥的羽毛編織而成。*防禦+80
e1(披風)=無領對襟、無袖的披衣,*俗稱「斗篷」。*防禦+2
e2(護肩)=披於肩臂上的鎧甲,*又稱「掩膊」。*防禦+6
e3(武士披風)=將帥所穿有護肩軟甲的戰帔。*防禦+12
e4(護心鏡)=防護前胸要害的披甲,形如*銅鏡。防禦+20
e5(霓虹羽衣)=東海霓虹鳥的羽毛織成的*披肩。*防禦+18 身法+18 吉運+18
e6(菩提袈裟)=高等僧衣,又名「無垢衣」,*多為高僧與長老所穿。*防禦+31 靈力+16
e7(虎紋披風)=以整張千年白額虎虎皮製成,*毛皮呈黃色,帶黑色橫紋。*防禦+40
e8(鳳紋披風)=相傳為織女縫製的披風,*繡鳳織錦,光彩奪目。*防禦+52
e9(龍紋披風)=布面繡雙龍搶珠之彩紋,*有神龍護體之功效。*防禦+60
ea(聖靈披風)=巫后的遺物,潛藏神聖的力*量。防禦+66 靈力+30
eb(草鞋)=以藺草編織而成,十分便宜,*穿起來很輕便,適宜行走。*防禦+1
ec(木鞋)=以木材削製而成,鞋面刻有吉祥*圖案。*防禦+2
ed(布靴)=粗布縫製的長統靴。*防禦+3 身法+2
ee(繡花鞋)=以絲緞縫製,鞋面繡有龍頭鳳尾*花。*防禦+4
ef(鐵履)=鞋底夾縫鐵片,較普通布靴重。*防禦+6
f0(武僧靴)=羅漢僧練武所穿的布靴。*防禦+8 身法+6
f1(鹿皮靴)=鞋面以鹿皮毛縫製,質地輕柔,*行動可如鹿般迅捷。*防禦+11 身法+9
f2(疾風靴)=以薄如雲霧的蟬紗織成,*助穿者疾行如風。*防禦+14 身法+17
f3(蓮花靴)=飾以金蓮的長統繡花鞋。*防禦+18 身法+5
f4(虎皮靴)=取自東北虎的皮毛縫製。*防禦+21 身法+16
f5(龍鱗靴)=以龍鱗編綴而成。*防禦+25 身法+12
f6(步雲靴)=雲中子羽化登仙後,*所遺留之神靴。*防禦+28 身法+20
f7(魅影神靴)=妖魔附體,身如鬼魅。*防禦+32 身法+26
f8(香袋)=填充木屑、香粉的小布包,*常用來裝飾兼避邪的物品。*靈力+8 吉運+9 避毒率+20%
f9(護腕)=粗布縫製之腕部護套。*防禦+2
fa(鐵護腕)=精鋼打造之腕部護環。*防禦+5
fb(竹笛)=青竹削製之七孔橫笛。*吉運+18
fc(珍珠)=蚌類所生的球狀物,*是珍貴的裝飾品。*吉運+20
fd(玉鐲)=戴在手臂上的玉製環形首飾。*防禦+5 吉運+9
fe(唸珠)=佛教徒記數唸經咒或佛號次數的*計算珠。*靈力+5 防禦+5
ff(銀針)=用銀針刺肉,以痛楚喚醒神智,*可解妖縛、昏睡、瘋魔。HP-9
100(銅鏡)=青銅鑄造的照容用具。*防禦+6
101(八卦鏡)=用朱砂在鏡面畫八卦,*可借用自然界的靈氣。*靈力+8 防禦+8
102(幹坤鏡)=銅鏡背面鑄有太極乾坤圖,*可吸取天地陰陽靈氣。*靈力+14 防禦+14
103(豹牙手環)=收集花豹的利牙串成的手環。*防禦+9
104(聖靈珠)=女媧末族祖傳寶物,曆代聖魂歸依*之所。合體法術: 武神*靈力+128 防禦+15 避毒率+35%
105(金罡珠)=大羅金仙修煉千年的內丹。*防禦+90
106(五毒珠)=成精蟾怪的內丹,*佩戴後百毒不侵。
107(風靈珠)=女媧降伏風神後,禁制風神於內的*寶珠。合體法術: 風卷殘雲*避風率+50%
108(雷靈珠)=女媧降伏雷神後,禁制雷神於內的*寶珠。合體法術: 狂雷*避雷率+50%
109(水靈珠)=女媧降伏雪妖後,禁制雪妖於內的*寶珠。合體法術: 風雪冰天*避水率+50%
10a(火靈珠)=女媧降伏火神後,禁制火神於內的*寶珠。合體法術: 煉獄真火*避火率+50%
10b(土靈珠)=女媧降伏山神後,禁制山神於內的*寶珠。合體法術: 泰山壓頂*避土率+50% 可用於脫離洞窟
10c(煉蠱皿)=可將毒蛇卵、毒蠍卵、毒蟾卵、*蜘蛛卵、蜈蚣卵煉成蠱。
10d(壽葫蘆)=戰鬥中發出真氣補充持有者,*有提神振氣之奇效。*HPMP每回合+20
10e(紫金葫蘆)=收妖煉丹,需與靈葫咒配合。
10f(布包)=長安富商的行李。
110(桂花酒)=摻了水的酒。
111(紫金丹)=水月宮最珍貴的仙丹靈藥。
112(玉佛珠)=西方如來檀前的唸珠,經佛法薰陶*變化通靈。合體法術: 佛法無邊*靈力+88 防禦+18 避毒率+30%
113(金鳳凰蛋殼)=藥材。
114(火眼麒麟角)=藥材。
116(毒龍膽)=千年毒蛟的膽,以毒攻毒可解天下*所有的毒。*若沒中毒吃毒龍膽會斃命。
117(破天錘)=用來敲碎仙靈島石像的法寶。
118(包袱)=嬸嬸替逍遙收拾的行李。
119(銀杏果)=藥材。
11a(鯉魚)=藥材。
11b(鹿茸)=藥材。
11c(釣竿)=借來的,記得還!
11d(捕獸夾)=獵戶放置的捕鹿的道具。
11e(六神丹)=韓家藥鋪的祖傳婦女良藥。
11f(情書)=士兵委托的情書。
120(玉佩)=婢女委托的玉佩。
121(石鑰匙)=開啟隱龍窟後洞石門的鑰匙。
122(天書)=書中仙附身於書中。
123(香蕉)=誰喜歡吃香蕉?
124(鳳紋手絹)=某人交付的信物。
125(手卷)=李逍遙的父母親所留下的武功*秘笈。
126(蘆葦漂)=可載人漂浮水面的草席。
127(夢蛇)=女媧族的變身魔法,*能力大幅提升。
128(氣療術)=我方單人HP+75
129(觀音咒)=我方單人HP+150
12a(凝神歸元)=我方單人HP+220
12b(元靈歸心術)=我方單人HP+500
12c(五氣朝元)=我方全體HP+300
12d(還魂咒)=我方單人復活*HP恢復10%
12e(贖魂)=我方單人復活*HP恢復30%
12f(回夢)=敵方單人昏睡四回合。
130(奪魂)=吸取敵人魂魄,中者立斃。
131(鬼降)=敵方單人瘋魔四回合。
132(淨衣咒)=解赤毒、屍毒、瘴毒。
133(冰心訣)=解妖縛、昏睡、瘋魔、咒封。
134(靈血咒)=解赤毒、屍毒、瘴毒、毒絲、*麻痹、催眠、瘋魔、咒封。
135(金剛咒)=使用後如有金鐘鐵罩護身,*增加防禦七回合。
136(真元護體)=使用後如有鐵鎧金甲護體,*增加防禦九回合。
137(天罡戰氣)=七回合內,使用武器攻擊,*威力提升。
138(風咒)=風系初級法術,*攻擊敵方單人。
139(旋風咒)=風系中級法術,*攻擊敵方全體。
13a(風卷殘雲)=風系高級法術,*攻擊敵方全體。
13b(風神)=召喚風神,*最強的風系法術。
13c(雷咒)=雷系初級法術,*攻擊敵方單人。
13d(五雷咒)=雷系中級法術,*攻擊敵方全體。
13e(天雷破)=雷系高級法術,*攻擊敵方單人。
13f(狂雷)=雷系高級法術,*攻擊敵方全體。
140(雷神)=召喚雷神,*最強的雷系法術。
141(冰咒)=冰系初級法術,*攻擊敵方單人。
142(玄冰咒)=冰系中級法術,*攻擊敵方全體。
143(風雪冰天)=冰系高級法術,*攻擊敵方全體。
144(風雪冰天)=冰系高級法術,*攻擊敵方全體。
145(雪妖)=召喚雪妖,*最強的冰系法術。
147(炎咒)=火系初級法術,*攻擊敵方單人。
148(三昧真火)=火系中級法術,*攻擊敵方全體。
149(炎殺咒)=火系高級法術,*攻擊敵方單人。
14a(煉獄真火)=火系高級法術,*攻擊敵方全體。
14c(土咒)=土系初級法術,*攻擊敵方單人。
14d(飛岩術)=土系中級法術,*攻擊敵方全體。
14e(地裂天崩)=土系中級法術,*攻擊敵方全體。
14f(泰山壓頂)=土系高級法術,*攻擊敵方全體。
150(山神)=召喚山神,*最強的土系法術。
151(氣劍指)=蘇州林家的家傳武藝,*攻擊敵方全體。
154(一陽指)=聚勁食指,發出剛猛的氣芒,*攻擊敵方單人。
155(七訣劍氣)=以指代劍,發出裂地劍氣*攻擊敵方全體。
156(斬龍訣)=以雄渾氣勁橫掃群魔,*攻擊敵方全體。
158(銅錢鏢)=將金錢當做暗器,攻擊敵方*單人,一次使用五百文錢。
159(禦劍術)=蜀山派入門劍法,*攻擊敵方單人。
15a(萬劍訣)=劍芒如雨直落,*攻擊敵方全體。
15c(天劍)=人劍合一,身化利劍,*攻擊敵方全體。
15d(天師符法)=茅山道士用來對付妖怪*的符法,攻擊敵方單人。
15f(武神)=召喚武神,神刀斬魔。
160(三屍咒)=下蠱攻擊敵方單人,*有蠱時才能使用。
161(禦蜂術)=以笛音指揮毒蜂,*攻擊敵方全體。
162(萬蟻蝕象)=操縱食人毒蟻,*攻擊敵方單人。
16b(劍神)=召喚劍神,萬劍齊飛。
172(酒神)=召喚酒神,*用全身真氣爆發攻擊敵人。
174(萬蠱蝕天)=放蠱攻擊敵方全體,*有蠱時才能使用。
176(爆炸蠱)=預先將法力灌輸在蠱蟲體*內,投擲敵人產生強烈爆炸。
179(飛龍探雲手)=偷取敵人的物品或金錢。
180(靈葫咒)=當妖物體力低於四分之一時,*可將其收入紫金葫蘆中煉藥。
185(火神)=召喚火神,*最強的火系法術。
186(醉仙望月步)=五回合內,使用武器攻擊,*可連續出手兩次。
188(金蟬脫殼)=戰鬥中逃跑。
189(仙風雲體術)=身法暫時提升九回合。
18a(乾坤一擲)=使用金錢鏢攻擊敵方全體,*會耗損大量金錢。

File diff suppressed because it is too large Load Diff

578
docs_assets/extra.css Normal file
View File

@@ -0,0 +1,578 @@
/* RetroBIOS custom theme */
/* ── Color palette ── */
:root {
--rb-primary: #4a4e8a;
--rb-primary-light: #6366a0;
--rb-primary-dark: #363870;
--rb-accent: #e8594f;
--rb-success: #2e7d32;
--rb-warning: #f57c00;
--rb-danger: #c62828;
--rb-info: #1565c0;
--rb-muted: #78909c;
--rb-surface: #f5f6fa;
--rb-border: #e0e3eb;
--rb-text-secondary: #546e7a;
}
[data-md-color-scheme="slate"] {
--rb-surface: #1e1e2e;
--rb-border: #313244;
--rb-text-secondary: #a6adc8;
}
/* ── Material theme overrides ── */
[data-md-color-scheme="default"] {
--md-primary-fg-color: var(--rb-primary);
--md-primary-fg-color--light: var(--rb-primary-light);
--md-primary-fg-color--dark: var(--rb-primary-dark);
--md-accent-fg-color: var(--rb-accent);
}
[data-md-color-scheme="slate"] {
--md-primary-fg-color: var(--rb-primary-light);
--md-accent-fg-color: var(--rb-accent);
}
/* ── Hero section (home page) ── */
.rb-hero {
background: linear-gradient(135deg, var(--rb-primary) 0%, var(--rb-primary-dark) 100%);
color: white;
padding: 2.5rem 2rem;
border-radius: 12px;
margin-bottom: 2rem;
position: relative;
overflow: hidden;
}
.rb-hero::before {
content: "";
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 100%;
background: linear-gradient(135deg, transparent 40%, rgba(255,255,255,0.04) 100%);
pointer-events: none;
}
.rb-hero h1 {
margin: 0 0 0.5rem;
font-size: 2rem;
font-weight: 700;
color: white !important;
border: none;
}
.rb-hero p {
margin: 0;
opacity: 0.9;
font-size: 1.1rem;
}
/* ── Stat cards ── */
.rb-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 1rem;
margin: 1.5rem 0;
}
.rb-stat {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 1.2rem;
text-align: center;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.rb-stat:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.rb-stat .rb-stat-value {
font-size: 1.8rem;
font-weight: 700;
color: var(--rb-primary);
line-height: 1.2;
display: block;
}
[data-md-color-scheme="slate"] .rb-stat .rb-stat-value {
color: var(--rb-primary-light);
}
.rb-stat .rb-stat-label {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--rb-text-secondary);
margin-top: 0.3rem;
display: block;
}
/* ── Progress bars (inline) ── */
.rb-progress {
display: inline-flex;
align-items: center;
gap: 0.5rem;
width: 100%;
}
.rb-progress-bar {
flex: 1;
height: 6px;
background: var(--rb-border);
border-radius: 3px;
overflow: hidden;
min-width: 60px;
}
.rb-progress-fill {
height: 100%;
border-radius: 3px;
transition: width 0.3s ease;
}
.rb-progress-fill[data-level="high"] { background: var(--rb-success); }
.rb-progress-fill[data-level="mid"] { background: var(--rb-warning); }
.rb-progress-fill[data-level="low"] { background: var(--rb-danger); }
.rb-progress-text {
font-size: 0.8rem;
font-weight: 600;
white-space: nowrap;
min-width: 3.5em;
text-align: right;
}
/* ── Status badges ── */
.rb-badge {
display: inline-block;
padding: 0.15em 0.6em;
border-radius: 10px;
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 0.02em;
line-height: 1.5;
white-space: nowrap;
}
.rb-badge-success { background: #e8f5e9; color: #1b5e20; }
.rb-badge-warning { background: #fff3e0; color: #e65100; }
.rb-badge-danger { background: #ffebee; color: #b71c1c; }
.rb-badge-info { background: #e3f2fd; color: #0d47a1; }
.rb-badge-muted { background: #eceff1; color: #455a64; }
[data-md-color-scheme="slate"] .rb-badge-success { background: #1b5e20; color: #a5d6a7; }
[data-md-color-scheme="slate"] .rb-badge-warning { background: #e65100; color: #ffcc80; }
[data-md-color-scheme="slate"] .rb-badge-danger { background: #b71c1c; color: #ef9a9a; }
[data-md-color-scheme="slate"] .rb-badge-info { background: #0d47a1; color: #90caf9; }
[data-md-color-scheme="slate"] .rb-badge-muted { background: #37474f; color: #b0bec5; }
/* ── Tables ── */
.md-typeset table:not([class]) {
border-collapse: separate;
border-spacing: 0;
font-size: 0.85rem;
border: 1px solid var(--rb-border);
border-radius: 8px;
overflow: hidden;
}
.md-typeset table:not([class]) th {
background: var(--rb-surface);
font-weight: 600;
text-transform: uppercase;
font-size: 0.75rem;
letter-spacing: 0.04em;
color: var(--rb-text-secondary);
padding: 0.75rem 1rem;
position: sticky;
top: 0;
z-index: 1;
}
.md-typeset table:not([class]) td {
padding: 0.6rem 1rem;
border-top: 1px solid var(--rb-border);
}
.md-typeset table:not([class]) tbody tr:hover {
background: rgba(74, 78, 138, 0.04);
}
[data-md-color-scheme="slate"] .md-typeset table:not([class]) tbody tr:hover {
background: rgba(99, 102, 160, 0.08);
}
/* Zebra striping */
.md-typeset table:not([class]) tbody tr:nth-child(even) {
background: rgba(0, 0, 0, 0.015);
}
[data-md-color-scheme="slate"] .md-typeset table:not([class]) tbody tr:nth-child(even) {
background: rgba(255, 255, 255, 0.02);
}
/* ── Platform cards (home page) ── */
.rb-platform-row td:first-child img {
vertical-align: middle;
border-radius: 4px;
}
/* ── Quick start grid ── */
.rb-quickstart {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 0.75rem;
margin: 1rem 0;
}
.rb-quickstart-item {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 0.8rem 1rem;
display: flex;
align-items: center;
gap: 0.6rem;
}
.rb-quickstart-item code {
background: transparent;
font-weight: 600;
color: var(--rb-primary);
}
/* ── Section separators ── */
.rb-section {
margin-top: 2rem;
padding-top: 1.5rem;
border-top: 1px solid var(--rb-border);
}
/* ── Methodology steps ── */
.rb-methodology ol {
counter-reset: method-step;
list-style: none;
padding-left: 0;
}
.rb-methodology ol li {
counter-increment: method-step;
padding: 0.6rem 0 0.6rem 2.5rem;
position: relative;
}
.rb-methodology ol li::before {
content: counter(method-step);
position: absolute;
left: 0;
top: 0.5rem;
width: 1.8rem;
height: 1.8rem;
background: var(--rb-primary);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.8rem;
}
/* ── Classification badges (emulators) ── */
.rb-cls-official_port { border-left: 3px solid var(--rb-success); }
.rb-cls-community_fork { border-left: 3px solid var(--rb-info); }
.rb-cls-pure_libretro { border-left: 3px solid var(--rb-primary); }
.rb-cls-game_engine { border-left: 3px solid #7b1fa2; }
.rb-cls-enhanced_fork { border-left: 3px solid #00838f; }
.rb-cls-frozen_snapshot { border-left: 3px solid var(--rb-muted); }
.rb-cls-embedded_hle { border-left: 3px solid #4e342e; }
.rb-cls-launcher { border-left: 3px solid #37474f; }
/* ── Gap analysis priority markers ── */
.rb-gap-required {
color: var(--rb-danger);
font-weight: 600;
}
.rb-gap-optional {
color: var(--rb-muted);
}
/* ── Scrollable table container improvements ── */
.md-typeset__scrollwrap {
margin: 1rem 0;
}
/* ── Footer timestamp ── */
.rb-timestamp {
font-size: 0.8rem;
color: var(--rb-text-secondary);
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid var(--rb-border);
}
/* ── Info card (platform/emulator metadata) ── */
.rb-info-card {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 1rem 1.2rem;
margin: 1rem 0;
display: grid;
grid-template-columns: auto 1fr;
gap: 0.3rem 1.2rem;
font-size: 0.9rem;
}
.rb-info-card dt {
font-weight: 600;
color: var(--rb-text-secondary);
white-space: nowrap;
}
.rb-info-card dd {
margin: 0;
}
/* ── File entry cards (emulator detail) ── */
.rb-file-entry {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 1rem 1.2rem;
margin: 0.75rem 0;
}
.rb-file-entry-required {
border-left: 3px solid var(--rb-danger);
}
.rb-file-entry-optional {
border-left: 3px solid var(--rb-muted);
}
.rb-file-header {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
margin-bottom: 0.5rem;
}
.rb-file-header code {
font-size: 0.95rem;
font-weight: 700;
}
.rb-file-entry ul {
margin: 0.3rem 0 0;
padding-left: 1.2rem;
}
.rb-file-entry li {
font-size: 0.85rem;
margin: 0.15rem 0;
}
/* ── Hash display (truncated with tooltip) ── */
.rb-hash {
font-family: monospace;
font-size: 0.78rem;
color: var(--rb-text-secondary);
cursor: help;
letter-spacing: -0.02em;
}
/* System page file cards */
.rb-sys-file {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 0.8rem 1rem;
margin: 0.6rem 0;
}
.rb-sys-file > p:first-child {
margin-top: 0;
}
.rb-sys-file ul {
margin: 0.3rem 0 0;
padding-left: 1rem;
font-size: 0.85rem;
}
.rb-sys-file li {
margin: 0.1rem 0;
}
/* Emulator metadata card */
.rb-meta-card {
background: var(--rb-surface);
border: 1px solid var(--rb-border);
border-radius: 8px;
padding: 0.8rem 0;
margin: 1rem 0;
overflow: hidden;
}
.rb-meta-card table {
border: none !important;
margin: 0 !important;
border-radius: 0 !important;
}
.rb-meta-card th {
display: none;
}
.rb-meta-card td:first-child {
font-weight: 600;
color: var(--rb-text-secondary);
white-space: nowrap;
width: 140px;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.rb-meta-card td {
border-top: 1px solid var(--rb-border) !important;
}
.rb-meta-card tr:first-child td {
border-top: none !important;
}
/* ── Platform detail: coverage bar ── */
.rb-coverage-bar {
background: var(--rb-border);
border-radius: 4px;
height: 8px;
overflow: hidden;
margin: 0.5rem 0;
max-width: 300px;
}
.rb-coverage-fill {
height: 100%;
border-radius: 4px;
background: var(--rb-success);
}
/* ── Emulator index: section accent ── */
.md-typeset h2 .rb-cls-dot {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 0.4rem;
vertical-align: middle;
}
.rb-dot-official_port { background: var(--rb-success); }
.rb-dot-community_fork { background: var(--rb-info); }
.rb-dot-pure_libretro { background: var(--rb-primary); }
.rb-dot-game_engine { background: #7b1fa2; }
.rb-dot-enhanced_fork { background: #00838f; }
.rb-dot-frozen_snapshot { background: var(--rb-muted); }
.rb-dot-embedded_hle { background: #4e342e; }
.rb-dot-launcher { background: #37474f; }
.rb-dot-other { background: #9e9e9e; }
/* ── Cross-ref: classification in table ── */
.rb-cls-label {
font-size: 0.8rem;
padding: 0.1em 0.5em;
border-radius: 4px;
background: var(--rb-surface);
border: 1px solid var(--rb-border);
white-space: nowrap;
}
/* ── Buttons ── */
.md-typeset .md-button {
border-radius: 6px;
font-weight: 600;
text-transform: none;
letter-spacing: 0;
}
/* Pack button in tables: smaller */
.md-typeset table .md-button {
font-size: 0.75rem;
padding: 0.3em 0.8em;
}
/* ── Hide permalink anchors in hero ── */
.rb-hero .headerlink {
display: none;
}
/* ── Compact stat variant ── */
.rb-stats-compact {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin: 1rem 0;
}
.rb-stats-compact .rb-stat {
padding: 0.6rem 1rem;
flex: 1;
min-width: 100px;
}
.rb-stats-compact .rb-stat-value {
font-size: 1.3rem;
}
.rb-stats-compact .rb-stat-label {
font-size: 0.7rem;
}
/* ── Responsive ── */
@media (max-width: 768px) {
.rb-hero {
padding: 1.5rem;
}
.rb-hero h1 {
font-size: 1.5rem;
}
.rb-stats {
grid-template-columns: repeat(2, 1fr);
gap: 0.5rem;
}
.rb-stat {
padding: 0.8rem;
}
.rb-stat .rb-stat-value {
font-size: 1.4rem;
}
.rb-stat .rb-stat-label {
font-size: 0.7rem;
}
.rb-file-entry {
padding: 0.7rem 0.8rem;
}
.rb-sys-file {
padding: 0.6rem 0.8rem;
}
}
@media (max-width: 480px) {
.rb-stats {
grid-template-columns: repeat(2, 1fr);
}
.rb-hero h1 {
font-size: 1.3rem;
}
}

View File

@@ -59,6 +59,7 @@ files:
path: sysdata/otp.bin path: sysdata/otp.bin
system: nintendo-3ds system: nintendo-3ds
required: false required: false
size: 256
validation: [size, crypto] validation: [size, crypto]
note: "OTP data for console key derivation" note: "OTP data for console key derivation"
source_ref: "src/core/hw/unique_data.cpp:126-167, src/core/hw/unique_data.cpp:213" source_ref: "src/core/hw/unique_data.cpp:126-167, src/core/hw/unique_data.cpp:213"
@@ -67,6 +68,7 @@ files:
path: nand/private/movable.sed path: nand/private/movable.sed
system: nintendo-3ds system: nintendo-3ds
required: false required: false
size: 320
validation: [size, signature] validation: [size, signature]
note: "console-unique key seed" note: "console-unique key seed"
source_ref: "src/core/hw/unique_data.cpp:170-200, src/core/hw/unique_data.cpp:217" source_ref: "src/core/hw/unique_data.cpp:170-200, src/core/hw/unique_data.cpp:217"
@@ -75,6 +77,7 @@ files:
path: nand/rw/sys/SecureInfo_A path: nand/rw/sys/SecureInfo_A
system: nintendo-3ds system: nintendo-3ds
required: false required: false
size: 273
validation: [size, signature] validation: [size, signature]
note: "console serial and region data" note: "console serial and region data"
source_ref: "src/core/hw/unique_data.cpp:43-92, src/core/hw/unique_data.cpp:205" source_ref: "src/core/hw/unique_data.cpp:43-92, src/core/hw/unique_data.cpp:205"
@@ -83,6 +86,7 @@ files:
path: nand/rw/sys/LocalFriendCodeSeed_B path: nand/rw/sys/LocalFriendCodeSeed_B
system: nintendo-3ds system: nintendo-3ds
required: false required: false
size: 284
validation: [size, signature] validation: [size, signature]
note: "friend code generation seed" note: "friend code generation seed"
source_ref: "src/core/hw/unique_data.cpp:94-123, src/core/hw/unique_data.cpp:209" source_ref: "src/core/hw/unique_data.cpp:94-123, src/core/hw/unique_data.cpp:209"

View File

@@ -92,10 +92,9 @@ files:
note: "override_bios=1. Falls back to region BIOS if not found." note: "override_bios=1. Falls back to region BIOS if not found."
- name: "ps1_rom.bin" - name: "ps1_rom.bin"
description: "PS3 embedded PS1 BIOS (region-free override)" description: "PS3 embedded PS1 BIOS, first 512KB extracted (region-free override)"
region: "Auto" region: "Auto"
required: false required: false
size: 524288
sha1: "c40146361eb8cf670b19fdc9759190257803cab7" sha1: "c40146361eb8cf670b19fdc9759190257803cab7"
md5: "81bbe60ba7a3d1cea1d48c14cbcc647b" md5: "81bbe60ba7a3d1cea1d48c14cbcc647b"
validation: [sha1] validation: [sha1]

View File

@@ -4,7 +4,7 @@ core_classification: official_port
source: "https://github.com/libretro/bsnes-libretro" source: "https://github.com/libretro/bsnes-libretro"
upstream: "https://github.com/bsnes-emu/bsnes" upstream: "https://github.com/bsnes-emu/bsnes"
logo: "https://raw.githubusercontent.com/bsnes-emu/bsnes/master/bsnes/target-bsnes/resource/bsnes.svg" logo: "https://raw.githubusercontent.com/bsnes-emu/bsnes/master/bsnes/target-bsnes/resource/bsnes.svg"
profiled_date: "2026-03-23" profiled_date: "2026-04-05"
core_version: "115" core_version: "115"
display_name: "Nintendo - SNES / SFC (bsnes)" display_name: "Nintendo - SNES / SFC (bsnes)"
cores: [bsnes] cores: [bsnes]
@@ -29,71 +29,91 @@ files:
# program ROM: 2048 x 24-bit words, data ROM: 1024 x 16-bit words # program ROM: 2048 x 24-bit words, data ROM: 1024 x 16-bit words
- name: "dsp1.program.rom" - name: "dsp1.program.rom"
size: 6144 # 0x1800 system: nintendo-snes
size: 6144
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 program ROM for DSP1. HLE fallback available" note: "NEC uPD7725 program ROM for DSP1"
source_ref: "sfc/cartridge/load.cpp:490-494, heuristics/super-famicom.cpp:601" source_ref: "sfc/cartridge/load.cpp:490-494, heuristics/super-famicom.cpp:601"
- name: "dsp1.data.rom" - name: "dsp1.data.rom"
size: 2048 # 0x800 system: nintendo-snes
size: 2048
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 data ROM for DSP1. HLE fallback available" note: "NEC uPD7725 data ROM for DSP1"
source_ref: "sfc/cartridge/load.cpp:498-503" source_ref: "sfc/cartridge/load.cpp:498-503"
- name: "dsp1b.program.rom" - name: "dsp1b.program.rom"
size: 6144 # 0x1800 system: nintendo-snes
size: 6144
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 program ROM for DSP1B (default NEC identifier). HLE fallback available" note: "NEC uPD7725 program ROM for DSP1B (default NEC identifier)"
source_ref: "heuristics/super-famicom.cpp:606" source_ref: "heuristics/super-famicom.cpp:606"
- name: "dsp1b.data.rom" - name: "dsp1b.data.rom"
size: 2048 # 0x800 system: nintendo-snes
size: 2048
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 data ROM for DSP1B. HLE fallback available" note: "NEC uPD7725 data ROM for DSP1B"
source_ref: "heuristics/super-famicom.cpp:606" source_ref: "heuristics/super-famicom.cpp:606"
- name: "dsp2.program.rom" - name: "dsp2.program.rom"
size: 6144 # 0x1800 system: nintendo-snes
size: 6144
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 program ROM for DSP2 (Dungeon Master). HLE fallback available" note: "NEC uPD7725 program ROM for DSP2 (Dungeon Master)"
source_ref: "sfc/cartridge/load.cpp:515-520, heuristics/super-famicom.cpp:602" source_ref: "sfc/cartridge/load.cpp:515-520, heuristics/super-famicom.cpp:602"
- name: "dsp2.data.rom" - name: "dsp2.data.rom"
size: 2048 # 0x800 system: nintendo-snes
size: 2048
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 data ROM for DSP2. HLE fallback available" note: "NEC uPD7725 data ROM for DSP2"
source_ref: "sfc/cartridge/load.cpp:498-503" source_ref: "sfc/cartridge/load.cpp:498-503"
- name: "dsp3.program.rom" - name: "dsp3.program.rom"
size: 6144 # 0x1800 system: nintendo-snes
size: 6144
validation: [size]
required: true required: true
note: "NEC uPD7725 program ROM for DSP3 (SD Gundam GX). No HLE fallback" note: "NEC uPD7725 program ROM for DSP3 (SD Gundam GX). No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:531-534" source_ref: "sfc/cartridge/load.cpp:531-534"
- name: "dsp3.data.rom" - name: "dsp3.data.rom"
size: 2048 # 0x800 system: nintendo-snes
size: 2048
validation: [size]
required: true required: true
note: "NEC uPD7725 data ROM for DSP3. No HLE fallback" note: "NEC uPD7725 data ROM for DSP3. No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:531-534" source_ref: "sfc/cartridge/load.cpp:531-534"
- name: "dsp4.program.rom" - name: "dsp4.program.rom"
size: 6144 # 0x1800 system: nintendo-snes
size: 6144
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 program ROM for DSP4 (Top Gear 3000). HLE fallback available" note: "NEC uPD7725 program ROM for DSP4 (Top Gear 3000)"
source_ref: "sfc/cartridge/load.cpp:522-528, heuristics/super-famicom.cpp:604-605" source_ref: "sfc/cartridge/load.cpp:522-528, heuristics/super-famicom.cpp:604-605"
- name: "dsp4.data.rom" - name: "dsp4.data.rom"
size: 2048 # 0x800 system: nintendo-snes
size: 2048
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD7725 data ROM for DSP4. HLE fallback available" note: "NEC uPD7725 data ROM for DSP4"
source_ref: "sfc/cartridge/load.cpp:498-503" source_ref: "sfc/cartridge/load.cpp:498-503"
# -- NEC uPD96050 coprocessor (ST010, ST011) -- # -- NEC uPD96050 coprocessor (ST010, ST011) --
@@ -101,27 +121,35 @@ files:
# program ROM: 16384 x 24-bit words, data ROM: 2048 x 16-bit words # program ROM: 16384 x 24-bit words, data ROM: 2048 x 16-bit words
- name: "st010.program.rom" - name: "st010.program.rom"
size: 49152 # 0xC000 system: nintendo-snes
size: 49152
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD96050 program ROM for ST010. HLE fallback available" note: "NEC uPD96050 program ROM for ST010"
source_ref: "sfc/cartridge/load.cpp:570-574, heuristics/super-famicom.cpp:583-587" source_ref: "sfc/cartridge/load.cpp:570-574, heuristics/super-famicom.cpp:583-587"
- name: "st010.data.rom" - name: "st010.data.rom"
size: 4096 # 0x1000 system: nintendo-snes
size: 4096
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "NEC uPD96050 data ROM for ST010. HLE fallback available" note: "NEC uPD96050 data ROM for ST010"
source_ref: "sfc/cartridge/load.cpp:578-583" source_ref: "sfc/cartridge/load.cpp:578-583"
- name: "st011.program.rom" - name: "st011.program.rom"
size: 49152 # 0xC000 system: nintendo-snes
size: 49152
validation: [size]
required: true required: true
note: "NEC uPD96050 program ROM for ST011 (2dan Morita Shougi). No HLE fallback" note: "NEC uPD96050 program ROM for ST011 (2dan Morita Shougi). No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:599-601, heuristics/super-famicom.cpp:586" source_ref: "sfc/cartridge/load.cpp:599-601, heuristics/super-famicom.cpp:586"
- name: "st011.data.rom" - name: "st011.data.rom"
size: 4096 # 0x1000 system: nintendo-snes
size: 4096
validation: [size]
required: true required: true
note: "NEC uPD96050 data ROM for ST011. No HLE fallback" note: "NEC uPD96050 data ROM for ST011. No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:599-601" source_ref: "sfc/cartridge/load.cpp:599-601"
@@ -131,13 +159,17 @@ files:
# No HLE fallback exists # No HLE fallback exists
- name: "st018.program.rom" - name: "st018.program.rom"
size: 131072 # 0x20000 (128 KB) system: nintendo-snes
size: 131072
validation: [size]
required: true required: true
note: "ARM6 program ROM for ST018 (Hayazashi Nidan Morita Shougi). No HLE fallback" note: "ARM6 program ROM for ST018 (Hayazashi Nidan Morita Shougi). No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:379-385, armdsp/armdsp.hpp:31, heuristics/super-famicom.cpp:580" source_ref: "sfc/cartridge/load.cpp:379-385, armdsp/armdsp.hpp:31, heuristics/super-famicom.cpp:580"
- name: "st018.data.rom" - name: "st018.data.rom"
size: 32768 # 0x8000 (32 KB) system: nintendo-snes
size: 32768
validation: [size]
required: true required: true
note: "ARM6 data ROM for ST018. No HLE fallback" note: "ARM6 data ROM for ST018. No HLE fallback"
source_ref: "sfc/cartridge/load.cpp:387-393, armdsp/armdsp.hpp:32" source_ref: "sfc/cartridge/load.cpp:387-393, armdsp/armdsp.hpp:32"
@@ -148,11 +180,16 @@ files:
# Built-in staticDataROM fallback also present for LLE when file missing # Built-in staticDataROM fallback also present for LLE when file missing
- name: "cx4.data.rom" - name: "cx4.data.rom"
size: 3072 # 0xC00 system: nintendo-snes
size: 3072
sha1: a002f4efba42775a31185d443f3ed1790b0e949a
md5: 037ac4296b6b6a5c47c440188d3c72e3
crc32: b6e76a6a
validation: [size]
required: false required: false
hle_fallback: true hle_fallback: true
note: "Hitachi HG51BS169 data ROM for Cx4 (Mega Man X2/X3). HLE fallback and built-in static ROM available" note: "Hitachi HG51BS169 data ROM for Cx4 (Mega Man X2/X3). HLE fallback and built-in static ROM available"
source_ref: "sfc/cartridge/load.cpp:444-456, hitachidsp/hitachidsp.hpp:49, heuristics/super-famicom.cpp:597" source_ref: "sfc/cartridge/load.cpp:444-456, hitachidsp/hitachidsp.hpp:49, heuristics/super-famicom.cpp:597, hitachidsp/data-rom.cpp:3 (staticDataROM[3072])"
# -- Super Game Boy cartridge ROM -- # -- Super Game Boy cartridge ROM --
# The SGB boot ROMs (256 bytes each) are embedded in icd/boot-roms.cpp. # The SGB boot ROMs (256 bytes each) are embedded in icd/boot-roms.cpp.
@@ -160,23 +197,26 @@ files:
# Core option bsnes_sgb_bios selects between SGB1.sfc and SGB2.sfc. # Core option bsnes_sgb_bios selects between SGB1.sfc and SGB2.sfc.
- name: "SGB1.sfc" - name: "SGB1.sfc"
system: nintendo-super-game-boy
required: false required: false
note: "Super Game Boy 1 cartridge ROM. Needed to play Game Boy games via SGB mode" note: "Super Game Boy 1 cartridge ROM, loaded when playing .gb/.gbc via SGB mode"
source_ref: "target-libretro/libretro.cpp:689,933, target-libretro/libretro_core_options.h:689" source_ref: "target-libretro/libretro.cpp:926-935 (system_dir + sgb_bios), libretro.cpp:509 (core option bsnes_sgb_bios)"
- name: "SGB2.sfc" - name: "SGB2.sfc"
system: nintendo-super-game-boy
required: false required: false
note: "Super Game Boy 2 cartridge ROM. Uses dedicated oscillator for accurate GB speed" note: "Super Game Boy 2 cartridge ROM, uses dedicated oscillator for accurate GB speed"
source_ref: "target-libretro/libretro.cpp:690,933, target-libretro/libretro_core_options.h:690" source_ref: "target-libretro/libretro.cpp:926-935 (system_dir + sgb_bios), libretro.cpp:509 (core option bsnes_sgb_bios)"
# -- BS-X Satellaview BIOS -- # -- BS-X Satellaview BIOS --
# Required for loading .bs (BS Memory) format games. # Required for loading .bs (BS Memory) format games.
# Hardcoded filename in libretro.cpp. # Hardcoded filename in libretro.cpp.
- name: "BS-X.bin" - name: "BS-X.bin"
system: nintendo-satellaview
required: true required: true
note: "BS-X Satellaview BIOS ROM. Required for .bs games" note: "BS-X Satellaview BIOS ROM, loaded from system_dir when running .bs games"
source_ref: "target-libretro/libretro.cpp:948" source_ref: "target-libretro/libretro.cpp:944-951 (system_dir + BS-X.bin hardcoded, .bs extension branch)"
notes: notes:
hle_available: true hle_available: true

View File

@@ -35,9 +35,10 @@ files:
system: nintendo-3ds system: nintendo-3ds
description: "ARM9 bootrom" description: "ARM9 bootrom"
required: false required: false
size: 65536
validation: [size] validation: [size]
source_ref: "src/core/hw/aes/key.cpp:162-172 LoadBootromKeys(), src/core/hw/rsa/rsa.cpp:55-65 InitSlots()" source_ref: "src/core/hw/aes/key.cpp:162-172 LoadBootromKeys(), src/core/hw/rsa/rsa.cpp:55-65 InitSlots()"
note: "expected size 65536 bytes, provides AES and RSA keys" note: "provides AES and RSA keys"
- name: shared_font.bin - name: shared_font.bin
path: "Citra/sysdata/shared_font.bin" path: "Citra/sysdata/shared_font.bin"

View File

@@ -720,7 +720,8 @@ files:
# MSX (machine_name: "MSX") # MSX (machine_name: "MSX")
# ------------------------------------------------------- # -------------------------------------------------------
- name: msx.rom - name: msx.rom
path: MSX/msx.rom aliases: [MSX.ROM]
path: MSX/MSX.ROM
description: "Generic MSX BIOS" description: "Generic MSX BIOS"
size: 32768 size: 32768
crc32: "94ee12f3" crc32: "94ee12f3"
@@ -768,7 +769,8 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:763-769" source_ref: "Machines/Utility/ROMCatalogue.cpp:763-769"
- name: msx2.rom - name: msx2.rom
path: MSX/msx2.rom aliases: [MSX2.ROM]
path: MSX/MSX2.ROM
description: "Generic MSX2 BIOS" description: "Generic MSX2 BIOS"
size: 32768 size: 32768
crc32: "6cdaf3a5" crc32: "6cdaf3a5"
@@ -778,7 +780,8 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:771-778" source_ref: "Machines/Utility/ROMCatalogue.cpp:771-778"
- name: msx2ext.rom - name: msx2ext.rom
path: MSX/msx2ext.rom aliases: [MSX2EXT.ROM]
path: MSX/MSX2EXT.ROM
description: "MSX2 extension ROM" description: "MSX2 extension ROM"
size: 16384 size: 16384
crc32: "66237ecf" crc32: "66237ecf"

View File

@@ -53,6 +53,7 @@ files:
- name: "cromwell_1024.bin" - name: "cromwell_1024.bin"
path: "cromwell_1024.bin" path: "cromwell_1024.bin"
size: 1048576
validation: [size] validation: [size]
required: true required: true
note: > note: >

View File

@@ -65,6 +65,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0x66f334fe" known_hash_adler32: "0x66f334fe"
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included" note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117" source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:84-117"
@@ -75,6 +76,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0xf3b93527" known_hash_adler32: "0xf3b93527"
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included" note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62" source_ref: "Source/Core/Common/CommonPaths.h:137, Source/Core/Core/DSP/DSPCore.cpp:32-33, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:55-62"

View File

@@ -238,6 +238,7 @@ files:
- name: CARTS.CRC - name: CARTS.CRC
required: false required: false
bundled: false bundled: false
unsourceable: "dead legacy code path, never created or distributed, replaced by CARTS.SHA"
note: "CRC database for cartridge identification and mapper detection. Tried first, before CARTS.SHA (fMSX/MSX.c:2697)." note: "CRC database for cartridge identification and mapper detection. Tried first, before CARTS.SHA (fMSX/MSX.c:2697)."
- name: CARTS.SHA - name: CARTS.SHA

View File

@@ -244,7 +244,7 @@ files:
- name: "fuse/128p-0.rom" - name: "fuse/128p-0.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Pentagon 128K/512K/1024 ROM 0. Required for Pentagon machines." note: "Pentagon 128K/512K/1024 ROM 0. Required for Pentagon machines."
@@ -253,7 +253,7 @@ files:
- name: "fuse/128p-1.rom" - name: "fuse/128p-1.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Pentagon 128K/512K/1024 ROM 1. Required for Pentagon machines." note: "Pentagon 128K/512K/1024 ROM 1. Required for Pentagon machines."
@@ -262,7 +262,7 @@ files:
- name: "fuse/trdos.rom" - name: "fuse/trdos.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "TR-DOS ROM (Beta 128 disk interface). Used by Pentagon and Scorpion." note: "TR-DOS ROM (Beta 128 disk interface). Used by Pentagon and Scorpion."
@@ -271,7 +271,7 @@ files:
- name: "fuse/gluck.rom" - name: "fuse/gluck.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Gluck ROM. Required for Pentagon 512K and 1024." note: "Gluck ROM. Required for Pentagon 512K and 1024."
@@ -281,7 +281,7 @@ files:
- name: "fuse/256s-0.rom" - name: "fuse/256s-0.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Scorpion 256K ROM 0. Required for Scorpion machine." note: "Scorpion 256K ROM 0. Required for Scorpion machine."
@@ -290,7 +290,7 @@ files:
- name: "fuse/256s-1.rom" - name: "fuse/256s-1.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Scorpion 256K ROM 1. Required for Scorpion machine." note: "Scorpion 256K ROM 1. Required for Scorpion machine."
@@ -299,7 +299,7 @@ files:
- name: "fuse/256s-2.rom" - name: "fuse/256s-2.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Scorpion 256K ROM 2. Required for Scorpion machine." note: "Scorpion 256K ROM 2. Required for Scorpion machine."
@@ -308,7 +308,7 @@ files:
- name: "fuse/256s-3.rom" - name: "fuse/256s-3.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: true required: true
md5: ""
size: 16384 size: 16384
validation: [size] validation: [size]
note: "Scorpion 256K ROM 3 (TR-DOS). Required for Scorpion machine." note: "Scorpion 256K ROM 3 (TR-DOS). Required for Scorpion machine."
@@ -318,7 +318,7 @@ files:
- name: "fuse/if1-2.rom" - name: "fuse/if1-2.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Interface 1 ROM (edition 2). Loaded by peripherals/if1.c:403." note: "Interface 1 ROM (edition 2). Loaded by peripherals/if1.c:403."
@@ -347,7 +347,7 @@ files:
- name: "fuse/didaktik80.rom" - name: "fuse/didaktik80.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 14336 size: 14336
validation: [size] validation: [size]
note: "Didaktik 80 disk interface ROM. Not embedded." note: "Didaktik 80 disk interface ROM. Not embedded."
@@ -356,7 +356,7 @@ files:
- name: "fuse/opus.rom" - name: "fuse/opus.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Opus Discovery disk interface ROM. Not embedded." note: "Opus Discovery disk interface ROM. Not embedded."
@@ -365,7 +365,7 @@ files:
- name: "fuse/mf1.rom" - name: "fuse/mf1.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Multiface 1 ROM. Not embedded." note: "Multiface 1 ROM. Not embedded."
@@ -374,7 +374,7 @@ files:
- name: "fuse/mf128.rom" - name: "fuse/mf128.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Multiface 128 ROM. Not embedded." note: "Multiface 128 ROM. Not embedded."
@@ -383,7 +383,7 @@ files:
- name: "fuse/mf3.rom" - name: "fuse/mf3.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Multiface 3 ROM. Not embedded." note: "Multiface 3 ROM. Not embedded."
@@ -402,7 +402,7 @@ files:
- name: "fuse/ttx2000s.rom" - name: "fuse/ttx2000s.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "TTX2000S teletext adapter ROM. Not embedded." note: "TTX2000S teletext adapter ROM. Not embedded."
@@ -411,7 +411,7 @@ files:
- name: "fuse/usource.rom" - name: "fuse/usource.rom"
system: sinclair-zxspectrum system: sinclair-zxspectrum
required: false required: false
md5: ""
size: 8192 size: 8192
validation: [size] validation: [size]
note: "Currah uSource ROM. Not embedded." note: "Currah uSource ROM. Not embedded."

View File

@@ -62,6 +62,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0x66f334fe" known_hash_adler32: "0x66f334fe"
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement included" note: "DSP instruction ROM for LLE audio. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67" source_ref: "Source/Core/Common/CommonPaths.h:112, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:142-150, Source/Core/Core/DSP/DSPCore.cpp:48,67"
@@ -72,6 +73,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0xf3b93527" known_hash_adler32: "0xf3b93527"
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included" note: "DSP coefficient ROM for LLE audio and HLE polyphase resampling. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68" source_ref: "Source/Core/Common/CommonPaths.h:113, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:143-153, Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp:43-72, Source/Core/Core/DSP/DSPCore.cpp:48,68"

View File

@@ -24,7 +24,7 @@ files:
hle_fallback: true hle_fallback: true
size: 4096 size: 4096
validation: {core: [size], upstream: [size, crc32]} validation: {core: [size], upstream: [size, crc32]}
crc32: "0x2ab23573" crc32: 2ab23573
source_ref: "src/NDS.h:196, src/NDS.cpp:467-477, src/frontend/Util_ROM.cpp:99-111" 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"
@@ -35,7 +35,7 @@ files:
hle_fallback: true hle_fallback: true
size: 16384 size: 16384
validation: {core: [size], upstream: [size, crc32]} validation: {core: [size], upstream: [size, crc32]}
crc32: "0x1280f0d5" crc32: 1280f0d5
source_ref: "src/NDS.h:197, src/NDS.cpp:482-492, src/frontend/Util_ROM.cpp:117-131" 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"
@@ -44,6 +44,8 @@ files:
description: "NDS firmware image" description: "NDS firmware image"
required: false required: false
hle_fallback: true hle_fallback: true
min_size: 262144
max_size: 524288
validation: [size] validation: [size]
source_ref: "src/SPI.cpp:192-211, src/frontend/Util_ROM.cpp:174-195" 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"
@@ -55,7 +57,7 @@ files:
required: true required: true
size: 65536 size: 65536
validation: {core: [size], upstream: [size, crc32]} validation: {core: [size], upstream: [size, crc32]}
crc32: "0xBAE84F6C" crc32: bae84f6c
source_ref: "src/DSi.h:33, src/DSi.cpp:587-599, src/frontend/Util_ROM.cpp:145-156" source_ref: "src/DSi.h:33, src/DSi.cpp:587-599, src/frontend/Util_ROM.cpp:145-156"
- name: dsi_bios7.bin - name: dsi_bios7.bin
@@ -64,7 +66,7 @@ files:
required: true required: true
size: 65536 size: 65536
validation: {core: [size], upstream: [size, crc32]} validation: {core: [size], upstream: [size, crc32]}
crc32: "0x4316CC42" crc32: 4316cc42
source_ref: "src/DSi.h:34, src/DSi.cpp:604-620, src/frontend/Util_ROM.cpp:158-170" source_ref: "src/DSi.h:34, src/DSi.cpp:604-620, src/frontend/Util_ROM.cpp:158-170"
note: "Contains eMMC key-Y at offset 0x8308 for NAND init" note: "Contains eMMC key-Y at offset 0x8308 for NAND init"

View File

@@ -27,7 +27,7 @@ files:
hle_fallback: true hle_fallback: true
size: 16384 size: 16384
validation: [size] validation: [size]
crc32: "0x1280f0d5" crc32: 1280f0d5
source_ref: "src/libretro/config/console.cpp:219, melonDS:src/MemConstants.h:31,36" source_ref: "src/libretro/config/console.cpp:219, melonDS:src/MemConstants.h:31,36"
- name: bios9.bin - name: bios9.bin
@@ -37,7 +37,7 @@ files:
hle_fallback: true hle_fallback: true
size: 4096 size: 4096
validation: [size] validation: [size]
crc32: "0x2ab23573" crc32: 2ab23573
source_ref: "src/libretro/config/console.cpp:220, melonDS:src/MemConstants.h:30,37" source_ref: "src/libretro/config/console.cpp:220, melonDS:src/MemConstants.h:30,37"
- name: firmware.bin - name: firmware.bin
@@ -55,7 +55,7 @@ files:
required: true required: true
size: 65536 size: 65536
validation: [size] validation: [size]
crc32: "0x4316CC42" crc32: 4316cc42
source_ref: "src/libretro/config/console.cpp:333, melonDS:src/MemConstants.h:32,44" source_ref: "src/libretro/config/console.cpp:333, melonDS:src/MemConstants.h:32,44"
note: "Contains eMMC key-Y at offset 0x8308 for NAND init" note: "Contains eMMC key-Y at offset 0x8308 for NAND init"
@@ -65,7 +65,7 @@ files:
required: true required: true
size: 65536 size: 65536
validation: [size] validation: [size]
crc32: "0xBAE84F6C" crc32: bae84f6c
source_ref: "src/libretro/config/console.cpp:338, melonDS:src/MemConstants.h:32,45" source_ref: "src/libretro/config/console.cpp:338, melonDS:src/MemConstants.h:32,45"
- name: dsi_firmware.bin - name: dsi_firmware.bin

View File

@@ -65,5 +65,7 @@ files:
description: "External NES color palette" description: "External NES color palette"
required: false required: false
source_ref: "Libretro/libretro.cpp:301-323 (load_custom_palette), Libretro/libretro.cpp:405-406 (called when mesen_palette == Custom)" source_ref: "Libretro/libretro.cpp:301-323 (load_custom_palette), Libretro/libretro.cpp:405-406 (called when mesen_palette == Custom)"
min_size: 192
max_size: 1536
validation: [size] validation: [size]
note: "Loaded when mesen_palette core option is Custom. Accepts exactly 192 bytes (64 RGB triplets) or 1536 bytes (512 entries for emphasis combos). Falls back to built-in default palette if size doesn't match." note: "Accepts 192 bytes (64 RGB triplets) or 1536 bytes (512 emphasis combos). Falls back to built-in default if size doesn't match."

View File

@@ -186,6 +186,7 @@ files:
path: "np2kai/gpib.rom" path: "np2kai/gpib.rom"
size: 8192 size: 8192
required: false required: false
unsourceable: "never publicly dumped, GP-IB emulation is stub code (source comment: not implemented)"
note: > note: >
GP-IB interface BIOS ROM (8 KB). If missing, GP-IB emulation GP-IB interface BIOS ROM (8 KB). If missing, GP-IB emulation
is disabled entirely. is disabled entirely.
@@ -198,6 +199,8 @@ files:
- name: "key.txt" - name: "key.txt"
path: "np2kai/key.txt" path: "np2kai/key.txt"
required: false required: false
hle_fallback: true
unsourceable: "user-created keyboard config, no default distributed in any NP2kai release"
note: > note: >
Keyboard remapping configuration (text file). User-created file Keyboard remapping configuration (text file). User-created file
for custom keyboard layout. The core uses built-in defaults if absent. for custom keyboard layout. The core uses built-in defaults if absent.

View File

@@ -81,5 +81,6 @@ files:
system: cave-story system: cave-story
description: "Tile attribute lookup table (maps tile codes to collision/behavior attributes)" description: "Tile attribute lookup table (maps tile codes to collision/behavior attributes)"
required: false required: false
hle_fallback: true
source_ref: "map.cpp:290-303 (loaded at init, hardcoded default if missing)" source_ref: "map.cpp:290-303 (loaded at init, hardcoded default if missing)"
note: "Not part of the freeware distribution. Generated by the standalone NXEngine extraction tool. The libretro core has hardcoded defaults in map.cpp:30." note: "Not part of the freeware distribution. Generated by the standalone NXEngine extraction tool. The libretro core has hardcoded defaults in map.cpp:30."

View File

@@ -68,6 +68,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0x66f334fe" known_hash_adler32: "0x66f334fe"
adler32_byteswap: true
note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included" note: "DSP instruction ROM for LLE audio. Free replacement (v0.4) included"
source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117" source_ref: "Source/Core/Common/CommonPaths.h:135, Source/Core/Core/HW/DSPLLE/DSPLLE.cpp:87-117"
@@ -79,6 +80,7 @@ files:
hle_fallback: true hle_fallback: true
validation: [size] validation: [size]
known_hash_adler32: "0xf3b93527" known_hash_adler32: "0xf3b93527"
adler32_byteswap: true
note: "DSP coefficient ROM for LLE audio. Free replacement included" note: "DSP coefficient ROM for LLE audio. Free replacement included"
source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/DSP/DSPCore.cpp:32-38" source_ref: "Source/Core/Common/CommonPaths.h:136, Source/Core/Core/DSP/DSPCore.cpp:32-38"

View File

@@ -247,6 +247,7 @@ files:
- name: "WHDLoad.key" - name: "WHDLoad.key"
system: commodore-amiga system: commodore-amiga
required: false required: false
unsourceable: "per-user signed registration key, never distributed generically, WHDLoad free since v18.2"
note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use." note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use."
source_ref: "libretro/libretro-core.c:5985-5998" source_ref: "libretro/libretro-core.c:5985-5998"

View File

@@ -251,6 +251,7 @@ files:
- name: "WHDLoad.key" - name: "WHDLoad.key"
system: commodore-amiga system: commodore-amiga
required: false required: false
unsourceable: "per-user signed registration key, never distributed generically, WHDLoad free since v18.2"
note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use." note: "WHDLoad license key. Copied to saves/WHDLoad/L/ for registered WHDLoad use."
source_ref: "libretro/libretro-core.c:5903-5916" source_ref: "libretro/libretro-core.c:5903-5916"

View File

@@ -533,7 +533,7 @@ files:
- name: "U-Boot LEON3" - name: "U-Boot LEON3"
path: "qemu/u-boot.bin" path: "qemu/u-boot.bin"
sha1: ""
required: false required: false
note: "U-Boot for LEON3 SPARC board. Not shipped with QEMU, user-supplied." note: "U-Boot for LEON3 SPARC board. Not shipped with QEMU, user-supplied."
source_ref: "hw/sparc/leon3.c:53" source_ref: "hw/sparc/leon3.c:53"
@@ -611,28 +611,28 @@ files:
# ======================================================== # ========================================================
- name: "MIPS BIOS (big-endian)" - name: "MIPS BIOS (big-endian)"
path: "qemu/mips_bios.bin" path: "qemu/mips_bios.bin"
sha1: ""
required: false required: false
note: "Default BIOS for big-endian MIPS machines (Malta, MIPSsim, Jazz). Not shipped with QEMU." note: "Default BIOS for big-endian MIPS machines (Malta, MIPSsim, Jazz). Not shipped with QEMU."
source_ref: "hw/mips/malta.c:97" source_ref: "hw/mips/malta.c:97"
- name: "MIPS BIOS (little-endian)" - name: "MIPS BIOS (little-endian)"
path: "qemu/mipsel_bios.bin" path: "qemu/mipsel_bios.bin"
sha1: ""
required: false required: false
note: "Default BIOS for little-endian MIPS machines (Malta, MIPSsim, Jazz). Not shipped with QEMU." note: "Default BIOS for little-endian MIPS machines (Malta, MIPSsim, Jazz). Not shipped with QEMU."
source_ref: "hw/mips/malta.c:99" source_ref: "hw/mips/malta.c:99"
- name: "Loongson3 BIOS" - name: "Loongson3 BIOS"
path: "qemu/bios_loongson3.bin" path: "qemu/bios_loongson3.bin"
sha1: ""
required: false required: false
note: "Default BIOS for Loongson3 virtual MIPS machine. Not shipped with QEMU." note: "Default BIOS for Loongson3 virtual MIPS machine. Not shipped with QEMU."
source_ref: "hw/mips/loongson3_virt.c:63" source_ref: "hw/mips/loongson3_virt.c:63"
- name: "PMON Fuloong2e" - name: "PMON Fuloong2e"
path: "qemu/pmon_2e.bin" path: "qemu/pmon_2e.bin"
sha1: ""
required: false required: false
note: "PMON monitor for Fuloong2e MIPS board. Not shipped with QEMU." note: "PMON monitor for Fuloong2e MIPS board. Not shipped with QEMU."
source_ref: "hw/mips/fuloong2e.c:58" source_ref: "hw/mips/fuloong2e.c:58"
@@ -642,7 +642,7 @@ files:
# ======================================================== # ========================================================
- name: "Macintosh ROM" - name: "Macintosh ROM"
path: "qemu/MacROM.bin" path: "qemu/MacROM.bin"
sha1: ""
required: false required: false
note: "Apple Macintosh ROM for Quadra 800 emulation. Not shipped with QEMU." note: "Apple Macintosh ROM for Quadra 800 emulation. Not shipped with QEMU."
source_ref: "hw/m68k/q800.c:62" source_ref: "hw/m68k/q800.c:62"
@@ -652,7 +652,7 @@ files:
# ======================================================== # ========================================================
- name: "Canon A1100 ROM" - name: "Canon A1100 ROM"
path: "qemu/canon-a1100-rom1.bin" path: "qemu/canon-a1100-rom1.bin"
sha1: ""
required: false required: false
note: "Canon PowerShot A1100 IS DIGIC camera ROM. Not shipped with QEMU." note: "Canon PowerShot A1100 IS DIGIC camera ROM. Not shipped with QEMU."
source_ref: "hw/arm/digic_boards.c:131" source_ref: "hw/arm/digic_boards.c:131"
@@ -702,7 +702,7 @@ files:
- name: "Virtex ML507 DTB (PPC)" - name: "Virtex ML507 DTB (PPC)"
path: "qemu/virtex-ml507.dtb" path: "qemu/virtex-ml507.dtb"
sha1: ""
required: false required: false
note: "Device tree blob for Xilinx Virtex ML507 PowerPC board. Not shipped with QEMU." note: "Device tree blob for Xilinx Virtex ML507 PowerPC board. Not shipped with QEMU."
source_ref: "hw/ppc/virtex_ml507.c:148" source_ref: "hw/ppc/virtex_ml507.c:148"

View File

@@ -24,36 +24,43 @@ notes: |
files: files:
- name: kvs1.wav - name: kvs1.wav
aliases: [KVS1.WAV]
description: "KidVid Voice Module audio tape 1 (Smurfs Save the Day)" description: "KidVid Voice Module audio tape 1 (Smurfs Save the Day)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvs2.wav - name: kvs2.wav
aliases: [KVS2.WAV]
description: "KidVid Voice Module audio tape 2 (Smurfs Save the Day)" description: "KidVid Voice Module audio tape 2 (Smurfs Save the Day)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvs3.wav - name: kvs3.wav
aliases: [KVS3.WAV]
description: "KidVid Voice Module audio tape 3 (Smurfs Save the Day)" description: "KidVid Voice Module audio tape 3 (Smurfs Save the Day)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb1.wav - name: kvb1.wav
aliases: [KVB1.WAV]
description: "KidVid Voice Module audio tape 1 (Berenstain Bears)" description: "KidVid Voice Module audio tape 1 (Berenstain Bears)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb2.wav - name: kvb2.wav
aliases: [KVB2.WAV]
description: "KidVid Voice Module audio tape 2 (Berenstain Bears)" description: "KidVid Voice Module audio tape 2 (Berenstain Bears)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb3.wav - name: kvb3.wav
aliases: [KVB3.WAV]
description: "KidVid Voice Module audio tape 3 (Berenstain Bears)" description: "KidVid Voice Module audio tape 3 (Berenstain Bears)"
required: false required: false
category: game_data category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182" source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvshared.wav - name: kvshared.wav
aliases: [KVSHARED.WAV]
description: "KidVid Voice Module shared audio samples" description: "KidVid Voice Module shared audio samples"
required: false required: false
category: game_data category: game_data

View File

@@ -70,11 +70,12 @@ files:
aliases: [] aliases: []
- name: "ps1_rom.bin" - name: "ps1_rom.bin"
description: "PS3 (v5.0 06-23-03 A)" description: "PS3 embedded PS1 BIOS (v5.0 06-23-03 A)"
region: "Auto" region: "Auto"
required: false required: false
md5: "81bbe60ba7a3d1cea1d48c14cbcc647b" md5: "81bbe60ba7a3d1cea1d48c14cbcc647b"
size: 4089584 size: [524288, 4194304, 4089584]
validation: [size, md5] validation: [size, md5]
source_ref: "src/core/bios.cpp:70" note: "Accepts PS1 (512KB), PS2 (4MB), and PS3 (0x3E66F0) sizes. Only first 512KB used."
source_ref: "src/core/bios.h:9, src/core/bios.cpp:70,83"
aliases: [] aliases: []

View File

@@ -86,6 +86,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 79015323128650c742a3694c9429aa91f355905e
md5: 57af4ae21d4b705c2991d98ed5c1f7b8
crc32: f833d117
note: "C64 BASIC V2 ROM. Embedded in core." note: "C64 BASIC V2 ROM. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:31" source_ref: "vice/src/c64/c64rom.h:31"
@@ -95,6 +98,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 1d503e56df85a62fee696e7618dc5b4e781df1bb
md5: 39065497630802346bce17963f13c092
crc32: dbe3e7c7
note: "C64 Kernal Rev 3 (default). Embedded in core." note: "C64 Kernal Rev 3 (default). Embedded in core."
source_ref: "vice/src/c64/c64rom.h:52" source_ref: "vice/src/c64/c64rom.h:52"
@@ -104,6 +110,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 87cc04d61fc748b82df09856847bb5c2754a2033
md5: 1ae0ea224f2b291dafa2c20b990bb7d4
crc32: dce782fa
note: "C64 Kernal Rev 1. Embedded in core." note: "C64 Kernal Rev 1. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:50" source_ref: "vice/src/c64/c64rom.h:50"
@@ -113,6 +122,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 0e2e4ee3f2d41f00bed72f9ab588b83e306fdb13
md5: 7360b296d64e18b88f6cf52289fd99a1
crc32: a5c687b3
note: "C64 Kernal Rev 2. Embedded in core." note: "C64 Kernal Rev 2. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:51" source_ref: "vice/src/c64/c64rom.h:51"
@@ -122,6 +134,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 3ad6cc1837c679a11f551ad1cf1a32dd84ace719
md5: ddee89b0fed19572da5245ea68ff11b5
crc32: 505365d4
note: "C64 GS (Games System) Kernal. Embedded in core." note: "C64 GS (Games System) Kernal. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:53" source_ref: "vice/src/c64/c64rom.h:53"
@@ -131,6 +146,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: aa136e91ecf3c5ac64f696b3dbcbfc5ba0871c98
md5: 187b8c713b51931e070872bd390b472a
crc32: 2c5965d4
note: "SX-64 Kernal. Embedded in core." note: "SX-64 Kernal. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:54" source_ref: "vice/src/c64/c64rom.h:54"
@@ -140,6 +158,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 6c4fa9465f6091b174df27dfe679499df447503c
md5: da92801e3a03b005b746a4dd0b639c7c
crc32: 789c8cc5
note: "PET64/Educator64 (4064) Kernal. Embedded in core." note: "PET64/Educator64 (4064) Kernal. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:55" source_ref: "vice/src/c64/c64rom.h:55"
@@ -149,6 +170,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 4ff0f11e80f4b57430d8f0c3799ed0f0e0f4565d
md5: 479553fd53346ec84054f0b1c6237397
crc32: 3a9ef6f1
note: "C64 Japanese Kernal. Embedded in core." note: "C64 Japanese Kernal. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:49" source_ref: "vice/src/c64/c64rom.h:49"
@@ -158,6 +182,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: adc7c31e18c7c7413d54802ef2f4193da14711aa
md5: 12a4202f5331d45af846af6c58fba946
crc32: ec4272ee
note: "C64 Character Generator ROM (default). Embedded in core." note: "C64 Character Generator ROM (default). Embedded in core."
source_ref: "vice/src/c64/c64rom.h:60" source_ref: "vice/src/c64/c64rom.h:60"
@@ -167,6 +194,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 0fad19dbcdb12461c99657b2979dbb5c2e47b527
md5: cf32a93c0a693ed359a4f483ef6db53d
crc32: 1604f6c1
note: "C64 Japanese Character Generator ROM. Embedded in core." note: "C64 Japanese Character Generator ROM. Embedded in core."
source_ref: "vice/src/c64/c64rom.h:61" source_ref: "vice/src/c64/c64rom.h:61"
@@ -180,6 +210,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: ceb6e1a1bf7e08eb9cbc651afa29e26adccf38ab
md5: 01f6903033b90cd506cde7802ec743c3
crc32: ba456b8e
note: "C128 Kernal (default international). Embedded in core." note: "C128 Kernal (default international). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:103" source_ref: "vice/src/c128/c128rom.h:103"
@@ -189,6 +222,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 3629b3fa28b6a30bcc027b647f26654929ed1b0f
md5: 9837409b6bdb7ce055409fa3eb3e9cf0
crc32: bff7550b
note: "C128 Kernal German. Embedded in core." note: "C128 Kernal German. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:105" source_ref: "vice/src/c128/c128rom.h:105"
@@ -198,6 +234,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 98c34e0dec9f52d7862b56bb287d2573eb3f6364
md5: 90907477d39db1b8fe1732692278a0e9
crc32: d311dab1
note: "C128 Kernal Swiss. Embedded in core." note: "C128 Kernal Swiss. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:104" source_ref: "vice/src/c128/c128rom.h:104"
@@ -207,6 +246,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 925177c99ee7e02870c32ad62a054db1327cf0c2
md5: 7852922295c103f067ba3c0f56378a95
crc32: 1cf7f729
note: "C128 Kernal Swedish. Embedded in core." note: "C128 Kernal Swedish. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:110" source_ref: "vice/src/c128/c128rom.h:110"
@@ -216,6 +258,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: d08e7991a6df14a843e92daafaf6756337959ba4
md5: 0a0eb549ec08624de11cf1f249f6f3dc
crc32: d3ecea84
note: "C128 Kernal Finnish (unidentified part number). Embedded in core." note: "C128 Kernal Finnish (unidentified part number). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:106" source_ref: "vice/src/c128/c128rom.h:106"
@@ -225,6 +270,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: a0680d04db3232fa9f58598e5c9f09c4fe94f601
md5: 7a7747aa70fd63402c6a95fba0bd6806
crc32: 2df282b8
note: "C128 Kernal French (unidentified part number). Embedded in core." note: "C128 Kernal French (unidentified part number). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:107" source_ref: "vice/src/c128/c128rom.h:107"
@@ -234,6 +282,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 592a626eb2b5372596ac374d3505c3ce78dd040f
md5: 142c8bd5934e9d97addb6776a2f2e8b8
crc32: 74d6b084
note: "C128 Kernal Italian (unidentified part number). Embedded in core." note: "C128 Kernal Italian (unidentified part number). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:108" source_ref: "vice/src/c128/c128rom.h:108"
@@ -243,6 +294,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 00fe2fd610a812121befab1e7238fa882c0f8257
md5: 498fdedaeab458931b6103d52d5a3ea1
crc32: a5406848
note: "C128 Kernal Norwegian (unidentified part number). Embedded in core." note: "C128 Kernal Norwegian (unidentified part number). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:109" source_ref: "vice/src/c128/c128rom.h:109"
@@ -252,6 +306,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: d53a7884404f7d18ebd60dd3080c8f8d71067441
md5: b86ce827c9108fbc7b9e02c690e81a23
crc32: 9f9c355b
note: "C128 BASIC low (BASIC part). Embedded in core." note: "C128 BASIC low (BASIC part). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:115" source_ref: "vice/src/c128/c128rom.h:115"
@@ -261,6 +318,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: c4fb4a714e48a7bf6c28659de0302183a0e0d6c0
md5: 87bb251707d0a2c915d6e0c69fdb0fed
crc32: 6e2c91a7
note: "C128 BASIC high (Editor part). Embedded in core." note: "C128 BASIC high (Editor part). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:116" source_ref: "vice/src/c128/c128rom.h:116"
@@ -288,6 +348,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: b4862cac7b9319d8e912887c97fc270d4c239349
md5: 8fa940c39225d40f37ddf7082fba8b21
crc32: dd2976d2
note: "C128 C64-mode Kernal Norwegian. Embedded in core." note: "C128 C64-mode Kernal Norwegian. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:136" source_ref: "vice/src/c128/c128rom.h:136"
@@ -297,6 +360,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: e4f52d9b36c030eb94524eb49f6f0774c1d02e5e
md5: 27e26dbb267c8ebf1cd47105a6ca71e7
crc32: f10c2c25
note: "C128 C64-mode Kernal Swedish. Embedded in core." note: "C128 C64-mode Kernal Swedish. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:137" source_ref: "vice/src/c128/c128rom.h:137"
@@ -306,6 +372,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 29ed066d513f2d5c09ff26d9166ba23c2afb2b3f
md5: 46b3cb2140f244c0ed1150c819e7bdc4
crc32: 6aaaafe6
note: "C128 Character Generator (default international). Embedded in core." note: "C128 Character Generator (default international). Embedded in core."
source_ref: "vice/src/c128/c128rom.h:92" source_ref: "vice/src/c128/c128rom.h:92"
@@ -315,6 +384,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 638f8aff51c2ac4f99a55b12c4f8c985ef4bebd3
md5: ec9e71614010c4efb851b83bcd685e9c
crc32: fe5a2db1
note: "C128 Character Generator German. Embedded in core." note: "C128 Character Generator German. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:95" source_ref: "vice/src/c128/c128rom.h:95"
@@ -324,6 +396,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 9119b27a1bf885fa4c76fff5d858c74c194dd2b8
md5: de3e110a48de76457dbc9ad320e2caa5
crc32: bad36b88
note: "C128 Character Generator Italian/French/Belgian. Embedded in core." note: "C128 Character Generator Italian/French/Belgian. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:93" source_ref: "vice/src/c128/c128rom.h:93"
@@ -333,6 +408,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 70eccd8b944146f6b60f1519b830a4ee8928d4fa
md5: 5cc3635e434fdc7023d0035e965ce76f
crc32: c8def186
note: "C128 Character Generator Swiss. Embedded in core." note: "C128 Character Generator Swiss. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:94" source_ref: "vice/src/c128/c128rom.h:94"
@@ -342,6 +420,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 5a87faa457979e7b6f434251a9e32f4483b337b3
md5: 7eead22a114154c809b33320c9250e26
crc32: ba95c625
note: "C128 Character Generator Norwegian. Embedded in core." note: "C128 Character Generator Norwegian. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:99" source_ref: "vice/src/c128/c128rom.h:99"
@@ -351,6 +432,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: aca3f7321ee7e6152f1f0afad646ae41964de4fb
md5: 06e46af13d13aa869218275e64d48b00
crc32: 7a70d9b8
note: "C128 Character Generator Finnish/Swedish. Embedded in core." note: "C128 Character Generator Finnish/Swedish. Embedded in core."
source_ref: "vice/src/c128/c128rom.h:96" source_ref: "vice/src/c128/c128rom.h:96"
@@ -364,6 +448,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2097152 size: 2097152
sha1: 72b4c8da075646cc9940e4377004c81192c7b0b1
md5: d6efbc538195f53cfc209543640cde71
crc32: 242daa5a
note: "C64 DTV flash ROM (2 MB). Contains kernal, basic, chargen. Embedded in core." note: "C64 DTV flash ROM (2 MB). Contains kernal, basic, chargen. Embedded in core."
source_ref: "vice/src/c64dtv/c64dtvflash.c:59-64" source_ref: "vice/src/c64dtv/c64dtvflash.c:59-64"
@@ -373,6 +460,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 79015323128650c742a3694c9429aa91f355905e
md5: 57af4ae21d4b705c2991d98ed5c1f7b8
crc32: f833d117
note: "C64 BASIC V2 ROM (DTV copy). Embedded in core." note: "C64 BASIC V2 ROM (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/" source_ref: "vice/data/C64DTV/"
@@ -382,6 +472,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: adc7c31e18c7c7413d54802ef2f4193da14711aa
md5: 12a4202f5331d45af846af6c58fba946
crc32: ec4272ee
note: "C64 Character Generator (DTV copy). Embedded in core." note: "C64 Character Generator (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/" source_ref: "vice/data/C64DTV/"
@@ -391,6 +484,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 1d503e56df85a62fee696e7618dc5b4e781df1bb
md5: 39065497630802346bce17963f13c092
crc32: dbe3e7c7
note: "C64 Kernal Rev 3 (DTV copy). Embedded in core." note: "C64 Kernal Rev 3 (DTV copy). Embedded in core."
source_ref: "vice/data/C64DTV/" source_ref: "vice/data/C64DTV/"
@@ -404,6 +500,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 587d1e90950675ab6b12d91248a3f0d640d02e8d
md5: 8b9237706f47a9b3498d8f881ef0244d
crc32: db4c43c1
note: "VIC-20 BASIC ROM. Embedded in core." note: "VIC-20 BASIC ROM. Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:43" source_ref: "vice/src/vic20/vic20rom.h:43"
@@ -413,6 +512,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: ce0137ed69f003a299f43538fa9eee27898e621e
md5: f0587624dcd7685710a8fdb35939617f
crc32: 4be07cb4
note: "VIC-20 Kernal PAL (default). Embedded in core." note: "VIC-20 Kernal PAL (default). Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:53" source_ref: "vice/src/vic20/vic20rom.h:53"
@@ -422,6 +524,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 06de7ec017a5e78bd6746d89c2ecebb646efeb19
md5: 0313e31e5f31e1f739c2377792460d67
crc32: e5e7c174
note: "VIC-20 Kernal NTSC. Embedded in core." note: "VIC-20 Kernal NTSC. Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:52" source_ref: "vice/src/vic20/vic20rom.h:52"
@@ -431,6 +536,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: c9ead45e6674d1042ca6199160e8583c23aeac22
md5: 317f93bcbc5ee15da085a51a306f2c61
crc32: 336900d7
note: "VIC-20 Kernal Japanese NTSC Rev 2. Embedded in core." note: "VIC-20 Kernal Japanese NTSC Rev 2. Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:51" source_ref: "vice/src/vic20/vic20rom.h:51"
@@ -440,6 +548,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 4fd85ab6647ee2ac7ba40f729323f2472d35b9b4
md5: d390e340e94e1bef0f2fdfe9fa850993
crc32: 83e032a6
note: "VIC-20 Character Generator (default). Embedded in core." note: "VIC-20 Character Generator (default). Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:56" source_ref: "vice/src/vic20/vic20rom.h:56"
@@ -449,6 +560,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: dae61ac03065aa2904af5c123ce821855898c555
md5: 7e6e41b5b60fec798743afd7063b42ed
crc32: fcfd8a4b
note: "VIC-20 Japanese Character Generator. Embedded in core." note: "VIC-20 Japanese Character Generator. Embedded in core."
source_ref: "vice/src/vic20/vic20rom.h:57" source_ref: "vice/src/vic20/vic20rom.h:57"
@@ -462,6 +576,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 161c96b4ad20f3a4f2321808e37a5ded26a135dd
md5: 44a4ae400e3b4f7533a47ae0df1be78c
crc32: 74eaae87
note: "Plus/4 BASIC ROM. Embedded in core." note: "Plus/4 BASIC ROM. Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:33" source_ref: "vice/src/plus4/plus4rom.h:33"
@@ -471,6 +588,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 7c7e07f016391174a557e790c4ef1cbe33512cdb
md5: 89f5263665a8dc10c8f8abc38f5f7eb9
crc32: 71c07bd4
note: "Plus/4 Kernal PAL Rev 5 (default PAL). Embedded in core." note: "Plus/4 Kernal PAL Rev 5 (default PAL). Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:36" source_ref: "vice/src/plus4/plus4rom.h:36"
@@ -480,6 +600,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: a3d9e5be091b98de39a046ab167fb7632d053682
md5: b3c450c36a88b491281d18fdf3e94ab0
crc32: 70295038
note: "Plus/4 Kernal NTSC Rev 5 (default NTSC). Embedded in core." note: "Plus/4 Kernal NTSC Rev 5 (default NTSC). Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:37" source_ref: "vice/src/plus4/plus4rom.h:37"
@@ -489,6 +612,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 3c77caf72914c1c0a0875b3a7f6935cd30c54201
md5: a213823557421b66f9813ff19af48c01
crc32: dbdc3319
note: "Plus/4 Kernal NTSC Rev 1 (V232 prototype). Embedded in core." note: "Plus/4 Kernal NTSC Rev 1 (V232 prototype). Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:35" source_ref: "vice/src/plus4/plus4rom.h:35"
@@ -498,6 +624,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: b9a5b5dacd57ca117ef0b3af29e91998bf4d7e5f
md5: 7abb51257595b233a1a63ae58c330a65
crc32: 84fd4f7a
note: "Commodore 364 prototype Kernal. Embedded in core." note: "Commodore 364 prototype Kernal. Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:38" source_ref: "vice/src/plus4/plus4rom.h:38"
@@ -507,6 +636,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 3b69f6e7cb4c18bb08e203fb18b7dabfa853390f
md5: 2994d5463ef8524deb4231a9c764767c
crc32: 4fd1d8cb
note: "3-Plus-1 software ROM low. Embedded in core." note: "3-Plus-1 software ROM low. Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:40" source_ref: "vice/src/plus4/plus4rom.h:40"
@@ -516,6 +648,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 0ad7ac2db7da692d972e586ca0dfd747d82c7693
md5: ac34591c820fe607d527e04e95bce465
crc32: 109de2fc
note: "3-Plus-1 software ROM high. Embedded in core." note: "3-Plus-1 software ROM high. Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:41" source_ref: "vice/src/plus4/plus4rom.h:41"
@@ -525,6 +660,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 59af401cbb2194f689898271c6e8aafa28a7af11
md5: 0073ace3874a2c5ca5de9cf64cdfbbd4
crc32: 5227c2ee
note: "Commodore 364 prototype function ROM low. Embedded in core." note: "Commodore 364 prototype function ROM low. Embedded in core."
source_ref: "vice/src/plus4/plus4rom.h:43" source_ref: "vice/src/plus4/plus4rom.h:43"
@@ -538,6 +676,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 3be9cd41b646fefa00d80f1c3433a06146e97c59
md5: f328e785835907006604423222db7bbf
crc32: aff78300
note: "PET BASIC 1.0 ROM (PET 2001). Embedded in core." note: "PET BASIC 1.0 ROM (PET 2001). Embedded in core."
source_ref: "vice/src/pet/petrom.h:55" source_ref: "vice/src/pet/petrom.h:55"
@@ -547,6 +688,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 9322a9f0354b9049847d98d3a045fbec860a6264
md5: b69739387bebe999227ae0cf25aa1e91
crc32: cf35e68b
note: "PET BASIC 2.0 ROM. Embedded in core." note: "PET BASIC 2.0 ROM. Embedded in core."
source_ref: "vice/src/pet/petrom.h:56" source_ref: "vice/src/pet/petrom.h:56"
@@ -556,6 +700,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 12288 size: 12288
sha1: d70bec479e1e3a0d0908a4897066e9959bbc11c8
md5: d22d2a1912a0cdbd9e7c8b103541b2c6
crc32: 2a940f0a
note: "PET BASIC 4.0 ROM. Embedded in core." note: "PET BASIC 4.0 ROM. Embedded in core."
source_ref: "vice/src/pet/petrom.h:57" source_ref: "vice/src/pet/petrom.h:57"
@@ -565,6 +712,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 32dc08828e88c74d6433156e64d402b564556308
md5: 61b7e2fd04d63b0702951ba40899cd72
crc32: f0186492
note: "PET Kernal 1.0 (PET 2001). Embedded in core." note: "PET Kernal 1.0 (PET 2001). Embedded in core."
source_ref: "vice/src/pet/petrom.h:51" source_ref: "vice/src/pet/petrom.h:51"
@@ -574,6 +724,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 38742bdf449f629bcba6276ef24d3daeb7da6e84
md5: 51a38bfef8f9e72cb64bf7d874b4c8c6
crc32: f02238e2
note: "PET Kernal 2.0. Embedded in core." note: "PET Kernal 2.0. Embedded in core."
source_ref: "vice/src/pet/petrom.h:52" source_ref: "vice/src/pet/petrom.h:52"
@@ -583,6 +736,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 96a0fa56e0c937da92971d9c99d504e44e898806
md5: 16ec21443ea5431ab63d511061054e6f
crc32: cc5298a1
note: "PET Kernal 4.0. Embedded in core." note: "PET Kernal 4.0. Embedded in core."
source_ref: "vice/src/pet/petrom.h:53" source_ref: "vice/src/pet/petrom.h:53"
@@ -592,6 +748,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: f02f5fb492ba93dbbd390f24c10f7a832dec432a
md5: ef9bd0e62dfc47eb463fef20d0344826
crc32: 9e1c5cea
note: "PET Editor 1.0 Normal (graphics keyboard). Embedded in core." note: "PET Editor 1.0 Normal (graphics keyboard). Embedded in core."
source_ref: "vice/src/pet/petrom.h:59" source_ref: "vice/src/pet/petrom.h:59"
@@ -601,6 +760,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 5e5502ce32f5a7e387d65efe058916282041e54b
md5: cb8e8404c0b28eda10469792dfd1dbc2
crc32: e459ab32
note: "PET Editor 2.0 Normal (graphics keyboard). Embedded in core." note: "PET Editor 2.0 Normal (graphics keyboard). Embedded in core."
source_ref: "vice/src/pet/petrom.h:60" source_ref: "vice/src/pet/petrom.h:60"
@@ -610,6 +772,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 174ace3a8c0348cd21d39cc864e2adc58b0101a9
md5: 7f87889ca7ee2537f0c1993d35d0fb18
crc32: 05db957e
note: "PET Editor 2.0 Business keyboard. Embedded in core." note: "PET Editor 2.0 Business keyboard. Embedded in core."
source_ref: "vice/src/pet/petrom.h:61" source_ref: "vice/src/pet/petrom.h:61"
@@ -619,6 +784,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 05af284c914d53a52987b5f602466de75765f650
md5: b76d756e7ac8752ae0035f3ce5f1383c
crc32: 3370e359
note: "PET Editor 4.0, 40 col, Normal keyboard, 50Hz. Embedded in core." note: "PET Editor 4.0, 40 col, Normal keyboard, 50Hz. Embedded in core."
source_ref: "vice/src/pet/petrom.h:62" source_ref: "vice/src/pet/petrom.h:62"
@@ -628,6 +796,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 9f91fbabfdd532d003d2508f399574ba8ec6ee5f
md5: 8e69e040489098522846b1b1c63682c2
crc32: 16fb070c
note: "PET Editor 4.0, 40 col, Business keyboard, 50Hz. Embedded in core." note: "PET Editor 4.0, 40 col, Business keyboard, 50Hz. Embedded in core."
source_ref: "vice/src/pet/petrom.h:65" source_ref: "vice/src/pet/petrom.h:65"
@@ -637,6 +808,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 81975eab31a8f4f51ae2a20d099a567c7b3f2dd1
md5: 3a0e2ef328040aa30b30a8134426879a
crc32: 845a44e6
note: "PET Editor 4.0, 80 col, Business keyboard, 50Hz. Embedded in core." note: "PET Editor 4.0, 80 col, Business keyboard, 50Hz. Embedded in core."
source_ref: "vice/src/pet/petrom.h:63" source_ref: "vice/src/pet/petrom.h:63"
@@ -646,6 +820,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 3e067cc621e4beafca2b90cb8f6dba975df2855b
md5: 29a82eb54e73ebc5673c718c489b174b
crc32: 54f32f45
note: "PET Character Generator 1 (original PET 2001). Embedded in core." note: "PET Character Generator 1 (original PET 2001). Embedded in core."
source_ref: "vice/src/pet/petrom.h:46" source_ref: "vice/src/pet/petrom.h:46"
@@ -655,6 +832,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: 0157a2d55b7ac4eaeb38475889ebeea52e2593db
md5: 9880432e633b15998d58884ff34c4e70
crc32: d8408674
note: "PET Character Generator 2. Embedded in core." note: "PET Character Generator 2. Embedded in core."
source_ref: "vice/src/pet/petrom.h:47" source_ref: "vice/src/pet/petrom.h:47"
@@ -664,6 +844,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: bf346f11595a3e65e55d6aeeaa2c0cec807b66c7
md5: dd30641d9e6a221edd725d1e529dcbdb
crc32: ee8229c4
note: "SuperPET Character Generator. Embedded in core." note: "SuperPET Character Generator. Embedded in core."
source_ref: "vice/src/pet/petrom.h:48" source_ref: "vice/src/pet/petrom.h:48"
@@ -673,6 +856,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 0414b3ab847c8977eb05c2fcc72efcf2f9d92871
md5: 6eb1c1bfa6ce1444737794432966dfcc
crc32: 728a998b
note: "SuperPET Waterloo microEngine 6809 ROM at $A000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $A000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:75" source_ref: "vice/src/pet/petrom.h:75"
@@ -682,6 +868,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: df154939b934d0aeeb376813ec1ba0d43c2a3378
md5: 537498d75ecf761d4991f9ebd85129ca
crc32: 6beb7c62
note: "SuperPET Waterloo microEngine 6809 ROM at $B000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $B000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:76" source_ref: "vice/src/pet/petrom.h:76"
@@ -691,6 +880,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 6c5b0cce97068f8841112ba6d5cd8e568b562fa3
md5: 3e8dd04902dc9fee172084698f84695f
crc32: 5db4983d
note: "SuperPET Waterloo microEngine 6809 ROM at $C000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $C000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:77" source_ref: "vice/src/pet/petrom.h:77"
@@ -700,6 +892,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: b42a2050a319a1ffca7868a8d8d635fadd37ec37
md5: 80f4d2351ee19673820989919c7c1e9b
crc32: f55fc559
note: "SuperPET Waterloo microEngine 6809 ROM at $D000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $D000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:78" source_ref: "vice/src/pet/petrom.h:78"
@@ -709,6 +904,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 2048 size: 2048
sha1: e8ce8347451a001214a5e71a13081b38b4be23bc
md5: a740ff5d0d1132ab18cfc1974fca908d
crc32: b2cee903
note: "SuperPET Waterloo microEngine 6809 ROM at $E000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $E000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:79" source_ref: "vice/src/pet/petrom.h:79"
@@ -718,6 +916,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 9b4a5134d20345171e7303445f87c4e0b9addc96
md5: 049e2d26fde71a741f6075ecbf0a432d
crc32: f42df0cb
note: "SuperPET Waterloo microEngine 6809 ROM at $F000. Embedded in core." note: "SuperPET Waterloo microEngine 6809 ROM at $F000. Embedded in core."
source_ref: "vice/src/pet/petrom.h:80" source_ref: "vice/src/pet/petrom.h:80"
@@ -731,6 +932,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 9409f92e167984096fe4d5913714bff6214c3b2d
md5: 3ad5c7182006bcad1597583dbc8505c9
crc32: a8ff9372
note: "CBM-II BASIC 128 (CBM 610/620/710/720). Embedded in core." note: "CBM-II BASIC 128 (CBM 610/620/710/720). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:41" source_ref: "vice/src/cbm2/cbm2rom.h:41"
@@ -740,6 +944,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 53314b4d565cc405a67a0936b935e6e08955580d
md5: 6a505014e543c62e99668080a3b80b40
crc32: 5db15870
note: "CBM-II BASIC 256 (CBM 710/720 with 256K). Embedded in core." note: "CBM-II BASIC 256 (CBM 710/720 with 256K). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:42" source_ref: "vice/src/cbm2/cbm2rom.h:42"
@@ -749,6 +956,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: e69531d45f5993f8e53c6bd9ab2a7bc10fe2d02f
md5: 5a9559ceaf1a0bef0e721242c67a030d
crc32: 9a468e5d
note: "CBM-II BASIC 500 (CBM 510/P500). Embedded in core." note: "CBM-II BASIC 500 (CBM 510/P500). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:43" source_ref: "vice/src/cbm2/cbm2rom.h:43"
@@ -758,6 +968,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: abb26418b9e1614a8f52bdeee0822d4a96071439
md5: e0346953e77bd1353ebf53aaa5b6f0b0
crc32: 09a5667e
note: "CBM-II Kernal (CBM 610/620/710/720). Embedded in core." note: "CBM-II Kernal (CBM 610/620/710/720). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:45" source_ref: "vice/src/cbm2/cbm2rom.h:45"
@@ -767,6 +980,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: 097197d4d08e0b82e0466a5f1fbd49a24f3d2523
md5: 1a19593625acdc5af96a5e78b1a23f37
crc32: f46bbd2b
note: "CBM-II Kernal 500 (CBM 510/P500). Embedded in core." note: "CBM-II Kernal 500 (CBM 510/P500). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:46" source_ref: "vice/src/cbm2/cbm2rom.h:46"
@@ -776,6 +992,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: adc7c31e18c7c7413d54802ef2f4193da14711aa
md5: 12a4202f5331d45af846af6c58fba946
crc32: ec4272ee
note: "CBM-II Character Generator 500 (VIC-II based, CBM 510/P500). Embedded in core." note: "CBM-II Character Generator 500 (VIC-II based, CBM 510/P500). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:37" source_ref: "vice/src/cbm2/cbm2rom.h:37"
@@ -785,6 +1004,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: e63bf18da48e5a53c99ef127c1ae721333d1d102
md5: 2818722af27ceae6952c08cf83a076f9
crc32: 1acf5098
note: "CBM-II Character Generator 600 (CBM 610/620). Embedded in core." note: "CBM-II Character Generator 600 (CBM 610/620). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:38" source_ref: "vice/src/cbm2/cbm2rom.h:38"
@@ -794,6 +1016,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: e7f3cbc8e282f79a00c3e95d75c8d725ee3c6287
md5: 03f32477905d77e2135857076ec31efa
crc32: 3a350bc3
note: "CBM-II Character Generator 700 (CBM 710/720). Embedded in core." note: "CBM-II Character Generator 700 (CBM 710/720). Embedded in core."
source_ref: "vice/src/cbm2/cbm2rom.h:39" source_ref: "vice/src/cbm2/cbm2rom.h:39"
@@ -807,6 +1032,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 65536 size: 65536
sha1: f5b6da17ee8206ff0d2258e1d6e8b798147c2650
md5: 006862e9a52d987970435988e3803c71
crc32: 89c1a062
note: "SuperCPU64 internal ROM (default). Embedded in core." note: "SuperCPU64 internal ROM (default). Embedded in core."
source_ref: "retrodep/ui.c:269" source_ref: "retrodep/ui.c:269"
@@ -816,6 +1044,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: adc7c31e18c7c7413d54802ef2f4193da14711aa
md5: 12a4202f5331d45af846af6c58fba946
crc32: ec4272ee
note: "C64 Character Generator (used by SCPU64). Embedded in core." note: "C64 Character Generator (used by SCPU64). Embedded in core."
source_ref: "vice/src/scpu64/scpu64rom.h:36" source_ref: "vice/src/scpu64/scpu64rom.h:36"
@@ -825,6 +1056,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 4096 size: 4096
sha1: 0fad19dbcdb12461c99657b2979dbb5c2e47b527
md5: cf32a93c0a693ed359a4f483ef6db53d
crc32: 1604f6c1
note: "C64 Japanese Character Generator (used by SCPU64). Embedded in core." note: "C64 Japanese Character Generator (used by SCPU64). Embedded in core."
source_ref: "vice/src/scpu64/scpu64rom.h:37" source_ref: "vice/src/scpu64/scpu64rom.h:37"
@@ -854,6 +1088,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: 3477c14e0c79faa445224dad16534f04ed143e44
md5: 87e849da3c87549848550fe4dd4d1aae
crc32: 718d42b1
note: "1540 drive DOS ROM. Embedded in core." note: "1540 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:88" source_ref: "vice/src/drive/driverom.h:88"
@@ -863,6 +1100,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: ab16f56989b27d89babe5f89c5a8cb3da71a82f0
md5: a0ce8439d1b8dcf2e1430461f7233a72
crc32: 57224cde
note: "1541 drive DOS ROM. Embedded in core." note: "1541 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:89" source_ref: "vice/src/drive/driverom.h:89"
@@ -872,6 +1112,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: d3b78c3dbac55f5199f33f3fe0036439811f7fb3
md5: ada295382a1f2df772a7e5c5c6f34215
crc32: 899fa3c5
note: "1541-II drive DOS ROM. Embedded in core." note: "1541-II drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:90" source_ref: "vice/src/drive/driverom.h:90"
@@ -881,6 +1124,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: fae3c788ad9a6cc2dbdfbcf6c0264b2ca921d55e
md5: 0c767bf0a84d7751af056e53a074c9e2
crc32: 6d16d024
note: "1551 drive DOS ROM (Plus/4 specific). Embedded in core." note: "1551 drive DOS ROM (Plus/4 specific). Embedded in core."
source_ref: "vice/src/drive/driverom.h:92" source_ref: "vice/src/drive/driverom.h:92"
@@ -890,6 +1136,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 32768 size: 32768
sha1: 5fc06dc82ff6840f183bd43a4d9b8a16956b2f56
md5: f0799353f0e22cf7d783e447adcafde2
crc32: 5a0c7937
note: "1570 drive DOS ROM. Embedded in core." note: "1570 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:93" source_ref: "vice/src/drive/driverom.h:93"
@@ -899,6 +1148,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 32768 size: 32768
sha1: f1be619c106641a685f6609e4d43d6fc9eac1e70
md5: dae964d64b7843ff86c008d396dda208
crc32: 5755bae3
note: "1571 drive DOS ROM. Embedded in core." note: "1571 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:94" source_ref: "vice/src/drive/driverom.h:94"
@@ -908,6 +1160,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 32768 size: 32768
sha1: 14ee7a0fb7e1c59c51fbf781f944387037daa3ee
md5: f9158328494b3e269f86ef419792c2e5
crc32: f24efcc4
note: "1571CR drive DOS ROM (cost-reduced, C128D internal). Embedded in core." note: "1571CR drive DOS ROM (cost-reduced, C128D internal). Embedded in core."
source_ref: "vice/src/drive/driverom.h:95" source_ref: "vice/src/drive/driverom.h:95"
@@ -917,6 +1172,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 32768 size: 32768
sha1: 01228eae6f066bd9b7b2b6a7fa3f667e41dad393
md5: 6a82f92aea2a3afa190fe32d565f39e7
crc32: a9011b84
note: "1581 drive DOS ROM. Embedded in core." note: "1581 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:96" source_ref: "vice/src/drive/driverom.h:96"
@@ -926,6 +1184,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: d50b093828888146596f17ae0df9ef3dfde71b05
md5: 2d967790361aa77de87a24fb93e342f9
crc32: 87e6a94e
note: "CBM 1001 (SFD-1001) drive DOS ROM. Embedded in core." note: "CBM 1001 (SFD-1001) drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:70" source_ref: "vice/src/drive/driverom.h:70"
@@ -935,6 +1196,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: c53e180a96649ceb3f421739e8dc66faba7cba44
md5: 3454c06fd2275f5bcbfe936dcdf8059b
crc32: 21b80fdf
note: "CBM 2031 drive DOS ROM. Embedded in core." note: "CBM 2031 drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:73" source_ref: "vice/src/drive/driverom.h:73"
@@ -944,6 +1208,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 8192 size: 8192
sha1: e37b3bfd801eb19dea50cf8b4a6af8613c3520d3
md5: 3efff682000fd841b4dd6560bf53e37c
crc32: d04c1fbb
note: "CBM 2040 dual drive DOS ROM. Embedded in core." note: "CBM 2040 dual drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:76" source_ref: "vice/src/drive/driverom.h:76"
@@ -953,6 +1220,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 12288 size: 12288
sha1: 02bd4b0c8508b3874b95799a9a63caf369c837de
md5: 139e72a58b7ddb2f92ceb18c8735c53c
crc32: f4967a7f
note: "CBM 3040 dual drive DOS ROM. Embedded in core." note: "CBM 3040 dual drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:79" source_ref: "vice/src/drive/driverom.h:79"
@@ -962,6 +1232,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 12288 size: 12288
sha1: 245abbe76581558d270cdbb6fe55f56748403d8e
md5: 2fce6a76c738d1a10c189bf0660d868e
crc32: 40e0ebaa
note: "CBM 4040 dual drive DOS ROM. Embedded in core." note: "CBM 4040 dual drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:82" source_ref: "vice/src/drive/driverom.h:82"
@@ -971,6 +1244,9 @@ files:
hle_fallback: true hle_fallback: true
embedded: true embedded: true
size: 16384 size: 16384
sha1: c48df2cbb0eea656c3243df7ea8bfefcd171b8e8
md5: d6d4df6f2811767de6f5bf46ad7fba69
crc32: 632a328e
note: "CBM D9090/D9060 hard drive DOS ROM. Embedded in core." note: "CBM D9090/D9060 hard drive DOS ROM. Embedded in core."
source_ref: "vice/src/drive/driverom.h:85" source_ref: "vice/src/drive/driverom.h:85"

View File

@@ -397,5 +397,6 @@ files:
system: dragon64 system: dragon64
description: "Ikon Ultra Drive Dragonfly ROM 2.3" description: "Ikon Ultra Drive Dragonfly ROM 2.3"
required: false required: false
unsourceable: "not yet dumped, only v1.3 publicly available, XRoar support is experimental (#ifdef WANT_EXPERIMENTAL)"
source_ref: "xroar.c:715 (romlist ikon), ikon.c:151 (default @ikon)" source_ref: "xroar.c:715 (romlist ikon), ikon.c:151 (default @ikon)"
note: "Experimental. Ikon Ultra Drive storage interface. Older version: dragonfly-1.3." note: "Experimental. Ikon Ultra Drive storage interface. Older version: dragonfly-1.3."

View File

@@ -138,6 +138,8 @@ files:
- name: Custom.dat - name: Custom.dat
path: zc210/sfx/Custom.dat path: zc210/sfx/Custom.dat
category: game_data
description: user-provided custom SFX replacement description: user-provided custom SFX replacement
required: false required: false
unsourceable: "user placeholder slot, README says 'rename your own SFX dat file to this name'"
source_ref: "zelda.cpp:1193-1218, libretro.cpp:148" source_ref: "zelda.cpp:1193-1218, libretro.cpp:148"

View File

@@ -101,4 +101,50 @@ foreach ($f in $toDownload) {
} }
} }
# Standalone emulator copies
if ($manifest.standalone_copies) {
Write-Host "`nStandalone emulators:"
foreach ($entry in $manifest.standalone_copies) {
if ($entry.note) {
$detectPaths = @()
if ($entry.detect -and $entry.detect.windows) {
$detectPaths = $entry.detect.windows
}
foreach ($dp in $detectPaths) {
$expanded = [Environment]::ExpandEnvironmentVariables($dp)
if (Test-Path $expanded) {
Write-Host " $($entry.note)"
break
}
}
continue
}
$sources = @()
if ($entry.pattern) {
$sources = Get-ChildItem -Path $biosPath -Filter $entry.pattern -File -ErrorAction SilentlyContinue
} elseif ($entry.file) {
$src = Join-Path $biosPath $entry.file
if (Test-Path $src) { $sources = @(Get-Item $src) }
}
if ($sources.Count -eq 0) { continue }
$targetDirs = @()
if ($entry.targets -and $entry.targets.windows) {
$targetDirs = $entry.targets.windows
}
foreach ($td in $targetDirs) {
$expanded = [Environment]::ExpandEnvironmentVariables($td)
if (-not (Test-Path $expanded)) { continue }
foreach ($s in $sources) {
$dest = Join-Path $expanded $s.Name
try {
Copy-Item $s.FullName $dest -Force
Write-Host " $($s.Name) -> $expanded"
} catch {
Write-Host " $($s.Name) -> $expanded FAILED" -ForegroundColor Red
}
}
}
}
}
Write-Host "`nDone. $downloaded downloaded, $upToDate already up to date." Write-Host "`nDone. $downloaded downloaded, $upToDate already up to date."

View File

@@ -192,9 +192,9 @@ def detect_platforms(os_type: str) -> list[tuple[str, Path]]:
if retrodeck_cfg.exists(): if retrodeck_cfg.exists():
bios_path = _parse_bash_var(retrodeck_cfg, "rdhome") bios_path = _parse_bash_var(retrodeck_cfg, "rdhome")
if bios_path: if bios_path:
found.append(("retrodeck", Path(bios_path) / "bios")) found.append(("retrodeck", Path(bios_path)))
else: else:
found.append(("retrodeck", home / "retrodeck" / "bios")) found.append(("retrodeck", home / "retrodeck"))
# RetroArch Flatpak # RetroArch Flatpak
flatpak_cfg = home / ".var" / "app" / "org.libretro.RetroArch" / "config" / "retroarch" / "retroarch.cfg" flatpak_cfg = home / ".var" / "app" / "org.libretro.RetroArch" / "config" / "retroarch" / "retroarch.cfg"
@@ -390,8 +390,16 @@ def do_standalone_copies(
) -> tuple[int, int]: ) -> tuple[int, int]:
"""Copy BIOS files to standalone emulator directories. """Copy BIOS files to standalone emulator directories.
Supports:
- file: single file copy
- pattern: glob match (e.g. "scph*.bin")
- note: informational message when detect path exists
- WSL fallback to linux targets
Returns (copied_count, skipped_count). Returns (copied_count, skipped_count).
""" """
from fnmatch import fnmatch
copies = manifest.get("standalone_copies", []) copies = manifest.get("standalone_copies", [])
if not copies: if not copies:
return 0, 0 return 0, 0
@@ -400,21 +408,48 @@ def do_standalone_copies(
skipped = 0 skipped = 0
for entry in copies: for entry in copies:
src = bios_path / entry["file"] # Note entries: print message if emulator detected
if not src.exists(): if "note" in entry:
detect_paths = entry.get("detect", {}).get(os_type, [])
if not detect_paths and os_type == "wsl":
detect_paths = entry.get("detect", {}).get("linux", [])
for dp in detect_paths:
expanded = Path(os.path.expandvars(os.path.expanduser(dp)))
if expanded.is_dir():
print(f" {entry['note']}")
break
continue continue
# Resolve source files
if "pattern" in entry:
sources = [
f for f in bios_path.rglob("*")
if fnmatch(f.name, entry["pattern"]) and f.is_file()
]
else:
src = bios_path / entry["file"]
sources = [src] if src.exists() else []
if not sources:
continue
# Resolve target directories with WSL fallback
targets = entry.get("targets", {}).get(os_type, []) targets = entry.get("targets", {}).get(os_type, [])
if not targets and os_type == "wsl":
targets = entry.get("targets", {}).get("linux", [])
for target_dir_str in targets: for target_dir_str in targets:
target_dir = Path(os.path.expandvars(os.path.expanduser(target_dir_str))) target_dir = Path(os.path.expandvars(os.path.expanduser(target_dir_str)))
if target_dir.is_dir(): if not target_dir.is_dir():
skipped += len(sources)
continue
for src in sources:
dest = target_dir / src.name dest = target_dir / src.name
try: try:
shutil.copy2(src, dest) shutil.copy2(src, dest)
copied += 1 copied += 1
except OSError: except OSError:
skipped += 1 skipped += 1
else:
skipped += 1
return copied, skipped return copied, skipped

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "batocera", "platform": "batocera",
"display_name": "Batocera", "display_name": "Batocera",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:32:22Z", "generated": "2026-04-18T07:55:01Z",
"base_destination": "bios", "base_destination": "bios",
"detect": [ "detect": [
{ {
@@ -13,9 +14,224 @@
"bios_path": "/userdata/bios" "bios_path": "/userdata/bios"
} }
], ],
"standalone_copies": [], "standalone_copies": [
"total_files": 1524, {
"total_size": 3888134489, "file": "prod.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys",
"$HOME/.config/Ryujinx/system"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys",
"%APPDATA%\\Ryujinx\\system"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys",
"$HOME/Library/Application Support/Ryujinx/system"
]
}
},
{
"file": "title.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys"
]
}
},
{
"file": "Citra/sysdata/aes_keys.txt",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"file": "Citra/sysdata/boot9.bin",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"pattern": "scph*.bin",
"targets": {
"linux": [
"$HOME/.local/share/duckstation/bios"
],
"windows": [
"%LOCALAPPDATA%\\DuckStation\\bios",
"%USERPROFILE%\\Documents\\DuckStation\\bios"
],
"darwin": [
"$HOME/Library/Application Support/DuckStation/bios"
]
}
},
{
"pattern": "ps2-*.bin",
"targets": {
"linux": [
"$HOME/.config/PCSX2/bios",
"$HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios"
],
"windows": [
"%USERPROFILE%\\Documents\\PCSX2\\bios"
],
"darwin": [
"$HOME/Library/Application Support/PCSX2/bios"
]
}
},
{
"note": "PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.",
"detect": {
"linux": [
"$HOME/.config/rpcs3"
],
"windows": [
"%APPDATA%\\rpcs3"
]
}
},
{
"file": "GC/USA/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/USA"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\USA"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/USA"
]
}
},
{
"file": "GC/EUR/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/EUR"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\EUR"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/EUR"
]
}
},
{
"file": "GC/JAP/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/JAP"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\JAP"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/JAP"
]
}
},
{
"file": "dsp_rom.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "dsp_coef.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "PPSSPP/ppge_atlas.zim",
"targets": {
"linux": [
"$HOME/.config/ppsspp/PSP/SYSTEM"
],
"windows": [
"%USERPROFILE%\\Documents\\PPSSPP\\PSP\\SYSTEM"
],
"darwin": [
"$HOME/Library/Application Support/PPSSPP/PSP/SYSTEM"
]
}
},
{
"file": "dc/dc_boot.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
},
{
"file": "dc/dc_nvmem.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
}
],
"total_files": 1540,
"total_size": 4337691265,
"files": [ "files": [
{ {
"dest": "panafz1.bin", "dest": "panafz1.bin",
@@ -864,13 +1080,6 @@
"repo_path": "bios/Elektronika/BK/MONIT10.ROM", "repo_path": "bios/Elektronika/BK/MONIT10.ROM",
"cores": null "cores": null
}, },
{
"dest": "bk0010.zip",
"sha1": "4aa3cec86fb5eb0cec7d7b3c8ddfe28b7f1c7963",
"size": 74578,
"repo_path": "bios/Arcade/MAME/bk0010.zip",
"cores": null
},
{ {
"dest": "lynx48k.zip", "dest": "lynx48k.zip",
"sha1": "64947e9b7d17870839aba5d93217183d480ff897", "sha1": "64947e9b7d17870839aba5d93217183d480ff897",
@@ -2307,7 +2516,7 @@
"dest": "psvita/PSP2UPDAT.PUP", "dest": "psvita/PSP2UPDAT.PUP",
"sha1": "ed3a4cb264fff283209f10ae58c96c6090fed187", "sha1": "ed3a4cb264fff283209f10ae58c96c6090fed187",
"size": 56778752, "size": 56778752,
"repo_path": "", "repo_path": "bios/Sony/PlayStation Vita/PSP2UPDAT.PUP",
"cores": null, "cores": null,
"storage": "release", "storage": "release",
"release_asset": "PSP2UPDAT.PUP" "release_asset": "PSP2UPDAT.PUP"
@@ -2595,6 +2804,15 @@
"Amiberry" "Amiberry"
] ]
}, },
{
"dest": "kick31.rom",
"sha1": "3b7f1493b27e212830f989f26ca76c02049f09ca",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/kick31.rom",
"cores": [
"Amiberry"
]
},
{ {
"dest": "kick.rom", "dest": "kick.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785", "sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
@@ -2902,10 +3120,19 @@
] ]
}, },
{ {
"dest": "Machines/Shared Roms/MSX2R2.ROM", "dest": "Machines/Shared Roms/MSX2J.rom",
"sha1": "04990aa1c3a3fc7294ec884b81deaa89832df614", "sha1": "0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSXR2.rom", "repo_path": "bios/Microsoft/MSX/.variants/MSX2.ROM.0081ea0d",
"cores": [
"blueMSX"
]
},
{
"dest": "Machines/Shared Roms/MSX2R2.ROM",
"sha1": "ebb7eb540a390509edfd36c84288ba85e63f2d1f",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2R2.ROM",
"cores": [ "cores": [
"blueMSX" "blueMSX"
] ]
@@ -4116,6 +4343,15 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "AmstradCPC/os464.rom", "dest": "AmstradCPC/os464.rom",
"sha1": "475c8080065a7aa9984daca0415a3d70a5305be2", "sha1": "475c8080065a7aa9984daca0415a3d70a5305be2",
@@ -4170,6 +4406,15 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "AmstradCPC/amsdos.rom",
"sha1": "39102c8e9cb55fcc0b9b62098780ed4a3cb6a4bb",
"size": 16384,
"repo_path": "bios/Amstrad/CPC/amsdos.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "AppleII/apple2o.rom", "dest": "AppleII/apple2o.rom",
"sha1": "78008be557f643e956a106121bcc182c0fb9ea6d", "sha1": "78008be557f643e956a106121bcc182c0fb9ea6d",
@@ -4206,6 +4451,33 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "AppleII/apple2-character.rom",
"sha1": "f9d312f128c9557d9d6ac03bfad6c3ddf83e5659",
"size": 2048,
"repo_path": "bios/Apple/Apple II/apple2-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleII/apple2eu-character.rom",
"sha1": "7060de104046736529c1e8a687a0dd7b84f8c51b",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2eu-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleII/apple2e-character.rom",
"sha1": "b2b5d87f52693817fc747df087a4aa1ddcdb1f10",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2e-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "AppleII/scsi.rom", "dest": "AppleII/scsi.rom",
"sha1": "3d7166f05daad1b022fa04c2569e788580158095", "sha1": "3d7166f05daad1b022fa04c2569e788580158095",
@@ -4233,6 +4505,24 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "AppleIIgs/apple2gs.chr",
"sha1": "34e2443e2ef960a36c047a09ed5a93f471797f89",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2gs.chr",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleIIgs/341s0632-2",
"sha1": "141d18c36a617ab9dce668445440d34354be0672",
"size": 4096,
"repo_path": "bios/Apple/Apple II/341s0632-2",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "AtariST/tos100.img", "dest": "AtariST/tos100.img",
"sha1": "9a6e4c88533a9eaa4d55cdc040e47443e0226eb2", "sha1": "9a6e4c88533a9eaa4d55cdc040e47443e0226eb2",
@@ -4269,6 +4559,15 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "DiskII/state-machine-16.rom",
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
"size": 256,
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "DiskII/boot-13.rom", "dest": "DiskII/boot-13.rom",
"sha1": "afd060e6f35faf3bb0146fa889fc787adf56330a", "sha1": "afd060e6f35faf3bb0146fa889fc787adf56330a",
@@ -4296,6 +4595,15 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "Enterprise/exos20.bin",
"sha1": "6033a0535136c40c47137e4d1cd9273c06d5fdff",
"size": 32768,
"repo_path": "bios/Enterprise/64-128/exos20.bin",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "Enterprise/exos23.bin", "dest": "Enterprise/exos23.bin",
"sha1": "c6241e1c248193108ce38b9a8e9dd33972cf47ba", "sha1": "c6241e1c248193108ce38b9a8e9dd33972cf47ba",
@@ -4414,7 +4722,7 @@
] ]
}, },
{ {
"dest": "MSX/msx.rom", "dest": "MSX/MSX.ROM",
"sha1": "409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498", "sha1": "409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX.ROM", "repo_path": "bios/Microsoft/MSX/MSX.ROM",
@@ -4422,6 +4730,15 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "MSX/msx-japanese.rom",
"sha1": "302afb5d8be26c758309ca3df611ae69cced2821",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/CLK/msx-japanese.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "MSX/msx-american.rom", "dest": "MSX/msx-american.rom",
"sha1": "3656bb3bbc17d280d2016fe4f6ff3cded3082a41", "sha1": "3656bb3bbc17d280d2016fe4f6ff3cded3082a41",
@@ -4450,7 +4767,7 @@
] ]
}, },
{ {
"dest": "MSX/msx2.rom", "dest": "MSX/MSX2.ROM",
"sha1": "6103b39f1e38d1aa2d84b1c3219c44f1abb5436e", "sha1": "6103b39f1e38d1aa2d84b1c3219c44f1abb5436e",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2.ROM", "repo_path": "bios/Microsoft/MSX/MSX2.ROM",
@@ -4459,7 +4776,7 @@
] ]
}, },
{ {
"dest": "MSX/msx2ext.rom", "dest": "MSX/MSX2EXT.ROM",
"sha1": "5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02", "sha1": "5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02",
"size": 16384, "size": 16384,
"repo_path": "bios/Microsoft/MSX/MSX2EXT.ROM", "repo_path": "bios/Microsoft/MSX/MSX2EXT.ROM",
@@ -5171,6 +5488,15 @@
"DuckStation" "DuckStation"
] ]
}, },
{
"dest": "scph1001_v20.bin",
"sha1": "649895efd79d14790eabb362e94eb0622093dfb9",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1001_v20.bin",
"cores": [
"DuckStation"
]
},
{ {
"dest": "scph3500.bin", "dest": "scph3500.bin",
"sha1": "e38466a4ba8005fba7e9e3c7b9efeba7205bee3f", "sha1": "e38466a4ba8005fba7e9e3c7b9efeba7205bee3f",
@@ -6046,6 +6372,39 @@
"FinalBurn Neo" "FinalBurn Neo"
] ]
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "gamegenie.nes", "dest": "gamegenie.nes",
"sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779", "sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779",
@@ -6091,6 +6450,15 @@
"fMSX" "fMSX"
] ]
}, },
{
"dest": "MSX2PEXT.ROM",
"sha1": "fe0254cbfc11405b79e7c86c7769bd6322b04995",
"size": 16384,
"repo_path": "bios/Microsoft/MSX/MSX2PEXT.ROM",
"cores": [
"fMSX"
]
},
{ {
"dest": "DISK.ROM", "dest": "DISK.ROM",
"sha1": "032cb1c1c75b9a191fa1230978971698d9d2a17f", "sha1": "032cb1c1c75b9a191fa1230978971698d9d2a17f",
@@ -6658,6 +7026,15 @@
"Genesis Plus GX" "Genesis Plus GX"
] ]
}, },
{
"dest": "ROM",
"sha1": "e4fc7560b69d062cb2da5b1ffbe11cd1ca03cc37",
"size": 131072,
"repo_path": "bios/Apple/Apple IIGS/ROM",
"cores": [
"GSplus"
]
},
{ {
"dest": "c600.rom", "dest": "c600.rom",
"sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16", "sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16",
@@ -8269,6 +8646,24 @@
"NXEngine" "NXEngine"
] ]
}, },
{
"dest": "nxengine/data/sprites.sif",
"sha1": "73acccee601b56a2b7f624b0227fa7e1d662ef4b",
"size": 59482,
"repo_path": "bios/Other/NXEngine/nxengine/data/sprites.sif",
"cores": [
"NXEngine"
]
},
{
"dest": "nxengine/tilekey.dat",
"sha1": "74c14b15dbc2f36c81d2ad9cb65e2893298415da",
"size": 1028,
"repo_path": "bios/Other/NXEngine/nxengine/tilekey.dat",
"cores": [
"NXEngine"
]
},
{ {
"dest": "NMS8245SystemROM1.08.bin", "dest": "NMS8245SystemROM1.08.bin",
"sha1": "cc57c1dcd7249ea9f8e2547244592e7d97308ed0", "sha1": "cc57c1dcd7249ea9f8e2547244592e7d97308ed0",
@@ -8413,6 +8808,15 @@
"PicoDrive" "PicoDrive"
] ]
}, },
{
"dest": "SegaCDBIOS9303.bin",
"sha1": "5adb6c3af218c60868e6b723ec47e36bbdf5e6f0",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/SegaCDBIOS9303.bin",
"cores": [
"PicoDrive"
]
},
{ {
"dest": "us_scd1_9210.bin", "dest": "us_scd1_9210.bin",
"sha1": "f4f315adcef9b8feb0364c21ab7f0eaf5457f3ed", "sha1": "f4f315adcef9b8feb0364c21ab7f0eaf5457f3ed",
@@ -8710,6 +9114,15 @@
"QUASI88" "QUASI88"
] ]
}, },
{
"dest": "dc_bios.bin",
"sha1": "8951d1bb219ab2ff8583033d2119c899cc81f18c",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/dc_bios.bin",
"cores": [
"Redream"
]
},
{ {
"dest": "same_cdi/bios/cdimono2.zip", "dest": "same_cdi/bios/cdimono2.zip",
"sha1": "9492247203b71c12d88fad0a5437376941c7870a", "sha1": "9492247203b71c12d88fad0a5437376941c7870a",
@@ -8863,6 +9276,15 @@
"shadps4" "shadps4"
] ]
}, },
{
"dest": "BIOS.col",
"sha1": "45bedc4cbdeac66c7df59e9e599195c778d86a92",
"size": 8192,
"repo_path": "bios/Coleco/ColecoVision/BIOS.col",
"cores": [
"SMS Plus GX"
]
},
{ {
"dest": "squirreljme-0.3.0-fast.jar", "dest": "squirreljme-0.3.0-fast.jar",
"sha1": "7c4cd0a5451eedeac9b328f48408dbc312198ccf", "sha1": "7c4cd0a5451eedeac9b328f48408dbc312198ccf",
@@ -8953,69 +9375,6 @@
"SquirrelJME" "SquirrelJME"
] ]
}, },
{
"dest": "kvs1.wav",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs2.wav",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs3.wav",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb1.wav",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb2.wav",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb3.wav",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvshared.wav",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
]
},
{ {
"dest": "KVS1.WAV", "dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604", "sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
@@ -9079,6 +9438,15 @@
"Stella 2023" "Stella 2023"
] ]
}, },
{
"dest": "MYTOWNS.ROM",
"sha1": "e245f8086df57ce6e48853f0e13525f738e5c4d8",
"size": 32,
"repo_path": "bios/Fujitsu/FM Towns/MYTOWNS.ROM",
"cores": [
"tsugaru"
]
},
{ {
"dest": "FMT_ALL.ROM", "dest": "FMT_ALL.ROM",
"sha1": "262aae14f334bc21499f7e2bfe8b7ec1079b1e04", "sha1": "262aae14f334bc21499f7e2bfe8b7ec1079b1e04",
@@ -10159,6 +10527,15 @@
"Vircon32" "Vircon32"
] ]
}, },
{
"dest": "xmil/IPLROM.X1T",
"sha1": "44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3",
"size": 32768,
"repo_path": "bios/Sharp/X1/.variants/IPLROM.X1T.44620f57",
"cores": [
"X Millennium"
]
},
{ {
"dest": "xmil/FNT0808.X1", "dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2", "sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
@@ -10276,6 +10653,24 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "bas13.rom",
"sha1": "28b92bebe35fa4f026a084416d6ea3b1552b63d3",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/bas13.rom",
"cores": [
"XRoar"
]
},
{
"dest": "bas12.rom",
"sha1": "0f14dc46c647510eb0b7bd3f53e33da07907d04f",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/bas12.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "bas11.rom", "dest": "bas11.rom",
"sha1": "cecb7c24ff1e0ab5836e4a7a8eb1b8e01f1fded3", "sha1": "cecb7c24ff1e0ab5836e4a7a8eb1b8e01f1fded3",
@@ -10285,6 +10680,24 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "bas10.rom",
"sha1": "1f08455cd48ce6a06132aea15c4778f264e19539",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/bas10.rom",
"cores": [
"XRoar"
]
},
{
"dest": "extbas11.rom",
"sha1": "ad927fb4f30746d820cb8b860ebb585e7f095dea",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/extbas11.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "extbas10.rom", "dest": "extbas10.rom",
"sha1": "7275f1e3f165ff6a4657e4e5e24cb8b817239f54", "sha1": "7275f1e3f165ff6a4657e4e5e24cb8b817239f54",
@@ -10294,6 +10707,42 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "coco3.rom",
"sha1": "e0d82953fb6fd03768604933df1ce8bc51fc427d",
"size": 32768,
"repo_path": "bios/Tandy/CoCo/coco3.rom",
"cores": [
"XRoar"
]
},
{
"dest": "coco3p.rom",
"sha1": "631e383068b1f52a8f419f4114b69501b21cf379",
"size": 32768,
"repo_path": "bios/Tandy/CoCo/coco3p.rom",
"cores": [
"XRoar"
]
},
{
"dest": "mc10.rom",
"sha1": "4afff2b4c120334481aab7b02c3552bf76f1bc43",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/mc10.rom",
"cores": [
"XRoar"
]
},
{
"dest": "alice.rom",
"sha1": "c2166b91e6396a311f486832012aa43e0d2b19f8",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/alice.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "deluxe.rom", "dest": "deluxe.rom",
"sha1": "d89196292b9ebd787647cf91bbb83c63da2b4390", "sha1": "d89196292b9ebd787647cf91bbb83c63da2b4390",
@@ -10366,6 +10815,15 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "disk11.rom",
"sha1": "10bdc5aa2d7d7f205f67b47b19003a4bd89defd1",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/disk11.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "hdbdw3bck.rom", "dest": "hdbdw3bck.rom",
"sha1": "8fd64f1c246489e0bf2b3743ae76332ff324716a", "sha1": "8fd64f1c246489e0bf2b3743ae76332ff324716a",
@@ -10411,6 +10869,15 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "delta2.rom",
"sha1": "686ebb5f39dd4fc907a0b748867d0a022d2f1a60",
"size": 8192,
"repo_path": "bios/Dragon/Dragon/delta2.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "cp450dsk.rom", "dest": "cp450dsk.rom",
"sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b", "sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b",
@@ -10996,69 +11463,6 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AmstradCPC/amsdos.rom",
"sha1": "39102c8e9cb55fcc0b9b62098780ed4a3cb6a4bb",
"size": 16384,
"repo_path": "bios/Amstrad/CPC/amsdos.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleII/apple2-character.rom",
"sha1": "f9d312f128c9557d9d6ac03bfad6c3ddf83e5659",
"size": 2048,
"repo_path": "bios/Apple/Apple II/apple2-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleII/apple2eu-character.rom",
"sha1": "7060de104046736529c1e8a687a0dd7b84f8c51b",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2eu-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleII/apple2e-character.rom",
"sha1": "b2b5d87f52693817fc747df087a4aa1ddcdb1f10",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2e-character.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleIIgs/apple2gs.chr",
"sha1": "34e2443e2ef960a36c047a09ed5a93f471797f89",
"size": 4096,
"repo_path": "bios/Apple/Apple II/apple2gs.chr",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "AppleIIgs/341s0632-2",
"sha1": "141d18c36a617ab9dce668445440d34354be0672",
"size": 4096,
"repo_path": "bios/Apple/Apple II/341s0632-2",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "ColecoVision/coleco.rom", "dest": "ColecoVision/coleco.rom",
"sha1": "45bedc4cbdeac66c7df59e9e599195c778d86a92", "sha1": "45bedc4cbdeac66c7df59e9e599195c778d86a92",
@@ -11068,33 +11472,6 @@
"Clock Signal (CLK)" "Clock Signal (CLK)"
] ]
}, },
{
"dest": "DiskII/state-machine-16.rom",
"sha1": "bc39fbd5b9a8d2287ac5d0a42e639fc4d3c2f9d4",
"size": 256,
"repo_path": "bios/Apple/Apple II/DiskII/state-machine-16.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "Enterprise/exos20.bin",
"sha1": "6033a0535136c40c47137e4d1cd9273c06d5fdff",
"size": 32768,
"repo_path": "bios/Enterprise/64-128/exos20.bin",
"cores": [
"Clock Signal (CLK)"
]
},
{
"dest": "MSX/msx-japanese.rom",
"sha1": "302afb5d8be26c758309ca3df611ae69cced2821",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/CLK/msx-japanese.rom",
"cores": [
"Clock Signal (CLK)"
]
},
{ {
"dest": "GBA/gba_bios.bin", "dest": "GBA/gba_bios.bin",
"sha1": "300c20df6731a33952ded8c436f7f186d25d3492", "sha1": "300c20df6731a33952ded8c436f7f186d25d3492",
@@ -11419,15 +11796,6 @@
"ScummVM" "ScummVM"
] ]
}, },
{
"dest": "xmil/IPLROM.X1T",
"sha1": "44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3",
"size": 32768,
"repo_path": "bios/Sharp/X1/.variants/IPLROM.X1T.44620f57",
"cores": [
"X Millennium"
]
},
{ {
"dest": "fbneo/bubsys.zip", "dest": "fbneo/bubsys.zip",
"sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366", "sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366",

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "bizhawk", "platform": "bizhawk",
"display_name": "BizHawk", "display_name": "BizHawk",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:32:26Z", "generated": "2026-04-18T07:55:07Z",
"base_destination": "Firmware", "base_destination": "Firmware",
"detect": [ "detect": [
{ {
@@ -18,8 +19,8 @@
} }
], ],
"standalone_copies": [], "standalone_copies": [],
"total_files": 527, "total_files": 530,
"total_size": 2068127713, "total_size": 2547895289,
"files": [ "files": [
{ {
"dest": "panafz1.bin", "dest": "panafz1.bin",
@@ -284,7 +285,7 @@
"dest": "VEC_Minestorm.vec", "dest": "VEC_Minestorm.vec",
"sha1": "65d07426b520ddd3115d40f255511e0fd2e20ae7", "sha1": "65d07426b520ddd3115d40f255511e0fd2e20ae7",
"size": 8192, "size": 8192,
"repo_path": "bios/GCE/Vectrex/VEC_MineStorm.vec", "repo_path": "bios/GCE/Vectrex/VEC_Minestorm.vec",
"cores": null "cores": null
}, },
{ {
@@ -1273,6 +1274,39 @@
"FinalBurn Neo" "FinalBurn Neo"
] ]
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "sl31253.bin", "dest": "sl31253.bin",
"sha1": "81193965a374d77b99b4743d317824b53c3e3c78", "sha1": "81193965a374d77b99b4743d317824b53c3e3c78",

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "emudeck", "platform": "emudeck",
"display_name": "EmuDeck", "display_name": "EmuDeck",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:32:33Z", "generated": "2026-04-03T09:43:22Z",
"base_destination": "bios", "base_destination": "bios",
"detect": [ "detect": [
{ {
@@ -33,25 +34,217 @@
"linux": [ "linux": [
"$HOME/.local/share/yuzu/keys", "$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys", "$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys",
"$HOME/.config/Ryujinx/system" "$HOME/.config/Ryujinx/system"
], ],
"windows": [ "windows": [
"%APPDATA%\\yuzu\\keys", "%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys" "%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys",
"%APPDATA%\\Ryujinx\\system"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys",
"$HOME/Library/Application Support/Ryujinx/system"
] ]
} }
}, },
{ {
"file": "aes_keys.txt", "file": "title.keys",
"targets": { "targets": {
"linux": [ "linux": [
"$HOME/Emulation/bios/citra/keys" "$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys"
]
}
},
{
"file": "Citra/sysdata/aes_keys.txt",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"file": "Citra/sysdata/boot9.bin",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"pattern": "scph*.bin",
"targets": {
"linux": [
"$HOME/.local/share/duckstation/bios"
],
"windows": [
"%LOCALAPPDATA%\\DuckStation\\bios",
"%USERPROFILE%\\Documents\\DuckStation\\bios"
],
"darwin": [
"$HOME/Library/Application Support/DuckStation/bios"
]
}
},
{
"pattern": "ps2-*.bin",
"targets": {
"linux": [
"$HOME/.config/PCSX2/bios",
"$HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios"
],
"windows": [
"%USERPROFILE%\\Documents\\PCSX2\\bios"
],
"darwin": [
"$HOME/Library/Application Support/PCSX2/bios"
]
}
},
{
"note": "PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.",
"detect": {
"linux": [
"$HOME/.config/rpcs3"
],
"windows": [
"%APPDATA%\\rpcs3"
]
}
},
{
"file": "GC/USA/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/USA"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\USA"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/USA"
]
}
},
{
"file": "GC/EUR/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/EUR"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\EUR"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/EUR"
]
}
},
{
"file": "GC/JAP/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/JAP"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\JAP"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/JAP"
]
}
},
{
"file": "dsp_rom.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "dsp_coef.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "PPSSPP/ppge_atlas.zim",
"targets": {
"linux": [
"$HOME/.config/ppsspp/PSP/SYSTEM"
],
"windows": [
"%USERPROFILE%\\Documents\\PPSSPP\\PSP\\SYSTEM"
],
"darwin": [
"$HOME/Library/Application Support/PPSSPP/PSP/SYSTEM"
]
}
},
{
"file": "dc/dc_boot.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
},
{
"file": "dc/dc_nvmem.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
] ]
} }
} }
], ],
"total_files": 509, "total_files": 526,
"total_size": 3267793222, "total_size": 3276716358,
"files": [ "files": [
{ {
"dest": "colecovision.rom", "dest": "colecovision.rom",
@@ -932,6 +1125,24 @@
"Dolphin" "Dolphin"
] ]
}, },
{
"dest": "scph1000.bin",
"sha1": "343883a7b555646da8cee54aadd2795b6e7dd070",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1000.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph1001.bin",
"sha1": "10155d8d6e6e832d6ea66db9bc098321fb5e8ebf",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1001.bin",
"cores": [
"DuckStation"
]
},
{ {
"dest": "scph1002a.bin", "dest": "scph1002a.bin",
"sha1": "20b98f3d80f11cbf5a7bfd0779b0e63760ecc62c", "sha1": "20b98f3d80f11cbf5a7bfd0779b0e63760ecc62c",
@@ -941,6 +1152,132 @@
"DuckStation" "DuckStation"
] ]
}, },
{
"dest": "scph1002b.bin",
"sha1": "76cf6b1b2a7c571a6ad07f2bac0db6cd8f71e2cc",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1002b.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph1002c.bin",
"sha1": "b6a11579caef3875504fcf3831b8e3922746df2c",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1002c.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "dtlh1100.bin",
"sha1": "73107d468fc7cb1d2c5b18b269715dd889ecef06",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/dtlh1100.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph3000.bin",
"sha1": "b06f4a861f74270be819aa2a07db8d0563a7cc4e",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph3000.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph1001_v20.bin",
"sha1": "649895efd79d14790eabb362e94eb0622093dfb9",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1001_v20.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph3500.bin",
"sha1": "e38466a4ba8005fba7e9e3c7b9efeba7205bee3f",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph3500.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph1001_v21.bin",
"sha1": "ca7af30b50d9756cbd764640126c454cff658479",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1001_v21.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph5000.bin",
"sha1": "ffa7f9a7fb19d773a0c3985a541c8e5623d2c30d",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph5000.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph7000.bin",
"sha1": "77b10118d21ac7ffa9b35f9c4fd814da240eb3e9",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7000.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph7000w.bin",
"sha1": "1b0dbdb23da9dc0776aac58d0755dc80fea20975",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7000w.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph7001.bin",
"sha1": "14df4f6c1e367ce097c11deae21566b4fe5647a9",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7001.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph7002.bin",
"sha1": "8d5de56a79954f29e9006929ba3fed9b6a418c1d",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph7002.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph100.bin",
"sha1": "339a48f4fcf63e10b5b867b8c93cfd40945faf6c",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph100.bin",
"cores": [
"DuckStation"
]
},
{
"dest": "scph101_v44.bin",
"sha1": "7771d6e90980408f753891648685def6dd42ef6d",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph101_v44.bin",
"cores": [
"DuckStation"
]
},
{ {
"dest": "scph101_v45.bin", "dest": "scph101_v45.bin",
"sha1": "dcffe16bd90a723499ad46c641424981338d8378", "sha1": "dcffe16bd90a723499ad46c641424981338d8378",
@@ -968,6 +1305,15 @@
"DuckStation" "DuckStation"
] ]
}, },
{
"dest": "scph1000r.bin",
"sha1": "7082bd57141fa0007b3adcd031f7ba23a20108a0",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph1000r.bin",
"cores": [
"DuckStation"
]
},
{ {
"dest": "ps2_scph18000.bin", "dest": "ps2_scph18000.bin",
"sha1": "d7d6be084f51354bc951d8fa2d8d912aa70abc5e", "sha1": "d7d6be084f51354bc951d8fa2d8d912aa70abc5e",
@@ -3422,9 +3768,9 @@
}, },
{ {
"dest": "psvita/PSP2UPDAT.PUP", "dest": "psvita/PSP2UPDAT.PUP",
"sha1": "3ae832c9800fcaa007eccfc48f24242967c111f8", "sha1": "ed3a4cb264fff283209f10ae58c96c6090fed187",
"size": 56768512, "size": 56778752,
"repo_path": "bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP", "repo_path": "bios/Sony/PlayStation Vita/PSP2UPDAT.PUP",
"cores": [ "cores": [
"Vita3K" "Vita3K"
], ],

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "lakka", "platform": "lakka",
"display_name": "Lakka", "display_name": "Lakka",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:32:49Z", "generated": "2026-04-18T07:55:35Z",
"base_destination": "system", "base_destination": "system",
"detect": [ "detect": [
{ {
@@ -14,8 +15,8 @@
} }
], ],
"standalone_copies": [], "standalone_copies": [],
"total_files": 1609, "total_files": 1627,
"total_size": 5248935496, "total_size": 5735234905,
"files": [ "files": [
{ {
"dest": "3do_arcade_saot.bin", "dest": "3do_arcade_saot.bin",
@@ -3158,6 +3159,15 @@
"Amiberry" "Amiberry"
] ]
}, },
{
"dest": "kick31.rom",
"sha1": "3b7f1493b27e212830f989f26ca76c02049f09ca",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/kick31.rom",
"cores": [
"Amiberry"
]
},
{ {
"dest": "kick.rom", "dest": "kick.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785", "sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
@@ -3429,10 +3439,19 @@
] ]
}, },
{ {
"dest": "Machines/Shared Roms/MSX2R2.ROM", "dest": "Machines/Shared Roms/MSX2J.rom",
"sha1": "04990aa1c3a3fc7294ec884b81deaa89832df614", "sha1": "0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSXR2.rom", "repo_path": "bios/Microsoft/MSX/.variants/MSX2.ROM.0081ea0d",
"cores": [
"blueMSX"
]
},
{
"dest": "Machines/Shared Roms/MSX2R2.ROM",
"sha1": "ebb7eb540a390509edfd36c84288ba85e63f2d1f",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2R2.ROM",
"cores": [ "cores": [
"blueMSX" "blueMSX"
] ]
@@ -3968,6 +3987,15 @@
"DirectXBox" "DirectXBox"
] ]
}, },
{
"dest": "GC/USA/IPL.bin",
"sha1": "ef9194ab4804aa0aa8540d846caf291b28331165",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/USA/IPL.bin",
"cores": [
"Dolphin"
]
},
{ {
"dest": "Wii/shared2/sys/SYSCONF", "dest": "Wii/shared2/sys/SYSCONF",
"sha1": "3256c026284a24fb99d2ec1558d95db3b5dcc2e9", "sha1": "3256c026284a24fb99d2ec1558d95db3b5dcc2e9",
@@ -5051,6 +5079,39 @@
"storage": "release", "storage": "release",
"release_asset": "vimana.zip" "release_asset": "vimana.zip"
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "nes.pal", "dest": "nes.pal",
"sha1": "37027d92e1015b82a7dc5c43e9f1649a961577ab", "sha1": "37027d92e1015b82a7dc5c43e9f1649a961577ab",
@@ -5195,6 +5256,15 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-204.rom",
"sha1": "c5839f5cb98a7a8947065c3ed2f14f5f42e334a1",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-204.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "amiga-os-205.rom", "dest": "amiga-os-205.rom",
"sha1": "02843c4253bbd29aba535b0aa3bd9a85034ecde4", "sha1": "02843c4253bbd29aba535b0aa3bd9a85034ecde4",
@@ -5204,6 +5274,24 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-120.rom",
"sha1": "11f9e62cf299f72184835b7b2a70a16333fc0d88",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/amiga-os-120.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-os-310-a1200.rom",
"sha1": "e21545723fe8374e91342617604f1b3d703094f1",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-a1200.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "amiga-os-310-a3000.rom", "dest": "amiga-os-310-a3000.rom",
"sha1": "f8e210d72b4c4853e0c9b85d223ba20e3d1b36ee", "sha1": "f8e210d72b4c4853e0c9b85d223ba20e3d1b36ee",
@@ -5213,6 +5301,33 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-310-a4000.rom",
"sha1": "5fe04842d04a489720f0f4bb0e46948199406f49",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-a4000.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-os-310-cd32.rom",
"sha1": "3525be8887f79b5929e017b42380a79edfee542d",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-cd32.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-ext-310-cd32.rom",
"sha1": "5bef3d628ce59cc02a66e6e4ae0da48f60e78f7f",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-ext-310-cd32.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "cd32fmv.rom", "dest": "cd32fmv.rom",
"sha1": "03ca81c7a7b259cf64bc9582863eca0f6529f435", "sha1": "03ca81c7a7b259cf64bc9582863eca0f6529f435",
@@ -5222,6 +5337,15 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-ext-130-cdtv.rom",
"sha1": "7ba40ffa17e500ed9fed041f3424bd81d9c907be",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/amiga-ext-130-cdtv.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "fuse/48.rom", "dest": "fuse/48.rom",
"sha1": "5ea7c2b824672e914525d1d5c419d71b84a426a2", "sha1": "5ea7c2b824672e914525d1d5c419d71b84a426a2",
@@ -7780,6 +7904,24 @@
"NXEngine" "NXEngine"
] ]
}, },
{
"dest": "nxengine/data/sprites.sif",
"sha1": "73acccee601b56a2b7f624b0227fa7e1d662ef4b",
"size": 59482,
"repo_path": "bios/Other/NXEngine/nxengine/data/sprites.sif",
"cores": [
"NXEngine"
]
},
{
"dest": "nxengine/tilekey.dat",
"sha1": "74c14b15dbc2f36c81d2ad9cb65e2893298415da",
"size": 1028,
"repo_path": "bios/Other/NXEngine/nxengine/tilekey.dat",
"cores": [
"NXEngine"
]
},
{ {
"dest": "mda.rom", "dest": "mda.rom",
"sha1": "c2a8b10808bf51a3c123ba3eb1e9dd608231916f", "sha1": "c2a8b10808bf51a3c123ba3eb1e9dd608231916f",
@@ -9424,6 +9566,24 @@
"QUASI88" "QUASI88"
] ]
}, },
{
"dest": "dc_bios.bin",
"sha1": "8951d1bb219ab2ff8583033d2119c899cc81f18c",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/dc_bios.bin",
"cores": [
"Redream"
]
},
{
"dest": "dc_flash.bin",
"sha1": "94d44d7f9529ec1642ba3771ed3c5f756d5bc872",
"size": 131072,
"repo_path": "bios/Sega/Dreamcast/dc_flash.bin",
"cores": [
"Redream"
]
},
{ {
"dest": "scph_v11j.bin", "dest": "scph_v11j.bin",
"sha1": "b06f4a861f74270be819aa2a07db8d0563a7cc4e", "sha1": "b06f4a861f74270be819aa2a07db8d0563a7cc4e",
@@ -9487,6 +9647,15 @@
"Rustation" "Rustation"
] ]
}, },
{
"dest": "scph102.bin",
"sha1": "beb0ac693c0dc26daf5665b3314db81480fa5c7c",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph102.bin",
"cores": [
"Rustation"
]
},
{ {
"dest": "rvvm/fw_payload.bin", "dest": "rvvm/fw_payload.bin",
"sha1": "c603ebeea2816d5c52985170aa7ac4b9dd5f7a8d", "sha1": "c603ebeea2816d5c52985170aa7ac4b9dd5f7a8d",
@@ -9541,6 +9710,15 @@
"SameBoy" "SameBoy"
] ]
}, },
{
"dest": "sdlpal/desc.dat",
"sha1": "8c20ff26ebfefbf9b050b67af8083704003595ba",
"size": 16027,
"repo_path": "bios/sdlpal/desc.dat",
"cores": [
"SDLPAL"
]
},
{ {
"dest": "SkyEmu/dmg_rom.bin", "dest": "SkyEmu/dmg_rom.bin",
"sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f", "sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f",
@@ -9659,66 +9837,66 @@
] ]
}, },
{ {
"dest": "kvs1.wav", "dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604", "sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329, "size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV", "repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvs2.wav", "dest": "KVS2.WAV",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c", "sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275, "size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV", "repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvs3.wav", "dest": "KVS3.WAV",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0", "sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920, "size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV", "repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb1.wav", "dest": "KVB1.WAV",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c", "sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542, "size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV", "repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb2.wav", "dest": "KVB2.WAV",
"sha1": "60a425c6bde3226ab731995562716321be20fc49", "sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878, "size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV", "repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb3.wav", "dest": "KVB3.WAV",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8", "sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992, "size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV", "repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvshared.wav", "dest": "KVSHARED.WAV",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3", "sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116, "size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV", "repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
@@ -10711,6 +10889,15 @@
"X Millennium" "X Millennium"
] ]
}, },
{
"dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
"size": 2048,
"repo_path": "bios/Sharp/X1/FNT0808.X1",
"cores": [
"X Millennium"
]
},
{ {
"dest": "xmil/FNT0816.X1", "dest": "xmil/FNT0816.X1",
"sha1": "4f06d20c997a79ee6af954b69498147789bf1847", "sha1": "4f06d20c997a79ee6af954b69498147789bf1847",
@@ -11467,15 +11654,6 @@
"Citra" "Citra"
] ]
}, },
{
"dest": "GC/USA/IPL.bin",
"sha1": "ef9194ab4804aa0aa8540d846caf291b28331165",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/USA/IPL.bin",
"cores": [
"Dolphin"
]
},
{ {
"dest": "GC/EUR/IPL.bin", "dest": "GC/EUR/IPL.bin",
"sha1": "80b8744ff5e43585392f55546bd03a673d11ef5f", "sha1": "80b8744ff5e43585392f55546bd03a673d11ef5f",
@@ -12043,15 +12221,6 @@
"UME 2015" "UME 2015"
] ]
}, },
{
"dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
"size": 2048,
"repo_path": "bios/Sharp/X1/FNT0808.X1",
"cores": [
"X Millennium"
]
},
{ {
"dest": "fbneo/bubsys.zip", "dest": "fbneo/bubsys.zip",
"sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366", "sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366",

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "recalbox", "platform": "recalbox",
"display_name": "Recalbox", "display_name": "Recalbox",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:33:29Z", "generated": "2026-04-18T07:56:06Z",
"base_destination": "bios", "base_destination": "bios",
"detect": [ "detect": [
{ {
@@ -13,9 +14,224 @@
"bios_path": "/recalbox/share/bios" "bios_path": "/recalbox/share/bios"
} }
], ],
"standalone_copies": [], "standalone_copies": [
"total_files": 1093, {
"total_size": 3499462394, "file": "prod.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys",
"$HOME/.config/Ryujinx/system"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys",
"%APPDATA%\\Ryujinx\\system"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys",
"$HOME/Library/Application Support/Ryujinx/system"
]
}
},
{
"file": "title.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys"
]
}
},
{
"file": "Citra/sysdata/aes_keys.txt",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"file": "Citra/sysdata/boot9.bin",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"pattern": "scph*.bin",
"targets": {
"linux": [
"$HOME/.local/share/duckstation/bios"
],
"windows": [
"%LOCALAPPDATA%\\DuckStation\\bios",
"%USERPROFILE%\\Documents\\DuckStation\\bios"
],
"darwin": [
"$HOME/Library/Application Support/DuckStation/bios"
]
}
},
{
"pattern": "ps2-*.bin",
"targets": {
"linux": [
"$HOME/.config/PCSX2/bios",
"$HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios"
],
"windows": [
"%USERPROFILE%\\Documents\\PCSX2\\bios"
],
"darwin": [
"$HOME/Library/Application Support/PCSX2/bios"
]
}
},
{
"note": "PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.",
"detect": {
"linux": [
"$HOME/.config/rpcs3"
],
"windows": [
"%APPDATA%\\rpcs3"
]
}
},
{
"file": "GC/USA/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/USA"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\USA"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/USA"
]
}
},
{
"file": "GC/EUR/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/EUR"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\EUR"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/EUR"
]
}
},
{
"file": "GC/JAP/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/JAP"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\JAP"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/JAP"
]
}
},
{
"file": "dsp_rom.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "dsp_coef.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "PPSSPP/ppge_atlas.zim",
"targets": {
"linux": [
"$HOME/.config/ppsspp/PSP/SYSTEM"
],
"windows": [
"%USERPROFILE%\\Documents\\PPSSPP\\PSP\\SYSTEM"
],
"darwin": [
"$HOME/Library/Application Support/PPSSPP/PSP/SYSTEM"
]
}
},
{
"file": "dc/dc_boot.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
},
{
"file": "dc/dc_nvmem.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
}
],
"total_files": 1100,
"total_size": 3946303603,
"files": [ "files": [
{ {
"dest": "3do/panafz1.bin", "dest": "3do/panafz1.bin",
@@ -539,7 +755,7 @@
"dest": "dragon/deltados.rom", "dest": "dragon/deltados.rom",
"sha1": "686ebb5f39dd4fc907a0b748867d0a022d2f1a60", "sha1": "686ebb5f39dd4fc907a0b748867d0a022d2f1a60",
"size": 8192, "size": 8192,
"repo_path": "bios/Dragon/Dragon/deltados.rom", "repo_path": "bios/Dragon/Dragon/delta2.rom",
"cores": null "cores": null
}, },
{ {
@@ -850,6 +1066,13 @@
"repo_path": "bios/Microsoft/MSX/MSX2EXT.ROM", "repo_path": "bios/Microsoft/MSX/MSX2EXT.ROM",
"cores": null "cores": null
}, },
{
"dest": "Machines/Shared Roms/MSX2J.rom",
"sha1": "0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/.variants/MSX2.ROM.0081ea0d",
"cores": null
},
{ {
"dest": "Machines/Shared Roms/MSX2P.rom", "dest": "Machines/Shared Roms/MSX2P.rom",
"sha1": "e90f80a61d94c617850c415e12ad70ac41e66bb7", "sha1": "e90f80a61d94c617850c415e12ad70ac41e66bb7",
@@ -866,9 +1089,9 @@
}, },
{ {
"dest": "Machines/Shared Roms/MSX2R2.ROM", "dest": "Machines/Shared Roms/MSX2R2.ROM",
"sha1": "04990aa1c3a3fc7294ec884b81deaa89832df614", "sha1": "ebb7eb540a390509edfd36c84288ba85e63f2d1f",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSXR2.rom", "repo_path": "bios/Microsoft/MSX/MSX2R2.ROM",
"cores": null "cores": null
}, },
{ {
@@ -1992,6 +2215,15 @@
"Amiberry" "Amiberry"
] ]
}, },
{
"dest": "kick31.rom",
"sha1": "3b7f1493b27e212830f989f26ca76c02049f09ca",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/kick31.rom",
"cores": [
"Amiberry"
]
},
{ {
"dest": "kick.rom", "dest": "kick.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785", "sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
@@ -3787,6 +4019,39 @@
"FinalBurn Neo" "FinalBurn Neo"
] ]
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "gamegenie.nes", "dest": "gamegenie.nes",
"sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779", "sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779",
@@ -4219,6 +4484,15 @@
"Genesis Plus GX" "Genesis Plus GX"
] ]
}, },
{
"dest": "ROM",
"sha1": "e4fc7560b69d062cb2da5b1ffbe11cd1ca03cc37",
"size": 131072,
"repo_path": "bios/Apple/Apple IIGS/ROM",
"cores": [
"GSplus"
]
},
{ {
"dest": "c600.rom", "dest": "c600.rom",
"sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16", "sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16",
@@ -6433,6 +6707,24 @@
"NXEngine" "NXEngine"
] ]
}, },
{
"dest": "nxengine/data/sprites.sif",
"sha1": "73acccee601b56a2b7f624b0227fa7e1d662ef4b",
"size": 59482,
"repo_path": "bios/Other/NXEngine/nxengine/data/sprites.sif",
"cores": [
"NXEngine"
]
},
{
"dest": "nxengine/tilekey.dat",
"sha1": "74c14b15dbc2f36c81d2ad9cb65e2893298415da",
"size": 1028,
"repo_path": "bios/Other/NXEngine/nxengine/tilekey.dat",
"cores": [
"NXEngine"
]
},
{ {
"dest": "64DD_IPL.bin", "dest": "64DD_IPL.bin",
"sha1": "bf861922dcb78c316360e3e742f4f70ff63c9bc3", "sha1": "bf861922dcb78c316360e3e742f4f70ff63c9bc3",
@@ -6676,69 +6968,6 @@
"SAME CDi" "SAME CDi"
] ]
}, },
{
"dest": "kvs1.wav",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs2.wav",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs3.wav",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb1.wav",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb2.wav",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb3.wav",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvshared.wav",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
]
},
{ {
"dest": "KVS1.WAV", "dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604", "sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
@@ -6802,6 +7031,33 @@
"Stella 2023" "Stella 2023"
] ]
}, },
{
"dest": "Gram Kracker.ctg",
"sha1": "56dd520570cdcdd60dda2eedc8af1e02a781dcc5",
"size": 7587,
"repo_path": "bios/Texas Instruments/TI-99/Gram Kracker.ctg",
"cores": [
"ti99sim"
]
},
{
"dest": "ti-pcard.ctg",
"sha1": "c7bf5fcfea0502011dca76d12efcc242e23421b9",
"size": 71924,
"repo_path": "bios/Texas Instruments/TI-99/ti-pcard.ctg",
"cores": [
"ti99sim"
]
},
{
"dest": "cf7+.ctg",
"sha1": "698c638e1773244a6bf8a353c87d210047cce402",
"size": 5768,
"repo_path": "bios/Texas Instruments/TI-99/cf7+.ctg",
"cores": [
"ti99sim"
]
},
{ {
"dest": "JiffyDOS_SX-64.bin", "dest": "JiffyDOS_SX-64.bin",
"sha1": "942c2150123dc30f40b3df6086132ef0a3c43948", "sha1": "942c2150123dc30f40b3df6086132ef0a3c43948",
@@ -6937,6 +7193,24 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "alpha-basic.rom",
"sha1": "1983b4fb398e3dd9668d424c666c5a0b3f1e2b69",
"size": 16384,
"repo_path": "bios/Dragon/Dragon/alpha-basic.rom",
"cores": [
"XRoar"
]
},
{
"dest": "alice.rom",
"sha1": "c2166b91e6396a311f486832012aa43e0d2b19f8",
"size": 8192,
"repo_path": "bios/Tandy/CoCo/alice.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "deluxe.rom", "dest": "deluxe.rom",
"sha1": "d89196292b9ebd787647cf91bbb83c63da2b4390", "sha1": "d89196292b9ebd787647cf91bbb83c63da2b4390",
@@ -7009,6 +7283,15 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "delta2.rom",
"sha1": "686ebb5f39dd4fc907a0b748867d0a022d2f1a60",
"size": 8192,
"repo_path": "bios/Dragon/Dragon/delta2.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "cp450dsk.rom", "dest": "cp450dsk.rom",
"sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b", "sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b",

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "retroarch", "platform": "retroarch",
"display_name": "RetroArch", "display_name": "RetroArch",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:32:49Z", "generated": "2026-04-18T07:55:35Z",
"base_destination": "system", "base_destination": "system",
"detect": [ "detect": [
{ {
@@ -31,9 +32,224 @@
"parse_key": "system_directory" "parse_key": "system_directory"
} }
], ],
"standalone_copies": [], "standalone_copies": [
"total_files": 1609, {
"total_size": 5248935496, "file": "prod.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys",
"$HOME/.config/Ryujinx/system"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys",
"%APPDATA%\\Ryujinx\\system"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys",
"$HOME/Library/Application Support/Ryujinx/system"
]
}
},
{
"file": "title.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys"
]
}
},
{
"file": "Citra/sysdata/aes_keys.txt",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"file": "Citra/sysdata/boot9.bin",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"pattern": "scph*.bin",
"targets": {
"linux": [
"$HOME/.local/share/duckstation/bios"
],
"windows": [
"%LOCALAPPDATA%\\DuckStation\\bios",
"%USERPROFILE%\\Documents\\DuckStation\\bios"
],
"darwin": [
"$HOME/Library/Application Support/DuckStation/bios"
]
}
},
{
"pattern": "ps2-*.bin",
"targets": {
"linux": [
"$HOME/.config/PCSX2/bios",
"$HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios"
],
"windows": [
"%USERPROFILE%\\Documents\\PCSX2\\bios"
],
"darwin": [
"$HOME/Library/Application Support/PCSX2/bios"
]
}
},
{
"note": "PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.",
"detect": {
"linux": [
"$HOME/.config/rpcs3"
],
"windows": [
"%APPDATA%\\rpcs3"
]
}
},
{
"file": "GC/USA/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/USA"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\USA"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/USA"
]
}
},
{
"file": "GC/EUR/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/EUR"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\EUR"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/EUR"
]
}
},
{
"file": "GC/JAP/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/JAP"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\JAP"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/JAP"
]
}
},
{
"file": "dsp_rom.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "dsp_coef.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "PPSSPP/ppge_atlas.zim",
"targets": {
"linux": [
"$HOME/.config/ppsspp/PSP/SYSTEM"
],
"windows": [
"%USERPROFILE%\\Documents\\PPSSPP\\PSP\\SYSTEM"
],
"darwin": [
"$HOME/Library/Application Support/PPSSPP/PSP/SYSTEM"
]
}
},
{
"file": "dc/dc_boot.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
},
{
"file": "dc/dc_nvmem.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
}
],
"total_files": 1627,
"total_size": 5735234905,
"files": [ "files": [
{ {
"dest": "3do_arcade_saot.bin", "dest": "3do_arcade_saot.bin",
@@ -3176,6 +3392,15 @@
"Amiberry" "Amiberry"
] ]
}, },
{
"dest": "kick31.rom",
"sha1": "3b7f1493b27e212830f989f26ca76c02049f09ca",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/kick31.rom",
"cores": [
"Amiberry"
]
},
{ {
"dest": "kick.rom", "dest": "kick.rom",
"sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785", "sha1": "891e9a547772fe0c6c19b610baf8bc4ea7fcb785",
@@ -3447,10 +3672,19 @@
] ]
}, },
{ {
"dest": "Machines/Shared Roms/MSX2R2.ROM", "dest": "Machines/Shared Roms/MSX2J.rom",
"sha1": "04990aa1c3a3fc7294ec884b81deaa89832df614", "sha1": "0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSXR2.rom", "repo_path": "bios/Microsoft/MSX/.variants/MSX2.ROM.0081ea0d",
"cores": [
"blueMSX"
]
},
{
"dest": "Machines/Shared Roms/MSX2R2.ROM",
"sha1": "ebb7eb540a390509edfd36c84288ba85e63f2d1f",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2R2.ROM",
"cores": [ "cores": [
"blueMSX" "blueMSX"
] ]
@@ -3986,6 +4220,15 @@
"DirectXBox" "DirectXBox"
] ]
}, },
{
"dest": "GC/USA/IPL.bin",
"sha1": "ef9194ab4804aa0aa8540d846caf291b28331165",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/USA/IPL.bin",
"cores": [
"Dolphin"
]
},
{ {
"dest": "Wii/shared2/sys/SYSCONF", "dest": "Wii/shared2/sys/SYSCONF",
"sha1": "3256c026284a24fb99d2ec1558d95db3b5dcc2e9", "sha1": "3256c026284a24fb99d2ec1558d95db3b5dcc2e9",
@@ -5069,6 +5312,39 @@
"storage": "release", "storage": "release",
"release_asset": "vimana.zip" "release_asset": "vimana.zip"
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "nes.pal", "dest": "nes.pal",
"sha1": "37027d92e1015b82a7dc5c43e9f1649a961577ab", "sha1": "37027d92e1015b82a7dc5c43e9f1649a961577ab",
@@ -5213,6 +5489,15 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-204.rom",
"sha1": "c5839f5cb98a7a8947065c3ed2f14f5f42e334a1",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-204.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "amiga-os-205.rom", "dest": "amiga-os-205.rom",
"sha1": "02843c4253bbd29aba535b0aa3bd9a85034ecde4", "sha1": "02843c4253bbd29aba535b0aa3bd9a85034ecde4",
@@ -5222,6 +5507,24 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-120.rom",
"sha1": "11f9e62cf299f72184835b7b2a70a16333fc0d88",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/amiga-os-120.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-os-310-a1200.rom",
"sha1": "e21545723fe8374e91342617604f1b3d703094f1",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-a1200.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "amiga-os-310-a3000.rom", "dest": "amiga-os-310-a3000.rom",
"sha1": "f8e210d72b4c4853e0c9b85d223ba20e3d1b36ee", "sha1": "f8e210d72b4c4853e0c9b85d223ba20e3d1b36ee",
@@ -5231,6 +5534,33 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-os-310-a4000.rom",
"sha1": "5fe04842d04a489720f0f4bb0e46948199406f49",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-a4000.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-os-310-cd32.rom",
"sha1": "3525be8887f79b5929e017b42380a79edfee542d",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-os-310-cd32.rom",
"cores": [
"FS-UAE"
]
},
{
"dest": "amiga-ext-310-cd32.rom",
"sha1": "5bef3d628ce59cc02a66e6e4ae0da48f60e78f7f",
"size": 524288,
"repo_path": "bios/Commodore/Amiga/amiga-ext-310-cd32.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "cd32fmv.rom", "dest": "cd32fmv.rom",
"sha1": "03ca81c7a7b259cf64bc9582863eca0f6529f435", "sha1": "03ca81c7a7b259cf64bc9582863eca0f6529f435",
@@ -5240,6 +5570,15 @@
"FS-UAE" "FS-UAE"
] ]
}, },
{
"dest": "amiga-ext-130-cdtv.rom",
"sha1": "7ba40ffa17e500ed9fed041f3424bd81d9c907be",
"size": 262144,
"repo_path": "bios/Commodore/Amiga/amiga-ext-130-cdtv.rom",
"cores": [
"FS-UAE"
]
},
{ {
"dest": "fuse/48.rom", "dest": "fuse/48.rom",
"sha1": "5ea7c2b824672e914525d1d5c419d71b84a426a2", "sha1": "5ea7c2b824672e914525d1d5c419d71b84a426a2",
@@ -7798,6 +8137,24 @@
"NXEngine" "NXEngine"
] ]
}, },
{
"dest": "nxengine/data/sprites.sif",
"sha1": "73acccee601b56a2b7f624b0227fa7e1d662ef4b",
"size": 59482,
"repo_path": "bios/Other/NXEngine/nxengine/data/sprites.sif",
"cores": [
"NXEngine"
]
},
{
"dest": "nxengine/tilekey.dat",
"sha1": "74c14b15dbc2f36c81d2ad9cb65e2893298415da",
"size": 1028,
"repo_path": "bios/Other/NXEngine/nxengine/tilekey.dat",
"cores": [
"NXEngine"
]
},
{ {
"dest": "mda.rom", "dest": "mda.rom",
"sha1": "c2a8b10808bf51a3c123ba3eb1e9dd608231916f", "sha1": "c2a8b10808bf51a3c123ba3eb1e9dd608231916f",
@@ -9442,6 +9799,24 @@
"QUASI88" "QUASI88"
] ]
}, },
{
"dest": "dc_bios.bin",
"sha1": "8951d1bb219ab2ff8583033d2119c899cc81f18c",
"size": 2097152,
"repo_path": "bios/Sega/Dreamcast/dc_bios.bin",
"cores": [
"Redream"
]
},
{
"dest": "dc_flash.bin",
"sha1": "94d44d7f9529ec1642ba3771ed3c5f756d5bc872",
"size": 131072,
"repo_path": "bios/Sega/Dreamcast/dc_flash.bin",
"cores": [
"Redream"
]
},
{ {
"dest": "scph_v11j.bin", "dest": "scph_v11j.bin",
"sha1": "b06f4a861f74270be819aa2a07db8d0563a7cc4e", "sha1": "b06f4a861f74270be819aa2a07db8d0563a7cc4e",
@@ -9505,6 +9880,15 @@
"Rustation" "Rustation"
] ]
}, },
{
"dest": "scph102.bin",
"sha1": "beb0ac693c0dc26daf5665b3314db81480fa5c7c",
"size": 524288,
"repo_path": "bios/Sony/PlayStation/scph102.bin",
"cores": [
"Rustation"
]
},
{ {
"dest": "rvvm/fw_payload.bin", "dest": "rvvm/fw_payload.bin",
"sha1": "c603ebeea2816d5c52985170aa7ac4b9dd5f7a8d", "sha1": "c603ebeea2816d5c52985170aa7ac4b9dd5f7a8d",
@@ -9559,6 +9943,15 @@
"SameBoy" "SameBoy"
] ]
}, },
{
"dest": "sdlpal/desc.dat",
"sha1": "8c20ff26ebfefbf9b050b67af8083704003595ba",
"size": 16027,
"repo_path": "bios/sdlpal/desc.dat",
"cores": [
"SDLPAL"
]
},
{ {
"dest": "SkyEmu/dmg_rom.bin", "dest": "SkyEmu/dmg_rom.bin",
"sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f", "sha1": "4ed31ec6b0b175bb109c0eb5fd3d193da823339f",
@@ -9677,66 +10070,66 @@
] ]
}, },
{ {
"dest": "kvs1.wav", "dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604", "sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329, "size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV", "repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvs2.wav", "dest": "KVS2.WAV",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c", "sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275, "size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV", "repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvs3.wav", "dest": "KVS3.WAV",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0", "sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920, "size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV", "repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb1.wav", "dest": "KVB1.WAV",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c", "sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542, "size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV", "repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb2.wav", "dest": "KVB2.WAV",
"sha1": "60a425c6bde3226ab731995562716321be20fc49", "sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878, "size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV", "repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvb3.wav", "dest": "KVB3.WAV",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8", "sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992, "size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV", "repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
"dest": "kvshared.wav", "dest": "KVSHARED.WAV",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3", "sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116, "size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV", "repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [ "cores": [
"Stella 2014" "Stella 2023"
] ]
}, },
{ {
@@ -10729,6 +11122,15 @@
"X Millennium" "X Millennium"
] ]
}, },
{
"dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
"size": 2048,
"repo_path": "bios/Sharp/X1/FNT0808.X1",
"cores": [
"X Millennium"
]
},
{ {
"dest": "xmil/FNT0816.X1", "dest": "xmil/FNT0816.X1",
"sha1": "4f06d20c997a79ee6af954b69498147789bf1847", "sha1": "4f06d20c997a79ee6af954b69498147789bf1847",
@@ -11485,15 +11887,6 @@
"Citra" "Citra"
] ]
}, },
{
"dest": "GC/USA/IPL.bin",
"sha1": "ef9194ab4804aa0aa8540d846caf291b28331165",
"size": 2097152,
"repo_path": "bios/Nintendo/GameCube/GC/USA/IPL.bin",
"cores": [
"Dolphin"
]
},
{ {
"dest": "GC/EUR/IPL.bin", "dest": "GC/EUR/IPL.bin",
"sha1": "80b8744ff5e43585392f55546bd03a673d11ef5f", "sha1": "80b8744ff5e43585392f55546bd03a673d11ef5f",
@@ -12061,15 +12454,6 @@
"UME 2015" "UME 2015"
] ]
}, },
{
"dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
"size": 2048,
"repo_path": "bios/Sharp/X1/FNT0808.X1",
"cores": [
"X Millennium"
]
},
{ {
"dest": "fbneo/bubsys.zip", "dest": "fbneo/bubsys.zip",
"sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366", "sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366",

View File

@@ -1,9 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"source": "full",
"platform": "retrobat", "platform": "retrobat",
"display_name": "RetroBat", "display_name": "RetroBat",
"version": "1.0", "version": "1.0",
"generated": "2026-03-31T12:33:39Z", "generated": "2026-04-03T09:44:16Z",
"base_destination": "bios", "base_destination": "bios",
"detect": [ "detect": [
{ {
@@ -12,9 +13,224 @@
"path": "%USERPROFILE%\\RetroBat\\bios" "path": "%USERPROFILE%\\RetroBat\\bios"
} }
], ],
"standalone_copies": [], "standalone_copies": [
"total_files": 1160, {
"total_size": 4297499791, "file": "prod.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys",
"$HOME/.config/Ryujinx/system"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys",
"%APPDATA%\\Ryujinx\\system"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys",
"$HOME/Library/Application Support/Ryujinx/system"
]
}
},
{
"file": "title.keys",
"targets": {
"linux": [
"$HOME/.local/share/yuzu/keys",
"$HOME/.local/share/eden/keys",
"$HOME/.local/share/citron/keys",
"$HOME/.local/share/suyu/keys"
],
"windows": [
"%APPDATA%\\yuzu\\keys",
"%APPDATA%\\eden\\keys",
"%APPDATA%\\citron\\keys",
"%APPDATA%\\suyu\\keys"
],
"darwin": [
"$HOME/Library/Application Support/yuzu/keys"
]
}
},
{
"file": "Citra/sysdata/aes_keys.txt",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"file": "Citra/sysdata/boot9.bin",
"targets": {
"linux": [
"$HOME/.local/share/azahar/sysdata"
],
"windows": [
"%APPDATA%\\Azahar\\sysdata"
]
}
},
{
"pattern": "scph*.bin",
"targets": {
"linux": [
"$HOME/.local/share/duckstation/bios"
],
"windows": [
"%LOCALAPPDATA%\\DuckStation\\bios",
"%USERPROFILE%\\Documents\\DuckStation\\bios"
],
"darwin": [
"$HOME/Library/Application Support/DuckStation/bios"
]
}
},
{
"pattern": "ps2-*.bin",
"targets": {
"linux": [
"$HOME/.config/PCSX2/bios",
"$HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios"
],
"windows": [
"%USERPROFILE%\\Documents\\PCSX2\\bios"
],
"darwin": [
"$HOME/Library/Application Support/PCSX2/bios"
]
}
},
{
"note": "PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.",
"detect": {
"linux": [
"$HOME/.config/rpcs3"
],
"windows": [
"%APPDATA%\\rpcs3"
]
}
},
{
"file": "GC/USA/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/USA"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\USA"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/USA"
]
}
},
{
"file": "GC/EUR/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/EUR"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\EUR"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/EUR"
]
}
},
{
"file": "GC/JAP/IPL.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu/GC/JAP"
],
"windows": [
"%APPDATA%\\Dolphin Emulator\\GC\\JAP"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin/GC/JAP"
]
}
},
{
"file": "dsp_rom.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "dsp_coef.bin",
"targets": {
"linux": [
"$HOME/.local/share/dolphin-emu"
],
"windows": [
"%APPDATA%\\Dolphin Emulator"
],
"darwin": [
"$HOME/Library/Application Support/Dolphin"
]
}
},
{
"file": "PPSSPP/ppge_atlas.zim",
"targets": {
"linux": [
"$HOME/.config/ppsspp/PSP/SYSTEM"
],
"windows": [
"%USERPROFILE%\\Documents\\PPSSPP\\PSP\\SYSTEM"
],
"darwin": [
"$HOME/Library/Application Support/PPSSPP/PSP/SYSTEM"
]
}
},
{
"file": "dc/dc_boot.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
},
{
"file": "dc/dc_nvmem.bin",
"targets": {
"linux": [
"$HOME/.local/share/flycast/data",
"$HOME/.var/app/org.flycast.Flycast/data/flycast"
],
"windows": [
"%APPDATA%\\flycast\\data"
]
}
}
],
"total_files": 1169,
"total_size": 4777641221,
"files": [ "files": [
{ {
"dest": "panafz1.bin", "dest": "panafz1.bin",
@@ -2525,10 +2741,19 @@
] ]
}, },
{ {
"dest": "Machines/Shared Roms/MSX2R2.ROM", "dest": "Machines/Shared Roms/MSX2J.rom",
"sha1": "04990aa1c3a3fc7294ec884b81deaa89832df614", "sha1": "0081ea0d25bc5cd8d70b60ad8cfdc7307812c0fd",
"size": 32768, "size": 32768,
"repo_path": "bios/Microsoft/MSX/MSXR2.rom", "repo_path": "bios/Microsoft/MSX/.variants/MSX2.ROM.0081ea0d",
"cores": [
"blueMSX"
]
},
{
"dest": "Machines/Shared Roms/MSX2R2.ROM",
"sha1": "ebb7eb540a390509edfd36c84288ba85e63f2d1f",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2R2.ROM",
"cores": [ "cores": [
"blueMSX" "blueMSX"
] ]
@@ -3967,6 +4192,39 @@
"storage": "release", "storage": "release",
"release_asset": "vimana.zip" "release_asset": "vimana.zip"
}, },
{
"dest": "fbneo/samples/donpachi.zip",
"sha1": "d380fb29287eb7fc9ff901a7653ad40785f7deb1",
"size": 208549253,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "donpachi.zip"
},
{
"dest": "fbneo/samples/sfz3mix.zip",
"sha1": "937cdc6ccf9de418b94d8b762aad36822f857ec9",
"size": 116329446,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "sfz3mix.zip"
},
{
"dest": "fbneo/samples/twotiger.zip",
"sha1": "74399cc36d97e9f74b387b87900505ebbf260ca9",
"size": 154888877,
"repo_path": "",
"cores": [
"FinalBurn Neo"
],
"storage": "release",
"release_asset": "twotiger.zip"
},
{ {
"dest": "gamegenie.nes", "dest": "gamegenie.nes",
"sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779", "sha1": "f430a0d752a9fa0c7032db8131f9090d18f71779",
@@ -4453,6 +4711,15 @@
"Genesis Plus GX" "Genesis Plus GX"
] ]
}, },
{
"dest": "ROM",
"sha1": "e4fc7560b69d062cb2da5b1ffbe11cd1ca03cc37",
"size": 131072,
"repo_path": "bios/Apple/Apple IIGS/ROM",
"cores": [
"GSplus"
]
},
{ {
"dest": "c600.rom", "dest": "c600.rom",
"sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16", "sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16",
@@ -6181,6 +6448,24 @@
"NXEngine" "NXEngine"
] ]
}, },
{
"dest": "nxengine/data/sprites.sif",
"sha1": "73acccee601b56a2b7f624b0227fa7e1d662ef4b",
"size": 59482,
"repo_path": "bios/Other/NXEngine/nxengine/data/sprites.sif",
"cores": [
"NXEngine"
]
},
{
"dest": "nxengine/tilekey.dat",
"sha1": "74c14b15dbc2f36c81d2ad9cb65e2893298415da",
"size": 1028,
"repo_path": "bios/Other/NXEngine/nxengine/tilekey.dat",
"cores": [
"NXEngine"
]
},
{ {
"dest": "panafz1j.bin", "dest": "panafz1j.bin",
"sha1": "ec7ec62d60ec0459a14ed56ebc66761ef3c80efc", "sha1": "ec7ec62d60ec0459a14ed56ebc66761ef3c80efc",
@@ -6352,6 +6637,15 @@
"PicoDrive" "PicoDrive"
] ]
}, },
{
"dest": "SegaCDBIOS9303.bin",
"sha1": "5adb6c3af218c60868e6b723ec47e36bbdf5e6f0",
"size": 131072,
"repo_path": "bios/Sega/Mega CD/SegaCDBIOS9303.bin",
"cores": [
"PicoDrive"
]
},
{ {
"dest": "us_scd1_9210.bin", "dest": "us_scd1_9210.bin",
"sha1": "f4f315adcef9b8feb0364c21ab7f0eaf5457f3ed", "sha1": "f4f315adcef9b8feb0364c21ab7f0eaf5457f3ed",
@@ -7096,15 +7390,24 @@
}, },
{ {
"dest": "psvita/PSP2UPDAT.PUP", "dest": "psvita/PSP2UPDAT.PUP",
"sha1": "3ae832c9800fcaa007eccfc48f24242967c111f8", "sha1": "ed3a4cb264fff283209f10ae58c96c6090fed187",
"size": 56768512, "size": 56778752,
"repo_path": "bios/Sony/PlayStation Vita/.variants/PSP2UPDAT.PUP", "repo_path": "bios/Sony/PlayStation Vita/PSP2UPDAT.PUP",
"cores": [ "cores": [
"Vita3K" "Vita3K"
], ],
"storage": "release", "storage": "release",
"release_asset": "PSP2UPDAT.PUP" "release_asset": "PSP2UPDAT.PUP"
}, },
{
"dest": "xmil/IPLROM.X1T",
"sha1": "44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3",
"size": 32768,
"repo_path": "bios/Sharp/X1/.variants/IPLROM.X1T.44620f57",
"cores": [
"X Millennium"
]
},
{ {
"dest": "xmil/FNT0808.X1", "dest": "xmil/FNT0808.X1",
"sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2", "sha1": "1c1a0d8c9f4c446ccd7470516b215ddca5052fb2",
@@ -7411,6 +7714,15 @@
"XRoar" "XRoar"
] ]
}, },
{
"dest": "delta2.rom",
"sha1": "686ebb5f39dd4fc907a0b748867d0a022d2f1a60",
"size": 8192,
"repo_path": "bios/Dragon/Dragon/delta2.rom",
"cores": [
"XRoar"
]
},
{ {
"dest": "cp450dsk.rom", "dest": "cp450dsk.rom",
"sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b", "sha1": "827697fa5b755f5dc1efb054cdbbeb04e405405b",
@@ -8194,15 +8506,6 @@
"ScummVM" "ScummVM"
] ]
}, },
{
"dest": "xmil/IPLROM.X1T",
"sha1": "44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3",
"size": 32768,
"repo_path": "bios/Sharp/X1/.variants/IPLROM.X1T.44620f57",
"cores": [
"X Millennium"
]
},
{ {
"dest": "fbneo/bubsys.zip", "dest": "fbneo/bubsys.zip",
"sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366", "sha1": "1c0ffcd308b0c8c6dbb74ad8b811a0767200d366",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,10 @@ theme:
icon: material/brightness-4 icon: material/brightness-4
name: Switch to auto name: Switch to auto
font: false font: false
logo: assets/images/logo.png
favicon: assets/images/favicon.png
icon:
logo: material/chip
features: features:
- navigation.tabs - navigation.tabs
- navigation.sections - navigation.sections
@@ -29,6 +33,8 @@ theme:
- search.highlight - search.highlight
- content.tabs.link - content.tabs.link
- toc.follow - toc.follow
extra_css:
- stylesheets/extra.css
markdown_extensions: markdown_extensions:
- tables - tables
- admonition - admonition
@@ -48,6 +54,7 @@ plugins:
- search - search
nav: nav:
- Home: index.md - Home: index.md
- Download: which-pack.md
- Platforms: - Platforms:
- Overview: platforms/index.md - Overview: platforms/index.md
- Batocera: platforms/batocera.md - Batocera: platforms/batocera.md
@@ -134,6 +141,7 @@ nav:
- VTech: systems/vtech.md - VTech: systems/vtech.md
- Vircon: systems/vircon.md - Vircon: systems/vircon.md
- ZC: systems/zc.md - ZC: systems/zc.md
- sdlpal: systems/sdlpal.md
- Emulators: - Emulators:
- Overview: emulators/index.md - Overview: emulators/index.md
- Official ports (63): - Official ports (63):
@@ -475,4 +483,5 @@ nav:
- Adding a scraper: wiki/adding-a-scraper.md - Adding a scraper: wiki/adding-a-scraper.md
- Testing guide: wiki/testing-guide.md - Testing guide: wiki/testing-guide.md
- Release process: wiki/release-process.md - Release process: wiki/release-process.md
- Community tools: wiki/community-tools.md
- Contributing: contributing.md - Contributing: contributing.md

View File

@@ -150,22 +150,23 @@ data_directories:
description: "SDLPAL Chinese Paladin game data (.mkf archives)" description: "SDLPAL Chinese Paladin game data (.mkf archives)"
# ref: OpenTyrian2000 — system/opentyrian/tyrian/ # ref: OpenTyrian2000 — system/opentyrian/tyrian/
# Tyrian 2.1 freeware data (also on buildbot as OpenTyrian.zip) # Tyrian 2.1 freeware data (buildbot URLs removed, sourced from release asset)
opentyrian: opentyrian:
source_url: "https://buildbot.libretro.com/assets/system/OpenTyrian%20%28Game%20Data%29.zip" source_url: "https://github.com/Abdess/retrobios/releases/download/large-files/opentyrian-data.zip"
source_type: zip source_type: zip
for_platforms: [retroarch, lakka, retropie] for_platforms: [retroarch, lakka, retropie]
local_cache: data/opentyrian local_cache: data/opentyrian
description: "OpenTyrian Tyrian 2.1 freeware game data" description: "OpenTyrian Tyrian 2.1 freeware game data"
# ref: syobonaction — system/syobonaction/ # ref: syobonaction — system/syobonaction/
# Freeware game data from OpenSyobonAction # Freeware game data from OpenSyobonAction (BGM, res, SE directories)
syobonaction: syobonaction:
source_url: "https://github.com/akemin-dayo/OpenSyobonAction" source_url: "https://github.com/akemin-dayo/OpenSyobonAction/archive/refs/heads/{version}.tar.gz"
source_type: git_subtree source_type: tarball
source_path: "res" source_path: "OpenSyobonAction-master"
version: master version: master
local_cache: data/syobonaction local_cache: data/syobonaction
exclude: [DxLib.cpp, DxLib.h, icon.ico, joyconfig.h, loadg.cpp, main.cpp, main.h, Makefile, README_ja.md, README.md]
description: "Syobon Action (Cat Mario) game data (sprites, BGM, SE)" description: "Syobon Action (Cat Mario) game data (sprites, BGM, SE)"
# ========================================================================= # =========================================================================
@@ -190,9 +191,10 @@ data_directories:
# Not on buildbot — sourced from libretro repo # Not on buildbot — sourced from libretro repo
# 532 files (tiles, fonts, databases, lua scripts, level descriptions) # 532 files (tiles, fonts, databases, lua scripts, level descriptions)
stonesoup: stonesoup:
source_url: "https://github.com/libretro/crawl-ref" source_url: "https://github.com/libretro/crawl-ref/archive/refs/heads/{version}.tar.gz"
source_type: git_subtree source_type: tarball
source_path: "crawl-ref/source/dat" source_path: "crawl-ref-master/crawl-ref/source/dat"
version: master
local_cache: data/stonesoup local_cache: data/stonesoup
description: "DCSS game data (tiles, fonts, databases, lua, level descriptions)" description: "DCSS game data (tiles, fonts, databases, lua, level descriptions)"

View File

@@ -32,6 +32,144 @@ platforms:
method: config_file method: config_file
config: '%APPDATA%\RetroArch\retroarch.cfg' config: '%APPDATA%\RetroArch\retroarch.cfg'
parse_key: system_directory parse_key: system_directory
standalone_copies:
# Switch emulators (keys)
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
batocera: batocera:
config: batocera.yml config: batocera.yml
status: active status: active
@@ -256,6 +394,144 @@ platforms:
method: file_exists method: file_exists
file: /etc/batocera-version file: /etc/batocera-version
bios_path: /userdata/bios bios_path: /userdata/bios
standalone_copies:
# Switch emulators (keys)
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
recalbox: recalbox:
config: recalbox.yml config: recalbox.yml
status: active status: active
@@ -468,6 +744,144 @@ platforms:
method: file_exists method: file_exists
file: /usr/bin/recalbox-settings file: /usr/bin/recalbox-settings
bios_path: /recalbox/share/bios bios_path: /recalbox/share/bios
standalone_copies:
# Switch emulators (keys)
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
retrobat: retrobat:
config: retrobat.yml config: retrobat.yml
status: active status: active
@@ -653,6 +1067,144 @@ platforms:
- os: windows - os: windows
method: path_exists method: path_exists
path: '%USERPROFILE%\RetroBat\bios' path: '%USERPROFILE%\RetroBat\bios'
standalone_copies:
# Switch emulators (keys)
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
emudeck: emudeck:
config: emudeck.yml config: emudeck.yml
status: active status: active
@@ -681,19 +1233,143 @@ platforms:
parse_key: $emulationPath parse_key: $emulationPath
bios_subdir: bios bios_subdir: bios
standalone_copies: standalone_copies:
# Switch emulators (keys)
- file: prod.keys - file: prod.keys
targets: targets:
linux: linux:
- $HOME/.local/share/yuzu/keys - $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys - $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system - $HOME/.config/Ryujinx/system
windows: windows:
- '%APPDATA%\yuzu\keys' - '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys' - '%APPDATA%\eden\keys'
- file: aes_keys.txt - '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets: targets:
linux: linux:
- $HOME/Emulation/bios/citra/keys - $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
lakka: lakka:
config: lakka.yml config: lakka.yml
status: active status: active
@@ -719,6 +1395,10 @@ platforms:
source_format: github_component_manifests source_format: github_component_manifests
hash_type: md5 hash_type: md5
schedule: monthly schedule: monthly
contributed_by:
- username: monster-penguin
contribution: platform support
pr: 36
cores: cores:
- azahar - azahar
- cemu - cemu
@@ -748,7 +1428,145 @@ platforms:
- os: linux - os: linux
method: path_exists method: path_exists
path: $HOME/.var/app/net.retrodeck.retrodeck path: $HOME/.var/app/net.retrodeck.retrodeck
bios_path: $HOME/retrodeck/bios bios_path: $HOME/retrodeck
standalone_copies:
# Switch emulators (keys)
- file: prod.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
- $HOME/.config/Ryujinx/system
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
- '%APPDATA%\Ryujinx\system'
darwin:
- $HOME/Library/Application Support/yuzu/keys
- $HOME/Library/Application Support/Ryujinx/system
- file: title.keys
targets:
linux:
- $HOME/.local/share/yuzu/keys
- $HOME/.local/share/eden/keys
- $HOME/.local/share/citron/keys
- $HOME/.local/share/suyu/keys
windows:
- '%APPDATA%\yuzu\keys'
- '%APPDATA%\eden\keys'
- '%APPDATA%\citron\keys'
- '%APPDATA%\suyu\keys'
darwin:
- $HOME/Library/Application Support/yuzu/keys
# 3DS emulators
- file: Citra/sysdata/aes_keys.txt
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
- file: Citra/sysdata/boot9.bin
targets:
linux:
- $HOME/.local/share/azahar/sysdata
windows:
- '%APPDATA%\Azahar\sysdata'
# DuckStation (PS1)
- pattern: 'scph*.bin'
targets:
linux:
- $HOME/.local/share/duckstation/bios
windows:
- '%LOCALAPPDATA%\DuckStation\bios'
- '%USERPROFILE%\Documents\DuckStation\bios'
darwin:
- $HOME/Library/Application Support/DuckStation/bios
# PCSX2 (PS2)
- pattern: 'ps2-*.bin'
targets:
linux:
- $HOME/.config/PCSX2/bios
- $HOME/.var/app/net.pcsx2.PCSX2/config/PCSX2/bios
windows:
- '%USERPROFILE%\Documents\PCSX2\bios'
darwin:
- $HOME/Library/Application Support/PCSX2/bios
# RPCS3 (PS3) - needs menu install
- note: 'PS3 firmware (PS3UPDAT.PUP) found. Install via RPCS3 > File > Install Firmware.'
detect:
linux:
- $HOME/.config/rpcs3
windows:
- '%APPDATA%\rpcs3'
# Dolphin (GameCube)
- file: GC/USA/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/USA
windows:
- '%APPDATA%\Dolphin Emulator\GC\USA'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/USA
- file: GC/EUR/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/EUR
windows:
- '%APPDATA%\Dolphin Emulator\GC\EUR'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/EUR
- file: GC/JAP/IPL.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu/GC/JAP
windows:
- '%APPDATA%\Dolphin Emulator\GC\JAP'
darwin:
- $HOME/Library/Application Support/Dolphin/GC/JAP
- file: dsp_rom.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
- file: dsp_coef.bin
targets:
linux:
- $HOME/.local/share/dolphin-emu
windows:
- '%APPDATA%\Dolphin Emulator'
darwin:
- $HOME/Library/Application Support/Dolphin
# PPSSPP
- file: PPSSPP/ppge_atlas.zim
targets:
linux:
- $HOME/.config/ppsspp/PSP/SYSTEM
windows:
- '%USERPROFILE%\Documents\PPSSPP\PSP\SYSTEM'
darwin:
- $HOME/Library/Application Support/PPSSPP/PSP/SYSTEM
# Flycast (Dreamcast)
- file: dc/dc_boot.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
- file: dc/dc_nvmem.bin
targets:
linux:
- $HOME/.local/share/flycast/data
- $HOME/.var/app/org.flycast.Flycast/data/flycast
windows:
- '%APPDATA%\flycast\data'
romm: romm:
config: romm.yml config: romm.yml
status: active status: active
@@ -758,6 +1576,10 @@ platforms:
source_format: json source_format: json
hash_type: sha1 hash_type: sha1
schedule: monthly schedule: monthly
contributed_by:
- username: PixNyb
contribution: platform support
pr: 37
inherits_from: emulatorjs inherits_from: emulatorjs
target_scraper: null target_scraper: null
target_source: null target_source: null

View File

@@ -1646,7 +1646,7 @@ systems:
- name: sc3000.zip - name: sc3000.zip
destination: sc3000.zip destination: sc3000.zip
required: true required: true
md5: a6a47eae38600e41cc67e887e36e70b7 md5: fda6619ba96bf00b849192f5e7460622
zipped_file: sc3000.rom zipped_file: sc3000.rom
native_id: sc3000 native_id: sc3000
name: Sega SC-3000 name: Sega SC-3000
@@ -3552,64 +3552,6 @@ systems:
destination: bk/MONIT10.ROM destination: bk/MONIT10.ROM
required: true required: true
md5: 95f8c41c6abf7640e35a6a03cecebd01 md5: 95f8c41c6abf7640e35a6a03cecebd01
- name: bk0010.zip
destination: bk0010.zip
required: true
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 95f8c41c6abf7640e35a6a03cecebd01
zipped_file: monit10.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: eb9e1cf1c1b36a2dece89624bfc59323
zipped_file: focal.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 93d2776ecf9abf49fb45f58ce3182143
zipped_file: tests.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 4a4530347ee18c547a0563aca73cf43d
zipped_file: basic10-1.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 86fc2f7797a0333300159aa222c3ad3f
zipped_file: basic10-2.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: fb8875a62b9b02a66670dcefc270d441
zipped_file: basic10-3.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: c113a36e51f4557594817bc35a4b63b7
zipped_file: bk11m_328_basic2.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 823d35a8c98f70d2d378a2c7568c3b23
zipped_file: bk11m_329_basic3.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: 1e6637f32aa7d1de03510030cac40bcf
zipped_file: bk11m_327_basic1.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: dc52f365d56fa1951f5d35b1101b9e3f
zipped_file: bk11m_325_ext.rom
- name: bk0010.zip
destination: bk0010.zip
required: true
md5: fe4627d1e3a1535874085050733263e7
zipped_file: bk11m_324_bos.rom
native_id: bk native_id: bk
name: Elektronika BK name: Elektronika BK
standalone_cores: standalone_cores:

View File

@@ -4372,7 +4372,7 @@ systems:
- name: peribox_ev.zip - name: peribox_ev.zip
destination: bios/peribox_ev.zip destination: bios/peribox_ev.zip
required: true required: true
md5: e32bdbc9488e706ab0360db52e0eee63 md5: e32bdbc9488e706a30533540e059e0dc
- name: permedia2.zip - name: permedia2.zip
destination: bios/permedia2.zip destination: bios/permedia2.zip
required: true required: true
@@ -4384,7 +4384,7 @@ systems:
- name: peribox_gen.zip - name: peribox_gen.zip
destination: bios/peribox_gen.zip destination: bios/peribox_gen.zip
required: true required: true
md5: c35855fdc7f6a72fa11f80cfb94b3c80 md5: c35855fdc7f6a72f1e4c56a0e2eabf88
- name: peribox_sg.zip - name: peribox_sg.zip
destination: bios/peribox_sg.zip destination: bios/peribox_sg.zip
required: true required: true
@@ -7978,8 +7978,8 @@ systems:
- name: Vectrex_Bios.bin - name: Vectrex_Bios.bin
destination: bios/Vectrex_Bios.bin destination: bios/Vectrex_Bios.bin
required: false required: false
- name: VEC_MineStorm.vec - name: VEC_Minestorm.vec
destination: bios/VEC_MineStorm.vec destination: bios/VEC_Minestorm.vec
required: false required: false
vsmile: vsmile:
files: files:

View File

@@ -21,12 +21,17 @@ import json
import os import os
import subprocess import subprocess
import sys import sys
import urllib.request
import urllib.error import urllib.error
import urllib.request
from pathlib import Path from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from common import list_registered_platforms, load_database, load_platform_config, require_yaml from common import (
list_registered_platforms,
load_database,
load_platform_config,
require_yaml,
)
yaml = require_yaml() yaml = require_yaml()
@@ -83,14 +88,16 @@ def find_missing(config: dict, db: dict) -> list[dict]:
found = any(m in by_md5 for m in md5_list) found = any(m in by_md5 for m in md5_list)
if not found: if not found:
missing.append({ missing.append(
"name": name, {
"system": sys_id, "name": name,
"sha1": sha1, "system": sys_id,
"md5": md5, "sha1": sha1,
"size": file_entry.get("size"), "md5": md5,
"destination": file_entry.get("destination", name), "size": file_entry.get("size"),
}) "destination": file_entry.get("destination", name),
}
)
return missing return missing
@@ -139,14 +146,16 @@ def step2_scan_branches(entry: dict) -> bytes | None:
try: try:
subprocess.run( subprocess.run(
["git", "rev-parse", "--verify", ref], ["git", "rev-parse", "--verify", ref],
capture_output=True, check=True, capture_output=True,
check=True,
) )
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
continue continue
result = subprocess.run( result = subprocess.run(
["git", "ls-tree", "-r", "--name-only", ref], ["git", "ls-tree", "-r", "--name-only", ref],
capture_output=True, text=True, capture_output=True,
text=True,
) )
for filepath in result.stdout.strip().split("\n"): for filepath in result.stdout.strip().split("\n"):
@@ -154,7 +163,8 @@ def step2_scan_branches(entry: dict) -> bytes | None:
try: try:
blob = subprocess.run( blob = subprocess.run(
["git", "show", f"{ref}:{filepath}"], ["git", "show", f"{ref}:{filepath}"],
capture_output=True, check=True, capture_output=True,
check=True,
) )
if verify_content(blob.stdout, entry): if verify_content(blob.stdout, entry):
return blob.stdout return blob.stdout
@@ -172,7 +182,9 @@ def step3_search_public_repos(entry: dict) -> bytes | None:
for url_template in PUBLIC_REPOS: for url_template in PUBLIC_REPOS:
url = url_template.format(name=name) url = url_template.format(name=name)
try: try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"}) req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp) data = _read_limited(resp)
if data is None: if data is None:
@@ -185,7 +197,9 @@ def step3_search_public_repos(entry: dict) -> bytes | None:
if "/" in destination: if "/" in destination:
url = url_template.format(name=destination) url = url_template.format(name=destination)
try: try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"}) req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp) data = _read_limited(resp)
if data is None: if data is None:
@@ -206,7 +220,9 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
for path in [name, f"system/{name}", f"bios/{name}"]: for path in [name, f"system/{name}", f"bios/{name}"]:
url = f"https://archive.org/download/{collection_id}/{path}" url = f"https://archive.org/download/{collection_id}/{path}"
try: try:
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-fetch/1.0"}) req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
data = _read_limited(resp) data = _read_limited(resp)
if data is None: if data is None:
@@ -221,12 +237,13 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
return None return None
search_url = ( search_url = (
f"https://archive.org/advancedsearch.php?" f"https://archive.org/advancedsearch.php?q=sha1:{sha1}&output=json&rows=1"
f"q=sha1:{sha1}&output=json&rows=1"
) )
try: try:
req = urllib.request.Request(search_url, headers={"User-Agent": "retrobios-fetch/1.0"}) req = urllib.request.Request(
search_url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read()) result = json.loads(resp.read())
docs = result.get("response", {}).get("docs", []) docs = result.get("response", {}).get("docs", [])
@@ -235,7 +252,9 @@ def step4_search_archive_org(entry: dict) -> bytes | None:
if identifier: if identifier:
dl_url = f"https://archive.org/download/{identifier}/{name}" dl_url = f"https://archive.org/download/{identifier}/{name}"
try: try:
req2 = urllib.request.Request(dl_url, headers={"User-Agent": "retrobios-fetch/1.0"}) req2 = urllib.request.Request(
dl_url, headers={"User-Agent": "retrobios-fetch/1.0"}
)
with urllib.request.urlopen(req2, timeout=30) as resp2: with urllib.request.urlopen(req2, timeout=30) as resp2:
data = _read_limited(resp2) data = _read_limited(resp2)
if data is not None and verify_content(data, entry): if data is not None and verify_content(data, entry):
@@ -297,7 +316,7 @@ def fetch_missing(
continue continue
if dry_run: if dry_run:
print(f" [DRY RUN] Would search branches, repos, archive.org") print(" [DRY RUN] Would search branches, repos, archive.org")
still_missing.append(entry) still_missing.append(entry)
stats["not_found"] += 1 stats["not_found"] += 1
continue continue
@@ -323,7 +342,7 @@ def fetch_missing(
stats["found"] += 1 stats["found"] += 1
continue continue
print(f" [5] Not found - needs community contribution") print(" [5] Not found - needs community contribution")
still_missing.append(entry) still_missing.append(entry)
stats["not_found"] += 1 stats["not_found"] += 1
@@ -345,16 +364,20 @@ def generate_issue_body(missing: list[dict], platform: str) -> str:
for entry in missing: for entry in missing:
sha1 = entry.get("sha1") or "N/A" sha1 = entry.get("sha1") or "N/A"
md5 = entry.get("md5") or "N/A" md5 = entry.get("md5") or "N/A"
lines.append(f"| `{entry['name']}` | {entry['system']} | `{sha1[:12]}...` | `{md5[:12]}...` |") lines.append(
f"| `{entry['name']}` | {entry['system']} | `{sha1[:12]}...` | `{md5[:12]}...` |"
)
lines.extend([ lines.extend(
"", [
"### How to Contribute", "",
"", "### How to Contribute",
"1. Fork this repository", "",
"2. Add the BIOS file to `bios/Manufacturer/Console/`", "1. Fork this repository",
"3. Create a Pull Request - checksums are verified automatically", "2. Add the BIOS file to `bios/Manufacturer/Console/`",
]) "3. Create a Pull Request - checksums are verified automatically",
]
)
return "\n".join(lines) return "\n".join(lines)
@@ -363,11 +386,15 @@ def main():
parser = argparse.ArgumentParser(description="Auto-fetch missing BIOS files") parser = argparse.ArgumentParser(description="Auto-fetch missing BIOS files")
parser.add_argument("--platform", "-p", help="Platform to check") parser.add_argument("--platform", "-p", help="Platform to check")
parser.add_argument("--all", action="store_true", help="Check all platforms") parser.add_argument("--all", action="store_true", help="Check all platforms")
parser.add_argument("--dry-run", action="store_true", help="Don't download, just report") parser.add_argument(
"--dry-run", action="store_true", help="Don't download, just report"
)
parser.add_argument("--db", default=DEFAULT_DB) parser.add_argument("--db", default=DEFAULT_DB)
parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR) parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR)
parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR) parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR)
parser.add_argument("--create-issues", action="store_true", help="Output GitHub Issue bodies") parser.add_argument(
"--create-issues", action="store_true", help="Output GitHub Issue bodies"
)
args = parser.parse_args() args = parser.parse_args()
if not os.path.exists(args.db): if not os.path.exists(args.db):
@@ -378,7 +405,8 @@ def main():
if args.all: if args.all:
platforms = list_registered_platforms( platforms = list_registered_platforms(
args.platforms_dir, include_archived=True, args.platforms_dir,
include_archived=True,
) )
elif args.platform: elif args.platform:
platforms = [args.platform] platforms = [args.platform]
@@ -389,19 +417,19 @@ def main():
all_still_missing = {} all_still_missing = {}
for platform in sorted(platforms): for platform in sorted(platforms):
print(f"\n{'='*60}") print(f"\n{'=' * 60}")
print(f"Platform: {platform}") print(f"Platform: {platform}")
print(f"{'='*60}") print(f"{'=' * 60}")
try: try:
config = load_platform_config(platform, args.platforms_dir) config = load_platform_config(platform, args.platforms_dir)
except FileNotFoundError: except FileNotFoundError:
print(f" Config not found, skipping") print(" Config not found, skipping")
continue continue
missing = find_missing(config, db) missing = find_missing(config, db)
if not missing: if not missing:
print(f" All BIOS files present!") print(" All BIOS files present!")
continue continue
print(f" {len(missing)} missing files") print(f" {len(missing)} missing files")
@@ -414,9 +442,9 @@ def main():
print(f"\n Results: {stats['found']} found, {stats['not_found']} not found") print(f"\n Results: {stats['found']} found, {stats['not_found']} not found")
if args.create_issues and all_still_missing: if args.create_issues and all_still_missing:
print(f"\n{'='*60}") print(f"\n{'=' * 60}")
print("GitHub Issue Bodies") print("GitHub Issue Bodies")
print(f"{'='*60}") print(f"{'=' * 60}")
for platform, missing in all_still_missing.items(): for platform, missing in all_still_missing.items():
print(f"\n--- Issue for {platform} ---\n") print(f"\n--- Issue for {platform} ---\n")
print(generate_issue_body(missing, platform)) print(generate_issue_body(missing, platform))

View File

@@ -9,6 +9,7 @@ Usage:
python scripts/check_buildbot_system.py --update python scripts/check_buildbot_system.py --update
python scripts/check_buildbot_system.py --json python scripts/check_buildbot_system.py --json
""" """
from __future__ import annotations from __future__ import annotations
import argparse import argparse
@@ -36,10 +37,14 @@ def fetch_index() -> set[str]:
"""Fetch .index from buildbot, return set of ZIP filenames.""" """Fetch .index from buildbot, return set of ZIP filenames."""
req = urllib.request.Request(INDEX_URL, headers={"User-Agent": USER_AGENT}) req = urllib.request.Request(INDEX_URL, headers={"User-Agent": USER_AGENT})
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp: with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
return {line.strip() for line in resp.read().decode().splitlines() if line.strip()} return {
line.strip() for line in resp.read().decode().splitlines() if line.strip()
}
def load_tracked_entries(registry_path: str = DEFAULT_REGISTRY) -> dict[str, tuple[str, str]]: def load_tracked_entries(
registry_path: str = DEFAULT_REGISTRY,
) -> dict[str, tuple[str, str]]:
"""Load buildbot entries from _data_dirs.yml. """Load buildbot entries from _data_dirs.yml.
Returns {decoded_zip_name: (key, source_url)}. Returns {decoded_zip_name: (key, source_url)}.
@@ -64,8 +69,9 @@ def load_tracked_entries(registry_path: str = DEFAULT_REGISTRY) -> dict[str, tup
def get_remote_etag(url: str) -> str | None: def get_remote_etag(url: str) -> str | None:
"""HEAD request to get ETag.""" """HEAD request to get ETag."""
try: try:
req = urllib.request.Request(url, method="HEAD", req = urllib.request.Request(
headers={"User-Agent": USER_AGENT}) url, method="HEAD", headers={"User-Agent": USER_AGENT}
)
with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp: with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
return resp.headers.get("ETag") or resp.headers.get("Last-Modified") or "" return resp.headers.get("ETag") or resp.headers.get("Last-Modified") or ""
except (urllib.error.URLError, OSError): except (urllib.error.URLError, OSError):
@@ -114,8 +120,15 @@ def check(registry_path: str = DEFAULT_REGISTRY) -> dict:
status = "OK" status = "OK"
else: else:
status = "UPDATED" status = "UPDATED"
results.append({"zip": z, "status": status, "key": key, results.append(
"stored_etag": stored, "remote_etag": remote or ""}) {
"zip": z,
"status": status,
"key": key,
"stored_etag": stored,
"remote_etag": remote or "",
}
)
return {"entries": results} return {"entries": results}
@@ -144,8 +157,13 @@ def update_changed(report: dict) -> None:
if e["status"] == "UPDATED" and e.get("key"): if e["status"] == "UPDATED" and e.get("key"):
log.info("refreshing %s ...", e["key"]) log.info("refreshing %s ...", e["key"])
subprocess.run( subprocess.run(
[sys.executable, "scripts/refresh_data_dirs.py", [
"--force", "--key", e["key"]], sys.executable,
"scripts/refresh_data_dirs.py",
"--force",
"--key",
e["key"],
],
check=False, check=False,
) )
@@ -155,10 +173,15 @@ def main() -> None:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Check buildbot system directory for changes", description="Check buildbot system directory for changes",
) )
parser.add_argument("--update", action="store_true", parser.add_argument(
help="Auto-refresh changed entries") "--update", action="store_true", help="Auto-refresh changed entries"
parser.add_argument("--json", action="store_true", dest="json_output", )
help="Machine-readable JSON output") parser.add_argument(
"--json",
action="store_true",
dest="json_output",
help="Machine-readable JSON output",
)
parser.add_argument("--registry", default=DEFAULT_REGISTRY) parser.add_argument("--registry", default=DEFAULT_REGISTRY)
args = parser.parse_args() args = parser.parse_args()

View File

@@ -26,9 +26,11 @@ def require_yaml():
"""Import and return yaml, exiting if PyYAML is not installed.""" """Import and return yaml, exiting if PyYAML is not installed."""
try: try:
import yaml as _yaml import yaml as _yaml
return _yaml return _yaml
except ImportError: except ImportError:
import sys import sys
print("Error: PyYAML required (pip install pyyaml)", file=sys.stderr) print("Error: PyYAML required (pip install pyyaml)", file=sys.stderr)
sys.exit(1) sys.exit(1)
@@ -154,12 +156,17 @@ def load_platform_config(platform_name: str, platforms_dir: str = "platforms") -
if "inherits" in config: if "inherits" in config:
parent = load_platform_config(config["inherits"], platforms_dir) parent = load_platform_config(config["inherits"], platforms_dir)
merged = {**parent} merged = {**parent}
merged.update({k: v for k, v in config.items() if k not in ("inherits", "overrides")}) merged.update(
{k: v for k, v in config.items() if k not in ("inherits", "overrides")}
)
if "overrides" in config and "systems" in config["overrides"]: if "overrides" in config and "systems" in config["overrides"]:
merged.setdefault("systems", {}) merged.setdefault("systems", {})
for sys_id, override in config["overrides"]["systems"].items(): for sys_id, override in config["overrides"]["systems"].items():
if sys_id in merged["systems"]: if sys_id in merged["systems"]:
merged["systems"][sys_id] = {**merged["systems"][sys_id], **override} merged["systems"][sys_id] = {
**merged["systems"][sys_id],
**override,
}
else: else:
merged["systems"][sys_id] = override merged["systems"][sys_id] = override
config = merged config = merged
@@ -346,12 +353,14 @@ def list_available_targets(
result = [] result = []
for tname, tdata in sorted(data.get("targets", {}).items()): for tname, tdata in sorted(data.get("targets", {}).items()):
aliases = overrides.get(tname, {}).get("aliases", []) aliases = overrides.get(tname, {}).get("aliases", [])
result.append({ result.append(
"name": tname, {
"architecture": tdata.get("architecture", ""), "name": tname,
"core_count": len(tdata.get("cores", [])), "architecture": tdata.get("architecture", ""),
"aliases": aliases, "core_count": len(tdata.get("cores", [])),
}) "aliases": aliases,
}
)
return result return result
@@ -398,7 +407,9 @@ def resolve_local_file(
if hint_base and hint_base not in names_to_try: if hint_base and hint_base not in names_to_try:
names_to_try.append(hint_base) names_to_try.append(hint_base)
md5_list = [m.strip().lower() for m in md5_raw.split(",") if m.strip()] if md5_raw else [] md5_list = (
[m.strip().lower() for m in md5_raw.split(",") if m.strip()] if md5_raw else []
)
files_db = db.get("files", {}) files_db = db.get("files", {})
by_md5 = db.get("indexes", {}).get("by_md5", {}) by_md5 = db.get("indexes", {}).get("by_md5", {})
by_name = db.get("indexes", {}).get("by_name", {}) by_name = db.get("indexes", {}).get("by_name", {})
@@ -480,7 +491,9 @@ def resolve_local_file(
if candidates: if candidates:
if zipped_file: if zipped_file:
candidates = [(p, m) for p, m in candidates if ".zip" in os.path.basename(p)] candidates = [
(p, m) for p, m in candidates if ".zip" in os.path.basename(p)
]
if md5_set: if md5_set:
for path, db_md5 in candidates: for path, db_md5 in candidates:
if ".zip" in os.path.basename(path): if ".zip" in os.path.basename(path):
@@ -530,7 +543,11 @@ def resolve_local_file(
if canonical and canonical != name: if canonical and canonical != name:
canonical_entry = {"name": canonical} canonical_entry = {"name": canonical}
result = resolve_local_file( result = resolve_local_file(
canonical_entry, db, zip_contents, dest_hint, _depth=_depth + 1, canonical_entry,
db,
zip_contents,
dest_hint,
_depth=_depth + 1,
data_dir_registry=data_dir_registry, data_dir_registry=data_dir_registry,
) )
if result[0]: if result[0]:
@@ -643,9 +660,7 @@ def build_zip_contents_index(db: dict, max_entry_size: int = 512 * 1024 * 1024)
if path.endswith(".zip") and os.path.exists(path): if path.endswith(".zip") and os.path.exists(path):
zip_entries.append((path, sha1)) zip_entries.append((path, sha1))
fingerprint = frozenset( fingerprint = frozenset((path, os.path.getmtime(path)) for path, _ in zip_entries)
(path, os.path.getmtime(path)) for path, _ in zip_entries
)
if _zip_contents_cache is not None and _zip_contents_cache[0] == fingerprint: if _zip_contents_cache is not None and _zip_contents_cache[0] == fingerprint:
return _zip_contents_cache[1] return _zip_contents_cache[1]
@@ -672,7 +687,8 @@ _emulator_profiles_cache: dict[tuple[str, bool], dict[str, dict]] = {}
def load_emulator_profiles( def load_emulator_profiles(
emulators_dir: str, skip_aliases: bool = True, emulators_dir: str,
skip_aliases: bool = True,
) -> dict[str, dict]: ) -> dict[str, dict]:
"""Load all emulator YAML profiles from a directory (cached).""" """Load all emulator YAML profiles from a directory (cached)."""
cache_key = (os.path.realpath(emulators_dir), skip_aliases) cache_key = (os.path.realpath(emulators_dir), skip_aliases)
@@ -701,7 +717,8 @@ def load_emulator_profiles(
def group_identical_platforms( def group_identical_platforms(
platforms: list[str], platforms_dir: str, platforms: list[str],
platforms_dir: str,
target_cores_cache: dict[str, set[str] | None] | None = None, target_cores_cache: dict[str, set[str] | None] | None = None,
) -> list[tuple[list[str], str]]: ) -> list[tuple[list[str], str]]:
"""Group platforms that produce identical packs (same files + base_destination). """Group platforms that produce identical packs (same files + base_destination).
@@ -726,15 +743,13 @@ def group_identical_platforms(
inherits[platform] = False inherits[platform] = False
continue continue
base_dest = config.get("base_destination", "")
entries = [] entries = []
for sys_id, system in sorted(config.get("systems", {}).items()): for sys_id, system in sorted(config.get("systems", {}).items()):
for fe in system.get("files", []): for fe in system.get("files", []):
dest = fe.get("destination", fe.get("name", "")) dest = fe.get("destination", fe.get("name", ""))
full_dest = f"{base_dest}/{dest}" if base_dest else dest
sha1 = fe.get("sha1", "") sha1 = fe.get("sha1", "")
md5 = fe.get("md5", "") md5 = fe.get("md5", "")
entries.append(f"{full_dest}|{sha1}|{md5}") entries.append(f"{dest}|{sha1}|{md5}")
fp = hashlib.sha1("|".join(sorted(entries)).encode()).hexdigest() fp = hashlib.sha1("|".join(sorted(entries)).encode()).hexdigest()
if target_cores_cache: if target_cores_cache:
@@ -744,7 +759,9 @@ def group_identical_platforms(
fp = hashlib.sha1(f"{fp}|{tc_str}".encode()).hexdigest() fp = hashlib.sha1(f"{fp}|{tc_str}".encode()).hexdigest()
fingerprints.setdefault(fp, []).append(platform) fingerprints.setdefault(fp, []).append(platform)
# Prefer the root platform (no inherits) as representative # Prefer the root platform (no inherits) as representative
if fp not in representatives or (not inherits[platform] and inherits.get(representatives[fp], False)): if fp not in representatives or (
not inherits[platform] and inherits.get(representatives[fp], False)
):
representatives[fp] = platform representatives[fp] = platform
result = [] result = []
@@ -756,7 +773,8 @@ def group_identical_platforms(
def resolve_platform_cores( def resolve_platform_cores(
config: dict, profiles: dict[str, dict], config: dict,
profiles: dict[str, dict],
target_cores: set[str] | None = None, target_cores: set[str] | None = None,
) -> set[str]: ) -> set[str]:
"""Resolve which emulator profiles are relevant for a platform. """Resolve which emulator profiles are relevant for a platform.
@@ -773,9 +791,9 @@ def resolve_platform_cores(
if cores_config == "all_libretro": if cores_config == "all_libretro":
result = { result = {
name for name, p in profiles.items() name
if "libretro" in p.get("type", "") for name, p in profiles.items()
and p.get("type") != "alias" if "libretro" in p.get("type", "") and p.get("type") != "alias"
} }
elif isinstance(cores_config, list): elif isinstance(cores_config, list):
core_set = {str(c) for c in cores_config} core_set = {str(c) for c in cores_config}
@@ -786,25 +804,22 @@ def resolve_platform_cores(
core_to_profile[name] = name core_to_profile[name] = name
for core_name in p.get("cores", []): for core_name in p.get("cores", []):
core_to_profile[str(core_name)] = name core_to_profile[str(core_name)] = name
result = { result = {core_to_profile[c] for c in core_set if c in core_to_profile}
core_to_profile[c]
for c in core_set
if c in core_to_profile
}
# Support "all_libretro" as a list element: combines all libretro # Support "all_libretro" as a list element: combines all libretro
# profiles with explicitly listed standalone cores (e.g. RetroDECK # profiles with explicitly listed standalone cores (e.g. RetroDECK
# ships RetroArch + standalone emulators) # ships RetroArch + standalone emulators)
if "all_libretro" in core_set or "retroarch" in core_set: if "all_libretro" in core_set or "retroarch" in core_set:
result |= { result |= {
name for name, p in profiles.items() name
if "libretro" in p.get("type", "") for name, p in profiles.items()
and p.get("type") != "alias" if "libretro" in p.get("type", "") and p.get("type") != "alias"
} }
else: else:
# Fallback: system ID intersection with normalization # Fallback: system ID intersection with normalization
norm_plat_systems = {_norm_system_id(s) for s in config.get("systems", {})} norm_plat_systems = {_norm_system_id(s) for s in config.get("systems", {})}
result = { result = {
name for name, p in profiles.items() name
for name, p in profiles.items()
if {_norm_system_id(s) for s in p.get("systems", [])} & norm_plat_systems if {_norm_system_id(s) for s in p.get("systems", [])} & norm_plat_systems
and p.get("type") != "alias" and p.get("type") != "alias"
} }
@@ -826,11 +841,34 @@ def resolve_platform_cores(
MANUFACTURER_PREFIXES = ( MANUFACTURER_PREFIXES = (
"acorn-", "apple-", "microsoft-", "nintendo-", "sony-", "sega-", "acorn-",
"snk-", "panasonic-", "nec-", "epoch-", "mattel-", "fairchild-", "apple-",
"hartung-", "tiger-", "magnavox-", "philips-", "bandai-", "casio-", "microsoft-",
"coleco-", "commodore-", "sharp-", "sinclair-", "atari-", "sammy-", "nintendo-",
"gce-", "interton-", "texas-instruments-", "videoton-", "sony-",
"sega-",
"snk-",
"panasonic-",
"nec-",
"epoch-",
"mattel-",
"fairchild-",
"hartung-",
"tiger-",
"magnavox-",
"philips-",
"bandai-",
"casio-",
"coleco-",
"commodore-",
"sharp-",
"sinclair-",
"atari-",
"sammy-",
"gce-",
"interton-",
"texas-instruments-",
"videoton-",
) )
@@ -877,7 +915,7 @@ def _norm_system_id(sid: str) -> str:
s = SYSTEM_ALIASES.get(s, s) s = SYSTEM_ALIASES.get(s, s)
for prefix in MANUFACTURER_PREFIXES: for prefix in MANUFACTURER_PREFIXES:
if s.startswith(prefix): if s.startswith(prefix):
s = s[len(prefix):] s = s[len(prefix) :]
break break
return s.replace("-", "") return s.replace("-", "")
@@ -984,9 +1022,9 @@ def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
import re import re
_TIMESTAMP_PATTERNS = [ _TIMESTAMP_PATTERNS = [
re.compile(r'"generated_at":\s*"[^"]*"'), # database.json re.compile(r'"generated_at":\s*"[^"]*"'), # database.json
re.compile(r'\*Auto-generated on [^*]*\*'), # README.md re.compile(r"\*Auto-generated on [^*]*\*"), # README.md
re.compile(r'\*Generated on [^*]*\*'), # docs site pages re.compile(r"\*Generated on [^*]*\*"), # docs site pages
] ]
@@ -1023,8 +1061,12 @@ LARGE_FILES_REPO = "Abdess/retrobios"
LARGE_FILES_CACHE = ".cache/large" LARGE_FILES_CACHE = ".cache/large"
def fetch_large_file(name: str, dest_dir: str = LARGE_FILES_CACHE, def fetch_large_file(
expected_sha1: str = "", expected_md5: str = "") -> str | None: name: str,
dest_dir: str = LARGE_FILES_CACHE,
expected_sha1: str = "",
expected_md5: str = "",
) -> str | None:
"""Download a large file from the 'large-files' GitHub release if not cached.""" """Download a large file from the 'large-files' GitHub release if not cached."""
cached = os.path.join(dest_dir, name) cached = os.path.join(dest_dir, name)
if os.path.exists(cached): if os.path.exists(cached):
@@ -1033,7 +1075,9 @@ def fetch_large_file(name: str, dest_dir: str = LARGE_FILES_CACHE,
if expected_sha1 and hashes["sha1"].lower() != expected_sha1.lower(): if expected_sha1 and hashes["sha1"].lower() != expected_sha1.lower():
os.unlink(cached) os.unlink(cached)
elif expected_md5: elif expected_md5:
md5_list = [m.strip().lower() for m in expected_md5.split(",") if m.strip()] md5_list = [
m.strip().lower() for m in expected_md5.split(",") if m.strip()
]
if hashes["md5"].lower() not in md5_list: if hashes["md5"].lower() not in md5_list:
os.unlink(cached) os.unlink(cached)
else: else:
@@ -1122,8 +1166,9 @@ def list_platform_system_ids(platform_name: str, platforms_dir: str) -> None:
file_count = len(systems[sys_id].get("files", [])) file_count = len(systems[sys_id].get("files", []))
mfr = systems[sys_id].get("manufacturer", "") mfr = systems[sys_id].get("manufacturer", "")
mfr_display = f" [{mfr.split('|')[0]}]" if mfr else "" mfr_display = f" [{mfr.split('|')[0]}]" if mfr else ""
print(f" {sys_id:35s} ({file_count} file{'s' if file_count != 1 else ''}){mfr_display}") print(
f" {sys_id:35s} ({file_count} file{'s' if file_count != 1 else ''}){mfr_display}"
)
def build_target_cores_cache( def build_target_cores_cache(

View File

@@ -19,7 +19,13 @@ import sys
from pathlib import Path from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__)) sys.path.insert(0, os.path.dirname(__file__))
from common import list_registered_platforms, load_database, load_emulator_profiles, load_platform_config, require_yaml from common import (
list_registered_platforms,
load_database,
load_emulator_profiles,
load_platform_config,
require_yaml,
)
yaml = require_yaml() yaml = require_yaml()
@@ -28,11 +34,15 @@ DEFAULT_PLATFORMS_DIR = "platforms"
DEFAULT_DB = "database.json" DEFAULT_DB = "database.json"
def load_platform_files(platforms_dir: str) -> tuple[dict[str, set[str]], dict[str, set[str]]]: def load_platform_files(
platforms_dir: str,
) -> tuple[dict[str, set[str]], dict[str, set[str]]]:
"""Load all platform configs and collect declared filenames + data_directories per system.""" """Load all platform configs and collect declared filenames + data_directories per system."""
declared = {} declared = {}
platform_data_dirs = {} platform_data_dirs = {}
for platform_name in list_registered_platforms(platforms_dir, include_archived=True): for platform_name in list_registered_platforms(
platforms_dir, include_archived=True
):
config = load_platform_config(platform_name, platforms_dir) config = load_platform_config(platform_name, platforms_dir)
for sys_id, system in config.get("systems", {}).items(): for sys_id, system in config.get("systems", {}).items():
for fe in system.get("files", []): for fe in system.get("files", []):
@@ -46,8 +56,9 @@ def load_platform_files(platforms_dir: str) -> tuple[dict[str, set[str]], dict[s
return declared, platform_data_dirs return declared, platform_data_dirs
def _build_supplemental_index(data_root: str = "data", def _build_supplemental_index(
bios_root: str = "bios") -> set[str]: data_root: str = "data", bios_root: str = "bios"
) -> set[str]:
"""Build a set of filenames and directory names in data/ and inside bios/ ZIPs.""" """Build a set of filenames and directory names in data/ and inside bios/ ZIPs."""
names: set[str] = set() names: set[str] = set()
root_path = Path(data_root) root_path = Path(data_root)
@@ -76,12 +87,15 @@ def _build_supplemental_index(data_root: str = "data",
names.add(dpath.name + "/") names.add(dpath.name + "/")
names.add(dpath.name.lower() + "/") names.add(dpath.name.lower() + "/")
import zipfile import zipfile
for zpath in bios_path.rglob("*.zip"): for zpath in bios_path.rglob("*.zip"):
try: try:
with zipfile.ZipFile(zpath) as zf: with zipfile.ZipFile(zpath) as zf:
for member in zf.namelist(): for member in zf.namelist():
if not member.endswith("/"): if not member.endswith("/"):
basename = member.rsplit("/", 1)[-1] if "/" in member else member basename = (
member.rsplit("/", 1)[-1] if "/" in member else member
)
names.add(basename) names.add(basename)
names.add(basename.lower()) names.add(basename.lower())
except (zipfile.BadZipFile, OSError): except (zipfile.BadZipFile, OSError):
@@ -89,28 +103,55 @@ def _build_supplemental_index(data_root: str = "data",
return names return names
def _find_in_repo(fname: str, by_name: dict[str, list], by_name_lower: dict[str, str], def _resolve_source(
data_names: set[str] | None = None) -> bool: fname: str,
by_name: dict[str, list],
by_name_lower: dict[str, str],
data_names: set[str] | None = None,
by_path_suffix: dict | None = None,
) -> str | None:
"""Return the source category for a file, or None if not found.
Returns ``"bios"`` (in database.json / bios/), ``"data"`` (in data/),
or ``None`` (not available anywhere).
"""
# bios/ via database.json by_name
if fname in by_name: if fname in by_name:
return True return "bios"
# For directory entries or paths, extract the meaningful basename
stripped = fname.rstrip("/") stripped = fname.rstrip("/")
basename = stripped.rsplit("/", 1)[-1] if "/" in stripped else None basename = stripped.rsplit("/", 1)[-1] if "/" in stripped else None
if basename and basename in by_name: if basename and basename in by_name:
return True return "bios"
key = fname.lower() key = fname.lower()
if key in by_name_lower: if key in by_name_lower:
return True return "bios"
if basename: if basename:
key = basename.lower() if basename.lower() in by_name_lower:
if key in by_name_lower: return "bios"
return True # bios/ via by_path_suffix (regional variants)
if by_path_suffix and fname in by_path_suffix:
return "bios"
# data/ supplemental index
if data_names: if data_names:
if fname in data_names or key in data_names: if fname in data_names or key in data_names:
return True return "data"
if basename and (basename in data_names or basename.lower() in data_names): if basename and (basename in data_names or basename.lower() in data_names):
return True return "data"
return False return None
def _resolve_archive_source(
archive_name: str,
by_name: dict[str, list],
by_name_lower: dict[str, str],
data_names: set[str] | None = None,
by_path_suffix: dict | None = None,
) -> str:
"""Resolve source for an archive (ZIP) name, returning a source category string."""
result = _resolve_source(
archive_name, by_name, by_name_lower, data_names, by_path_suffix,
)
return result if result is not None else "missing"
def cross_reference( def cross_reference(
@@ -119,86 +160,184 @@ def cross_reference(
db: dict, db: dict,
platform_data_dirs: dict[str, set[str]] | None = None, platform_data_dirs: dict[str, set[str]] | None = None,
data_names: set[str] | None = None, data_names: set[str] | None = None,
all_declared: set[str] | None = None,
) -> dict: ) -> dict:
"""Compare emulator profiles against platform declarations. """Compare emulator profiles against platform declarations.
Returns a report with gaps (files emulators need but platforms don't list) Returns a report with gaps (files emulators need but platforms don't list)
and coverage stats. Files covered by matching data_directories between and coverage stats. Each gap entry carries a ``source`` field indicating
emulator profile and platform config are not reported as gaps. where the file is available: ``"bios"`` (bios/ via database.json),
Checks both bios/ (via database) and data/ (via data_names index). ``"data"`` (data/ directory), ``"large_file"`` (GitHub release asset),
or ``"missing"`` (not available anywhere).
The boolean ``in_repo`` is derived: ``source != "missing"``.
When *all_declared* is provided (flat set of every filename declared by
any platform for any system), it is used for the ``in_platform`` check
instead of the per-system lookup. This is appropriate for the global
gap analysis page where "undeclared" means "no platform declares it at all".
""" """
platform_data_dirs = platform_data_dirs or {} platform_data_dirs = platform_data_dirs or {}
by_name = db.get("indexes", {}).get("by_name", {}) by_name = db.get("indexes", {}).get("by_name", {})
by_name_lower = {k.lower(): k for k in by_name} by_name_lower = {k.lower(): k for k in by_name}
by_md5 = db.get("indexes", {}).get("by_md5", {})
by_path_suffix = db.get("indexes", {}).get("by_path_suffix", {})
db_files = db.get("files", {})
report = {} report = {}
for emu_name, profile in profiles.items(): for emu_name, profile in profiles.items():
emu_files = profile.get("files", []) emu_files = profile.get("files", [])
systems = profile.get("systems", []) systems = profile.get("systems", [])
platform_names = set() # Skip filename-agnostic profiles (BIOS detected without fixed names)
for sys_id in systems: if profile.get("bios_mode") == "agnostic":
platform_names.update(declared.get(sys_id, set())) continue
if all_declared is not None:
platform_names = all_declared
else:
platform_names = set()
for sys_id in systems:
platform_names.update(declared.get(sys_id, set()))
gaps = [] gaps = []
covered = [] covered = []
by_md5 = db.get("indexes", {}).get("by_md5", {}) unsourceable_list: list[dict] = []
archive_gaps: dict[str, dict] = {}
seen_files: set[str] = set()
for f in emu_files: for f in emu_files:
fname = f.get("name", "") fname = f.get("name", "")
if not fname: if not fname or fname in seen_files:
continue
# Collect unsourceable files separately (documented, not a gap)
unsourceable_reason = f.get("unsourceable", "")
if unsourceable_reason:
seen_files.add(fname)
unsourceable_list.append({
"name": fname,
"required": f.get("required", False),
"reason": unsourceable_reason,
"source_ref": f.get("source_ref", ""),
})
continue continue
# Skip pattern placeholders (e.g., <bios>.bin, <user-selected>.bin) # Skip pattern placeholders (e.g., <bios>.bin, <user-selected>.bin)
if "<" in fname or ">" in fname: if "<" in fname or ">" in fname or "*" in fname:
continue continue
# Skip UI-imported files with explicit path: null (not resolvable by pack) # Skip UI-imported files with explicit path: null (not resolvable by pack)
if "path" in f and f["path"] is None: if "path" in f and f["path"] is None:
continue continue
# Skip release asset files (stored in GitHub releases, not bios/)
if f.get("storage") == "release":
continue
# Skip standalone-only files # Skip standalone-only files
file_mode = f.get("mode", "both") file_mode = f.get("mode", "both")
if file_mode == "standalone": if file_mode == "standalone":
continue continue
# Skip files loaded from non-system directories (save_dir, content_dir)
load_from = f.get("load_from", "")
if load_from and load_from != "system_dir":
continue
# Skip filename-agnostic files (handled by agnostic scan)
if f.get("agnostic"):
continue
archive = f.get("archive")
# Check platform declaration (by name or archive)
in_platform = fname in platform_names in_platform = fname in platform_names
in_repo = _find_in_repo(fname, by_name, by_name_lower, data_names) if not in_platform and archive:
if not in_repo: in_platform = archive in platform_names
path_field = f.get("path", "")
if path_field and path_field != fname: if in_platform:
in_repo = _find_in_repo(path_field, by_name, by_name_lower, data_names) seen_files.add(fname)
# Try MD5 hash match (handles files that exist under different names) covered.append({
if not in_repo: "name": fname,
md5_raw = f.get("md5", "") "required": f.get("required", False),
if md5_raw: "in_platform": True,
for md5_val in md5_raw.split(","): })
md5_val = md5_val.strip().lower() continue
if md5_val and by_md5.get(md5_val):
in_repo = True seen_files.add(fname)
break
# Try SHA1 hash match # Group archived files by archive name
if not in_repo: if archive:
sha1 = f.get("sha1", "") if archive not in archive_gaps:
if sha1 and sha1 in db.get("files", {}): source = _resolve_archive_source(
in_repo = True archive, by_name, by_name_lower, data_names,
by_path_suffix,
)
archive_gaps[archive] = {
"name": archive,
"required": False,
"note": "",
"source_ref": "",
"in_platform": False,
"in_repo": source != "missing",
"source": source,
"archive": archive,
"archive_file_count": 0,
"archive_required_count": 0,
}
entry = archive_gaps[archive]
entry["archive_file_count"] += 1
if f.get("required", False):
entry["archive_required_count"] += 1
entry["required"] = True
if not entry["source_ref"] and f.get("source_ref"):
entry["source_ref"] = f["source_ref"]
continue
# --- resolve source provenance ---
storage = f.get("storage", "")
if storage in ("release", "large_file"):
source = "large_file"
else:
source = _resolve_source(
fname, by_name, by_name_lower, data_names, by_path_suffix
)
if source is None:
path_field = f.get("path", "")
if path_field and path_field != fname:
source = _resolve_source(
path_field, by_name, by_name_lower,
data_names, by_path_suffix,
)
# Try MD5 hash match
if source is None:
md5_raw = f.get("md5", "")
if md5_raw:
for md5_val in md5_raw.split(","):
md5_val = md5_val.strip().lower()
if md5_val and by_md5.get(md5_val):
source = "bios"
break
# Try SHA1 hash match
if source is None:
sha1 = f.get("sha1", "")
if sha1 and sha1 in db_files:
source = "bios"
if source is None:
source = "missing"
in_repo = source != "missing"
entry = { entry = {
"name": fname, "name": fname,
"required": f.get("required", False), "required": f.get("required", False),
"note": f.get("note", ""), "note": f.get("note", ""),
"source_ref": f.get("source_ref", ""), "source_ref": f.get("source_ref", ""),
"in_platform": in_platform, "in_platform": False,
"in_repo": in_repo, "in_repo": in_repo,
"source": source,
} }
gaps.append(entry)
if not in_platform: # Append grouped archive gaps
gaps.append(entry) for ag in sorted(archive_gaps.values(), key=lambda e: e["name"]):
else: gaps.append(ag)
covered.append(entry)
report[emu_name] = { report[emu_name] = {
"emulator": profile.get("emulator", emu_name), "emulator": profile.get("emulator", emu_name),
@@ -207,8 +346,12 @@ def cross_reference(
"platform_covered": len(covered), "platform_covered": len(covered),
"gaps": len(gaps), "gaps": len(gaps),
"gap_in_repo": sum(1 for g in gaps if g["in_repo"]), "gap_in_repo": sum(1 for g in gaps if g["in_repo"]),
"gap_missing": sum(1 for g in gaps if not g["in_repo"]), "gap_missing": sum(1 for g in gaps if g["source"] == "missing"),
"gap_bios": sum(1 for g in gaps if g["source"] == "bios"),
"gap_data": sum(1 for g in gaps if g["source"] == "data"),
"gap_large_file": sum(1 for g in gaps if g["source"] == "large_file"),
"gap_details": gaps, "gap_details": gaps,
"unsourceable": unsourceable_list,
} }
return report return report
@@ -220,37 +363,49 @@ def print_report(report: dict) -> None:
print("=" * 60) print("=" * 60)
total_gaps = 0 total_gaps = 0
total_in_repo = 0 totals: dict[str, int] = {"bios": 0, "data": 0, "large_file": 0, "missing": 0}
total_missing = 0
for emu_name, data in sorted(report.items()): for emu_name, data in sorted(report.items()):
gaps = data["gaps"] gaps = data["gaps"]
if gaps == 0: if gaps == 0:
status = "OK" continue
else:
status = f"{data['gap_in_repo']} in repo, {data['gap_missing']} missing" parts = []
for key in ("bios", "data", "large_file", "missing"):
count = data.get(f"gap_{key}", 0)
if count:
parts.append(f"{count} {key}")
status = ", ".join(parts) if parts else "OK"
print(f"\n{data['emulator']} ({', '.join(data['systems'])})") print(f"\n{data['emulator']} ({', '.join(data['systems'])})")
print(f" {data['total_files']} files in profile, " print(
f"{data['platform_covered']} declared by platforms, " f" {data['total_files']} files in profile, "
f"{gaps} undeclared") f"{data['platform_covered']} declared by platforms, "
f"{gaps} undeclared"
)
print(f" Gaps: {status}")
if gaps > 0: for g in data["gap_details"]:
print(f" Gaps: {status}") req = "*" if g["required"] else " "
for g in data["gap_details"]: src = g.get("source", "missing").upper()
req = "*" if g["required"] else " " note = f" -- {g['note']}" if g["note"] else ""
loc = "repo" if g["in_repo"] else "MISSING" archive_info = ""
note = f" -- {g['note']}" if g["note"] else "" if g.get("archive"):
print(f" {req} {g['name']} [{loc}]{note}") fc = g.get("archive_file_count", 0)
rc = g.get("archive_required_count", 0)
archive_info = f" ({fc} files, {rc} required)"
print(f" {req} {g['name']} [{src}]{archive_info}{note}")
total_gaps += gaps total_gaps += gaps
total_in_repo += data["gap_in_repo"] for key in totals:
total_missing += data["gap_missing"] totals[key] += data.get(f"gap_{key}", 0)
print(f"\n{'=' * 60}") print(f"\n{'=' * 60}")
print(f"Total: {total_gaps} undeclared files across all emulators") print(f"Total: {total_gaps} undeclared files across all emulators")
print(f" {total_in_repo} already in repo (can be added to packs)") available = totals["bios"] + totals["data"] + totals["large_file"]
print(f" {total_missing} missing from repo (need to be sourced)") print(f" {available} available (bios: {totals['bios']}, data: {totals['data']}, "
f"large_file: {totals['large_file']})")
print(f" {totals['missing']} missing (need to be sourced)")
def main(): def main():
@@ -259,7 +414,9 @@ def main():
parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR) parser.add_argument("--platforms-dir", default=DEFAULT_PLATFORMS_DIR)
parser.add_argument("--db", default=DEFAULT_DB) parser.add_argument("--db", default=DEFAULT_DB)
parser.add_argument("--emulator", "-e", help="Analyze single emulator") parser.add_argument("--emulator", "-e", help="Analyze single emulator")
parser.add_argument("--platform", "-p", help="Platform name (required for --target)") parser.add_argument(
"--platform", "-p", help="Platform name (required for --target)"
)
parser.add_argument("--target", "-t", help="Hardware target (e.g., switch, rpi4)") parser.add_argument("--target", "-t", help="Hardware target (e.g., switch, rpi4)")
parser.add_argument("--json", action="store_true", help="JSON output") parser.add_argument("--json", action="store_true", help="JSON output")
args = parser.parse_args() args = parser.parse_args()
@@ -272,7 +429,10 @@ def main():
if not args.platform: if not args.platform:
parser.error("--target requires --platform") parser.error("--target requires --platform")
from common import load_target_config, resolve_platform_cores from common import load_target_config, resolve_platform_cores
target_cores = load_target_config(args.platform, args.target, args.platforms_dir)
target_cores = load_target_config(
args.platform, args.target, args.platforms_dir
)
config = load_platform_config(args.platform, args.platforms_dir) config = load_platform_config(args.platform, args.platforms_dir)
relevant = resolve_platform_cores(config, profiles, target_cores=target_cores) relevant = resolve_platform_cores(config, profiles, target_cores=target_cores)
profiles = {k: v for k, v in profiles.items() if k in relevant} profiles = {k: v for k, v in profiles.items() if k in relevant}

View File

@@ -14,6 +14,7 @@ Source refs:
Azahar src/core/hw/rsa/rsa.cpp Azahar src/core/hw/rsa/rsa.cpp
Azahar src/core/file_sys/otp.cpp Azahar src/core/file_sys/otp.cpp
""" """
from __future__ import annotations from __future__ import annotations
import hashlib import hashlib
@@ -22,9 +23,9 @@ import subprocess
from collections.abc import Callable from collections.abc import Callable
from pathlib import Path from pathlib import Path
# Key file parsing (keys.txt / aes_keys.txt format) # Key file parsing (keys.txt / aes_keys.txt format)
def parse_keys_file(path: str | Path) -> dict[str, dict[str, bytes]]: def parse_keys_file(path: str | Path) -> dict[str, dict[str, bytes]]:
"""Parse a 3DS keys file with :AES, :RSA, :ECC sections. """Parse a 3DS keys file with :AES, :RSA, :ECC sections.
@@ -67,6 +68,7 @@ def find_keys_file(bios_dir: str | Path) -> Path | None:
# Pure Python RSA-2048 PKCS1v15 SHA256 verification (zero dependencies) # Pure Python RSA-2048 PKCS1v15 SHA256 verification (zero dependencies)
def _rsa_verify_pkcs1v15_sha256( def _rsa_verify_pkcs1v15_sha256(
message: bytes, message: bytes,
signature: bytes, signature: bytes,
@@ -98,14 +100,29 @@ def _rsa_verify_pkcs1v15_sha256(
# PKCS#1 v1.5 signature encoding: 0x00 0x01 [0xFF padding] 0x00 [DigestInfo] # PKCS#1 v1.5 signature encoding: 0x00 0x01 [0xFF padding] 0x00 [DigestInfo]
# DigestInfo for SHA-256: # DigestInfo for SHA-256:
# SEQUENCE { SEQUENCE { OID sha256, NULL }, OCTET STRING hash } # SEQUENCE { SEQUENCE { OID sha256, NULL }, OCTET STRING hash }
digest_info_prefix = bytes([ digest_info_prefix = bytes(
0x30, 0x31, # SEQUENCE (49 bytes) [
0x30, 0x0D, # SEQUENCE (13 bytes) 0x30,
0x06, 0x09, # OID (9 bytes) 0x31, # SEQUENCE (49 bytes)
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, # sha256 0x30,
0x05, 0x00, # NULL 0x0D, # SEQUENCE (13 bytes)
0x04, 0x20, # OCTET STRING (32 bytes) 0x06,
]) 0x09, # OID (9 bytes)
0x60,
0x86,
0x48,
0x01,
0x65,
0x03,
0x04,
0x02,
0x01, # sha256
0x05,
0x00, # NULL
0x04,
0x20, # OCTET STRING (32 bytes)
]
)
sha256_hash = hashlib.sha256(message).digest() sha256_hash = hashlib.sha256(message).digest()
expected_digest_info = digest_info_prefix + sha256_hash expected_digest_info = digest_info_prefix + sha256_hash
@@ -122,11 +139,13 @@ def _rsa_verify_pkcs1v15_sha256(
# AES-128-CBC decryption (with fallback) # AES-128-CBC decryption (with fallback)
def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
"""Decrypt AES-128-CBC without padding.""" """Decrypt AES-128-CBC without padding."""
# Try cryptography library first # Try cryptography library first
try: try:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
cipher = Cipher(algorithms.AES(key), modes.CBC(iv)) cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor() decryptor = cipher.decryptor()
return decryptor.update(data) + decryptor.finalize() return decryptor.update(data) + decryptor.finalize()
@@ -136,6 +155,7 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
# Try pycryptodome # Try pycryptodome
try: try:
from Crypto.Cipher import AES # type: ignore[import-untyped] from Crypto.Cipher import AES # type: ignore[import-untyped]
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.decrypt(data) return cipher.decrypt(data)
except ImportError: except ImportError:
@@ -145,8 +165,15 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
try: try:
result = subprocess.run( result = subprocess.run(
[ [
"openssl", "enc", "-aes-128-cbc", "-d", "openssl",
"-K", key.hex(), "-iv", iv.hex(), "-nopad", "enc",
"-aes-128-cbc",
"-d",
"-K",
key.hex(),
"-iv",
iv.hex(),
"-nopad",
], ],
input=data, input=data,
capture_output=True, capture_output=True,
@@ -162,6 +189,7 @@ def _aes_128_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
# File verification functions # File verification functions
def verify_secure_info_a( def verify_secure_info_a(
filepath: str | Path, filepath: str | Path,
keys: dict[str, dict[str, bytes]], keys: dict[str, dict[str, bytes]],
@@ -204,7 +232,10 @@ def verify_secure_info_a(
continue continue
modified_body = bytes([test_region]) + body[1:] modified_body = bytes([test_region]) + body[1:]
if _rsa_verify_pkcs1v15_sha256(modified_body, signature, modulus, exponent): if _rsa_verify_pkcs1v15_sha256(modified_body, signature, modulus, exponent):
return False, f"signature invalid (region changed from {test_region} to {region_byte})" return (
False,
f"signature invalid (region changed from {test_region} to {region_byte})",
)
return False, "signature invalid" return False, "signature invalid"
@@ -307,7 +338,7 @@ def verify_otp(
Returns (valid, reason_string). Returns (valid, reason_string).
""" """
from sect233r1 import ecdsa_verify_sha256, _ec_mul, _Gx, _Gy, _N from sect233r1 import _N, _ec_mul, _Gx, _Gy, ecdsa_verify_sha256
data = bytearray(Path(filepath).read_bytes()) data = bytearray(Path(filepath).read_bytes())
@@ -322,7 +353,10 @@ def verify_otp(
magic = struct.unpack_from("<I", data, 0)[0] magic = struct.unpack_from("<I", data, 0)[0]
if magic != 0xDEADB00F: if magic != 0xDEADB00F:
if not otp_key or not otp_iv: if not otp_key or not otp_iv:
return False, "encrypted OTP but missing AES keys (otpKey/otpIV) in keys file" return (
False,
"encrypted OTP but missing AES keys (otpKey/otpIV) in keys file",
)
try: try:
data = bytearray(_aes_128_cbc_decrypt(bytes(data), otp_key, otp_iv)) data = bytearray(_aes_128_cbc_decrypt(bytes(data), otp_key, otp_iv))
except RuntimeError as e: except RuntimeError as e:
@@ -343,7 +377,10 @@ def verify_otp(
ecc_keys = keys.get("ECC", {}) ecc_keys = keys.get("ECC", {})
root_public_xy = ecc_keys.get("rootPublicXY") root_public_xy = ecc_keys.get("rootPublicXY")
if not root_public_xy or len(root_public_xy) != 60: if not root_public_xy or len(root_public_xy) != 60:
return True, "decrypted, magic valid, SHA-256 valid (ECC skipped: no rootPublicXY)" return (
True,
"decrypted, magic valid, SHA-256 valid (ECC skipped: no rootPublicXY)",
)
# Extract CTCert fields from OTP body # Extract CTCert fields from OTP body
device_id = struct.unpack_from("<I", data, 0x04)[0] device_id = struct.unpack_from("<I", data, 0x04)[0]
@@ -368,9 +405,7 @@ def verify_otp(
pub_point = _ec_mul(priv_key_int, (_Gx, _Gy)) pub_point = _ec_mul(priv_key_int, (_Gx, _Gy))
if pub_point is None: if pub_point is None:
return False, "ECC cert: derived public key is point at infinity" return False, "ECC cert: derived public key is point at infinity"
pub_key_xy = ( pub_key_xy = pub_point[0].to_bytes(30, "big") + pub_point[1].to_bytes(30, "big")
pub_point[0].to_bytes(30, "big") + pub_point[1].to_bytes(30, "big")
)
# Build certificate body (what was signed) # Build certificate body (what was signed)
# Issuer: "Nintendo CA - G3_NintendoCTR2prod" or "...dev" # Issuer: "Nintendo CA - G3_NintendoCTR2prod" or "...dev"
@@ -379,12 +414,12 @@ def verify_otp(
issuer_str = b"Nintendo CA - G3_NintendoCTR2prod" issuer_str = b"Nintendo CA - G3_NintendoCTR2prod"
else: else:
issuer_str = b"Nintendo CA - G3_NintendoCTR2dev" issuer_str = b"Nintendo CA - G3_NintendoCTR2dev"
issuer[:len(issuer_str)] = issuer_str issuer[: len(issuer_str)] = issuer_str
# Name: "CT{device_id:08X}-{system_type:02X}" # Name: "CT{device_id:08X}-{system_type:02X}"
name = bytearray(0x40) name = bytearray(0x40)
name_str = f"CT{device_id:08X}-{system_type:02X}".encode() name_str = f"CT{device_id:08X}-{system_type:02X}".encode()
name[:len(name_str)] = name_str name[: len(name_str)] = name_str
# Key type = 2 (ECC), big-endian u32 # Key type = 2 (ECC), big-endian u32
key_type = struct.pack(">I", 2) key_type = struct.pack(">I", 2)

View File

@@ -17,6 +17,7 @@ Two types of deduplication:
After dedup, run generate_db.py --force to rebuild database indexes. After dedup, run generate_db.py --force to rebuild database indexes.
""" """
from __future__ import annotations from __future__ import annotations
import argparse import argparse
@@ -110,13 +111,10 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict:
unique_names = sorted(by_name.keys()) unique_names = sorted(by_name.keys())
if len(unique_names) > 1: if len(unique_names) > 1:
# Check if these are all in MAME/Arcade dirs AND all ZIPs # Check if these are all in MAME/Arcade dirs AND all ZIPs
all_mame_zip = ( all_mame_zip = all(
all( any(_is_mame_dir(p) for p in name_paths)
any(_is_mame_dir(p) for p in name_paths) for name_paths in by_name.values()
for name_paths in by_name.values() ) and all(n.endswith(".zip") for n in unique_names)
)
and all(n.endswith(".zip") for n in unique_names)
)
if all_mame_zip: if all_mame_zip:
# MAME device clones: different ZIP names, same ROM content # MAME device clones: different ZIP names, same ROM content
# Keep one canonical, remove clones, record in clone map # Keep one canonical, remove clones, record in clone map
@@ -202,7 +200,9 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict:
prefix = "Would remove" if dry_run else "Removed" prefix = "Would remove" if dry_run else "Removed"
print(f"\n{prefix}: {total_removed} files") print(f"\n{prefix}: {total_removed} files")
print(f"Space {'to save' if dry_run else 'saved'}: {total_saved / 1024 / 1024:.1f} MB") print(
f"Space {'to save' if dry_run else 'saved'}: {total_saved / 1024 / 1024:.1f} MB"
)
if not dry_run and empty_cleaned: if not dry_run and empty_cleaned:
print(f"Cleaned {empty_cleaned} empty directories") print(f"Cleaned {empty_cleaned} empty directories")
@@ -211,21 +211,27 @@ def deduplicate(bios_dir: str, dry_run: bool = False) -> dict:
clone_path = "_mame_clones.json" clone_path = "_mame_clones.json"
if dry_run: if dry_run:
print(f"\nWould write MAME clone map: {clone_path}") print(f"\nWould write MAME clone map: {clone_path}")
print(f" {len(mame_clones)} canonical ZIPs with " print(
f"{sum(len(v['clones']) for v in mame_clones.values())} clones") f" {len(mame_clones)} canonical ZIPs with "
f"{sum(len(v['clones']) for v in mame_clones.values())} clones"
)
else: else:
with open(clone_path, "w") as f: with open(clone_path, "w") as f:
json.dump(mame_clones, f, indent=2, sort_keys=True) json.dump(mame_clones, f, indent=2, sort_keys=True)
print(f"\nWrote MAME clone map: {clone_path}") print(f"\nWrote MAME clone map: {clone_path}")
print(f" {len(mame_clones)} canonical ZIPs with " print(
f"{sum(len(v['clones']) for v in mame_clones.values())} clones") f" {len(mame_clones)} canonical ZIPs with "
f"{sum(len(v['clones']) for v in mame_clones.values())} clones"
)
return results return results
def main() -> None: def main() -> None:
parser = argparse.ArgumentParser(description="Deduplicate bios/ directory") parser = argparse.ArgumentParser(description="Deduplicate bios/ directory")
parser.add_argument("--dry-run", action="store_true", help="Preview without deleting") parser.add_argument(
"--dry-run", action="store_true", help="Preview without deleting"
)
parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR) parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR)
args = parser.parse_args() args = parser.parse_args()

View File

@@ -22,10 +22,10 @@ Usage:
] ]
build_deterministic_zip("neogeo.zip", recipe, atom_store) build_deterministic_zip("neogeo.zip", recipe, atom_store)
""" """
from __future__ import annotations from __future__ import annotations
import hashlib import hashlib
import struct
import zipfile import zipfile
import zlib import zlib
from io import BytesIO from io import BytesIO
@@ -63,7 +63,9 @@ def build_deterministic_zip(
# Sort by filename for deterministic order # Sort by filename for deterministic order
sorted_recipe = sorted(recipe, key=lambda r: r["name"]) sorted_recipe = sorted(recipe, key=lambda r: r["name"])
with zipfile.ZipFile(str(output_path), "w", compression, compresslevel=_COMPRESS_LEVEL) as zf: with zipfile.ZipFile(
str(output_path), "w", compression, compresslevel=_COMPRESS_LEVEL
) as zf:
for entry in sorted_recipe: for entry in sorted_recipe:
name = entry["name"] name = entry["name"]
expected_crc = entry.get("crc32", "").lower() expected_crc = entry.get("crc32", "").lower()
@@ -127,12 +129,14 @@ def extract_atoms_with_names(zip_path: str | Path) -> list[dict]:
continue continue
data = zf.read(info.filename) data = zf.read(info.filename)
crc = format(zlib.crc32(data) & 0xFFFFFFFF, "08x") crc = format(zlib.crc32(data) & 0xFFFFFFFF, "08x")
result.append({ result.append(
"name": info.filename, {
"crc32": crc, "name": info.filename,
"size": len(data), "crc32": crc,
"data": data, "size": len(data),
}) "data": data,
}
)
return result return result
@@ -154,7 +158,9 @@ def verify_zip_determinism(zip_path: str | Path) -> tuple[bool, str, str]:
# Rebuild to memory # Rebuild to memory
buf = BytesIO() buf = BytesIO()
sorted_recipe = sorted(recipe, key=lambda r: r["name"]) sorted_recipe = sorted(recipe, key=lambda r: r["name"])
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED, compresslevel=_COMPRESS_LEVEL) as zf: with zipfile.ZipFile(
buf, "w", zipfile.ZIP_DEFLATED, compresslevel=_COMPRESS_LEVEL
) as zf:
for entry in sorted_recipe: for entry in sorted_recipe:
info = zipfile.ZipInfo(filename=entry["name"], date_time=_FIXED_DATE_TIME) info = zipfile.ZipInfo(filename=entry["name"], date_time=_FIXED_DATE_TIME)
info.compress_type = zipfile.ZIP_DEFLATED info.compress_type = zipfile.ZIP_DEFLATED

View File

@@ -78,13 +78,17 @@ def _format_terminal(report: dict) -> str:
lines.append(f" + {m['name']} [{cores}]") lines.append(f" + {m['name']} [{cores}]")
for h in div.get("hash_mismatch", []): for h in div.get("hash_mismatch", []):
ht = h["hash_type"] ht = h["hash_type"]
lines.append(f" ~ {h['name']} {ht}: {h[f'truth_{ht}']} != {h[f'scraped_{ht}']}") lines.append(
f" ~ {h['name']} {ht}: {h[f'truth_{ht}']} != {h[f'scraped_{ht}']}"
)
for p in div.get("extra_phantom", []): for p in div.get("extra_phantom", []):
lines.append(f" - {p['name']} (phantom)") lines.append(f" - {p['name']} (phantom)")
for u in div.get("extra_unprofiled", []): for u in div.get("extra_unprofiled", []):
lines.append(f" ? {u['name']} (unprofiled)") lines.append(f" ? {u['name']} (unprofiled)")
for r in div.get("required_mismatch", []): for r in div.get("required_mismatch", []):
lines.append(f" ! {r['name']} required: {r['truth_required']} != {r['scraped_required']}") lines.append(
f" ! {r['name']} required: {r['truth_required']} != {r['scraped_required']}"
)
uncovered = report.get("uncovered_systems", []) uncovered = report.get("uncovered_systems", [])
if uncovered: if uncovered:
@@ -125,13 +129,17 @@ def _format_markdown(report: dict) -> str:
lines.append(f"- **Add** `{m['name']}`{refs}") lines.append(f"- **Add** `{m['name']}`{refs}")
for h in div.get("hash_mismatch", []): for h in div.get("hash_mismatch", []):
ht = h["hash_type"] ht = h["hash_type"]
lines.append(f"- **Fix hash** `{h['name']}` {ht}: `{h[f'truth_{ht}']}` != `{h[f'scraped_{ht}']}`") lines.append(
f"- **Fix hash** `{h['name']}` {ht}: `{h[f'truth_{ht}']}` != `{h[f'scraped_{ht}']}`"
)
for p in div.get("extra_phantom", []): for p in div.get("extra_phantom", []):
lines.append(f"- **Remove** `{p['name']}` (phantom)") lines.append(f"- **Remove** `{p['name']}` (phantom)")
for u in div.get("extra_unprofiled", []): for u in div.get("extra_unprofiled", []):
lines.append(f"- **Check** `{u['name']}` (unprofiled cores)") lines.append(f"- **Check** `{u['name']}` (unprofiled cores)")
for r in div.get("required_mismatch", []): for r in div.get("required_mismatch", []):
lines.append(f"- **Fix required** `{r['name']}`: truth={r['truth_required']}, scraped={r['scraped_required']}") lines.append(
f"- **Fix required** `{r['name']}`: truth={r['truth_required']}, scraped={r['scraped_required']}"
)
lines.append("") lines.append("")
uncovered = report.get("uncovered_systems", []) uncovered = report.get("uncovered_systems", [])
@@ -148,17 +156,25 @@ def _format_markdown(report: dict) -> str:
def main() -> None: def main() -> None:
parser = argparse.ArgumentParser(description="Compare scraped vs truth YAMLs") parser = argparse.ArgumentParser(description="Compare scraped vs truth YAMLs")
group = parser.add_mutually_exclusive_group(required=True) group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--all", action="store_true", help="diff all registered platforms") group.add_argument(
"--all", action="store_true", help="diff all registered platforms"
)
group.add_argument("--platform", help="diff a single platform") group.add_argument("--platform", help="diff a single platform")
parser.add_argument("--json", action="store_true", dest="json_output", help="JSON output") parser.add_argument(
parser.add_argument("--format", choices=["terminal", "markdown"], default="terminal") "--json", action="store_true", dest="json_output", help="JSON output"
)
parser.add_argument(
"--format", choices=["terminal", "markdown"], default="terminal"
)
parser.add_argument("--truth-dir", default="dist/truth") parser.add_argument("--truth-dir", default="dist/truth")
parser.add_argument("--platforms-dir", default="platforms") parser.add_argument("--platforms-dir", default="platforms")
parser.add_argument("--include-archived", action="store_true") parser.add_argument("--include-archived", action="store_true")
args = parser.parse_args() args = parser.parse_args()
if args.all: if args.all:
platforms = list_registered_platforms(args.platforms_dir, include_archived=args.include_archived) platforms = list_registered_platforms(
args.platforms_dir, include_archived=args.include_archived
)
else: else:
platforms = [args.platform] platforms = [args.platform]
@@ -169,7 +185,10 @@ def main() -> None:
truth = _load_truth(args.truth_dir, platform) truth = _load_truth(args.truth_dir, platform)
if truth is None: if truth is None:
if not args.json_output: if not args.json_output:
print(f"skip {platform}: no truth YAML in {args.truth_dir}/", file=sys.stderr) print(
f"skip {platform}: no truth YAML in {args.truth_dir}/",
file=sys.stderr,
)
continue continue
try: try:

View File

@@ -16,8 +16,8 @@ import argparse
import json import json
import os import os
import sys import sys
import urllib.request
import urllib.error import urllib.error
import urllib.request
import zipfile import zipfile
from pathlib import Path from pathlib import Path
@@ -31,10 +31,13 @@ REPO = "Abdess/retrobios"
def get_latest_release() -> dict: def get_latest_release() -> dict:
"""Fetch latest release info from GitHub API.""" """Fetch latest release info from GitHub API."""
url = f"{GITHUB_API}/repos/{REPO}/releases/latest" url = f"{GITHUB_API}/repos/{REPO}/releases/latest"
req = urllib.request.Request(url, headers={ req = urllib.request.Request(
"User-Agent": "retrobios-downloader/1.0", url,
"Accept": "application/vnd.github.v3+json", headers={
}) "User-Agent": "retrobios-downloader/1.0",
"Accept": "application/vnd.github.v3+json",
},
)
try: try:
with urllib.request.urlopen(req, timeout=30) as resp: with urllib.request.urlopen(req, timeout=30) as resp:
@@ -71,7 +74,9 @@ def find_asset(release: dict, platform: str) -> dict | None:
def download_file(url: str, dest: str, expected_size: int = 0): def download_file(url: str, dest: str, expected_size: int = 0):
"""Download a file with progress indication.""" """Download a file with progress indication."""
req = urllib.request.Request(url, headers={"User-Agent": "retrobios-downloader/1.0"}) req = urllib.request.Request(
url, headers={"User-Agent": "retrobios-downloader/1.0"}
)
with urllib.request.urlopen(req, timeout=300) as resp: with urllib.request.urlopen(req, timeout=300) as resp:
total = int(resp.headers.get("Content-Length", expected_size)) total = int(resp.headers.get("Content-Length", expected_size))
@@ -88,7 +93,11 @@ def download_file(url: str, dest: str, expected_size: int = 0):
if total > 0: if total > 0:
pct = downloaded * 100 // total pct = downloaded * 100 // total
bar = "=" * (pct // 2) + " " * (50 - pct // 2) bar = "=" * (pct // 2) + " " * (50 - pct // 2)
print(f"\r [{bar}] {pct}% ({downloaded:,}/{total:,})", end="", flush=True) print(
f"\r [{bar}] {pct}% ({downloaded:,}/{total:,})",
end="",
flush=True,
)
print() print()
@@ -114,11 +123,14 @@ def verify_files(platform: str, dest_dir: str, release: dict):
return return
import tempfile import tempfile
tmp = tempfile.NamedTemporaryFile(suffix=".json", delete=False) tmp = tempfile.NamedTemporaryFile(suffix=".json", delete=False)
tmp.close() tmp.close()
try: try:
download_file(db_asset["browser_download_url"], tmp.name, db_asset.get("size", 0)) download_file(
db_asset["browser_download_url"], tmp.name, db_asset.get("size", 0)
)
with open(tmp.name) as f: with open(tmp.name) as f:
db = json.load(f) db = json.load(f)
finally: finally:
@@ -142,7 +154,9 @@ def verify_files(platform: str, dest_dir: str, release: dict):
break break
else: else:
mismatched += 1 mismatched += 1
print(f" MISMATCH: {name} (expected {sha1[:12]}..., got {local_sha1[:12]}...)") print(
f" MISMATCH: {name} (expected {sha1[:12]}..., got {local_sha1[:12]}...)"
)
found = True found = True
break break
@@ -166,7 +180,7 @@ def show_info(platform: str, release: dict):
print(f" Platform: {platform}") print(f" Platform: {platform}")
print(f" File: {asset['name']}") print(f" File: {asset['name']}")
print(f" Size: {asset['size']:,} bytes ({asset['size'] / (1024*1024):.1f} MB)") print(f" Size: {asset['size']:,} bytes ({asset['size'] / (1024 * 1024):.1f} MB)")
print(f" Downloads: {asset.get('download_count', 'N/A')}") print(f" Downloads: {asset.get('download_count', 'N/A')}")
print(f" Updated: {asset.get('updated_at', 'N/A')}") print(f" Updated: {asset.get('updated_at', 'N/A')}")
@@ -200,7 +214,12 @@ Examples:
print(f" - {p}") print(f" - {p}")
else: else:
print("No platform packs found in latest release") print("No platform packs found in latest release")
except (urllib.error.URLError, urllib.error.HTTPError, OSError, json.JSONDecodeError) as e: except (
urllib.error.URLError,
urllib.error.HTTPError,
OSError,
json.JSONDecodeError,
) as e:
print(f"Error: {e}") print(f"Error: {e}")
return return
@@ -233,6 +252,7 @@ Examples:
sys.exit(1) sys.exit(1)
import tempfile import tempfile
fd, zip_path = tempfile.mkstemp(suffix=".zip") fd, zip_path = tempfile.mkstemp(suffix=".zip")
os.close(fd) os.close(fd)

View File

@@ -9,11 +9,9 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent)) sys.path.insert(0, str(Path(__file__).resolve().parent))
import yaml import yaml
from common import list_registered_platforms, load_platform_config from common import list_registered_platforms, load_platform_config
from exporter import discover_exporters from exporter import discover_exporters
OUTPUT_FILENAMES: dict[str, str] = { OUTPUT_FILENAMES: dict[str, str] = {
"retroarch": "System.dat", "retroarch": "System.dat",
"lakka": "System.dat", "lakka": "System.dat",
@@ -94,23 +92,31 @@ def main() -> None:
group.add_argument("--all", action="store_true", help="export all platforms") group.add_argument("--all", action="store_true", help="export all platforms")
group.add_argument("--platform", help="export a single platform") group.add_argument("--platform", help="export a single platform")
parser.add_argument( parser.add_argument(
"--output-dir", default="dist/upstream", help="output directory", "--output-dir",
default="dist/upstream",
help="output directory",
) )
parser.add_argument( parser.add_argument(
"--truth-dir", default="dist/truth", help="truth YAML directory", "--truth-dir",
default="dist/truth",
help="truth YAML directory",
) )
parser.add_argument( parser.add_argument(
"--platforms-dir", default="platforms", help="platform configs directory", "--platforms-dir",
default="platforms",
help="platform configs directory",
) )
parser.add_argument( parser.add_argument(
"--include-archived", action="store_true", "--include-archived",
action="store_true",
help="include archived platforms", help="include archived platforms",
) )
args = parser.parse_args() args = parser.parse_args()
if args.all: if args.all:
platforms = list_registered_platforms( platforms = list_registered_platforms(
args.platforms_dir, include_archived=args.include_archived, args.platforms_dir,
include_archived=args.include_archived,
) )
else: else:
platforms = [args.platform] platforms = [args.platform]

View File

@@ -38,7 +38,8 @@ class BaseExporter(ABC):
@staticmethod @staticmethod
def _display_name( def _display_name(
sys_id: str, scraped_sys: dict | None = None, sys_id: str,
scraped_sys: dict | None = None,
) -> str: ) -> str:
"""Get display name for a system from scraped data or slug.""" """Get display name for a system from scraped data or slug."""
if scraped_sys: if scraped_sys:
@@ -47,9 +48,28 @@ class BaseExporter(ABC):
return name return name
# Fallback: convert slug to display name with acronym handling # Fallback: convert slug to display name with acronym handling
_UPPER = { _UPPER = {
"3do", "cdi", "cpc", "cps1", "cps2", "cps3", "dos", "gba", "3do",
"gbc", "hle", "msx", "nes", "nds", "ngp", "psp", "psx", "cdi",
"sms", "snes", "stv", "tvc", "vb", "zx", "cpc",
"cps1",
"cps2",
"cps3",
"dos",
"gba",
"gbc",
"hle",
"msx",
"nes",
"nds",
"ngp",
"psp",
"psx",
"sms",
"snes",
"stv",
"tvc",
"vb",
"zx",
} }
parts = sys_id.replace("-", " ").split() parts = sys_id.replace("-", " ").split()
result = [] result = []

View File

@@ -11,8 +11,6 @@ from pathlib import Path
from .base_exporter import BaseExporter from .base_exporter import BaseExporter
class Exporter(BaseExporter): class Exporter(BaseExporter):
"""Export truth data to Batocera batocera-systems format.""" """Export truth data to Batocera batocera-systems format."""
@@ -44,7 +42,9 @@ class Exporter(BaseExporter):
continue continue
native_id = native_map.get(sys_id, sys_id) native_id = native_map.get(sys_id, sys_id)
scraped_sys = scraped_data.get("systems", {}).get(sys_id) if scraped_data else None scraped_sys = (
scraped_data.get("systems", {}).get(sys_id) if scraped_data else None
)
display_name = self._display_name(sys_id, scraped_sys) display_name = self._display_name(sys_id, scraped_sys)
# Build md5 lookup from scraped data for this system # Build md5 lookup from scraped data for this system
@@ -74,9 +74,7 @@ class Exporter(BaseExporter):
# Original format requires md5 for every entry — skip without # Original format requires md5 for every entry — skip without
if not md5: if not md5:
continue continue
bios_parts.append( bios_parts.append(f'{{ "md5": "{md5}", "file": "bios/{dest}" }}')
f'{{ "md5": "{md5}", "file": "bios/{dest}" }}'
)
bios_str = ", ".join(bios_parts) bios_str = ", ".join(bios_parts)
line = ( line = (

View File

@@ -156,7 +156,9 @@ class Exporter(BaseExporter):
continue continue
md5 = fe.get("md5", "") md5 = fe.get("md5", "")
if isinstance(md5, list): if isinstance(md5, list):
md5s.extend(m for m in md5 if m and re.fullmatch(r"[a-f0-9]{32}", m)) md5s.extend(
m for m in md5 if m and re.fullmatch(r"[a-f0-9]{32}", m)
)
elif md5 and re.fullmatch(r"[a-f0-9]{32}", md5): elif md5 and re.fullmatch(r"[a-f0-9]{32}", md5):
md5s.append(md5) md5s.append(md5)
if md5s: if md5s:
@@ -195,7 +197,8 @@ class Exporter(BaseExporter):
# Only flag if the system has usable data for the function type # Only flag if the system has usable data for the function type
if cfg["pattern"] == "md5": if cfg["pattern"] == "md5":
has_md5 = any( has_md5 = any(
fe.get("md5") and isinstance(fe.get("md5"), str) fe.get("md5")
and isinstance(fe.get("md5"), str)
and re.fullmatch(r"[a-f0-9]{32}", fe["md5"]) and re.fullmatch(r"[a-f0-9]{32}", fe["md5"])
for fe in sys_data["files"] for fe in sys_data["files"]
) )

View File

@@ -15,8 +15,6 @@ from pathlib import Path
from .base_exporter import BaseExporter from .base_exporter import BaseExporter
class Exporter(BaseExporter): class Exporter(BaseExporter):
"""Export truth data to Recalbox es_bios.xml format.""" """Export truth data to Recalbox es_bios.xml format."""
@@ -51,7 +49,9 @@ class Exporter(BaseExporter):
continue continue
native_id = native_map.get(sys_id, sys_id) native_id = native_map.get(sys_id, sys_id)
scraped_sys = scraped_data.get("systems", {}).get(sys_id) if scraped_data else None scraped_sys = (
scraped_data.get("systems", {}).get(sys_id) if scraped_data else None
)
display_name = self._display_name(sys_id, scraped_sys) display_name = self._display_name(sys_id, scraped_sys)
lines.append(f' <system fullname="{display_name}" platform="{native_id}">') lines.append(f' <system fullname="{display_name}" platform="{native_id}">')
@@ -85,7 +85,9 @@ class Exporter(BaseExporter):
# Build cores string from _cores # Build cores string from _cores
cores_list = fe.get("_cores", []) cores_list = fe.get("_cores", [])
core_str = ",".join(f"libretro/{c}" for c in cores_list) if cores_list else "" core_str = (
",".join(f"libretro/{c}" for c in cores_list) if cores_list else ""
)
attrs = [f'path="{path}"'] attrs = [f'path="{path}"']
if md5: if md5:
@@ -97,7 +99,7 @@ class Exporter(BaseExporter):
if core_str: if core_str:
attrs.append(f'core="{core_str}"') attrs.append(f'core="{core_str}"')
lines.append(f' <bios {" ".join(attrs)} />') lines.append(f" <bios {' '.join(attrs)} />")
lines.append(" </system>") lines.append(" </system>")
@@ -125,6 +127,9 @@ class Exporter(BaseExporter):
if name.startswith("_") or self._is_pattern(name): if name.startswith("_") or self._is_pattern(name):
continue continue
dest = self._dest(fe) dest = self._dest(fe)
if name.lower() not in exported_paths and dest.lower() not in exported_paths: if (
name.lower() not in exported_paths
and dest.lower() not in exported_paths
):
issues.append(f"missing: {name}") issues.append(f"missing: {name}")
return issues return issues

View File

@@ -15,8 +15,6 @@ from pathlib import Path
from .base_exporter import BaseExporter from .base_exporter import BaseExporter
class Exporter(BaseExporter): class Exporter(BaseExporter):
"""Export truth data to RetroBat batocera-systems.json format.""" """Export truth data to RetroBat batocera-systems.json format."""
@@ -47,7 +45,9 @@ class Exporter(BaseExporter):
continue continue
native_id = native_map.get(sys_id, sys_id) native_id = native_map.get(sys_id, sys_id)
scraped_sys = scraped_data.get("systems", {}).get(sys_id) if scraped_data else None scraped_sys = (
scraped_data.get("systems", {}).get(sys_id) if scraped_data else None
)
display_name = self._display_name(sys_id, scraped_sys) display_name = self._display_name(sys_id, scraped_sys)
bios_files: list[OrderedDict] = [] bios_files: list[OrderedDict] = []
@@ -70,7 +70,9 @@ class Exporter(BaseExporter):
if bios_files: if bios_files:
if native_id in output: if native_id in output:
existing_files = {e.get("file") for e in output[native_id]["biosFiles"]} existing_files = {
e.get("file") for e in output[native_id]["biosFiles"]
}
for entry in bios_files: for entry in bios_files:
if entry.get("file") not in existing_files: if entry.get("file") not in existing_files:
output[native_id]["biosFiles"].append(entry) output[native_id]["biosFiles"].append(entry)

View File

@@ -170,7 +170,9 @@ class Exporter(BaseExporter):
if native_id in manifest: if native_id in manifest:
# Merge into existing component (multiple truth systems # Merge into existing component (multiple truth systems
# may map to the same native ID) # may map to the same native ID)
existing_names = {e["filename"] for e in manifest[native_id]["bios"]} existing_names = {
e["filename"] for e in manifest[native_id]["bios"]
}
for entry in bios_entries: for entry in bios_entries:
if entry["filename"] not in existing_names: if entry["filename"] not in existing_names:
manifest[native_id]["bios"].append(entry) manifest[native_id]["bios"].append(entry)

View File

@@ -58,16 +58,18 @@ class Exporter(BaseExporter):
] ]
if version: if version:
lines.append(f"\tversion {version}") lines.append(f"\tversion {version}")
lines.extend([ lines.extend(
'\tauthor "libretro"', [
'\thomepage "https://github.com/libretro/libretro-database/blob/master/dat/System.dat"', '\tauthor "libretro"',
'\turl "https://raw.githubusercontent.com/libretro/libretro-database/master/dat/System.dat"', '\thomepage "https://github.com/libretro/libretro-database/blob/master/dat/System.dat"',
")", '\turl "https://raw.githubusercontent.com/libretro/libretro-database/master/dat/System.dat"',
"", ")",
"game (", "",
'\tname "System"', "game (",
'\tcomment "System"', '\tname "System"',
]) '\tcomment "System"',
]
)
systems = truth_data.get("systems", {}) systems = truth_data.get("systems", {})
for sys_id in sorted(systems): for sys_id in sorted(systems):

View File

@@ -44,7 +44,11 @@ def _canonical_name(filepath: Path) -> str:
if "/.variants/" in str(filepath) or "\\.variants\\" in str(filepath): if "/.variants/" in str(filepath) or "\\.variants\\" in str(filepath):
# naomi2.zip.da79eca4 -> naomi2.zip # naomi2.zip.da79eca4 -> naomi2.zip
parts = name.rsplit(".", 1) parts = name.rsplit(".", 1)
if len(parts) == 2 and len(parts[1]) == 8 and all(c in "0123456789abcdef" for c in parts[1]): if (
len(parts) == 2
and len(parts[1]) == 8
and all(c in "0123456789abcdef" for c in parts[1])
):
return parts[0] return parts[0]
return name return name
@@ -83,7 +87,9 @@ def scan_bios_dir(bios_dir: Path, cache: dict, force: bool) -> tuple[dict, dict,
if existing_is_variant and not is_variant: if existing_is_variant and not is_variant:
if sha1 not in aliases: if sha1 not in aliases:
aliases[sha1] = [] aliases[sha1] = []
aliases[sha1].append({"name": files[sha1]["name"], "path": files[sha1]["path"]}) aliases[sha1].append(
{"name": files[sha1]["name"], "path": files[sha1]["path"]}
)
files[sha1] = { files[sha1] = {
"path": rel_path, "path": rel_path,
"name": _canonical_name(filepath), "name": _canonical_name(filepath),
@@ -93,7 +99,9 @@ def scan_bios_dir(bios_dir: Path, cache: dict, force: bool) -> tuple[dict, dict,
else: else:
if sha1 not in aliases: if sha1 not in aliases:
aliases[sha1] = [] aliases[sha1] = []
aliases[sha1].append({"name": _canonical_name(filepath), "path": rel_path}) aliases[sha1].append(
{"name": _canonical_name(filepath), "path": rel_path}
)
else: else:
entry = { entry = {
"path": rel_path, "path": rel_path,
@@ -114,7 +122,9 @@ def scan_bios_dir(bios_dir: Path, cache: dict, force: bool) -> tuple[dict, dict,
# Non-variant file should be primary over .variants/ file # Non-variant file should be primary over .variants/ file
if sha1 not in aliases: if sha1 not in aliases:
aliases[sha1] = [] aliases[sha1] = []
aliases[sha1].append({"name": files[sha1]["name"], "path": files[sha1]["path"]}) aliases[sha1].append(
{"name": files[sha1]["name"], "path": files[sha1]["path"]}
)
files[sha1] = { files[sha1] = {
"path": rel_path, "path": rel_path,
"name": _canonical_name(filepath), "name": _canonical_name(filepath),
@@ -124,7 +134,9 @@ def scan_bios_dir(bios_dir: Path, cache: dict, force: bool) -> tuple[dict, dict,
else: else:
if sha1 not in aliases: if sha1 not in aliases:
aliases[sha1] = [] aliases[sha1] = []
aliases[sha1].append({"name": _canonical_name(filepath), "path": rel_path}) aliases[sha1].append(
{"name": _canonical_name(filepath), "path": rel_path}
)
else: else:
entry = { entry = {
"path": rel_path, "path": rel_path,
@@ -156,6 +168,7 @@ def build_indexes(files: dict, aliases: dict) -> dict:
by_md5 = {} by_md5 = {}
by_name = {} by_name = {}
by_crc32 = {} by_crc32 = {}
by_sha256 = {}
by_path_suffix = {} by_path_suffix = {}
for sha1, entry in files.items(): for sha1, entry in files.items():
@@ -167,6 +180,7 @@ def build_indexes(files: dict, aliases: dict) -> dict:
by_name[name].append(sha1) by_name[name].append(sha1)
by_crc32[entry["crc32"]] = sha1 by_crc32[entry["crc32"]] = sha1
by_sha256[entry["sha256"]] = sha1
# Path suffix index for regional variant resolution # Path suffix index for regional variant resolution
suffix = _path_suffix(entry["path"]) suffix = _path_suffix(entry["path"])
@@ -196,6 +210,7 @@ def build_indexes(files: dict, aliases: dict) -> dict:
"by_md5": by_md5, "by_md5": by_md5,
"by_name": by_name, "by_name": by_name,
"by_crc32": by_crc32, "by_crc32": by_crc32,
"by_sha256": by_sha256,
"by_path_suffix": by_path_suffix, "by_path_suffix": by_path_suffix,
} }
@@ -275,8 +290,12 @@ def _preserve_large_file_entries(files: dict, db_path: str) -> int:
def main(): def main():
parser = argparse.ArgumentParser(description="Generate multi-indexed BIOS database") parser = argparse.ArgumentParser(description="Generate multi-indexed BIOS database")
parser.add_argument("--force", action="store_true", help="Force rehash all files") parser.add_argument("--force", action="store_true", help="Force rehash all files")
parser.add_argument("--bios-dir", default=DEFAULT_BIOS_DIR, help="BIOS directory path") parser.add_argument(
parser.add_argument("--output", "-o", default=DEFAULT_OUTPUT, help="Output JSON file") "--bios-dir", default=DEFAULT_BIOS_DIR, help="BIOS directory path"
)
parser.add_argument(
"--output", "-o", default=DEFAULT_OUTPUT, help="Output JSON file"
)
args = parser.parse_args() args = parser.parse_args()
bios_dir = Path(args.bios_dir) bios_dir = Path(args.bios_dir)
@@ -354,7 +373,10 @@ def _collect_all_aliases(files: dict) -> dict:
if platforms_dir.is_dir(): if platforms_dir.is_dir():
try: try:
import yaml import yaml
for platform_name in list_registered_platforms(str(platforms_dir), include_archived=True):
for platform_name in list_registered_platforms(
str(platforms_dir), include_archived=True
):
config_file = platforms_dir / f"{platform_name}.yml" config_file = platforms_dir / f"{platform_name}.yml"
try: try:
with open(config_file) as f: with open(config_file) as f:
@@ -383,6 +405,7 @@ def _collect_all_aliases(files: dict) -> dict:
try: try:
sys.path.insert(0, "scripts") sys.path.insert(0, "scripts")
from scraper.coreinfo_scraper import Scraper as CoreInfoScraper from scraper.coreinfo_scraper import Scraper as CoreInfoScraper
ci_reqs = CoreInfoScraper().fetch_requirements() ci_reqs = CoreInfoScraper().fetch_requirements()
for r in ci_reqs: for r in ci_reqs:
basename = r.name basename = r.name
@@ -400,6 +423,7 @@ def _collect_all_aliases(files: dict) -> dict:
if emulators_dir.is_dir(): if emulators_dir.is_dir():
try: try:
import yaml import yaml
for emu_file in emulators_dir.glob("*.yml"): for emu_file in emulators_dir.glob("*.yml"):
if emu_file.name.endswith(".old.yml"): if emu_file.name.endswith(".old.yml"):
continue continue
@@ -454,10 +478,17 @@ def _collect_all_aliases(files: dict) -> dict:
# ZX Spectrum # ZX Spectrum
["48.rom", "zx48.rom"], ["48.rom", "zx48.rom"],
# SquirrelJME - all JARs are the same # SquirrelJME - all JARs are the same
["squirreljme.sqc", "squirreljme.jar", "squirreljme-fast.jar", [
"squirreljme-slow.jar", "squirreljme-slow-test.jar", "squirreljme.sqc",
"squirreljme-0.3.0.jar", "squirreljme-0.3.0-fast.jar", "squirreljme.jar",
"squirreljme-0.3.0-slow.jar", "squirreljme-0.3.0-slow-test.jar"], "squirreljme-fast.jar",
"squirreljme-slow.jar",
"squirreljme-slow-test.jar",
"squirreljme-0.3.0.jar",
"squirreljme-0.3.0-fast.jar",
"squirreljme-0.3.0-slow.jar",
"squirreljme-0.3.0-slow-test.jar",
],
# Arcade - FBNeo spectrum # Arcade - FBNeo spectrum
["spectrum.zip", "fbneo/spectrum.zip", "spec48k.zip"], ["spectrum.zip", "fbneo/spectrum.zip", "spec48k.zip"],
] ]

File diff suppressed because it is too large Load Diff

View File

@@ -18,15 +18,29 @@ from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__)) sys.path.insert(0, os.path.dirname(__file__))
from common import list_registered_platforms, load_database, load_platform_config, write_if_changed from common import (
list_registered_platforms,
load_database,
load_platform_config,
write_if_changed,
)
from verify import verify_platform from verify import verify_platform
def compute_coverage(platform_name: str, platforms_dir: str, db: dict,
data_registry: dict | None = None, def compute_coverage(
supplemental_names: set[str] | None = None) -> dict: platform_name: str,
platforms_dir: str,
db: dict,
data_registry: dict | None = None,
supplemental_names: set[str] | None = None,
) -> dict:
config = load_platform_config(platform_name, platforms_dir) config = load_platform_config(platform_name, platforms_dir)
result = verify_platform(config, db, data_dir_registry=data_registry, result = verify_platform(
supplemental_names=supplemental_names) config,
db,
data_dir_registry=data_registry,
supplemental_names=supplemental_names,
)
sc = result.get("status_counts", {}) sc = result.get("status_counts", {})
ok = sc.get("ok", 0) ok = sc.get("ok", 0)
untested = sc.get("untested", 0) untested = sc.get("untested", 0)
@@ -55,8 +69,9 @@ REPO = "Abdess/retrobios"
def fetch_contributors() -> list[dict]: def fetch_contributors() -> list[dict]:
"""Fetch contributors from GitHub API, exclude bots.""" """Fetch contributors from GitHub API, exclude bots."""
import urllib.request
import urllib.error import urllib.error
import urllib.request
url = f"https://api.github.com/repos/{REPO}/contributors" url = f"https://api.github.com/repos/{REPO}/contributors"
headers = {"User-Agent": "retrobios-readme/1.0"} headers = {"User-Agent": "retrobios-readme/1.0"}
token = os.environ.get("GITHUB_TOKEN", "") token = os.environ.get("GITHUB_TOKEN", "")
@@ -68,7 +83,8 @@ def fetch_contributors() -> list[dict]:
data = json.loads(resp.read().decode()) data = json.loads(resp.read().decode())
owner = REPO.split("/")[0] owner = REPO.split("/")[0]
return [ return [
c for c in data c
for c in data
if not c.get("login", "").endswith("[bot]") if not c.get("login", "").endswith("[bot]")
and c.get("type") == "User" and c.get("type") == "User"
and c.get("login") != owner and c.get("login") != owner
@@ -87,21 +103,28 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
from common import load_data_dir_registry from common import load_data_dir_registry
from cross_reference import _build_supplemental_index from cross_reference import _build_supplemental_index
data_registry = load_data_dir_registry(platforms_dir) data_registry = load_data_dir_registry(platforms_dir)
suppl_names = _build_supplemental_index() suppl_names = _build_supplemental_index()
coverages = {} coverages = {}
for name in platform_names: for name in platform_names:
try: try:
coverages[name] = compute_coverage(name, platforms_dir, db, coverages[name] = compute_coverage(
data_registry, suppl_names) name, platforms_dir, db, data_registry, suppl_names
)
except FileNotFoundError: except FileNotFoundError:
pass pass
emulator_count = sum( emulator_count = (
1 for f in Path("emulators").glob("*.yml") sum(
if not f.name.endswith(".old.yml") 1
) if Path("emulators").exists() else 0 for f in Path("emulators").glob("*.yml")
if not f.name.endswith(".old.yml")
)
if Path("emulators").exists()
else 0
)
# Count systems from emulator profiles # Count systems from emulator profiles
system_ids: set[str] = set() system_ids: set[str] = set()
@@ -109,6 +132,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
if emu_dir.exists(): if emu_dir.exists():
try: try:
import yaml import yaml
for f in emu_dir.glob("*.yml"): for f in emu_dir.glob("*.yml"):
if f.name.endswith(".old.yml"): if f.name.endswith(".old.yml"):
continue continue
@@ -119,11 +143,17 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
pass pass
lines = [ lines = [
"# RetroBIOS", '<p align="center">',
' <img src=".github/assets/banner.png" alt="RetroBIOS" width="400">',
"</p>",
"", "",
f"Complete BIOS and firmware packs for " f"Complete BIOS and firmware packs for "
f"{', '.join(c['platform'] for c in sorted(coverages.values(), key=lambda x: x['platform'])[:-1])}" f"{', '.join(c['platform'] for c in sorted(coverages.values(), key=lambda x: x[
f", and {sorted(coverages.values(), key=lambda x: x['platform'])[-1]['platform']}.", 'platform'
])[:-1])}"
f", and {sorted(coverages.values(), key=lambda x: x[
'platform'
])[-1]['platform']}.",
"", "",
f"**{total_files:,}** verified files across **{len(system_ids)}** systems," f"**{total_files:,}** verified files across **{len(system_ids)}** systems,"
f" ready to extract into your emulator's BIOS directory.", f" ready to extract into your emulator's BIOS directory.",
@@ -170,48 +200,78 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
display = cov["platform"] display = cov["platform"]
path = extract_paths.get(display, "") path = extract_paths.get(display, "")
lines.append( lines.append(
f"| {display} | {cov['total']} | {path} | " f"| {display} | {cov['total']} | {path} | [Download]({RELEASE_URL}) |"
f"[Download]({RELEASE_URL}) |"
) )
lines.extend([ lines.extend(
"", [
"## What's included", "",
"", "## What's included",
"BIOS, firmware, and system files for consoles from Atari to PlayStation 3.", "",
f"Each file is checked against the emulator's source code to match what the" "BIOS, firmware, and system files for consoles from Atari to PlayStation 3.",
f" code actually loads at runtime.", "Each file is checked against the emulator's source code to match what the"
"", " code actually loads at runtime.",
f"- **{len(coverages)} platforms** supported with platform-specific verification", "",
f"- **{emulator_count} emulators** profiled from source (RetroArch cores + standalone)", f"- **{len(coverages)} platforms** supported with platform-specific verification",
f"- **{len(system_ids)} systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)", f"- **{emulator_count} emulators** profiled from source (RetroArch cores + standalone)",
f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums", f"- **{len(system_ids)} systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)",
f"- **{size_mb:.0f} MB** total collection size", f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums",
"", f"- **{size_mb:.0f} MB** total collection size",
"## Supported systems", "",
"", "## Supported systems",
]) "",
]
)
# Show well-known systems for SEO, link to full list # Show well-known systems for SEO, link to full list
well_known = [ well_known = [
"NES", "SNES", "Nintendo 64", "GameCube", "Wii", "Game Boy", "Game Boy Advance", "NES",
"Nintendo DS", "Nintendo 3DS", "Switch", "SNES",
"PlayStation", "PlayStation 2", "PlayStation 3", "PSP", "PS Vita", "Nintendo 64",
"Mega Drive", "Saturn", "Dreamcast", "Game Gear", "Master System", "GameCube",
"Neo Geo", "Atari 2600", "Atari 7800", "Atari Lynx", "Atari ST", "Wii",
"MSX", "PC Engine", "TurboGrafx-16", "ColecoVision", "Intellivision", "Game Boy",
"Commodore 64", "Amiga", "ZX Spectrum", "Arcade (MAME)", "Game Boy Advance",
"Nintendo DS",
"Nintendo 3DS",
"Switch",
"PlayStation",
"PlayStation 2",
"PlayStation 3",
"PSP",
"PS Vita",
"Mega Drive",
"Saturn",
"Dreamcast",
"Game Gear",
"Master System",
"Neo Geo",
"Atari 2600",
"Atari 7800",
"Atari Lynx",
"Atari ST",
"MSX",
"PC Engine",
"TurboGrafx-16",
"ColecoVision",
"Intellivision",
"Commodore 64",
"Amiga",
"ZX Spectrum",
"Arcade (MAME)",
] ]
lines.extend([ lines.extend(
", ".join(well_known) + f", and {len(system_ids) - len(well_known)}+ more.", [
"", ", ".join(well_known) + f", and {len(system_ids) - len(well_known)}+ more.",
f"Full list with per-file details: **[{SITE_URL}]({SITE_URL})**", "",
"", f"Full list with per-file details: **[{SITE_URL}]({SITE_URL})**",
"## Coverage", "",
"", "## Coverage",
"| Platform | Coverage | Verified | Untested | Missing |", "",
"|----------|----------|----------|----------|---------|", "| Platform | Coverage | Verified | Untested | Missing |",
]) "|----------|----------|----------|----------|---------|",
]
)
for name, cov in sorted(coverages.items(), key=lambda x: x[1]["platform"]): for name, cov in sorted(coverages.items(), key=lambda x: x[1]["platform"]):
pct = f"{cov['percentage']:.1f}%" pct = f"{cov['percentage']:.1f}%"
@@ -220,62 +280,66 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
f"{cov['verified']} | {cov['untested']} | {cov['missing']} |" f"{cov['verified']} | {cov['untested']} | {cov['missing']} |"
) )
lines.extend([ lines.extend(
"", [
"## Build your own pack", "",
"", "## Build your own pack",
"Clone the repo and generate packs for any platform, emulator, or system:", "",
"", "Clone the repo and generate packs for any platform, emulator, or system:",
"```bash", "",
"# Full platform pack", "```bash",
"python scripts/generate_pack.py --platform retroarch --output-dir dist/", "# Full platform pack",
"python scripts/generate_pack.py --platform batocera --output-dir dist/", "python scripts/generate_pack.py --platform retroarch --output-dir dist/",
"", "python scripts/generate_pack.py --platform batocera --output-dir dist/",
"# Single emulator or system", "",
"python scripts/generate_pack.py --emulator dolphin", "# Single emulator or system",
"python scripts/generate_pack.py --system sony-playstation-2", "python scripts/generate_pack.py --emulator dolphin",
"", "python scripts/generate_pack.py --system sony-playstation-2",
"# List available emulators and systems", "",
"python scripts/generate_pack.py --list-emulators", "# List available emulators and systems",
"python scripts/generate_pack.py --list-systems", "python scripts/generate_pack.py --list-emulators",
"", "python scripts/generate_pack.py --list-systems",
"# Verify your BIOS collection", "",
"python scripts/verify.py --all", "# Verify your BIOS collection",
"python scripts/verify.py --platform batocera", "python scripts/verify.py --all",
"python scripts/verify.py --emulator flycast", "python scripts/verify.py --platform batocera",
"python scripts/verify.py --platform retroarch --verbose # emulator ground truth", "python scripts/verify.py --emulator flycast",
"```", "python scripts/verify.py --platform retroarch --verbose # emulator ground truth",
"", "```",
f"Only dependency: Python 3 + `pyyaml`.", "",
"", "Only dependency: Python 3 + `pyyaml`.",
"## Documentation site", "",
"", "## Documentation site",
f"The [documentation site]({SITE_URL}) provides:", "",
"", f"The [documentation site]({SITE_URL}) provides:",
f"- **Per-platform pages** with file-by-file verification status and hashes", "",
f"- **Per-emulator profiles** with source code references for every file", "- **Per-platform pages** with file-by-file verification status and hashes",
f"- **Per-system pages** showing which emulators and platforms cover each console", "- **Per-emulator profiles** with source code references for every file",
f"- **Gap analysis** identifying missing files and undeclared core requirements", "- **Per-system pages** showing which emulators and platforms cover each console",
f"- **Cross-reference** mapping files across {len(coverages)} platforms and {emulator_count} emulators", "- **Gap analysis** identifying missing files and undeclared core requirements",
"", f"- **Cross-reference** mapping files across {len(coverages)} platforms and {emulator_count} emulators",
"## How it works", "",
"", "## How it works",
"Documentation and metadata can drift from what emulators actually load.", "",
"To keep packs accurate, each file is checked against the emulator's source code.", "Documentation and metadata can drift from what emulators actually load.",
"", "To keep packs accurate, each file is checked against the emulator's source code.",
"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", "1. **Read emulator source code** - trace every file the code loads, its expected hash and size",
"3. **Build packs** - include baseline files plus what each platform's cores need", "2. **Cross-reference with platforms** - match against what each platform declares",
"4. **Verify** - run platform-native checks and emulator-level validation", "3. **Build packs** - include baseline files plus what each platform's cores need",
"", "4. **Verify** - run platform-native checks and emulator-level validation",
]) "",
]
)
contributors = fetch_contributors() contributors = fetch_contributors()
if contributors: if contributors:
lines.extend([ lines.extend(
"## Contributors", [
"", "## Contributors",
]) "",
]
)
for c in contributors: for c in contributors:
login = c["login"] login = c["login"]
avatar = c.get("avatar_url", "") avatar = c.get("avatar_url", "")
@@ -285,18 +349,27 @@ def generate_readme(db: dict, platforms_dir: str) -> str:
) )
lines.append("") lines.append("")
lines.extend([ lines.extend(
"", [
"## Contributing", "",
"", "## Community tools",
"See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.", "",
"", "- [BIOS Preservation Tool](https://github.com/monster-penguin/BIOS-Preservation-Tool)"
"## License", " by [monster-penguin](https://github.com/monster-penguin)"
"", " - scan, verify, and stage your own BIOS collection"
"This repository provides BIOS files for personal backup and archival purposes.", " using RetroBIOS hash metadata",
"", "",
f"*Auto-generated on {ts}*", "## Contributing",
]) "",
"See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.",
"",
"## License",
"",
"This repository provides BIOS files for personal backup and archival purposes.",
"",
f"*Auto-generated on {ts}*",
]
)
return "\n".join(lines) + "\n" return "\n".join(lines) + "\n"
@@ -311,6 +384,16 @@ def generate_contributing() -> str:
3. Variants (alternate hashes): `bios/Manufacturer/Console/.variants/` 3. Variants (alternate hashes): `bios/Manufacturer/Console/.variants/`
4. Create a Pull Request - checksums are verified automatically 4. Create a Pull Request - checksums are verified automatically
## Add a new platform
1. Write a scraper in `scripts/scraper/`
2. Create the platform YAML in `platforms/`
3. Register in `platforms/_registry.yml`
4. Submit a Pull Request
Contributors who add platform support are credited in the README,
on the documentation site, and in the BIOS packs.
## File conventions ## File conventions
- Files >50 MB go in GitHub release assets (`large-files` release) - Files >50 MB go in GitHub release assets (`large-files` release)
@@ -332,7 +415,11 @@ def main():
print(f"{status} ./README.md") print(f"{status} ./README.md")
contributing = generate_contributing() contributing = generate_contributing()
status = "Generated" if write_if_changed("CONTRIBUTING.md", contributing) else "Unchanged" status = (
"Generated"
if write_if_changed("CONTRIBUTING.md", contributing)
else "Unchanged"
)
print(f"{status} ./CONTRIBUTING.md") print(f"{status} ./CONTRIBUTING.md")

File diff suppressed because it is too large Load Diff

View File

@@ -39,20 +39,28 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
group.add_argument("--all", action="store_true", help="all registered platforms") group.add_argument("--all", action="store_true", help="all registered platforms")
group.add_argument("--platform", help="single platform name") group.add_argument("--platform", help="single platform name")
parser.add_argument( parser.add_argument(
"--output-dir", default=DEFAULT_OUTPUT_DIR, help="output directory", "--output-dir",
default=DEFAULT_OUTPUT_DIR,
help="output directory",
) )
parser.add_argument( parser.add_argument(
"--target", "-t", default=None, help="hardware target filter", "--target",
"-t",
default=None,
help="hardware target filter",
) )
parser.add_argument( parser.add_argument(
"--include-archived", action="store_true", "--include-archived",
action="store_true",
help="include archived platforms with --all", help="include archived platforms with --all",
) )
parser.add_argument( parser.add_argument(
"--platforms-dir", default=DEFAULT_PLATFORMS_DIR, "--platforms-dir",
default=DEFAULT_PLATFORMS_DIR,
) )
parser.add_argument( parser.add_argument(
"--emulators-dir", default=DEFAULT_EMULATORS_DIR, "--emulators-dir",
default=DEFAULT_EMULATORS_DIR,
) )
parser.add_argument("--db", default=DEFAULT_DB_FILE, help="database.json path") parser.add_argument("--db", default=DEFAULT_DB_FILE, help="database.json path")
return parser.parse_args(argv) return parser.parse_args(argv)
@@ -77,7 +85,8 @@ def main(argv: list[str] | None = None) -> None:
# Determine platforms # Determine platforms
if args.all: if args.all:
platforms = list_registered_platforms( platforms = list_registered_platforms(
args.platforms_dir, include_archived=args.include_archived, args.platforms_dir,
include_archived=args.include_archived,
) )
else: else:
platforms = [args.platform] platforms = [args.platform]
@@ -90,7 +99,9 @@ def main(argv: list[str] | None = None) -> None:
if args.target: if args.target:
try: try:
target_cores = load_target_config( target_cores = load_target_config(
name, args.target, args.platforms_dir, name,
args.target,
args.platforms_dir,
) )
except FileNotFoundError: except FileNotFoundError:
print(f" {name}: no target config, skipped") print(f" {name}: no target config, skipped")
@@ -105,15 +116,22 @@ def main(argv: list[str] | None = None) -> None:
registry_entry = registry.get(name, {}) registry_entry = registry.get(name, {})
result = generate_platform_truth( result = generate_platform_truth(
name, config, registry_entry, profiles, name,
db=db, target_cores=target_cores, config,
registry_entry,
profiles,
db=db,
target_cores=target_cores,
) )
out_path = os.path.join(args.output_dir, f"{name}.yml") out_path = os.path.join(args.output_dir, f"{name}.yml")
with open(out_path, "w") as f: with open(out_path, "w") as f:
yaml.dump( yaml.dump(
result, f, result,
default_flow_style=False, sort_keys=False, allow_unicode=True, f,
default_flow_style=False,
sort_keys=False,
allow_unicode=True,
) )
n_systems = len(result.get("systems", {})) n_systems = len(result.get("systems", {}))

Some files were not shown because too many files have changed in this diff Show More