From d9c74888e803cf2d3e319f2a383ed819a7512e24 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 17 Oct 2026 15:38:07 +0200 Subject: [PATCH] feat: list rocknix cores per device ROCKNIX builds a different emulator set per SoC, and without a target list an H700 handheld received the PS2, PS3 and GameCube firmware of emulators its image lacks. The new target scraper reads the emulators metapackage per device; seven cores ROCKNIX ships get profiles and the Super Famicom Box ROMs one of them needs are collected. --- bios/Nintendo/Super Famicom Box/KROM1.BIN | Bin 0 -> 65536 bytes bios/Nintendo/Super Famicom Box/MB90082.BIN | Bin 0 -> 9216 bytes emulators/daedalusx64.yml | 74 + emulators/dsperate.yml | 137 ++ emulators/fbalpha2019.yml | 452 ++++ emulators/flycast2021.yml | 180 ++ emulators/mednafen_supafaust.yml | 2 +- emulators/mupen64plus_next.yml | 2 +- emulators/nanoboyadvance.yml | 47 + emulators/supersnes9x.yml | 133 ++ emulators/touchhle.yml | 206 ++ emulators/x1.yml | 1 + platforms/_registry.yml | 2 + platforms/targets/_overrides.yml | 16 + platforms/targets/rocknix.yml | 2088 +++++++++++++++++ .../targets/rocknix_targets_scraper.py | 202 ++ tests/test_target_scrapers.py | 57 + 17 files changed, 3597 insertions(+), 2 deletions(-) create mode 100644 bios/Nintendo/Super Famicom Box/KROM1.BIN create mode 100644 bios/Nintendo/Super Famicom Box/MB90082.BIN create mode 100644 emulators/daedalusx64.yml create mode 100644 emulators/dsperate.yml create mode 100644 emulators/fbalpha2019.yml create mode 100644 emulators/flycast2021.yml create mode 100644 emulators/nanoboyadvance.yml create mode 100644 emulators/supersnes9x.yml create mode 100644 emulators/touchhle.yml create mode 100644 platforms/targets/rocknix.yml create mode 100644 scripts/scraper/targets/rocknix_targets_scraper.py diff --git a/bios/Nintendo/Super Famicom Box/KROM1.BIN b/bios/Nintendo/Super Famicom Box/KROM1.BIN new file mode 100644 index 0000000000000000000000000000000000000000..d11bdc0c64b55d05a561f56dad36740f4cacc3cd GIT binary patch literal 65536 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

=GWZ%Sz#W;Pfh$Tegq+Lt&5(1? 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 Sx4`c$@PF9?2g>gs`~Lt@thu-V literal 0 HcmV?d00001 diff --git a/bios/Nintendo/Super Famicom Box/MB90082.BIN b/bios/Nintendo/Super Famicom Box/MB90082.BIN new file mode 100644 index 0000000000000000000000000000000000000000..2dc30f48e923d81f3d16fa9a2f0571fe218e04f1 GIT binary patch literal 9216 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/fba/, then /. A missing + archive is only logged. + ref: src/burner/libretro/libretro.cpp:560-587 + + The archives come from BurnDrvGetZipName: the game, its board ROM set + (szBoardROM of the BurnDriver), then its parents. ColecoVision, MSX and + Spectrum drivers have their own GetZipName that strips the system prefix, so + cv_coleco opens coleco.zip, msx_msx opens msx.zip, spec_spectrum opens + spectrum.zip and spec_spec128 opens spec128.zip. The PGM single board sets + thegladpcb, dmnfrntpcb and svgpcb also open pgm.zip. + ref: src/burn/burn.cpp:94-133, src/burn/drv/coleco/d_coleco.cpp:638-670, + src/burn/drv/msx/d_msx.cpp:1680-1712, src/burn/drv/spectrum/d_spectrum.cpp:202-235, + src/burner/libretro/libretro.cpp:603-617 + + Every ROM is matched by CRC32 across all opened archives first, then by name. + A board ROM set is appended to the game's list at index 0x80, so its entries + are checked like the game's own: any entry without BRF_OPT that is found in + no archive aborts the load. The one exception is the Neo Geo MVS BIOS + sp-s3.sp1, skipped when another MVS, AES or Universe BIOS was found. + ref: src/burn/stdfunc.h:13-28, src/burner/libretro/libretro.cpp:635-657, + src/burner/libretro/libretro.cpp:733-748, src/burner/libretro/retro_common.cpp:4-47 + + Four Midway MCR games (kickman, kickc, wacko, nflfoot) name "ssio" as their + board ROM set instead of "midssio", so they open ssio.zip. + ref: src/burn/drv/pre90s/d_mcr.cpp:1782, src/burn/drv/pre90s/d_mcr.cpp:1820, + src/burn/drv/pre90s/d_mcr.cpp:2298, src/burn/drv/pre90s/d_mcr.cpp:3174 + + Neo Geo CD content runs the neocdz driver, whose board ROM set is neogeo: it + opens neocdz.zip then neogeo.zip. + ref: src/burner/libretro/libretro.cpp:1316-1317, src/burn/drv/neogeo/d_neogeo.cpp:1283-1299 + + Samples are read from /fba/samples/.zip and the high score + table from /fba/hiscore.dat (core option fba-hiscores, enabled by + default). + ref: src/burner/libretro/libretro.cpp:1158-1161, src/burn/hiscore.cpp:408, + src/burner/libretro/retro_common.cpp:85 + +files: + - name: "neogeo.zip" + category: bios_zip + system: snk-neogeo-mvs + description: "Neo Geo system BIOS ROM set" + required: true + note: "sm1.sm1, sfix.sfix and 000-lo.lo are required. sp-s3.sp1 is required unless one of the other 68K BIOS images is present; all other members are BRF_OPT." + source_ref: "src/burn/drv/neogeo/d_neogeo.cpp:930-981, src/burn/drv/neogeo/d_neogeo.cpp:1207-1216, src/burner/libretro/libretro.cpp:733-748" + contents: + - name: "sp-s3.sp1" + size: 131072 + crc32: "91b64be3" + - name: "sp-s2.sp1" + size: 131072 + crc32: "9036d879" + - name: "sp-s.sp1" + size: 131072 + crc32: "c7f2fa45" + - name: "sp-u2.sp1" + size: 131072 + crc32: "e72943de" + - name: "sp1-u2" + size: 131072 + crc32: "62f021f4" + - name: "sp-e.sp1" + size: 131072 + crc32: "2723a5b5" + - name: "sp1-u4.bin" + size: 131072 + crc32: "1179a30f" + - name: "sp1-u3.bin" + size: 131072 + crc32: "2025b7a2" + - name: "vs-bios.rom" + size: 131072 + crc32: "f0e8f27d" + - name: "sp-j2.sp1" + size: 131072 + crc32: "acede59c" + - name: "sp1.jipan.1024" + size: 131072 + crc32: "9fb0abe4" + - name: "sp-45.sp1" + size: 524288 + crc32: "03cc9f6a" + - name: "sp-j3.sp1" + size: 524288 + crc32: "486cb450" + - name: "japan-j3.bin" + size: 131072 + crc32: "dff6d41f" + - name: "sp1-j3.bin" + size: 131072 + crc32: "fbc6d469" + - name: "neo-po.bin" + size: 131072 + crc32: "16d0c132" + - name: "neo-epo.bin" + size: 131072 + crc32: "d27a71f1" + - name: "neodebug.bin" + size: 131072 + crc32: "698ebb7d" + - name: "sp-1v1_3db8c.bin" + size: 131072 + crc32: "162f0ebe" + - name: "uni-bios_3_3.rom" + size: 131072 + crc32: "24858466" + - name: "uni-bios_3_2.rom" + size: 131072 + crc32: "a4e8b9b3" + - name: "uni-bios_3_1.rom" + size: 131072 + crc32: "0c58093f" + - name: "uni-bios_3_0.rom" + size: 131072 + crc32: "a97c89a9" + - name: "uni-bios_2_3.rom" + size: 131072 + crc32: "27664eb5" + - name: "uni-bios_2_3o.rom" + size: 131072 + crc32: "601720ae" + - name: "uni-bios_2_2.rom" + size: 131072 + crc32: "2d50996a" + - name: "uni-bios_2_1.rom" + size: 131072 + crc32: "8dabf76b" + - name: "uni-bios_2_0.rom" + size: 131072 + crc32: "0c12c2ad" + - name: "uni-bios_1_3.rom" + size: 131072 + crc32: "b24b44a0" + - name: "uni-bios_1_2.rom" + size: 131072 + crc32: "4fa698e9" + - name: "uni-bios_1_2o.rom" + size: 131072 + crc32: "e19d3ce9" + - name: "uni-bios_1_1.rom" + size: 131072 + crc32: "5dda0d84" + - name: "uni-bios_1_0.rom" + size: 131072 + crc32: "0ce453a0" + - name: "neopen.sp1" + size: 131072 + crc32: "cb915e76" + - name: "sm1.sm1" + size: 131072 + crc32: "94416d67" + - name: "sfix.sfix" + size: 131072 + crc32: "c2ea0cfd" + - name: "000-lo.lo" + size: 131072 + crc32: "5a86cff2" + + - name: "neocdz.zip" + category: bios_zip + system: snk-neogeo-cd + description: "Neo Geo CDZ system ROM set" + required: true + note: "Both members are required. Matching is by CRC32 across neocdz.zip and neogeo.zip, so a neogeo.zip that also holds neocd.bin stands in for this archive." + source_ref: "src/burn/drv/neogeo/d_neogeo.cpp:1283-1299, src/burner/libretro/libretro.cpp:1316-1317" + contents: + - name: "neocd.bin" + size: 524288 + crc32: "df9de490" + - name: "000-lo.lo" + size: 131072 + crc32: "5a86cff2" + + - name: "pgm.zip" + category: bios_zip + system: igs-pgm + description: "IGS PolyGame Master system BIOS ROM set" + required: true + note: "No member carries BRF_OPT, so all six are required for every PGM game, ddp3_bios.u37 and bios.u42 included." + source_ref: "src/burn/drv/pgm/d_pgm.cpp:511-524, src/burn/drv/pgm/d_pgm.cpp:529-538" + contents: + - name: "pgm_t01s.rom" + size: 2097152 + crc32: "1a7123a0" + - name: "pgm_m01s.rom" + size: 2097152 + crc32: "45ae7159" + - name: "pgm_p01s.u20" + size: 131072 + crc32: "e42b166e" + - name: "pgm_p02s.u20" + size: 131072 + crc32: "78c15fa2" + - name: "ddp3_bios.u37" + size: 524288 + crc32: "b3cc5c8f" + - name: "bios.u42" + size: 131072 + crc32: "517cf7a2" + + - name: "skns.zip" + category: bios_zip + system: super-kaneko-nova + description: "Super Kaneko Nova System BIOS ROM set" + required: true + note: "The five regional BIOS images are all required: none carries BRF_OPT." + source_ref: "src/burn/drv/pst90s/d_suprnova.cpp:1788-1799, src/burn/drv/pst90s/d_suprnova.cpp:1808-1817" + contents: + - name: "sknsj1.u10" + size: 524288 + crc32: "7e2b836c" + - name: "sknse2.u10" + size: 524288 + crc32: "e2b9d7d1" + - name: "sknsa1.u10" + size: 524288 + crc32: "745e5212" + - name: "sknsu1.u10" + size: 524288 + crc32: "384d21ec" + - name: "sknsk1.u10" + size: 524288 + crc32: "ff1c9f79" + + - name: "midssio.zip" + category: bios_zip + system: midway-mcr + description: "Midway SSIO sound board PROM" + required: true + source_ref: "src/burn/drv/pre90s/d_mcr.cpp:1615-1621, src/burn/drv/pre90s/d_mcr.cpp:1626-1635" + contents: + - name: "82s123.12d" + size: 32 + crc32: "e1281ee9" + + - name: "ssio.zip" + aliases: ["midssio.zip"] + category: bios_zip + system: midway-mcr + description: "Midway SSIO sound board PROM, board name used by four games" + required: true + note: "Opened for kickman, kickc, wacko and nflfoot, whose driver names \"ssio\" as board ROM set. They pick the same SsiopromRomDesc entry as midssio." + source_ref: "src/burn/drv/pre90s/d_mcr.cpp:1615-1621, src/burn/drv/pre90s/d_mcr.cpp:1778-1782" + contents: + - name: "82s123.12d" + size: 32 + crc32: "e1281ee9" + + - name: "coleco.zip" + category: bios_zip + system: coleco-colecovision + description: "ColecoVision system BIOS ROM set" + required: true + note: "coleco.rom is required; colecoa.rom, svi603.rom and czz50.rom are BRF_OPT. Archive name from CVGetZipName, which drops the cv_ prefix of cv_coleco." + source_ref: "src/burn/drv/coleco/d_coleco.cpp:638-670, src/burn/drv/coleco/d_coleco.cpp:675-680" + contents: + - name: "coleco.rom" + size: 8192 + crc32: "3aa93ef3" + - name: "colecoa.rom" + size: 8192 + crc32: "39bb16fc" + - name: "svi603.rom" + size: 8192 + crc32: "19e91b82" + - name: "czz50.rom" + size: 16384 + crc32: "4999abc6" + + - name: "msx.zip" + category: bios_zip + system: msx + description: "MSX1 system BIOS ROM set" + required: true + note: "msx.rom is required; msxj.rom and kanji.rom are BRF_OPT. Archive name from MSXGetZipName, which drops the msx_ prefix of msx_msx." + source_ref: "src/burn/drv/msx/d_msx.cpp:1680-1712, src/burn/drv/msx/d_msx.cpp:1716-1720" + contents: + - name: "msx.rom" + size: 32768 + crc32: "a317e6b4" + - name: "msxj.rom" + size: 32768 + crc32: "071135e0" + - name: "kanji.rom" + size: 262144 + crc32: "1f6406fb" + + - name: "spectrum.zip" + category: bios_zip + system: sinclair-spectrum + description: "ZX Spectrum 48K ROM set" + required: true + note: "Archive name from SpectrumGetZipName, which drops the spec_ prefix of spec_spectrum." + source_ref: "src/burn/drv/spectrum/d_spectrum.cpp:202-235, src/burn/drv/spectrum/d_spectrum.cpp:237-239" + contents: + - name: "spectrum.rom" + size: 16384 + crc32: "ddee531f" + + - name: "spec128.zip" + category: bios_zip + system: sinclair-spectrum + description: "ZX Spectrum 128 ROM set" + required: true + note: "Opened by the 128K games. Archive name from SpectrumGetZipName, which drops the spec_ prefix of spec_spec128." + source_ref: "src/burn/drv/spectrum/d_spectrum.cpp:202-235, src/burn/drv/spectrum/d_spectrum.cpp:244-247" + contents: + - name: "zx128_0.rom" + size: 16384 + crc32: "e76799d2" + - name: "zx128_1.rom" + size: 16384 + crc32: "b96a36be" + + - name: "nmk004.zip" + category: bios_zip + system: nmk16 + description: "NMK004 sound MCU internal ROM" + required: true + source_ref: "src/burn/drv/pst90s/d_nmk16.cpp:5982-5988, src/burn/drv/pst90s/d_nmk16.cpp:5993-6002" + contents: + - name: "nmk004.bin" + size: 8192 + crc32: "83b6f611" + + - name: "decocass.zip" + category: bios_zip + system: deco-cassette + description: "DECO Cassette System BIOS ROM set" + required: true + note: "The program ROMs and cassmcu.1c are required; the six PROMs (v2.3m, v4.10d, v3.3j, dsp-3_p3-.e5, rms-3_p4-.f6, dsp-3_p5-.m4) are BRF_OPT." + source_ref: "src/burn/drv/dataeast/d_decocass.cpp:3392-3446, src/burn/drv/dataeast/d_decocass.cpp:3456-3465" + contents: + - name: "v0a-.7e" + size: 4096 + crc32: "3d33ac34" + - name: "v1-.5a" + size: 2048 + crc32: "b66b2c2a" + - name: "v2.3m" + size: 32 + crc32: "238fdb40" + - name: "v4.10d" + size: 32 + crc32: "3b5836b4" + - name: "v3.3j" + size: 32 + crc32: "51eef657" + - name: "dsp-3_p0-a.m9" + size: 2048 + crc32: "2541e34b" + - name: "dsp-3_p1-.l9" + size: 2048 + crc32: "3bfff5f3" + - name: "rms-3_p2-.c9" + size: 1024 + crc32: "6c4a891f" + - name: "dsp-3_p3-.e5" + size: 32 + crc32: "539a5a64" + - name: "rms-3_p4-.f6" + size: 32 + crc32: "9014c0fd" + - name: "dsp-3_p5-.m4" + size: 32 + crc32: "e52089a0" + - name: "v0b-.7e" + size: 4096 + crc32: "23d929b7" + - name: "dsp-3_p0-b.m9" + size: 2048 + crc32: "b67a91d9" + - name: "cassmcu.1c" + size: 1024 + crc32: "a6df18fd" + + - name: "isgsm.zip" + category: bios_zip + system: sega-system16b + description: "ISG Selection Master Type 2006 system BIOS" + required: true + source_ref: "src/burn/drv/sega/d_sys16b.cpp:10631-10633, src/burn/drv/sega/d_sys16b.cpp:11202-11211" + contents: + - name: "ism2006v00.u1" + size: 131072 + crc32: "2292585c" + + - name: "cchip.zip" + category: bios_zip + system: taito-cchip + description: "Taito C-Chip uPD78C11 internal ROM" + required: true + note: "Named as board ROM set by Operation Wolf, Rainbow Islands, Volfied and others; there is no BurnDriver called cchip, the name comes from szBoardROM." + source_ref: "src/burn/drv/taito/d_taitomisc.cpp:1369-1373, src/burn/drv/taito/d_taitomisc.cpp:6250" + contents: + - name: "cchip_upd78c11.bin" + size: 4096 + crc32: "43021521" + + - name: "ym2608.zip" + category: bios_zip + system: ym2608 + description: "Yamaha YM2608 internal ADPCM ROM" + required: true + source_ref: "src/burn/drv/pre90s/d_wc90.cpp:186-192, src/burn/drv/pre90s/d_wc90.cpp:1261-1270" + contents: + - name: "ym2608_adpcm_rom.bin" + size: 8192 + crc32: "23c9e0d8" + + - name: "hiscore.dat" + path: "fba/hiscore.dat" + system: arcade + required: false + description: "High score address database" + note: "Read when the fba-hiscores option is enabled, which is the default. Without it no high score is kept." + source_ref: "src/burn/hiscore.cpp:400-420, src/burner/libretro/libretro.cpp:1158" diff --git a/emulators/flycast2021.yml b/emulators/flycast2021.yml new file mode 100644 index 00000000..063af00f --- /dev/null +++ b/emulators/flycast2021.yml @@ -0,0 +1,180 @@ +emulator: "Flycast 2021" +type: libretro +core_classification: frozen_snapshot +source: "https://github.com/metallic77/flycast" +upstream: "https://github.com/libretro/flycast" +profiled_date: "2026-10-17" +source_commit: "603814c9f73b773c455d9a497f389d2f93a257fd" +upstream_commit: "4c293f306bc16a265c2d768af5d0cea138426054" +pin_frozen: "ROCKNIX 20261001 builds this revision. No branch of metallic77/flycast holds it any more: master was put back on the libretro merge base 4c293f30, so HEAD is the code before the fork's own commits." +core_version: "0.1" +display_name: "Sega - Dreamcast/Naomi (Flycast 2021)" +cores: + - "flycast2021" +systems: + - sega-dreamcast + - sega-naomi + - sega-atomiswave + +notes: | + The libretro/flycast tree as of April 2022 (merge base 4c293f30), from before + the libretro fork was rebased on flyinghead's Flycast, with 22 commits by + metallic77 on top that tune defaults and build flags for low-end handhelds. + ROCKNIX renames the core option prefix from reicast to flycast2021 and + installs the library as flycast2021_libretro.so. + ref: core/libretro/libretro.cpp:2296-2300 + + Every system file lives in /dc/. + ref: core/libretro/libretro.cpp:1893-1896 + + Dreamcast: the boot ROM is looked for as dc_boot.bin, dc_boot.bin.bin, + dc_bios.bin, dc_bios.bin.bin, the first that yields a full 2 MB read wins. + The HLE BIOS core option (hle_bios) defaults to enabled, and when it is on, or + when no boot ROM loads, reios boots the disc instead. Booting to the BIOS menu, + or starting without a disc, needs the real boot ROM and fails with -3 without + it. + ref: core/hw/holly/sb_mem.cpp:32-65, core/hw/holly/sb_mem.cpp:215-233, + core/hw/flashrom/flashrom.h:54-67, core/hw/flashrom/flashrom.h:84-118, + core/nullDC.cpp:420-431, core/nullDC.cpp:455-463, + core/libretro/libretro_core_options.h:133-145, core/libretro/libretro.cpp:726-731 + + NAOMI and Atomiswave: a BIOS archive is opened as /dc/ with .7z + then .zip appended. Each member is looked for in the game archive, its parent, + then the BIOS archive, by CRC32 and then by name; the BIOS table carries no + CRC32, so only the name matches. The member for the configured region is + tried first, then the first member listed. A game whose table entry names a + BIOS refuses to start without it; the others default to naomi. Five archive + names are reachable from the game table: naomi, awbios, f355bios, f355dlx, + hod2bios. airlbios and naomigd have table entries but no game names them. + ref: core/hw/naomi/naomi_cart.cpp:76-176, core/hw/naomi/naomi_cart.cpp:227-247, + core/archive/archive.cpp:26-42, core/hw/naomi/naomi_roms.h:76-217 + + LoadRomFiles also reads naomi_boot.bin, naomi_boot.bin.bin, naomi_bios.bin, + naomi_bios.bin.bin and epr-21576d.bin for NAOMI, but naomi_cart_Close clears + bios_loaded before the cartridge loads, so that file never stands in for + naomi.zip. + ref: core/hw/holly/sb_mem.cpp:59, core/hw/naomi/naomi_cart.cpp:427-444, + core/hw/naomi/naomi_cart.cpp:472-484 + +files: + - name: "dc_boot.bin" + path: "dc/dc_boot.bin" + aliases: ["dc_boot.bin.bin", "dc_bios.bin", "dc_bios.bin.bin"] + system: sega-dreamcast + required: false + hle_fallback: true + min_size: 2097152 + validation: [size] + description: "Dreamcast boot ROM" + note: "Read as 2 MB into the system ROM; a shorter file is rejected. Needed only to boot to the BIOS menu or when the HLE BIOS option is disabled." + source_ref: "core/hw/holly/sb_mem.cpp:50-65, core/hw/holly/sb_mem.cpp:215-229, core/hw/flashrom/flashrom.h:54-67, core/nullDC.cpp:420-431" + + - name: "dc_nvmem.bin" + path: "dc/dc_nvmem.bin" + aliases: ["dc_flash_wb.bin", "dc_flash.bin", "dc_flash.bin.bin"] + system: sega-dreamcast + required: false + min_size: 131072 + validation: [size] + description: "Dreamcast flash ROM" + note: "Loaded with the boot ROM and by the HLE path; a missing file leaves the flash blank and the core runs. Written back as dc_nvmem.bin." + source_ref: "core/hw/holly/sb_mem.cpp:196-213, core/hw/holly/sb_mem.cpp:231, core/hw/holly/sb_mem.cpp:236-243, core/hw/holly/sb_mem.cpp:271-278" + + - name: "font.bin" + path: "dc/font.bin" + system: sega-dreamcast + required: false + description: "Dreamcast system font for the HLE BIOS" + note: "Read whole into the font table of the reios ROM image. Absent, a built-in font is copied there." + source_ref: "core/reios/reios.cpp:736-755" + + - name: "naomi.zip" + path: "dc/naomi.zip" + category: bios_zip + system: sega-naomi + required: true + description: "NAOMI BIOS archive" + note: "Default BIOS of every NAOMI game whose table entry names none, cartridge, .lst, .bin and .dat images alike. One member is loaded: the one for the configured region, else epr-21576h.ic27." + source_ref: "core/hw/naomi/naomi_roms.h:132-189, core/hw/naomi/naomi_cart.cpp:227-247, core/hw/naomi/naomi_cart.cpp:472-484" + contents: + - name: "epr-21576h.ic27" + size: 2097152 + description: "Japan" + - name: "epr-21578h.ic27" + size: 2097152 + description: "Export" + - name: "epr-21577h.ic27" + size: 2097152 + description: "USA" + - name: "epr-21579d.ic27" + size: 2097152 + description: "Korea" + + - name: "awbios.zip" + path: "dc/awbios.zip" + category: bios_zip + system: sega-atomiswave + required: true + description: "Atomiswave BIOS archive" + note: "Named by all 34 Atomiswave games. Loaded into the flash chip, whose writable part is then reloaded from the save directory." + source_ref: "core/hw/naomi/naomi_roms.h:86-94, core/hw/naomi/naomi_cart.cpp:89-92, core/hw/naomi/naomi_cart.cpp:171-173" + contents: + - name: "bios0.ic23" + size: 131072 + + - name: "f355bios.zip" + path: "dc/f355bios.zip" + category: bios_zip + system: sega-naomi + required: true + description: "Ferrari F355 Challenge BIOS archive" + note: "Named by three Ferrari F355 Challenge entries, which refuse to start without it." + source_ref: "core/hw/naomi/naomi_roms.h:95-103, core/hw/naomi/naomi_cart.cpp:238-243" + contents: + - name: "epr-22851.ic27" + size: 2097152 + description: "Export" + - name: "epr-22850.ic27" + size: 2097152 + description: "USA" + - name: "epr-22849.ic27" + size: 2097152 + description: "Japan" + + - name: "f355dlx.zip" + path: "dc/f355dlx.zip" + category: bios_zip + system: sega-naomi + required: true + description: "Ferrari F355 Challenge Deluxe BIOS archive" + note: "Named by the f355 entry, which refuses to start without it." + source_ref: "core/hw/naomi/naomi_roms.h:104-119, core/hw/naomi/naomi_roms.h:1701, core/hw/naomi/naomi_cart.cpp:238-243" + contents: + - name: "epr-21864.ic27" + size: 2097152 + description: "Export" + - name: "epr-21863.ic27" + size: 2097152 + description: "USA" + - name: "epr-21862.ic27" + size: 2097152 + description: "Japan" + + - name: "hod2bios.zip" + path: "dc/hod2bios.zip" + category: bios_zip + system: sega-naomi + required: true + description: "The House of the Dead 2 BIOS archive" + note: "Named by four House of the Dead 2 entries, which refuse to start without it." + source_ref: "core/hw/naomi/naomi_roms.h:120-131, core/hw/naomi/naomi_cart.cpp:238-243" + contents: + - name: "epr-21331.ic27" + size: 2097152 + description: "Export" + - name: "epr-21330.ic27" + size: 2097152 + description: "USA" + - name: "epr-21329.ic27" + size: 2097152 + description: "Japan" diff --git a/emulators/mednafen_supafaust.yml b/emulators/mednafen_supafaust.yml index 21ef670d..a3b91783 100644 --- a/emulators/mednafen_supafaust.yml +++ b/emulators/mednafen_supafaust.yml @@ -7,7 +7,7 @@ profiled_date: "2026-03-24" source_commit: "642d1d1b6684aa7e306a02a89885f3f5456a5157" core_version: "1.29.0" display_name: "Nintendo - SNES / SFC (Beetle Supafaust)" -cores: [mednafen_supafaust, supafaust] +cores: [mednafen_supafaust, supafaust, beetle_supafaust] systems: [nintendo-snes] # Port of Mednafen's experimental snes_faust module. diff --git a/emulators/mupen64plus_next.yml b/emulators/mupen64plus_next.yml index 5b07c393..9571717e 100644 --- a/emulators/mupen64plus_next.yml +++ b/emulators/mupen64plus_next.yml @@ -8,7 +8,7 @@ source_commit: "12edd2c74a517ff86dfa8cfc71ad75e4c10486d5" core_version: "2.6.0" display_name: "Nintendo - Nintendo 64 (Mupen64Plus-Next)" systems: [nintendo-64, nintendo-64dd] -cores: [mupen64plus_next, mupen64plus_next_develop, mupen64plus_next_gles3, mupen64plus_next_gles2, mupen64plus, mupen64plus-next] +cores: [mupen64plus_next, mupen64plus_next_develop, mupen64plus_next_gles3, mupen64plus_next_gles2, mupen64plus, mupen64plus-next, mupen64plus_nx] files: - name: "IPL.n64" diff --git a/emulators/nanoboyadvance.yml b/emulators/nanoboyadvance.yml new file mode 100644 index 00000000..15ae81b5 --- /dev/null +++ b/emulators/nanoboyadvance.yml @@ -0,0 +1,47 @@ +emulator: "NanoBoyAdvance" +type: standalone +core_classification: other +source: "https://github.com/nba-emu/NanoBoyAdvance" +profiled_date: "2026-10-17" +source_commit: "3bb6f478f977dbfd3106508536e5fbce90d1898b" +pin_frozen: "ROCKNIX 20261001 builds this revision of the SDL2 frontend (v1.6 plus four commits). Later upstream work is not part of that build." +core_version: "1.6" +display_name: "Nintendo - Game Boy Advance (NanoBoyAdvance)" +cores: + - "nanoboyadvance" + - "nanoboyadvance-sa" +systems: + - nintendo-gba + +notes: | + Game Boy Advance emulator. ROCKNIX builds the SDL2 frontend only + (PLATFORM_SDL2=ON, PLATFORM_QT=OFF). + + The SDL2 frontend changes the working directory to the executable's + directory, then reads config.toml there. The BIOS path is the general.bios_path + key of that file, default "bios.bin", overridden by --bios on the command line. + ref: src/platform/sdl/main.cpp:288-293, src/platform/core/src/config.cpp:36, + src/platform/core/include/platform/config.hpp:17, src/platform/sdl/main.cpp:98-102 + + The BIOS is required. BIOSLoader refuses a missing path, a directory, and any + size other than 16 KB; the frontend prints the reason and exits. There is no + built-in replacement. bios_skip only jumps past the boot screen after the BIOS + is loaded. + ref: src/platform/core/src/loader/bios.cpp:17-48, src/platform/sdl/main.cpp:177-192, + src/nba/src/core.cpp:42-44 + + ROCKNIX patches config.toml and keymap.toml to /storage/.config/nanoboyadvance/ + and its config.toml sets bios_path = /storage/roms/bios/gba_bios.bin. + +files: + - name: "bios.bin" + path: "bios.bin" + aliases: ["gba_bios.bin"] + system: nintendo-gba + required: true + size: 16384 + validation: [size] + config_key: "general.bios_path" + description: "Game Boy Advance BIOS" + note: "Any file name through general.bios_path or --bios; bios.bin beside the executable when neither is set. ROCKNIX points the key at gba_bios.bin in its BIOS directory." + source_ref: "src/platform/core/src/loader/bios.cpp:17-48, src/platform/core/src/config.cpp:36, src/platform/sdl/main.cpp:177-192" diff --git a/emulators/supersnes9x.yml b/emulators/supersnes9x.yml new file mode 100644 index 00000000..1ab8a9ca --- /dev/null +++ b/emulators/supersnes9x.yml @@ -0,0 +1,133 @@ +emulator: "SuperSnes9x" +type: libretro +core_classification: enhanced_fork +source: "https://github.com/shanytc/snes9x" +upstream: "https://github.com/snes9xgit/snes9x" +profiled_date: "2026-10-17" +source_commit: "691e47b40fb38fa522a5471462344a2f0206b7a8" +pin_frozen: "ROCKNIX 20261001 builds this revision. Later commits on shanytc/snes9x rework the Super Famicom Box loader and are not part of that build." +core_version: "1.63.29" +display_name: "Nintendo - SNES / SFC / SGB / GB / GBC (SuperSnes9x)" +cores: + - "supersnes9x" +systems: + - nintendo-snes + - nintendo-satellaview + - nintendo-sufami-turbo + - nintendo-sfcbox + - nintendo-sgb + - nintendo-gb + - nintendo-gbc + +notes: | + Snes9x fork that adds a Game Boy core behind a Super Game Boy subsystem, the + Super Famicom Box (HD64180 supervisor) and other boards. The libretro build + compiles sfcbox.cpp, hd64180.cpp and the sgb/ tree. + ref: snes9x.h:11-13, libretro/Makefile.common:53-69 + + BIOS_DIR is the frontend's system directory. LoadBIOS, used for BS-X.bin and + STBIOS.bin, tries the content directory first and requires the read to fill + the whole buffer it is given. + ref: libretro/libretro.cpp:2320-2326, libretro/libretro.cpp:1145-1176 + + Game Boy content: with the snes9x_sgb_bios option at its default (auto) the + core looks for an SGB2 BIOS, then an SGB1 BIOS, in the content directory, + BIOS_DIR, then the working directory. A candidate is accepted only when its + header at 0x7FC0 reads "Super GAMEBOY", the next byte deciding SGB2. Without + one the built-in BIOS-less Game Boy core runs the cart. In BIOS mode a + 256-byte GB-side boot ROM is read too, and used only when it contains the + 3E F1 handshake sequence; otherwise an embedded SGB boot ROM is used. + ref: libretro/libretro.cpp:657-671, memmap.cpp:1088-1155, + memmap.cpp:1165-1213, memmap.cpp:1655-1686, memmap.cpp:1858-1883 + + Satellaview: a BS-X cart loads only with BS-X.bin (1 MB). The BS-X slot code + reads BS-X.bin or BS-X.bios from BIOS_DIR. + ref: libretro/libretro.cpp:1308-1311, bsx.cpp:1204-1235, bsx.cpp:1301-1307 + + Sufami Turbo: a cart loads only with STBIOS.bin (256 KB). The Sufami Turbo + subsystem asks LoadBIOS for 0x100000 bytes, so a 256 KB STBIOS.bin fails that + path; the plain content path and the two-cart path ask for 0x40000. + ref: libretro/libretro.cpp:1302-1305, libretro/libretro.cpp:1413-1425, + libretro/libretro.cpp:1445-1455 + + Super Famicom Box: the supervisor ROM is looked for in BIOS_DIR, the content + directory, its BIOS and ../BIOS subfolders, then the directory of the loaded + file. Without it the image is refused. The OSD font is optional. + ref: sfcbox.cpp:1350-1407, memmap.cpp:2561-2562 + +files: + - name: "BS-X.bin" + aliases: ["BS-X.bios"] + system: nintendo-satellaview + required: true + min_size: 1048576 + validation: [size] + description: "Satellaview BS-X BIOS" + note: "Required for BS-X carts. BS-X.bios is accepted by the slot code in bsx.cpp only." + source_ref: "libretro/libretro.cpp:1145-1176, libretro/libretro.cpp:1308-1311, bsx.cpp:1204-1235" + + - name: "STBIOS.bin" + system: nintendo-sufami-turbo + required: true + min_size: 262144 + validation: [size] + description: "Sufami Turbo BIOS" + note: "Required for Sufami Turbo carts. The Sufami Turbo subsystem reads 1 MB and rejects a 256 KB file." + source_ref: "libretro/libretro.cpp:1145-1176, libretro/libretro.cpp:1302-1305, libretro/libretro.cpp:1445-1455" + + - name: "sgb2.sfc" + aliases: ["SGB2.sfc", "Super Game Boy 2 (Japan).sfc"] + system: nintendo-sgb + required: false + description: "Super Game Boy 2 SNES BIOS" + note: "Preferred over sgb.sfc in auto mode. Header at 0x7FC0 must read \"Super GAMEBOY2\". Without an SGB BIOS, GB content runs on the BIOS-less core." + source_ref: "memmap.cpp:1088-1155, memmap.cpp:1655-1665" + + - name: "sgb.sfc" + aliases: ["SGB.sfc", "sgb1.sfc", "SGB1.sfc", "Super Game Boy (World).sfc"] + system: nintendo-sgb + required: false + description: "Super Game Boy SNES BIOS" + note: "Used when no SGB2 BIOS is found, or alone with the option set to sgb1. Header at 0x7FC0 must read \"Super GAMEBOY\" not followed by '2'." + source_ref: "memmap.cpp:1088-1155, memmap.cpp:1655-1665" + + - name: "sgb2.boot.rom" + aliases: ["sgb2_bios.bin"] + system: nintendo-sgb + required: false + hle_fallback: true + size: 256 + validation: [size] + description: "Super Game Boy 2 GB-side boot ROM" + note: "Read in SGB2 BIOS mode; used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." + source_ref: "memmap.cpp:1165-1213, memmap.cpp:1858-1883" + + - name: "sgb.boot.rom" + aliases: ["sgb1.boot.rom", "sgb_bios.bin"] + system: nintendo-sgb + required: false + hle_fallback: true + size: 256 + validation: [size] + description: "Super Game Boy GB-side boot ROM" + note: "Read in SGB1 BIOS mode; used only when it contains the 3E F1 handshake bytes, else the embedded boot ROM runs." + source_ref: "memmap.cpp:1165-1213, memmap.cpp:1858-1883" + + - name: "KROM1.BIN" + aliases: ["KROM.BIN", "krom1.bin"] + system: nintendo-sfcbox + required: true + min_size: 65536 + validation: [size] + description: "Super Famicom Box supervisor ROM (HD64180)" + note: "Required for Super Famicom Box images: LoadSFCBox returns false without it." + source_ref: "sfcbox.cpp:1350-1398, sfcbox.h:20, memmap.cpp:2561-2562" + + - name: "MB90082.BIN" + system: nintendo-sfcbox + required: false + min_size: 9216 + validation: [size] + description: "Super Famicom Box OSD character ROM" + note: "Absent, the supervisor overlay is not drawn." + source_ref: "sfcbox.cpp:1400-1403, sfcbox.h:25" diff --git a/emulators/touchhle.yml b/emulators/touchhle.yml new file mode 100644 index 00000000..189656c0 --- /dev/null +++ b/emulators/touchhle.yml @@ -0,0 +1,206 @@ +emulator: "touchHLE" +type: standalone +core_classification: embedded_hle +source: "https://github.com/touchHLE/touchHLE" +profiled_date: "2026-10-17" +source_commit: "3c5850585ba55615b17a58c58331b6d6f52d4a9d" +pin_frozen: "ROCKNIX 20261001 builds this revision. Later upstream commits are not part of that build." +core_version: "0.2.3" +display_name: "Apple - iPhone OS (touchHLE)" +cores: + - "touchhle" + - "touchhle-sa" +systems: + - apple-ios + +notes: | + High-level emulator for iPhone OS apps. The operating system and its + frameworks are reimplemented in Rust, so no Apple firmware or system file is + opened. What it reads besides the app are resources bundled with it: three + Free Software ARMv6 libraries, fonts, and a table of default per-app options. + ref: Cargo.toml:7, src/paths.rs:9-12, src/paths.rs:28-36 + + Resources are opened relative to the working directory, or the Resources + folder of a macOS bundle. ROCKNIX patches the Linux base to /usr/lib/touchHLE. + ref: src/paths.rs:63-82 + + The libraries are mapped into the guest at /usr/lib under their own names and + aliases. An app binary that links one of them loads it from there, and fails + to start with "Could not load bundled dylib" when the host file is missing. + ref: src/fs.rs:588-622, src/environment.rs:384-413 + + Fonts are opened the first time an app draws text in that face, and a + missing or unparsable file is a panic. The Liberation families stand in for + the iPhone OS faces; Noto Sans JP is used for strings holding kana or kanji. + ROCKNIX installs only the LiberationSans files, so an app that asks for a + monospace, serif or Japanese face stops there. + ref: src/font.rs:70-129, src/frameworks/uikit/ui_font.rs:26-43, + src/frameworks/uikit/ui_font.rs:180-205 + + touchHLE_default_options.txt is read before the user's touchHLE_options.txt; + when it cannot be opened a warning is printed and the app runs without it. + ref: src/lib.rs:319-323 + +files: + - name: "libgcc_s.1.dylib" + path: "touchHLE_dylibs/libgcc_s.1.dylib" + system: apple-ios + required: false + bundled: true + description: "GCC runtime library from the iPhoneOS 4.0 SDK" + note: "Exposed as /usr/lib/libgcc_s.1.dylib. Needed by apps that link it." + source_ref: "src/fs.rs:588-622, src/environment.rs:384-413" + + - name: "libstdc++.6.0.9.dylib" + path: "touchHLE_dylibs/libstdc++.6.0.9.dylib" + system: apple-ios + required: false + bundled: true + description: "GNU C++ standard library from the iPhoneOS 4.0 SDK" + note: "Exposed as /usr/lib/libstdc++.6.dylib and /usr/lib/libstdc++.6.0.9.dylib. Needed by apps that link it." + source_ref: "src/fs.rs:588-622, src/environment.rs:384-413" + + - name: "libz.1.2.3.dylib" + path: "touchHLE_dylibs/libz.1.2.3.dylib" + system: apple-ios + required: false + bundled: true + description: "zlib built from Apple's zlib-23.0.1 sources" + note: "Exposed as /usr/lib/libz.1.2.3.dylib, libz.1.dylib, libz.dylib and libz.1.1.3.dylib. Needed by apps that link it." + source_ref: "src/fs.rs:588-622, src/environment.rs:384-413" + + - name: "LiberationMono-Regular.ttf" + path: "touchHLE_fonts/LiberationMono-Regular.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:88-90" + + - name: "LiberationMono-Bold.ttf" + path: "touchHLE_fonts/LiberationMono-Bold.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:91-93" + + - name: "LiberationMono-BoldItalic.ttf" + path: "touchHLE_fonts/LiberationMono-BoldItalic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:94-96" + + - name: "LiberationMono-Italic.ttf" + path: "touchHLE_fonts/LiberationMono-Italic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:97-99" + + - name: "LiberationSans-Regular.ttf" + path: "touchHLE_fonts/LiberationSans-Regular.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:100-102" + + - name: "LiberationSans-Bold.ttf" + path: "touchHLE_fonts/LiberationSans-Bold.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:103-105" + + - name: "LiberationSans-BoldItalic.ttf" + path: "touchHLE_fonts/LiberationSans-BoldItalic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:106-108" + + - name: "LiberationSans-Italic.ttf" + path: "touchHLE_fonts/LiberationSans-Italic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:109-111" + + - name: "LiberationSerif-Regular.ttf" + path: "touchHLE_fonts/LiberationSerif-Regular.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:112-114" + + - name: "LiberationSerif-Bold.ttf" + path: "touchHLE_fonts/LiberationSerif-Bold.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:115-117" + + - name: "LiberationSerif-BoldItalic.ttf" + path: "touchHLE_fonts/LiberationSerif-BoldItalic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:118-120" + + - name: "LiberationSerif-Italic.ttf" + path: "touchHLE_fonts/LiberationSerif-Italic.ttf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:121-123" + + - name: "NotoSansJP-Regular.otf" + path: "touchHLE_fonts/NotoSansJP-Regular.otf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:124-126" + + - name: "NotoSansJP-Bold.otf" + path: "touchHLE_fonts/NotoSansJP-Bold.otf" + system: apple-ios + required: false + bundled: true + description: "Bundled font" + note: "Opened on first use of its face; touchHLE panics when it is missing." + source_ref: "src/font.rs:70-85, src/font.rs:127-129" + + - name: "touchHLE_default_options.txt" + path: "touchHLE_default_options.txt" + system: apple-ios + required: false + bundled: true + category: game_data + description: "Default options per app" + note: "Command-line style options keyed by app bundle identifier, applied before the user's own file." + source_ref: "src/paths.rs:36, src/lib.rs:319-323" diff --git a/emulators/x1.yml b/emulators/x1.yml index e2533cda..71759257 100644 --- a/emulators/x1.yml +++ b/emulators/x1.yml @@ -9,6 +9,7 @@ core_version: "0.60a" display_name: "Sharp X1 (X Millennium)" cores: - x1 + - xmil systems: - sharp-x1 diff --git a/platforms/_registry.yml b/platforms/_registry.yml index 6b1c34da..c1def9da 100644 --- a/platforms/_registry.yml +++ b/platforms/_registry.yml @@ -374,6 +374,8 @@ platforms: logo: https://avatars.githubusercontent.com/u/152618023 scraper: rocknix schedule: weekly + target_scraper: rocknix_targets + target_source: https://github.com/ROCKNIX/distribution/blob/next/projects/ROCKNIX/packages/virtual/emulators/package.mk install: detect: - os: linux diff --git a/platforms/targets/_overrides.yml b/platforms/targets/_overrides.yml index ab19c2ef..dec39866 100644 --- a/platforms/targets/_overrides.yml +++ b/platforms/targets/_overrides.yml @@ -112,3 +112,19 @@ retropie: _default: # Homebrew game scriptmodule, not an emulator. remove_cores: [superflappybirds] + +rocknix: + targets: + _default: + # Runtimes and launchers the emulators metapackage installs beside the + # emulators: x86 translation (box64, box86), Windows (wine), the Steam + # and Heroic clients, and PortMaster, which installs ports. + remove_cores: + - box64 + - box86 + - heroic + - portmaster + - steam + - wine + amd64: + aliases: [x86_64, pc] diff --git a/platforms/targets/rocknix.yml b/platforms/targets/rocknix.yml new file mode 100644 index 00000000..6116885c --- /dev/null +++ b/platforms/targets/rocknix.yml @@ -0,0 +1,2088 @@ +platform: rocknix +source: https://github.com/ROCKNIX/distribution/tree/20261001/projects/ROCKNIX/packages/virtual/emulators/package.mk +scraped_at: '2026-10-17T13:15:29Z' +targets: + amd64: + architecture: x86_64 + cores: + - '81' + - a5200 + - amiberry + - arduous + - ares + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - boom3 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daphne + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gopher64 + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - vitaquake3 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro + h700: + architecture: aarch64 + cores: + - '81' + - a5200 + - amiberry + - arduous + - atari800 + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + rk3326: + architecture: aarch64 + cores: + - '81' + - a5200 + - amiberry + - arduous + - atari800 + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + rk3399: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + rk3566: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + rk3576: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + rk3588: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + s922x: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + sm4450: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daedalusx64 + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - heroic + - hypseus-singe + - jaxe + - kronos + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - steam + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro + sm6115: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - crocods + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - hypseus-singe + - jaxe + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xmil + - yabasanshiro + sm8250: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daedalusx64 + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gpsp + - gw + - gzdoom + - handy + - hatari + - heroic + - hypseus-singe + - jaxe + - kronos + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - rpcs3 + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - steam + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro + sm8550: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - ares + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - box86 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daedalusx64 + - daphne + - desmume + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - drastic + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gopher64 + - gpsp + - gw + - gzdoom + - handy + - hatari + - heroic + - hypseus-singe + - jaxe + - kronos + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - rpcs3 + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - steam + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro + sm8650: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - ares + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daphne + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gopher64 + - gw + - gzdoom + - handy + - hatari + - heroic + - hypseus-singe + - jaxe + - kronos + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - rpcs3 + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - steam + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro + sm8750: + architecture: aarch64 + cores: + - '81' + - a5200 + - aethersx2 + - amiberry + - arduous + - ares + - armsx2 + - atari800 + - azahar + - b2 + - beetle_gba + - beetle_lynx + - beetle_ngp + - beetle_pce + - beetle_pce_fast + - beetle_pcfx + - beetle_psx + - beetle_saturn + - beetle_supafaust + - beetle_supergrafx + - beetle_vb + - beetle_wswan + - bigpemu + - bk + - bluemsx + - box64 + - bsnes + - bsnes2014_accuracy + - bsnes2014_balanced + - bsnes2014_performance + - bsnes_hd + - bsnes_mercury_accuracy + - bsnes_mercury_balanced + - bsnes_mercury_performance + - cap32 + - cemu + - crocods + - daphne + - dolphin + - dosbox_core + - dosbox_pure + - doublecherrygb + - dsperate + - duckstation + - easyrpg + - ecwolf + - emuscv + - fake08 + - fbalpha2012 + - fbalpha2019 + - fbneo + - fceumm + - flycast + - flycast2021 + - fmsx + - freechaf + - freeintv + - freej2me + - fuse + - gambatte + - gearboy + - gearcoleco + - geargrafx + - gearlynx + - gearsystem + - genesis_plus_gx + - genesis_plus_gx_wide + - geolith + - gopher64 + - gw + - gzdoom + - handy + - hatari + - heroic + - hypseus-singe + - jaxe + - kronos + - mame + - mame2003_plus + - mame2010 + - mame2015 + - mednafen + - melonds + - melonds_ds + - mesen + - mesen_s + - mgba + - minivmac + - mojozork + - moonlight + - mu + - mupen64plus + - mupen64plus_nx + - nanoboyadvance + - neocd + - nestopia + - np2kai + - o2em + - openbor + - opera + - parallel_n64 + - pcsx_rearmed + - pico-8 + - picodrive + - pokemini + - portmaster + - potator + - ppsspp + - prboom + - prosystem + - puae + - puae2021 + - px68k + - quasi88 + - quicknes + - race + - rpcs3 + - same_cdi + - sameboy + - sameduck + - scummvm + - skyemu + - smsplus_gx + - snes9x + - snes9x2002 + - snes9x2005_plus + - snes9x2010 + - steam + - stella + - supermodel + - supersnes9x + - swanstation + - tgbdual + - theodore + - tic80 + - touchhle + - tyrquake + - uae4arm + - uzem + - vba_next + - vbam + - vecx + - vice + - vircon32 + - virtualjaguar + - vita3k + - vitaquake2 + - wasm4 + - wine + - xemu + - xmil + - yabasanshiro diff --git a/scripts/scraper/targets/rocknix_targets_scraper.py b/scripts/scraper/targets/rocknix_targets_scraper.py new file mode 100644 index 00000000..161170b2 --- /dev/null +++ b/scripts/scraper/targets/rocknix_targets_scraper.py @@ -0,0 +1,202 @@ +"""Scraper for ROCKNIX per-device emulator availability. + +Sources (ROCKNIX/distribution, at the release tag platforms/rocknix.yml names): + - projects/ROCKNIX/packages/virtual/emulators/package.mk -- the cores every + image carries, those aarch64 adds, and a `case "${DEVICE}"` block per SoC + - projects/ROCKNIX/devices//options -- ENABLE_32BIT, which the 32-bit + cores of a device depend on (distributions/ROCKNIX/options defaults it on) + +An H700 or RK3326 handheld carries neither Dolphin nor AetherSX2: without a +target list, its pack shipped the PS2, GameCube and PS3 firmware anyway. +""" + +from __future__ import annotations + +import argparse +import re +import sys +from datetime import datetime, timezone + +import yaml + +from . import BaseTargetScraper + +PLATFORM_NAME = "rocknix" + +RAW_BASE = "https://raw.githubusercontent.com/ROCKNIX/distribution/{tag}" +GITHUB_API = "https://api.github.com/repos/ROCKNIX/distribution/contents" +EMULATORS_MK = "projects/ROCKNIX/packages/virtual/emulators/package.mk" +DEVICES_DIR = "projects/ROCKNIX/devices" + +try: + from ..base_scraper import fetch_bytes, github_headers + from ..rocknix_scraper import GITHUB_REPO +except ImportError: + from scraper.base_scraper import fetch_bytes, github_headers + from scraper.rocknix_scraper import GITHUB_REPO + +# `NAME="a b \ +# c"` or `NAME+=" a b"`, continuation lines joined first. +_ASSIGN_RE = re.compile(r'^\s*(?:\[[^\]]*\]\s*&&\s*)?(\w+)(\+?=)"([^"]*)"', re.MULTILINE) +_CASE_RE = re.compile(r'case "\$\{DEVICE\}" in(.*?)\besac\b', re.DOTALL) +_ARM_RE = re.compile(r"^\s*([A-Z0-9|]+)\)\s*$", re.MULTILINE) +_AARCH64_RE = re.compile( + r'if \[ "\$\{ARCH\}" = "aarch64" \]; then(.*?)\bfi\b', re.DOTALL +) + + +def _assignments(text: str) -> list[tuple[str, str, list[str]]]: + """(variable, operator, words) of each quoted assignment, in order.""" + joined = re.sub(r"\\\n", " ", text) + return [(name, op, value.split()) for name, op, value in _ASSIGN_RE.findall(joined)] + + +def _apply(state: dict[str, list[str]], text: str, with_32bit: bool) -> None: + for name, op, words in _assignments(text): + if name == "EMUS_32BIT" and not with_32bit: + continue + if op == "=": + state[name] = list(words) + else: + state.setdefault(name, []).extend(words) + + +def parse_device_cores( + package_mk: str, device: str, arch: str, with_32bit: bool +) -> tuple[list[str], list[str]]: + """(libretro packages, standalone packages) one device's image carries.""" + case = _CASE_RE.search(package_mk) + head = package_mk[: case.start()] if case else package_mk + aarch64 = _AARCH64_RE.search(head) + base = head if aarch64 is None else head[: aarch64.start()] + head[aarch64.end():] + state: dict[str, list[str]] = {} + _apply(state, base, with_32bit) + if arch == "aarch64" and aarch64 is not None: + _apply(state, aarch64.group(1), with_32bit) + if case is not None: + arms = list(_ARM_RE.finditer(case.group(1))) + for index, arm in enumerate(arms): + if device not in arm.group(1).split("|"): + continue + end = arms[index + 1].start() if index + 1 < len(arms) else len(case.group(1)) + _apply(state, case.group(1)[arm.end():end], with_32bit) + libretro = state.get("LIBRETRO_CORES", []) + [ + p for p in state.get("EMUS_32BIT", []) if re.search(r"[-_]lr$", p) + ] + standalone = state.get("PKG_EMUS", []) + [ + p for p in state.get("EMUS_32BIT", []) if not re.search(r"[-_]lr$", p) + ] + return libretro, standalone + + +def core_names(libretro: list[str], standalone: list[str]) -> list[str]: + """Package names as the profiles' cores: lists spell them. + + A libretro package is the core's name with `-lr` (`beetle-psx-lr`, + `neocd_lr`), spelled with underscores as the buildbot names it; a + standalone package drops its `-sa` (`duckstation-sa`, `hatarisa`). + """ + names = {re.sub(r"[-_]lr$", "", package).replace("-", "_") for package in libretro} + names.update(re.sub(r"-?sa$", "", package) for package in standalone) + return sorted(names) + + +# A package that builds nothing itself and pulls other cores in. idtech-lr +# installs ecwolf, prboom, tyrquake and vitaquake2 (vitaquake3 and boom3 on +# x86_64); no profile could name it. +METAPACKAGES = {"idtech-lr": "projects/ROCKNIX/packages/emulators/libretro/idtech-lr/package.mk"} +_IF_RE = re.compile(r'^if \[ "\$\{(\w+)\}" = "?([\w-]+)"? \]; then\n(.*?)^fi$', + re.MULTILINE | re.DOTALL) + + +def metapackage_cores(package_mk: str, arch: str) -> list[str]: + """The -lr packages a metapackage depends on for one architecture. + + OPENGLES_SUPPORT is yes on every ROCKNIX device (config/graphic, from + OPENGLES="mesa" in projects/ROCKNIX/options); TARGET_ARCH is the device's. + """ + found: list[str] = [] + for variable, value, body in _IF_RE.findall(package_mk): + if variable == "TARGET_ARCH" and value != arch: + continue + if variable not in ("TARGET_ARCH", "OPENGLES_SUPPORT"): + continue + for _name, _op, words in _assignments(body): + found += [w for w in words if re.search(r"[-_]lr$", w)] + return found + + +class Scraper(BaseTargetScraper): + """Per-device core lists from ROCKNIX's emulators metapackage.""" + + def __init__(self, url: str = "https://github.com/ROCKNIX/distribution"): + super().__init__(url=url) + self.tag = "" + + def _raw(self, path: str) -> str: + return fetch_bytes(f"{RAW_BASE.format(tag=self.tag)}/{path}").decode("utf-8") + + def _devices(self) -> list[str]: + import json # noqa: PLC0415 + + listing = json.loads(fetch_bytes( + f"{GITHUB_API}/{DEVICES_DIR}?ref={self.tag}", headers=github_headers() + )) + devices = [item["name"] for item in listing if item.get("type") == "dir"] + if not devices: + raise RuntimeError(f"no device in {DEVICES_DIR} at {self.tag}") + return sorted(devices) + + def fetch_targets(self) -> dict: + from scraper.base_scraper import fetch_github_latest_version # noqa: PLC0415 + + self.tag = fetch_github_latest_version(GITHUB_REPO) + if not self.tag: + raise RuntimeError("cannot read ROCKNIX's latest release tag") + package_mk = self._raw(EMULATORS_MK) + if "LIBRETRO_CORES" not in package_mk: + raise RuntimeError(f"no LIBRETRO_CORES in {EMULATORS_MK} at {self.tag}") + + targets: dict[str, dict] = {} + for device in self._devices(): + options = self._raw(f"{DEVICES_DIR}/{device}/options") + arch = "x86_64" if device == "AMD64" else "aarch64" + with_32bit = not re.search(r'ENABLE_32BIT="false"', options) + libretro, standalone = parse_device_cores(package_mk, device, arch, with_32bit) + for meta, path in METAPACKAGES.items(): + if meta in libretro: + libretro.remove(meta) + libretro += metapackage_cores(self._raw(path), arch) + cores = core_names(libretro, standalone) + targets[device.lower()] = {"architecture": arch, "cores": cores} + print(f" {device.lower()} ({arch}): {len(cores)} cores", file=sys.stderr) + + return { + "platform": PLATFORM_NAME, + "source": f"{self.url}/tree/{self.tag}/{EMULATORS_MK}", + "scraped_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "targets": targets, + } + + +def main() -> None: + parser = argparse.ArgumentParser(description="Scrape ROCKNIX per-device cores") + parser.add_argument("--dry-run", action="store_true", help="Show target summary") + parser.add_argument("--output", "-o", help="Output YAML file") + args = parser.parse_args() + + scraper = Scraper() + data = scraper.fetch_targets() + if args.dry_run: + for name, info in data["targets"].items(): + print(f" {name} ({info['architecture']}): {len(info['cores'])} cores") + return + if args.output: + scraper.write_output(data, args.output) + print(f"Written to {args.output}") + return + print(yaml.dump(data, default_flow_style=False, sort_keys=False)) + + +if __name__ == "__main__": + main() diff --git a/tests/test_target_scrapers.py b/tests/test_target_scrapers.py index f9ec403b..15a0bbe8 100644 --- a/tests/test_target_scrapers.py +++ b/tests/test_target_scrapers.py @@ -176,6 +176,63 @@ class BatoceraKconfig(unittest.TestCase): "BR2_PACKAGE_RUFFLE"} & active) +class RocknixPerDevice(unittest.TestCase): + """ROCKNIX had no target list: an H700 handheld got the PS2, GameCube + and PS3 firmware of emulators its image does not carry.""" + + PACKAGE_MK = ( + 'PKG_EMUS="amiberry duckstation-sa hatarisa"\n' + 'EMUS_32BIT=""\n' + 'LIBRETRO_CORES="81-lr beetle-psx-lr \\\n' + ' neocd_lr idtech-lr"\n' + 'if [ "${ARCH}" = "aarch64" ]; then\n' + ' LIBRETRO_CORES+=" duckstation-lr"\n' + 'fi\n' + 'case "${DEVICE}" in\n' + ' H700|RK3326)\n' + ' [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="box86 gpsp-lr"\n' + ' PKG_EMUS+=" drastic-sa"\n' + ' ;;\n' + ' SM8550)\n' + ' PKG_EMUS+=" aethersx2-sa dolphin-sa"\n' + ' ;;\n' + ' AMD64)\n' + ' PKG_EMUS+=" dolphin-sa"\n' + 'esac\n' + ) + IDTECH = ( + 'if [ "${OPENGLES_SUPPORT}" = yes ]; then\n' + ' PKG_DEPENDS_TARGET+=" ecwolf-lr prboom-lr"\n' + 'fi\n' + 'if [ "${TARGET_ARCH}" = "x86_64" ]; then\n' + ' PKG_DEPENDS_TARGET+=" vitaquake3-lr"\n' + 'fi\n' + ) + + def test_each_device_gets_its_own_cores(self): + from scraper.targets.rocknix_targets_scraper import ( # noqa: PLC0415 + core_names, + parse_device_cores, + ) + + h700 = core_names(*parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", True)) + self.assertTrue({"drastic", "gpsp", "duckstation", "beetle_psx", "hatari", + "81", "neocd"} <= set(h700)) + self.assertFalse({"aethersx2", "dolphin"} & set(h700)) + no32 = core_names(*parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", False)) + self.assertNotIn("gpsp", no32) + amd64 = core_names(*parse_device_cores(self.PACKAGE_MK, "AMD64", "x86_64", False)) + self.assertIn("dolphin", amd64) + self.assertNotIn("drastic", amd64) + + def test_a_metapackage_names_the_cores_it_installs(self): + from scraper.targets.rocknix_targets_scraper import metapackage_cores # noqa: PLC0415 + + self.assertEqual(metapackage_cores(self.IDTECH, "aarch64"), ["ecwolf-lr", "prboom-lr"]) + self.assertEqual(metapackage_cores(self.IDTECH, "x86_64"), + ["ecwolf-lr", "prboom-lr", "vitaquake3-lr"]) + + class RetroPieModuleFlags(unittest.TestCase): """The RetroPie target list read flags as requirements and libretro alone.