From 349914fda28ba4f4549564aabfbb5804f84a31ca Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:16:00 +0100 Subject: [PATCH 1/6] fix: list boards offline from the given list --list-targets offline was refused, and its advice to give --manifest or --from-pack was refused in turn. It now reads the boards where --target reads them: the pack's list or targets/.json beside --manifest. --- install.ps1 | 2 +- install.py | 5 +++-- install.sh | 2 +- install/launchers/index.json | 16 ++++++++-------- tests/test_install_offline.py | 15 +++++++++++++++ 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/install.ps1 b/install.ps1 index f1c93ca4c..caa70f050 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "d9b9e08c5a3ff983f8bb440512edd0c68e33493ff6c3c5b119dfe72582b3a3d1" + $defaultInstallSha256 = "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 0f61a0b21..ec50d19a4 100644 --- a/install.py +++ b/install.py @@ -13451,9 +13451,10 @@ def main() -> None: ): parser.error("--from copies files into the BIOS folder, which a listing " "does not write") - if (args.from_pack or args.manifest) and (args.list_platforms or args.list_targets): + if (args.from_pack or args.manifest) and args.list_platforms: + # --list-targets reads its boards from them, where --target does. parser.error("--from-pack and --manifest give a file list, which --list-platforms " - "and --list-targets do not read") + "does not read") if args.no_game_data and (args.list_platforms or args.list_targets): parser.error("--no-game-data narrows a file list, not --list-platforms " "or --list-targets") diff --git a/install.sh b/install.sh index 2cdd22977..befed61da 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="d9b9e08c5a3ff983f8bb440512edd0c68e33493ff6c3c5b119dfe72582b3a3d1" +DEFAULT_INSTALL_SHA256="8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index be5af75db..414cef37b 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1098257, - "sha256": "d9b9e08c5a3ff983f8bb440512edd0c68e33493ff6c3c5b119dfe72582b3a3d1", + "size": 1098291, + "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1151884, - "sha256": "54ff79a8c51879532db206bb24dd7b3a884a2c8de1d3bcc07f1a2d4f66084c71" + "size": 1151918, + "sha256": "4981792f43dd11f8bb09f0c9981abe721934a84d5d8a49c05bfca44d736ddd83" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1098257, - "sha256": "d9b9e08c5a3ff983f8bb440512edd0c68e33493ff6c3c5b119dfe72582b3a3d1", + "size": 1098291, + "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1098257, - "sha256": "d9b9e08c5a3ff983f8bb440512edd0c68e33493ff6c3c5b119dfe72582b3a3d1", + "size": 1098291, + "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", "executable": false }, { diff --git a/tests/test_install_offline.py b/tests/test_install_offline.py index 04b3ab018..dd6849439 100644 --- a/tests/test_install_offline.py +++ b/tests/test_install_offline.py @@ -463,6 +463,21 @@ class ABoardWithoutTheNetwork(Scratch): self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) self.assertIn("for target psx-board", proc.stdout) + def test_the_boards_are_listed_from_where_target_reads_them(self): + """Offline, the refusal of --list-targets named --manifest, and + --manifest with --list-targets was refused: no form listed a board.""" + (self.root / "targets").mkdir() + (self.root / "targets" / "retroarch.json").write_text(json.dumps(BOARDS)) + _carrying(self.pack, {"install_list": manifest(), "targets": BOARDS}) + for given in (["--offline", "--manifest", str(self.list)], + ["--from-pack", str(self.pack)]): + with self.subTest(given=given[-1]): + proc = self.run_installer(*given, "--list-targets", "--no-input") + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + for board in BOARDS: + self.assertIn(f" {board} (", proc.stdout) + self.assertFalse(self.dest.exists()) + def test_a_pack_without_a_list_says_why(self): proc = self.run_installer("--from-pack", str(self.pack), "--target", "gba-board", "--no-input") From a2e8809945fdcbe5085351119d68df5a1e6dbb18 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:40:34 +0100 Subject: [PATCH 2/6] fix: map a card's image name to its board Batocera and KNULLI write the image name, not the board, to the card's board file (post-image-script.sh). The target scraper now records each board's images from Config.in, the target lists carry them, and the installer maps a card's image to its board. KNULLI's boot/knulli.board is read too. --- install.ps1 | 2 +- install.py | 28 +- install.sh | 2 +- install/launchers/index.json | 16 +- install/targets/batocera.json | 6971 +++++++++-------- install/targets/knulli.json | 2617 ++++--- platforms/targets/batocera.yml | 125 +- platforms/targets/knulli.yml | 44 +- schemas/target-manifest.schema.json | 6 +- scripts/generate_pack.py | 18 +- .../targets/batocera_targets_scraper.py | 35 + tests/test_install.py | 40 + tests/test_target_scrapers.py | 19 +- wiki/installer.md | 4 +- 14 files changed, 5236 insertions(+), 4691 deletions(-) diff --git a/install.ps1 b/install.ps1 index caa70f050..3bdff2ca4 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1" + $defaultInstallSha256 = "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index ec50d19a4..295726e74 100644 --- a/install.py +++ b/install.py @@ -1488,8 +1488,11 @@ _BOARD_NAMES: dict[str, dict[str, str]] = { # the FAT one beside SHARE (batocera-43.1, board/batocera/scripts/ # post-image-script.sh:60), and reads it there itself (package/batocera/ # core/batocera-scripts/scripts/batocera-info). batocera.arch is inside the -# image, out of a computer's reach. -_CARD_BOARD_FILES: dict[str, str] = {"batocera": "boot/batocera.board"} +# image, out of a computer's reach. KNULLI writes boot/knulli.board the same +# way (knulli-linux 20260511, board/scripts/post-image-script.sh:66). Both +# write the image's name, which the target list maps to its board. +_CARD_BOARD_FILES: dict[str, str] = {"batocera": "boot/batocera.board", + "knulli": "boot/knulli.board"} def card_board(platform: str) -> str | None: @@ -3905,9 +3908,26 @@ def _validate_targets(data: object) -> dict[str, dict]: ): raise ValueError(f"invalid core list for target {target}") normalized[target] = {"cores": cores} + images = value.get("images") if isinstance(value, dict) else None + if images is None: + continue + if not isinstance(images, list) or len(images) > 10_000 or not all( + isinstance(image, str) and 0 < len(image) <= 128 for image in images): + raise ValueError(f"invalid image list for target {target}") + normalized[target]["images"] = images return normalized +def board_target(board: str, targets: dict[str, dict]) -> str | None: + """The target a board name stands for: the name itself, else the one + target whose images carry it. A card names its image (Batocera writes + anbernic-rg35xx-plus for the h700 target, x86-64-v3 for zen3).""" + if board in targets: + return board + owners = [name for name, info in targets.items() if board in info.get("images", ())] + return owners[0] if len(owners) == 1 else None + + NETWORK_ADVICE = (" Check the connection, and HTTPS_PROXY if this network needs a " "proxy, then run the same command again.\n" f" More help: {TROUBLESHOOTING_PAGE}") @@ -15195,9 +15215,11 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: board, where = card_board(plat_name), "found on the card" if board: known = fetch_targets(plat_name) or {} + image, board = board, board_target(board, known) or board if board in known: target = board - words = f"Board {board} {where} (--every-board installs all boards)" + named = board if image == board else f"{board} ({image})" + words = f"Board {named} {where} (--every-board installs all boards)" else: words = (f"Board {board} {where} has no " f"{PLATFORM_NAMES.get(plat_name, plat_name)} core list: " diff --git a/install.sh b/install.sh index befed61da..015c38707 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1" +DEFAULT_INSTALL_SHA256="4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 414cef37b..524a9dc01 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1098291, - "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", + "size": 1099572, + "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1151918, - "sha256": "4981792f43dd11f8bb09f0c9981abe721934a84d5d8a49c05bfca44d736ddd83" + "size": 1153199, + "sha256": "284143d1c9bed3becfbe1ecee2e690cd11dc0ee495c8beeb9d7dca70cd63622e" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1098291, - "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", + "size": 1099572, + "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1098291, - "sha256": "8e1b953a928a794c79d73105dc4b45dccd5a2f55651f8a262ac51783352f16c1", + "size": 1099572, + "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", "executable": false }, { diff --git a/install/targets/batocera.json b/install/targets/batocera.json index 76b6dad70..3b38510ca 100644 --- a/install/targets/batocera.json +++ b/install/targets/batocera.json @@ -1,160 +1,165 @@ { - "a3gen2": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "vkquake", - "vkquake3", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], + "a3gen2": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "vkquake", + "vkquake3", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "khadas-vim4" + ] + }, "bcm2711": [ "81", "a5200", @@ -1216,718 +1221,766 @@ "yquake2", "zc210" ], - "h3": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dice", - "dosbox_pure", - "easyrpg", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "lightspark", - "lowresnx", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pocketsnes", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "px68k", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "vb", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "h5": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "duckstation-legacy", - "easyrpg", - "ecwolf", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "h6": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "duckstation-legacy", - "easyrpg", - "ecwolf", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "h616": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "h700": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "supermodel-legacy", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], + "h3": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dice", + "dosbox_pure", + "easyrpg", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "lightspark", + "lowresnx", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pocketsnes", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "px68k", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "vb", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "bananapi-m2-zero", + "cha", + "orangepi-one", + "orangepi-pc", + "orangepi-plus2e" + ] + }, + "h5": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "duckstation-legacy", + "easyrpg", + "ecwolf", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "orangepi-pc2", + "tritium-h5" + ] + }, + "h6": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "duckstation-legacy", + "easyrpg", + "ecwolf", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "orangepi-3", + "orangepi-3-lts", + "orangepi-one-plus" + ] + }, + "h616": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "orangepi-zero2", + "orangepi-zero3", + "x96-mate" + ] + }, + "h700": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "supermodel-legacy", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "anbernic-rg28xx", + "anbernic-rg34xx", + "anbernic-rg34xx-sp", + "anbernic-rg35xx-2024", + "anbernic-rg35xx-2024-rev6-panel", + "anbernic-rg35xx-h", + "anbernic-rg35xx-h-rev6-panel", + "anbernic-rg35xx-plus", + "anbernic-rg35xx-plus-rev6-panel", + "anbernic-rg35xx-pro", + "anbernic-rg35xx-sp", + "anbernic-rg35xx-sp-v2-panel", + "anbernic-rg40xx-h", + "anbernic-rg40xx-v", + "anbernic-rgcubexx" + ] + }, "jh7110": [ "81", "a5200", @@ -2349,1409 +2402,1494 @@ "yquake2", "zc210" ], - "qcs6490": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "azahar", - "beetle-saturn", - "bennugd", - "bk", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "clk", - "corsixth", - "devilutionx", - "dhewm3", - "dice", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tsugaru", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vircon32", - "virtualjaguar", - "vitaquake2", - "vkquake", - "vkquake2", - "vkquake3", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "ymir", - "yquake2", - "zc210" - ], - "rk3128": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dice", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "lightspark", - "lowresnx", - "lutro", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "rk3288": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "easyrpg", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mesen", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "rk3326": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "rk3328": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "duckstation-legacy", - "easyrpg", - "ecwolf", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "rk3399": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox_pure", - "dosbox_staging", - "duckstation", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "rk3568": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "supermodel-legacy", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "rk3588": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "beetle-saturn", - "bennugd", - "bk", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dhewm3", - "dice", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "supermodel-legacy", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tsugaru", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "vkquake", - "vkquake2", - "vkquake3", - "vpinball", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "ymir", - "yquake2", - "zc210" - ], - "rk3588-sdio": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "beetle-saturn", - "bennugd", - "bk", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dhewm3", - "dice", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "supermodel-legacy", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tsugaru", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "vkquake", - "vkquake2", - "vkquake3", - "vpinball", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "ymir", - "yquake2", - "zc210" - ], + "qcs6490": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "azahar", + "beetle-saturn", + "bennugd", + "bk", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "clk", + "corsixth", + "devilutionx", + "dhewm3", + "dice", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tsugaru", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vircon32", + "virtualjaguar", + "vitaquake2", + "vkquake", + "vkquake2", + "vkquake3", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "ymir", + "yquake2", + "zc210" + ], + "images": [ + "dragonq6a" + ] + }, + "rk3128": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dice", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "lightspark", + "lowresnx", + "lutro", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "powkiddy_a13", + "ps5000", + "ps7000" + ] + }, + "rk3288": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "easyrpg", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mesen", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "miqi", + "tinkerboard" + ] + }, + "rk3326": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "r36s", + "rg351v-v2", + "rk3326" + ] + }, + "rk3328": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "duckstation-legacy", + "easyrpg", + "ecwolf", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "roc-cc", + "rock64" + ] + }, + "rk3399": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox_pure", + "dosbox_staging", + "duckstation", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "hugsun-x99", + "nanopi-m4v2", + "orangepi-800", + "orangepi4-lts", + "rg552", + "rock-pi-4", + "rock960", + "rockpro64" + ] + }, + "rk3568": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "supermodel-legacy", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "anbernic-rgxx3", + "firefly-station-m2", + "firefly-station-p2", + "odroid-m1", + "odroid-m1s", + "orangepi-3b", + "powkiddy-x55", + "radxa-zero-3w", + "rock-3a", + "rock-3c" + ] + }, + "rk3588": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "beetle-saturn", + "bennugd", + "bk", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dhewm3", + "dice", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "supermodel-legacy", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tsugaru", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "vkquake", + "vkquake2", + "vkquake3", + "vpinball", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "ymir", + "yquake2", + "zc210" + ], + "images": [ + "bananapi-m7", + "coolpi-4b", + "firefly-station-m3", + "friendlyelec-cm3588-nas", + "gameforce-ace", + "indiedroid-nova", + "khadas-edge-2", + "mekotronics-r58", + "nanopi-m6", + "orangepi-5", + "orangepi-5-plus", + "orangepi-5-pro", + "orangepi-5b", + "quartzpro64", + "rock-5a", + "rock-5b", + "rock-5b-plus", + "rock-5c" + ] + }, + "rk3588-sdio": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "beetle-saturn", + "bennugd", + "bk", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dhewm3", + "dice", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "supermodel-legacy", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tsugaru", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "vkquake", + "vkquake2", + "vkquake3", + "vpinball", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "ymir", + "yquake2", + "zc210" + ], + "images": [ + "orangepi-5-max", + "orangepi-5-ultra" + ] + }, "rpi-zero": [ "81", "a5200", @@ -5192,753 +5330,794 @@ "yquake2", "zc210" ], - "s905": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "duckstation-legacy", - "easyrpg", - "ecwolf", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "pce_fast", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yquake2", - "zc210" - ], - "s905gen2": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "s905gen3": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mesen", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "s922x": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], - "s9gen4": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], + "s905": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "duckstation-legacy", + "easyrpg", + "ecwolf", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "pce_fast", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yquake2", + "zc210" + ], + "images": [ + "lepotato", + "lepotatov2", + "minix-neo-u1", + "odroidc2", + "p201", + "tvbox", + "vim" + ] + }, + "s905gen2": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "khadas-vim2", + "radxa-zero" + ] + }, + "s905gen3": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mesen", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "khadas-vim3l", + "odroidc4", + "tvbox-gen3" + ] + }, + "s922x": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "gtking", + "gtkingpro", + "odroidn2", + "odroidn2l", + "odroidn2plus", + "ogu", + "vim3", + "zero2" + ] + }, + "s9gen4": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "khadas-vim1s" + ] + }, "sm8250": [ "81", "a5200", @@ -6299,169 +6478,174 @@ "yquake2", "zc210" ], - "t527": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bk", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dice", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ioquake3", - "iortcw", - "jazz2-native", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "pd777", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "redream", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "supermodel-legacy", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "yquake2", - "zc210" - ], + "t527": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bk", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dice", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ioquake3", + "iortcw", + "jazz2-native", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "pd777", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "redream", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "supermodel-legacy", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "yquake2", + "zc210" + ], + "images": [ + "orangepi-4a" + ] + }, "x86_64": [ "81", "a5200", @@ -6672,214 +6856,219 @@ "yquake2", "zc210" ], - "zen3": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "azahar", - "beetle-saturn", - "bennugd", - "bigpemu", - "bk", - "blastem", - "bluemsx", - "boom3", - "bsnes", - "bsnes_hd", - "bstone", - "cannonball", - "cap32", - "catacombgl", - "cdogs", - "cemu", - "cgenius", - "clk", - "corsixth", - "demul", - "desmume", - "devilutionx", - "dhewm3", - "dice", - "dolphin", - "dosbox", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "duckstation", - "dxx-rebirth", - "easyrpg", - "ecwolf", - "eduke32", - "emuscv", - "ep128emu-core", - "etlegacy", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fsuae", - "fury", - "fuse", - "gambatte", - "gearcoleco", - "gearsystem", - "genesisplusgx", - "genesisplusgx-expanded", - "genesisplusgx-wide", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hatarib", - "hcl", - "holani", - "hurrican", - "hypseus-singe", - "ikemen", - "iortcw", - "jazz2-native", - "kronos", - "lightspark", - "lindbergh-loader", - "lowresnx", - "lutro", - "mame", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "model2emu", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "openjk", - "openjkdf2", - "openmohaa", - "openmsx", - "opera", - "parallel_n64", - "pce", - "pce_fast", - "pcfx", - "pcsx2", - "pcsx_rearmed", - "pd777", - "picodrive", - "play", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "pyxel", - "quasi88", - "raze", - "redream", - "reminiscence", - "rpcs3", - "ruffle", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "shadps4", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic-mania", - "sonic2013", - "sonic3-air", - "soniccd", - "stella", - "superbroswar", - "supermodel", - "swanstation", - "taradino", - "tgbdual", - "theforceengine", - "theodore", - "thextech", - "tic80", - "tr1x", - "tr2x", - "tsugaru", - "tyrian", - "tyrquake", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vircon32", - "virtualjaguar", - "vita3k", - "vitaquake2", - "vkquake", - "vkquake2", - "vkquake3", - "vpinball", - "wasm4", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xash3d_fwgs", - "xemu", - "xenia", - "xenia-canary", - "xpet", - "xplus4", - "xrick", - "xroar", - "xscpu64", - "xvic", - "yabasanshiro", - "ymir", - "yquake2", - "zc210" - ] + "zen3": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "azahar", + "beetle-saturn", + "bennugd", + "bigpemu", + "bk", + "blastem", + "bluemsx", + "boom3", + "bsnes", + "bsnes_hd", + "bstone", + "cannonball", + "cap32", + "catacombgl", + "cdogs", + "cemu", + "cgenius", + "clk", + "corsixth", + "demul", + "desmume", + "devilutionx", + "dhewm3", + "dice", + "dolphin", + "dosbox", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "duckstation", + "dxx-rebirth", + "easyrpg", + "ecwolf", + "eduke32", + "emuscv", + "ep128emu-core", + "etlegacy", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fsuae", + "fury", + "fuse", + "gambatte", + "gearcoleco", + "gearsystem", + "genesisplusgx", + "genesisplusgx-expanded", + "genesisplusgx-wide", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hatarib", + "hcl", + "holani", + "hurrican", + "hypseus-singe", + "ikemen", + "iortcw", + "jazz2-native", + "kronos", + "lightspark", + "lindbergh-loader", + "lowresnx", + "lutro", + "mame", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "model2emu", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "openjk", + "openjkdf2", + "openmohaa", + "openmsx", + "opera", + "parallel_n64", + "pce", + "pce_fast", + "pcfx", + "pcsx2", + "pcsx_rearmed", + "pd777", + "picodrive", + "play", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "pyxel", + "quasi88", + "raze", + "redream", + "reminiscence", + "rpcs3", + "ruffle", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "shadps4", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic-mania", + "sonic2013", + "sonic3-air", + "soniccd", + "stella", + "superbroswar", + "supermodel", + "swanstation", + "taradino", + "tgbdual", + "theforceengine", + "theodore", + "thextech", + "tic80", + "tr1x", + "tr2x", + "tsugaru", + "tyrian", + "tyrquake", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vircon32", + "virtualjaguar", + "vita3k", + "vitaquake2", + "vkquake", + "vkquake2", + "vkquake3", + "vpinball", + "wasm4", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xash3d_fwgs", + "xemu", + "xenia", + "xenia-canary", + "xpet", + "xplus4", + "xrick", + "xroar", + "xscpu64", + "xvic", + "yabasanshiro", + "ymir", + "yquake2", + "zc210" + ], + "images": [ + "x86-64-v3" + ] + } } diff --git a/install/targets/knulli.json b/install/targets/knulli.json index 4473119aa..533167e6b 100644 --- a/install/targets/knulli.json +++ b/install/targets/knulli.json @@ -1,1278 +1,1347 @@ { - "a133": [ - "81", - "a5200", - "abuse", - "advanced_drastic", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbalpha", - "fbneo", - "fceumm", - "flycast", - "flycast-xtreme", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "genesisplusgx-wide", - "geolith", - "gpsp", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "parallel_n64", - "pce", - "pce_fast", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "a527": [ - "81", - "a5200", - "abuse", - "aethersx2", - "amiberry", - "arduous", - "atari800", - "azahar", - "bennugd", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "flycast-xtreme", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "atm7039": [ - "81", - "a5200", - "abuse", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "lowresnx", - "lutro", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "h700": [ - "81", - "a5200", - "abuse", - "advanced_drastic", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bsnes", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbalpha", - "fbneo", - "fceumm", - "flycast", - "flycast-xtreme", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "genesisplusgx-wide", - "geolith", - "gpsp", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melondsds", - "mesen", - "mesen-s", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce", - "pce_fast", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "virtualjaguar", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "r16": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "lowresnx", - "lutro", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "zc210" - ], - "rk3128": [ - "81", - "a5200", - "abuse", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "devilutionx", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbalpha", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gpsp", - "gsplus", - "gw", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "lightspark", - "lowresnx", - "lutro", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "mgba", - "minivmac", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "samcoupe", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "rk3326": [ - "81", - "a5200", - "abuse", - "advanced_drastic", - "amiberry", - "arduous", - "atari800", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dosbox_pure", - "dosbox_staging", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "parallel_n64", - "pce_fast", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "rk3566": [ - "81", - "a5200", - "abuse", - "advanced_drastic", - "amiberry", - "arduous", - "atari800", - "azahar", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "flycastvl", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "melondsds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], - "rk3576": [ - "81", - "a5200", - "abuse", - "aethersx2", - "amiberry", - "arduous", - "atari800", - "azahar", - "bennugd", - "bluemsx", - "bstone", - "cannonball", - "cap32", - "cdogs", - "cgenius", - "corsixth", - "devilutionx", - "dolphin", - "dosbox-x", - "dosbox_pure", - "dosbox_staging", - "dosboxx", - "easyrpg", - "eduke32", - "emuscv", - "fake08", - "fallout1-ce", - "fallout2-ce", - "fbneo", - "fceumm", - "flycast", - "fmsx", - "freechaf", - "freeintv", - "fury", - "fuse", - "gambatte", - "gearsystem", - "genesisplusgx", - "geolith", - "gsplus", - "gw", - "gzdoom", - "handy", - "hatari", - "hcl", - "holani", - "hurrican", - "ioquake3", - "iortcw", - "lightspark", - "lowresnx", - "lutro", - "mame", - "mame0139", - "mame078plus", - "mednafen_lynx", - "mednafen_ngp", - "mednafen_psx", - "mednafen_supergrafx", - "mednafen_wswan", - "melonds", - "mgba", - "minivmac", - "moonlight", - "mrboom", - "mupen64plus", - "mupen64plus-next", - "neocd", - "nestopia", - "np2kai", - "nxengine", - "o2em", - "openbor", - "openbor4432", - "openbor6412", - "openbor7142", - "openbor7530", - "openjazz", - "opera", - "parallel_n64", - "pce_fast", - "pcfx", - "pcsx_rearmed", - "picodrive", - "pokemini", - "potator", - "ppsspp", - "prboom", - "prosystem", - "puae", - "puae2021", - "px68k", - "pygame", - "quasi88", - "raze", - "reminiscence", - "samcoupe", - "same_cdi", - "sameduck", - "scummvm", - "sdlpop", - "smsplus", - "snes9x", - "snes9x_next", - "solarus", - "sonic2013", - "soniccd", - "stella", - "superbroswar", - "swanstation", - "taradino", - "tgbdual", - "theodore", - "thextech", - "tic80", - "tyrian", - "tyrquake", - "uae4arm", - "uzem", - "vb", - "vba-m", - "vecx", - "vice", - "vice_x128", - "vice_x64", - "vice_x64sc", - "vice_xpet", - "vice_xplus4", - "vice_xscpu64", - "vice_xvic", - "vita3k", - "vitaquake2", - "x1", - "x128", - "x16emu", - "x64", - "x64dtv", - "xpet", - "xplus4", - "xrick", - "xscpu64", - "xvic", - "yabasanshiro", - "zc210" - ], + "a133": { + "cores": [ + "81", + "a5200", + "abuse", + "advanced_drastic", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbalpha", + "fbneo", + "fceumm", + "flycast", + "flycast-xtreme", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "genesisplusgx-wide", + "geolith", + "gpsp", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "parallel_n64", + "pce", + "pce_fast", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "magicx-zero-28", + "magicx-zero-40", + "powkiddy-v20", + "powkiddy-v90s", + "trimui-brick", + "trimui-smart-pro" + ] + }, + "a527": { + "cores": [ + "81", + "a5200", + "abuse", + "aethersx2", + "amiberry", + "arduous", + "atari800", + "azahar", + "bennugd", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "flycast-xtreme", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "helegany-action-pi", + "trimui-smart-pro-s" + ] + }, + "atm7039": { + "cores": [ + "81", + "a5200", + "abuse", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "lowresnx", + "lutro", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "rg35xx" + ] + }, + "h700": { + "cores": [ + "81", + "a5200", + "abuse", + "advanced_drastic", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bsnes", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbalpha", + "fbneo", + "fceumm", + "flycast", + "flycast-xtreme", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "genesisplusgx-wide", + "geolith", + "gpsp", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melondsds", + "mesen", + "mesen-s", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce", + "pce_fast", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "virtualjaguar", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "rg-cubexx", + "rg28xx", + "rg34xx", + "rg34xx-sp", + "rg35xx-h", + "rg35xx-plus", + "rg35xx-pro", + "rg35xx-sp", + "rg40xx-h", + "rg40xx-v" + ] + }, + "r16": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "lowresnx", + "lutro", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "zc210" + ], + "images": [ + "miyoo-a30" + ] + }, + "rk3128": { + "cores": [ + "81", + "a5200", + "abuse", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "devilutionx", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbalpha", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gpsp", + "gsplus", + "gw", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "lightspark", + "lowresnx", + "lutro", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "mgba", + "minivmac", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "samcoupe", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "powkiddy_a13", + "ps5000", + "ps7000" + ] + }, + "rk3326": { + "cores": [ + "81", + "a5200", + "abuse", + "advanced_drastic", + "amiberry", + "arduous", + "atari800", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dosbox_pure", + "dosbox_staging", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "parallel_n64", + "pce_fast", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "g350", + "magicx-mini-m", + "pixel2", + "r36s" + ] + }, + "rk3566": { + "cores": [ + "81", + "a5200", + "abuse", + "advanced_drastic", + "amiberry", + "arduous", + "atari800", + "azahar", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "flycastvl", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "melondsds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "miyoo-flip", + "powkiddy-rgb30", + "powkiddy-x55", + "rg-arc-s", + "rg-ds" + ] + }, + "rk3576": { + "cores": [ + "81", + "a5200", + "abuse", + "aethersx2", + "amiberry", + "arduous", + "atari800", + "azahar", + "bennugd", + "bluemsx", + "bstone", + "cannonball", + "cap32", + "cdogs", + "cgenius", + "corsixth", + "devilutionx", + "dolphin", + "dosbox-x", + "dosbox_pure", + "dosbox_staging", + "dosboxx", + "easyrpg", + "eduke32", + "emuscv", + "fake08", + "fallout1-ce", + "fallout2-ce", + "fbneo", + "fceumm", + "flycast", + "fmsx", + "freechaf", + "freeintv", + "fury", + "fuse", + "gambatte", + "gearsystem", + "genesisplusgx", + "geolith", + "gsplus", + "gw", + "gzdoom", + "handy", + "hatari", + "hcl", + "holani", + "hurrican", + "ioquake3", + "iortcw", + "lightspark", + "lowresnx", + "lutro", + "mame", + "mame0139", + "mame078plus", + "mednafen_lynx", + "mednafen_ngp", + "mednafen_psx", + "mednafen_supergrafx", + "mednafen_wswan", + "melonds", + "mgba", + "minivmac", + "moonlight", + "mrboom", + "mupen64plus", + "mupen64plus-next", + "neocd", + "nestopia", + "np2kai", + "nxengine", + "o2em", + "openbor", + "openbor4432", + "openbor6412", + "openbor7142", + "openbor7530", + "openjazz", + "opera", + "parallel_n64", + "pce_fast", + "pcfx", + "pcsx_rearmed", + "picodrive", + "pokemini", + "potator", + "ppsspp", + "prboom", + "prosystem", + "puae", + "puae2021", + "px68k", + "pygame", + "quasi88", + "raze", + "reminiscence", + "samcoupe", + "same_cdi", + "sameduck", + "scummvm", + "sdlpop", + "smsplus", + "snes9x", + "snes9x_next", + "solarus", + "sonic2013", + "soniccd", + "stella", + "superbroswar", + "swanstation", + "taradino", + "tgbdual", + "theodore", + "thextech", + "tic80", + "tyrian", + "tyrquake", + "uae4arm", + "uzem", + "vb", + "vba-m", + "vecx", + "vice", + "vice_x128", + "vice_x64", + "vice_x64sc", + "vice_xpet", + "vice_xplus4", + "vice_xscpu64", + "vice_xvic", + "vita3k", + "vitaquake2", + "x1", + "x128", + "x16emu", + "x64", + "x64dtv", + "xpet", + "xplus4", + "xrick", + "xscpu64", + "xvic", + "yabasanshiro", + "zc210" + ], + "images": [ + "rg-vita-pro" + ] + }, "sm8250": [ "81", "a5200", diff --git a/platforms/targets/batocera.yml b/platforms/targets/batocera.yml index e77967855..4127e3b01 100644 --- a/platforms/targets/batocera.yml +++ b/platforms/targets/batocera.yml @@ -1,6 +1,6 @@ platform: batocera source: https://github.com/batocera-linux/batocera.linux/tree/batocera-43.1 -scraped_at: '2026-11-05T10:55:18Z' +scraped_at: '2026-11-06T02:18:59Z' targets: a3gen2: architecture: aarch64 @@ -169,6 +169,8 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - khadas-vim4 bcm2711: architecture: aarch64 cores: @@ -1063,6 +1065,12 @@ targets: - xvic - yquake2 - zc210 + images: + - bananapi-m2-zero + - cha + - orangepi-one + - orangepi-pc + - orangepi-plus2e h5: architecture: aarch64 cores: @@ -1214,6 +1222,9 @@ targets: - xvic - yquake2 - zc210 + images: + - orangepi-pc2 + - tritium-h5 h6: architecture: aarch64 cores: @@ -1364,6 +1375,10 @@ targets: - xvic - yquake2 - zc210 + images: + - orangepi-3 + - orangepi-3-lts + - orangepi-one-plus h616: architecture: aarch64 cores: @@ -1523,6 +1538,10 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - orangepi-zero2 + - orangepi-zero3 + - x96-mate h700: architecture: aarch64 cores: @@ -1695,6 +1714,22 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - anbernic-rg28xx + - anbernic-rg34xx + - anbernic-rg34xx-sp + - anbernic-rg35xx-2024 + - anbernic-rg35xx-2024-rev6-panel + - anbernic-rg35xx-h + - anbernic-rg35xx-h-rev6-panel + - anbernic-rg35xx-plus + - anbernic-rg35xx-plus-rev6-panel + - anbernic-rg35xx-pro + - anbernic-rg35xx-sp + - anbernic-rg35xx-sp-v2-panel + - anbernic-rg40xx-h + - anbernic-rg40xx-v + - anbernic-rgcubexx jh7110: architecture: riscv64 cores: @@ -2328,6 +2363,8 @@ targets: - ymir - yquake2 - zc210 + images: + - dragonq6a rk3128: architecture: arm cores: @@ -2471,6 +2508,10 @@ targets: - xvic - yquake2 - zc210 + images: + - powkiddy_a13 + - ps5000 + - ps7000 rk3288: architecture: arm cores: @@ -2626,6 +2667,9 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - miqi + - tinkerboard rk3326: architecture: aarch64 cores: @@ -2780,6 +2824,10 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - r36s + - rg351v-v2 + - rk3326 rk3328: architecture: aarch64 cores: @@ -2932,6 +2980,9 @@ targets: - xvic - yquake2 - zc210 + images: + - roc-cc + - rock64 rk3399: architecture: aarch64 cores: @@ -3094,6 +3145,15 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - hugsun-x99 + - nanopi-m4v2 + - orangepi-800 + - orangepi4-lts + - rg552 + - rock-pi-4 + - rock960 + - rockpro64 rk3568: architecture: aarch64 cores: @@ -3268,6 +3328,17 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - anbernic-rgxx3 + - firefly-station-m2 + - firefly-station-p2 + - odroid-m1 + - odroid-m1s + - orangepi-3b + - powkiddy-x55 + - radxa-zero-3w + - rock-3a + - rock-3c rk3588-sdio: architecture: aarch64 cores: @@ -3455,6 +3526,9 @@ targets: - ymir - yquake2 - zc210 + images: + - orangepi-5-max + - orangepi-5-ultra rk3588: architecture: aarch64 cores: @@ -3642,6 +3716,25 @@ targets: - ymir - yquake2 - zc210 + images: + - bananapi-m7 + - coolpi-4b + - firefly-station-m3 + - friendlyelec-cm3588-nas + - gameforce-ace + - indiedroid-nova + - khadas-edge-2 + - mekotronics-r58 + - nanopi-m6 + - orangepi-5 + - orangepi-5-plus + - orangepi-5-pro + - orangepi-5b + - quartzpro64 + - rock-5a + - rock-5b + - rock-5b-plus + - rock-5c s812: architecture: arm cores: @@ -3940,6 +4033,14 @@ targets: - xvic - yquake2 - zc210 + images: + - lepotato + - lepotatov2 + - minix-neo-u1 + - odroidc2 + - p201 + - tvbox + - vim s905gen2: architecture: aarch64 cores: @@ -4102,6 +4203,9 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - khadas-vim2 + - radxa-zero s905gen3: architecture: aarch64 cores: @@ -4264,6 +4368,10 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - khadas-vim3l + - odroidc4 + - tvbox-gen3 s922x: architecture: aarch64 cores: @@ -4431,6 +4539,15 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - gtking + - gtkingpro + - odroidn2 + - odroidn2l + - odroidn2plus + - ogu + - vim3 + - zero2 s9gen4: architecture: aarch64 cores: @@ -4591,6 +4708,8 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - khadas-vim1s sm8250: architecture: aarch64 cores: @@ -5147,6 +5266,8 @@ targets: - yabasanshiro - yquake2 - zc210 + images: + - orangepi-4a x86_64: architecture: x86_64 cores: @@ -5599,3 +5720,5 @@ targets: - ymir - yquake2 - zc210 + images: + - x86-64-v3 diff --git a/platforms/targets/knulli.yml b/platforms/targets/knulli.yml index 9cb410a70..c98caaf92 100644 --- a/platforms/targets/knulli.yml +++ b/platforms/targets/knulli.yml @@ -1,6 +1,6 @@ platform: knulli source: https://github.com/knulli-cfw/knulli-linux/tree/20260511 -scraped_at: '2026-11-05T10:55:16Z' +scraped_at: '2026-11-06T02:19:00Z' targets: a133: architecture: aarch64 @@ -165,6 +165,13 @@ targets: - xvic - yabasanshiro - zc210 + images: + - magicx-zero-28 + - magicx-zero-40 + - powkiddy-v20 + - powkiddy-v90s + - trimui-brick + - trimui-smart-pro a527: architecture: aarch64 cores: @@ -329,6 +336,9 @@ targets: - xvic - yabasanshiro - zc210 + images: + - helegany-action-pi + - trimui-smart-pro-s atm7039: architecture: arm cores: @@ -460,6 +470,8 @@ targets: - xvic - yabasanshiro - zc210 + images: + - rg35xx h700: architecture: aarch64 cores: @@ -625,6 +637,17 @@ targets: - xvic - yabasanshiro - zc210 + images: + - rg-cubexx + - rg28xx + - rg34xx + - rg34xx-sp + - rg35xx-h + - rg35xx-plus + - rg35xx-pro + - rg35xx-sp + - rg40xx-h + - rg40xx-v r16: architecture: arm cores: @@ -762,6 +785,8 @@ targets: - xscpu64 - xvic - zc210 + images: + - miyoo-a30 rk3128: architecture: arm cores: @@ -901,6 +926,10 @@ targets: - xvic - yabasanshiro - zc210 + images: + - powkiddy_a13 + - ps5000 + - ps7000 rk3326: architecture: aarch64 cores: @@ -1052,6 +1081,11 @@ targets: - xvic - yabasanshiro - zc210 + images: + - g350 + - magicx-mini-m + - pixel2 + - r36s rk3566: architecture: aarch64 cores: @@ -1211,6 +1245,12 @@ targets: - xvic - yabasanshiro - zc210 + images: + - miyoo-flip + - powkiddy-rgb30 + - powkiddy-x55 + - rg-arc-s + - rg-ds rk3576: architecture: aarch64 cores: @@ -1369,6 +1409,8 @@ targets: - xvic - yabasanshiro - zc210 + images: + - rg-vita-pro sm8250: architecture: aarch64 cores: diff --git a/schemas/target-manifest.schema.json b/schemas/target-manifest.schema.json index bb6351536..fcb8f70b9 100644 --- a/schemas/target-manifest.schema.json +++ b/schemas/target-manifest.schema.json @@ -13,7 +13,11 @@ "additionalProperties": false, "required": ["cores"], "properties": { - "cores": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true } + "cores": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true }, + "images": { + "description": "The image names the target builds, as a card's board file writes them (boot/batocera.board, boot/knulli.board).", + "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true + } } } ] diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index 4039b1655..f0ae9f092 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -2415,7 +2415,7 @@ def generate_target_manifests(targets_dir: str, output_dir: str) -> None: print(f"Generated {count} target manifest(s) in {output_dir}") -def target_list(yml_file: Path) -> dict[str, list[str] | None]: +def target_list(yml_file: Path) -> dict[str, list[str] | dict | None]: """A platform's cores per hardware target, as install/targets/ publishes them and a pack carries them: aliases included, overrides applied.""" targets_path = yml_file.parent @@ -2443,7 +2443,7 @@ def target_list(yml_file: Path) -> dict[str, list[str] | None]: if names: alias_map[tname] = names - result: dict[str, list[str] | None] = {} + result: dict[str, list[str] | dict | None] = {} for target_name, target_info in targets.items(): if not isinstance(target_name, str) or not target_name: raise ValueError(f"{yml_file}: target names must be non-empty strings") @@ -2468,7 +2468,15 @@ def target_list(yml_file: Path) -> dict[str, list[str] | None]: resolved = load_target_config( yml_file.stem, target_name, str(targets_path.parent) ) - result[target_name] = None if resolved is None else sorted(resolved) + listed = None if resolved is None else sorted(resolved) + images = target_info.get("images") + # The image names a card's board file holds (Batocera writes + # anbernic-rg35xx-plus for the h700 target): the installer reads + # the board of a card prepared on a computer through them. + result[target_name] = ( + {"cores": listed, "images": images} + if images and listed is not None else listed + ) for target_name, names in alias_map.items(): if target_name not in result: @@ -2478,7 +2486,9 @@ def target_list(yml_file: Path) -> dict[str, list[str] | None]: raise ValueError( f"{yml_file}: alias {alias!r} collides with a target name" ) - result[alias] = result[target_name] + # An alias names the board, not its images. + held = result[target_name] + result[alias] = held["cores"] if isinstance(held, dict) else held return result diff --git a/scripts/scraper/targets/batocera_targets_scraper.py b/scripts/scraper/targets/batocera_targets_scraper.py index 6ce15beb4..f13615ccb 100644 --- a/scripts/scraper/targets/batocera_targets_scraper.py +++ b/scripts/scraper/targets/batocera_targets_scraper.py @@ -36,6 +36,35 @@ except ImportError: _TARGET_FLAG_RE = re.compile(r"^(BR2_PACKAGE_BATOCERA_TARGET_\w+)=y", re.MULTILINE) +# The images a target flag builds, each a board directory whose last segment +# post-image-script.sh writes to boot/.board on the card +# (batocera-43.1 board/batocera/scripts/post-image-script.sh:50,60, KNULLI +# 20260511 board/scripts/post-image-script.sh:57,66): Config.in lists them +# under BR2_TARGET__IMAGES, one "default" per target flag. +_IMAGES_DEFAULT_RE = re.compile( + r'^\s*default\s+"([^"]*)"\s+if\s+(BR2_PACKAGE_BATOCERA_TARGET_\w+)\s*$') + + +def _parse_images(text: str) -> dict[str, list[str]]: + """Each target flag's image names, in the words a card's board file uses.""" + lines = text.replace("\\\n", " ").splitlines() + start = next((n for n, line in enumerate(lines) + if re.match(r"^\s*config\s+BR2_TARGET_[A-Z]+_IMAGES\s*$", line)), None) + if start is None: + return {} + images: dict[str, list[str]] = {} + for line in lines[start + 1:]: + if not line.strip(): + continue + m = _IMAGES_DEFAULT_RE.match(line) + if m: + images.setdefault(m.group(2), []).extend( + path.rsplit("/", 1)[-1] for path in m.group(1).split()) + elif not re.match(r"^\s*(string|default|help)\b", line): + break + return images + + _IF_RE = re.compile(r"^if\s+(.*)$") _DEFAULT_Y_RE = re.compile(r"^\s*default\s+y\s*(?:#.*)?$") @@ -428,6 +457,9 @@ class Scraper(BaseTargetScraper): ) if not package_to_emulators: raise RuntimeError(f"no package->emulator mappings parsed from {es_systems_url}") + images_by_flag = _parse_images(config_in_text) + if not images_by_flag: + raise RuntimeError(f"no target image list parsed from {config_in_url}") targets: dict[str, dict] = {} for board_name in sorted(boards): @@ -456,6 +488,9 @@ class Scraper(BaseTargetScraper): "architecture": arch, "cores": sorted(emulators), } + images = sorted(set(images_by_flag.get(primary_flag, []))) + if images and images != [target_key]: + targets[target_key]["images"] = images print( f" {len(emulators)} emulators ({len(selected_packages)} packages selected)", file=sys.stderr, diff --git a/tests/test_install.py b/tests/test_install.py index ba5a61eda..b86e1744c 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1584,6 +1584,8 @@ class TargetFlagIsAppliedOrRefused(unittest.TestCase): with self.subTest(platform=platform): self.assertEqual(sorted(targets), sorted(known)) for target, cores in targets.items(): + # A target that names its card images carries them beside. + cores = cores["cores"] if isinstance(cores, dict) else cores with self.subTest(platform=platform, target=target): resolved = load_target_config(platform, target, platforms) self.assertEqual(cores, None if resolved is None else sorted(resolved)) @@ -3347,6 +3349,44 @@ class ACardPreparedOnAComputerGetsItsBoard(unittest.TestCase): files = {event["dest"] for event in events if event["event"] == "file"} self.assertEqual(files, {"pi.bin"}) + def test_a_card_naming_its_image_gets_the_board_of_that_image(self): + """A Batocera RG35XX Plus card names anbernic-rg35xx-plus, a zen3 one + x86-64-v3: neither is a target name, and the card took every + board's files (9.0 GB where h700 reads 6.1).""" + (self.boot / "boot" / "batocera.board").write_text("anbernic-rg35xx-plus\n") + (self.list.parent / "targets" / "batocera.json").write_text(json.dumps({ + "h700": {"cores": ["picore"], "images": ["anbernic-rg28xx", + "anbernic-rg35xx-plus"]}, + "x86_64": ["pccore"]})) + out, events = self.run_main() + [board] = [event for event in events if event["event"] == "board"] + self.assertEqual((board["board"], board["applied"]), ("h700", True)) + self.assertIn("Board h700 (anbernic-rg35xx-plus) found on the card", out) + files = {event["dest"] for event in events if event["event"] == "file"} + self.assertEqual(files, {"pi.bin"}) + + def test_an_image_two_boards_build_names_neither(self): + targets = install._validate_targets({ + "zen3": {"cores": ["a"], "images": ["x86-64-v3"]}, + "rk3326": {"cores": ["b"], "images": ["r36s"]}, + "rk3566": {"cores": ["c"], "images": ["r36s"]}}) + self.assertEqual(install.board_target("x86-64-v3", targets), "zen3") + self.assertEqual(install.board_target("zen3", targets), "zen3") + self.assertIsNone(install.board_target("r36s", targets)) + + def test_a_knulli_card_names_its_image_too(self): + (self.boot / "boot" / "knulli.board").write_text("rg35xx-plus\n") + with unittest.mock.patch.object(install, "_mounted_cards", return_value=[self.boot]): + self.assertEqual(install.card_board("knulli"), "rg35xx-plus") + published = json.loads((REPO_ROOT / "install" / "targets" / "knulli.json").read_text()) + self.assertEqual(install.board_target( + "rg35xx-plus", install._validate_targets(published)), "h700") + batocera = install._validate_targets(json.loads( + (REPO_ROOT / "install" / "targets" / "batocera.json").read_text())) + for image, board in (("anbernic-rg35xx-plus", "h700"), ("x86-64-v3", "zen3"), + ("odroidn2", "s922x"), ("bcm2711", "bcm2711")): + self.assertEqual(install.board_target(image, batocera), board) + def test_every_board_keeps_them_all(self): _out, events = self.run_main("--every-board") self.assertFalse([event for event in events if event["event"] == "board"]) diff --git a/tests/test_target_scrapers.py b/tests/test_target_scrapers.py index 5b4d7ab78..35a6226f4 100644 --- a/tests/test_target_scrapers.py +++ b/tests/test_target_scrapers.py @@ -96,7 +96,9 @@ class FailedRequestsStopTheScrape(unittest.TestCase): b"BR2_PACKAGE_BATOCERA_SYSTEM=y\n") if url.endswith("Config.in"): return _Body(b"config BR2_PACKAGE_BATOCERA_SYSTEM\n" - b"\tselect BR2_PACKAGE_MGBA\n") + b"\tselect BR2_PACKAGE_MGBA\n\n" + b"config BR2_TARGET_BATOCERA_IMAGES\n\tstring \"x\"\n" + b"\tdefault \"x86_64\" if BR2_PACKAGE_BATOCERA_TARGET_X86_64\n") return _Body( b"gba:\n emulators:\n libretro:\n" b" mgba: {requireAnyOf: [BR2_PACKAGE_MGBA]}\n" @@ -263,7 +265,14 @@ class KnulliPerBoard(unittest.TestCase): "\tconfig BR2_PACKAGE_BATOCERA_GLES3\n\tdefault y\nendif\n\n" "config BR2_PACKAGE_KNULLI_SYSTEM\n" "\tselect BR2_PACKAGE_LIBRETRO_MGBA\n" - "\tselect BR2_PACKAGE_PPSSPP\tif BR2_PACKAGE_BATOCERA_GLES3\n" + "\tselect BR2_PACKAGE_PPSSPP\tif BR2_PACKAGE_BATOCERA_GLES3\n\n" + "config BR2_TARGET_KNULLI_IMAGES_DEFINITIONS\n" + "\tbool \"target images definitions\"\n" + "\tconfig BR2_TARGET_KNULLI_IMAGES\n\tstring \"target images\"\n" + "\tdefault \"allwinner/h700/rg35xx-sp allwinner/h700/rg35xx-plus\" \\\n" + "\t\tif BR2_PACKAGE_BATOCERA_TARGET_H700\n" + "\tdefault \"allwinner/r16/miyoo-a30\"\tif BR2_PACKAGE_BATOCERA_TARGET_SUNXI_R16\n\n" + "\tchoice\n\tprompt \"knulli target\"\n" ), "package/emulationstation/knulli-es-system/es_systems.yml": ( "gba:\n emulators:\n libretro:\n" @@ -316,10 +325,12 @@ class KnulliPerBoard(unittest.TestCase): self.assertEqual(data["source"], f"https://github.com/knulli-cfw/knulli-linux/tree/{pin}") self.assertEqual(sorted(data["targets"]), ["h700", "r16"]) + # The images name what a card's boot/knulli.board holds. self.assertEqual(data["targets"]["h700"], - {"architecture": "aarch64", "cores": ["mgba", "ppsspp"]}) + {"architecture": "aarch64", "cores": ["mgba", "ppsspp"], + "images": ["rg35xx-plus", "rg35xx-sp"]}) self.assertEqual(data["targets"]["r16"], - {"architecture": "arm", "cores": ["mgba"]}) + {"architecture": "arm", "cores": ["mgba"], "images": ["miyoo-a30"]}) self.assertTrue(all(pin in url or "buildroot/c2d7985b" in url for url in seen), seen) diff --git a/wiki/installer.md b/wiki/installer.md index a5d888ada..c83131855 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -961,7 +961,7 @@ what the options name, everything by default. |--------|--------| | `--platform NAME` | Install for this platform instead of the detected one. A system `--list-platforms` names under its own files (`muos`, `arkos`) stands for the file list it gets, and the run says which. ES-DE, LaunchBox and Android, which keep no BIOS folder, are answered with the run that fills each emulator's folder. Unknown names are refused with the closest ones | | `--dest PATH` | Destination directory, overriding detection. Without `--platform`, the file list is the platform detected here: at a terminal the installer asks, Enter taking the one found, and otherwise it uses the one found, RetroArch's when nothing is found, and refuses when several are. The run prints whose list it is. A folder that does not exist is named with the nearest one that does, then created, except for a system that runs from its SD card, which refuses it. When more than its last level is missing (a mistyped path), a run at a terminal asks first, and the answer defaults to no | -| `--target NAME` | Keep only the files the cores of that hardware target need, and the systems they emulate. An unknown target is refused rather than ignored, since carrying on would install everything. On Batocera, Recalbox, ROCKNIX, Lakka, KNULLI and RetroPie the board is read from the system (`batocera.arch`, `recalbox.arch`, `HW_DEVICE`, `LIBREELEC_DEVICE` or `LIBREELEC_PROJECT`, `knulli.arch`, the Pi model in `/proc/cpuinfo` where `/opt/retropie` exists) and applied when no `--target` is given, from a pack alone too when it carries the core list per board. On a computer, the board a Batocera card names on its BATOCERA partition (`boot/batocera.board`) is applied the same way, in line mode and on the full screen | +| `--target NAME` | Keep only the files the cores of that hardware target need, and the systems they emulate. An unknown target is refused rather than ignored, since carrying on would install everything. On Batocera, Recalbox, ROCKNIX, Lakka, KNULLI and RetroPie the board is read from the system (`batocera.arch`, `recalbox.arch`, `HW_DEVICE`, `LIBREELEC_DEVICE` or `LIBREELEC_PROJECT`, `knulli.arch`, the Pi model in `/proc/cpuinfo` where `/opt/retropie` exists) and applied when no `--target` is given, from a pack alone too when it carries the core list per board. On a computer, the board a Batocera or KNULLI card names on its boot partition (`boot/batocera.board`, `boot/knulli.board`) is applied the same way, in line mode and on the full screen. The card names its image (`anbernic-rg35xx-plus`, `x86-64-v3`), which the target list maps to its board (`h700`, `zen3`) | | `--every-board` | Install the files of every board instead of the one the system names, for a card that moves between devices | | `--installed-cores` | Keep only what the cores already installed read (RetroArch, Lakka, RetroPie). See [Installed cores](#installed-cores) | | `--cores-dir PATH` | The folder RetroArch loads its cores from, for `--installed-cores` when it is not found. Implies `--installed-cores`. A folder that does not exist or cannot be opened is refused with the reason (code 1) | @@ -1785,7 +1785,7 @@ other schemas under `api/v1/schemas/`. | `error` | `stage`, `reason`, `platform`, `message` | The file list could not be read (`stage` is `manifest`): `reason` is `network`, `not_found` or `invalid`, `clock` when the server's certificate was refused and the system clock reads a date before the installer was written, `no_ca` when the machine holds no list of trusted certificates (`SSL_CERT_FILE` names one), `no_ssl` when this Python was built without its `ssl` module and cannot use HTTPS, or `offline` when `--offline` forbids the request. A folder named with `--from` cannot be read (`stage` is `from`, `reason` `not_found`, `not_a_folder` for a file that is no ZIP, `unreadable`, or `system` for the root of the system, `/proc`, `/sys` or `/dev`). The BIOS folder sits under a folder this user cannot open (`stage` is `dest`, `reason` `unreadable`), and the run ends with code 1 before anything is written. A platform, target, system, core or emulator named on the command line is unknown or cannot be used here (`stage` is `option`, `reason` `unknown`, `platform` the platform it was checked against or the name typed), refused before any download with code 2. The BIOS folder cannot be created (`stage` is `dest`, `reason` `not_writable`): a `summary` follows with what the run installed before it. Two systems are detected on one machine and no `--dest` names the folder (`stage` is `detect`, `reason` `conflict`). The platform named with `--platform` is found nowhere and no folder can be assumed for it: a card system with no card named, a portable emulator, Batocera or Recalbox named on a computer (their folder is the `bios` folder of their SHARE drive), or no usual folder on this system or one set aside behind a folder this user cannot open (`stage` is `detect`, `reason` `not_found`). So is a platform named by a file list or a pack, in a run without questions where it is found nowhere here. A `--dest` refused as the card of the system named carries the same `stage` and `reason`: another system's card, a folder inside a card, a drive with none of the files its card always has, or a folder that does not exist. `message` says it in words, and is the only thing that tells these cases apart | | `scanned` | `folder`, `files`, `truncated`, `other_drives` | Each folder named with `--from`, once read and before `detect`. `files` counts the files found, `truncated` is true when the search stopped at 200,000 of them, and `other_drives` lists the folders below it on another drive, which were not entered | | `version` | `platform`, `list_version`, `installed_version`, `message` | Before `choices`, when the system here runs another version than the one the list was built for: `list_version` is the list's, `installed_version` the one the system's version file states, and `message` says it and what it means. Not written when either version is unknown. The run goes on | -| `board` | `platform`, `board`, `applied`, `message` | Before `choices`, with no `--target` and no `--every-board`, when the system names its board or a Batocera card mounted here does (`boot/batocera.board` on its BATOCERA partition): `applied` is true when the run keeps that board's files only, false for a board the platform's list does not name, which keeps every board's files. `message` says it | +| `board` | `platform`, `board`, `applied`, `message` | Before `choices`, with no `--target` and no `--every-board`, when the system names its board or a Batocera or KNULLI card mounted here does (`boot/batocera.board` or `boot/knulli.board` on its boot partition, `board` then being the board its image maps to): `applied` is true when the run keeps that board's files only, false for a board the platform's list does not name, which keeps every board's files. `message` says it | | `choices` | `platform`, `systems` | Before `checking`: the systems the run's list lets one choose among, sorted by id, `other` last for the files no system names. The run's other options apply (`--core`, `--region`, `--no-game-data`, the files left out for an unknown save directory), `--system` does not: these are the systems a screen lists to choose from, and the count a `--system` is out of | | `set_aside` | `platform`, `dests` | Right after `choices`: the files of the list the run sets aside before any choice, in list order, those read from a save directory whose place is not known among them. A screen chooses its cores among the rest, the cores `--core` accepts | | `file` | `platform`, `dest`, `systems`, `size`, `state` | Each file of the list after the check. `state` is `present` (hash verified), `wrong_hash` or `missing` | From f8702a19f7ce32400351f951a7917cf9126f37be Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:41:18 +0100 Subject: [PATCH 3/6] feat: treat a Lakka card as a card setup Lakka keeps its BIOS on its STORAGE partition (/storage/system). A computer now tells that partition by the retroarch.cfg RetroArch writes there, whose system_directory is Lakka's /tmp/system overlay, and --platform lakka on a computer asks for the card instead of writing to /storage/system here. --- install.ps1 | 2 +- install.py | 14 +++++++++++++- install.sh | 2 +- install/launchers/index.json | 16 ++++++++-------- tests/test_install_tui.py | 4 ++++ wiki/installer.md | 3 ++- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/install.ps1 b/install.ps1 index 3bdff2ca4..425d1554c 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243" + $defaultInstallSha256 = "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 295726e74..ab13fccdf 100644 --- a/install.py +++ b/install.py @@ -13868,6 +13868,18 @@ _SHARE_RULES: tuple[_OsRule, ...] = ( _OsRule("rocknix", "ROCKNIX", "file_matches", (".config/system/configs/system.cfg", r"^root\.password=rocknix\s*$"), "roms/bios"), + # Lakka's is /storage, its STORAGE partition (Lakka-LibreELEC v6.1, + # packages/sysutils/busybox/scripts/fs-resize:31). RetroArch reads its + # BIOS through /tmp/system, an overlay whose upper folder is + # /storage/system (packages/lakka/retroarch_base/retroarch/system.d/ + # tmp-system.mount:12). With HOME=/storage (config/retroarch-env.conf:1) + # RetroArch writes .config/retroarch/retroarch.cfg from the /etc + # skeleton at its first start (RetroArch 69a4f0ea, configuration.c: + # 3650-3676), whose system_directory is that overlay (config/ + # retroarch.cfg:3217): no other system we install for reads /tmp/system. + _OsRule("lakka", "Lakka", "file_matches", + (".config/retroarch/retroarch.cfg", + r'^system_directory = "/tmp/system"\s*$'), "system"), # MiSTer's is its exFAT partition, /media/fat (Main_MiSTer e0a234f9, # file_io.cpp:1177), whose root holds the MiSTer binary and menu.rbf # (Distribution_MiSTer ce602319) and which reads each core's files @@ -19449,7 +19461,7 @@ def setup_list(setups: list, mounted: set, needle: str = "", # The systems that run from an SD card on a board kept on a desk, not in # the hand: their row stays among the platforms, and the handhelds' block, # which leads when nothing is found here, keeps Onion four presses away. -_DESK_CARDS = frozenset({"misterfpga"}) +_DESK_CARDS = frozenset({"misterfpga", "lakka"}) # The setups a computer runs, by its system, first in the setup list when # nothing was found here. RetroBat runs on Windows alone (retrobat.org), and diff --git a/install.sh b/install.sh index 015c38707..2acffc1b5 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243" +DEFAULT_INSTALL_SHA256="78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 524a9dc01..56277c1c3 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1099572, - "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", + "size": 1100388, + "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1153199, - "sha256": "284143d1c9bed3becfbe1ecee2e690cd11dc0ee495c8beeb9d7dca70cd63622e" + "size": 1154015, + "sha256": "03bcbdf8385808576afb0899860e5f11af37a9aee709b72481064e7a0ee79afa" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1099572, - "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", + "size": 1100388, + "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1099572, - "sha256": "4d5fbd4fcf4fc42e4ae02ebfa568fd906ef673d003eefcae22e38e520d70c243", + "size": 1100388, + "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", "executable": false }, { diff --git a/tests/test_install_tui.py b/tests/test_install_tui.py index d10ea0d13..24bbd3485 100644 --- a/tests/test_install_tui.py +++ b/tests/test_install_tui.py @@ -2284,6 +2284,10 @@ class CardsSpaceAndConfirm(unittest.TestCase): "bios"), "ROCKNIX": ({".config/system/configs/system.cfg": "root.password=rocknix\n"}, "rocknix", "roms/bios"), + # Lakka's STORAGE partition, once RetroArch has written its config. + "Lakka": ({".config/retroarch/retroarch.cfg": + 'menu_driver = "xmb"\nsystem_directory = "/tmp/system"\n'}, + "lakka", "system"), } def card(self, files: dict) -> Path: diff --git a/wiki/installer.md b/wiki/installer.md index c83131855..af2339730 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -1101,6 +1101,7 @@ gives for the device, below the card's root instead of its mount point: | `system/configs/emulationstation/about.info` holding the line `KNULLI` | KNULLI | `bios`, KNULLI's list | | `system/batocera.conf` holding the line `system.hostname=KNULLI` | KNULLI | `bios`, KNULLI's list | | `.config/system/configs/system.cfg` holding the line `root.password=rocknix` | ROCKNIX | `roms/bios`, ROCKNIX's list | +| `.config/retroarch/retroarch.cfg` holding the line `system_directory = "/tmp/system"` | Lakka | `system`, Lakka's list | | `MiSTer`, `menu.rbf` | MiSTer FPGA | `games`, MiSTer FPGA's list | | `MUOS/` | muOS | `MUOS/bios`, RetroArch's list | | `spruce/` | spruceOS | `BIOS`, RetroArch's list | @@ -1225,7 +1226,7 @@ beside its executable wherever the archive was extracted, so a forced `--platform bizhawk` that finds no install stops and asks for `--dest`. The systems that run from an SD card keep their files there: MinUI, NextUI, -MyMinUI, KNULLI, ROCKNIX, MiSTer FPGA, AmberELEC and EmuELEC (the card's games part, which +MyMinUI, KNULLI, ROCKNIX, Lakka (its STORAGE partition, which a Linux computer reads, once Lakka has started once), MiSTer FPGA, AmberELEC and EmuELEC (the card's games part, which they mount as `/storage/roms`), and each system of the [Linux handhelds](../platforms/linux-handhelds.md) that gets RetroArch's list (Onion, muOS, spruceOS, ArkOS, UnofficialOS and the others). Run on the From 2ecbea56b54a1f267e5c4f098026eb8be50bf44d Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:44:17 +0100 Subject: [PATCH 4/6] fix: skip data trees a read-only folder refuses A BIOS folder this user cannot write no longer tries each data tree's archive and blames its URL with a raw errno. The tree is counted failed for the same cause as the BIOS files, so the summary keeps its one line and its advice. --- install.ps1 | 2 +- install.py | 25 ++++++++++++++++++++++--- install.sh | 2 +- install/launchers/index.json | 16 ++++++++-------- tests/test_install_offline.py | 27 +++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/install.ps1 b/install.ps1 index 425d1554c..a96745599 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2" + $defaultInstallSha256 = "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index ab13fccdf..fe18bfa61 100644 --- a/install.py +++ b/install.py @@ -7198,7 +7198,12 @@ def install_data_directory(entry: dict, bios_path: Path, # Kept apart, so the advice is the offline one, not the network's. counts["error"] = OfflineReason(str(exc)) except (urllib.error.URLError, OSError, ValueError, tarfile.TarError) as exc: - counts["error"] = str(getattr(exc, "reason", None) or exc) + # The tree's folder refused, not the source: said as the BIOS files + # say it, never as an archive that could not be read. + counts["error"] = (NOT_WRITABLE if isinstance(exc, OSError) + and not isinstance(exc, urllib.error.URLError) + and _write_refused(exc) and not _folder_writable(root) + else str(getattr(exc, "reason", None) or exc)) except _MEMBER_ERRORS as exc: # A damaged, encrypted or unsupported member, in words. counts["error"] = unreadable_words(exc) @@ -15838,8 +15843,19 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # PPSSPP's assets. Fetched from their source archive, each file # checked against the hash the list records. if data_dirs and not total_interrupted: - print("\nData directories:") + # A tree whose folder this user cannot write is not fetched: the + # BIOS files above already said the cause and its remedy, and + # each archive was named as unreadable. + writable = [] for entry, state in data_states: + if state[1] and not _folder_writable(state[0]): + failures.append((entry["ref"], NOT_WRITABLE)) + total_errors += 1 + else: + writable.append((entry, state)) + if writable: + print("\nData directories:") + for entry, state in writable: counts = install_data_directory(entry, bios_path, state) total_downloaded += counts["installed"] data_landed += counts["installed"] @@ -15866,7 +15882,10 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: f", {counts['changed'] + counts['absent']} no longer in " "the source (the pack has them)") print(line) - if counts["error"]: + if counts["error"] == NOT_WRITABLE: + failures.append((entry["ref"], NOT_WRITABLE)) + total_errors += 1 + elif counts["error"]: print(f" {entry['ref']}: could not read " f"{LOCAL.pack.name if LOCAL.pack is not None else entry['url']}: " f"{counts['error']}", file=sys.stderr) diff --git a/install.sh b/install.sh index 2acffc1b5..556c6aec4 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2" +DEFAULT_INSTALL_SHA256="c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 56277c1c3..3cba41420 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1100388, - "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", + "size": 1101457, + "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1154015, - "sha256": "03bcbdf8385808576afb0899860e5f11af37a9aee709b72481064e7a0ee79afa" + "size": 1155084, + "sha256": "41b72bf029de9d855312e472cc9a10046f71692a55e02c4a959efdf4201505ad" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1100388, - "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", + "size": 1101457, + "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1100388, - "sha256": "78ef177611168c1c7699cafa8982f901aaaf5342b6c55d6e158ba18fb4cc0ae2", + "size": 1101457, + "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", "executable": false }, { diff --git a/tests/test_install_offline.py b/tests/test_install_offline.py index dd6849439..b46ea29be 100644 --- a/tests/test_install_offline.py +++ b/tests/test_install_offline.py @@ -951,6 +951,33 @@ class OfflineLeavesFilesMissing(Scratch): self.assertNotIn("could not read", proc.stderr) self.assertNotIn("no longer in the source", proc.stdout) + @unittest.skipIf(os.name == "nt" or os.geteuid() == 0, + "a read-only folder is refused by POSIX permissions") + def test_a_tree_in_a_folder_not_writable_is_not_fetched(self): + """A read-only card blamed each data archive's URL with a raw + errno, and that second cause split the one-line summary.""" + listed = manifest() + listed["data_directories"] = [{ + "ref": "bluemsx", "dest": "Machines", "type": "zip", + "url": "https://example.invalid/blueMSX.zip", "systems": ["nintendo-gba"], + "files": {"a.txt": {"sha1": _sha1(b"a"), "size": 1}}, + }, { + "ref": "fbneo-cheats", "dest": "fbneo/cheats", "type": "zip", + "url": "https://example.invalid/cheats.zip", "systems": ["nintendo-gba"], + "files": {"b.txt": {"sha1": _sha1(b"b"), "size": 1}}, + }] + self.list.write_text(json.dumps(listed)) + self.complete() + self.dest.chmod(0o555) + self.addCleanup(self.dest.chmod, 0o755) + proc = self.run_installer("--manifest", str(self.list), "--no-input") + out = proc.stdout + proc.stderr + self.assertEqual(proc.returncode, 2, out) + self.assertNotIn("could not read", out) + self.assertNotIn("Errno", out) + self.assertNotIn("Data directories:", out) + self.assertIn("failed: 2 files (folder not writable), first bluemsx", out) + class OneOfflineVocabulary(Scratch): """--offline said one From 7e504e8469a4bc933878d3d57eeee6f548260780 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:51:36 +0100 Subject: [PATCH 5/6] fix: show and count data archive downloads A data tree's archive came with no progress line, and the run ended on the BIOS bytes alone (310.5 KB where 82 MB arrived). Its download now draws the progress line and adds its bytes and time to the end line, a cut attempt taken back. It writes no progress event: those count the download event's files. --- install.ps1 | 2 +- install.py | 47 +++++++++++++++++---- install.sh | 2 +- install/launchers/index.json | 16 +++---- scripts/generate_installer_doc.py | 3 +- tests/test_install.py | 69 +++++++++++++++++++++++++++++-- wiki/installer.md | 4 +- 7 files changed, 119 insertions(+), 24 deletions(-) diff --git a/install.ps1 b/install.ps1 index a96745599..896cdaf76 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014" + $defaultInstallSha256 = "34fd006cc0456c61b9a621e52f35cee6d3fd55ff14bbc6cea207ddc7bc57d858" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index fe18bfa61..01c0b9425 100644 --- a/install.py +++ b/install.py @@ -528,7 +528,8 @@ class Progress: BAR = 24 - def __init__(self, total_files: int, total_bytes: int, term: Terminal) -> None: + def __init__(self, total_files: int, total_bytes: int, term: Terminal, + events: bool = True) -> None: self.total_files = total_files self.expected_bytes = total_bytes self.total_bytes = max(total_bytes, 1) @@ -548,6 +549,15 @@ class Progress: self._drawn = 0.0 self._evented = self.start self._lock = threading.Lock() + # A data tree's archive draws the line and writes no event: the + # progress events count the files of the download event. + self.events = events + + def expect(self, total_bytes: int) -> None: + """The size the transfer turns out to have, once its server says it.""" + with self._lock: + self.expected_bytes = total_bytes + self.total_bytes = max(total_bytes, 1) def add(self, count: int, resumed: bool = False, network: bool | None = None) -> None: """count bytes written, resumed ones left out of the speed. network @@ -563,7 +573,7 @@ class Progress: if self.term.live and not self.term.quiet and now - self._drawn >= 0.1: self._drawn = now self._draw() - if EVENTS.on and now - self._evented >= EVENT_PROGRESS_INTERVAL: + if self.events and EVENTS.on and now - self._evented >= EVENT_PROGRESS_INTERVAL: self._evented = now EVENTS.emit("progress", files_done=self.files, files_total=self.total_files, bytes_done=self.bytes, bytes_total=self.expected_bytes) @@ -7052,15 +7062,20 @@ def download_files( return failed, interrupted -def _fetch_archive(url: str, directory: Path) -> Path: - """A data directory's source archive, in *directory*, retried like files.""" +def _fetch_archive(url: str, directory: Path, progress: Progress | None = None) -> Path: + """A data directory's source archive, in *directory*, retried like files. + progress draws its bytes as they come, an attempt that failed taken back.""" _network_allowed(url) reason: Exception | None = None for attempt in range(1, MAX_RETRIES + 1): handle = tempfile.NamedTemporaryFile(dir=directory, suffix=".archive", delete=False) + received = 0 try: with handle, urllib.request.urlopen(url, timeout=60) as resp: - received = 0 + if progress is not None: + length = resp.headers.get("Content-Length", "") + if length.isdigit(): + progress.expect(int(length)) while True: if _stop.is_set(): raise _Interrupted() @@ -7071,6 +7086,8 @@ def _fetch_archive(url: str, directory: Path) -> Path: if received > MAX_DATA_ARCHIVE_SIZE: raise ValueError("archive exceeds the size limit") handle.write(chunk) + if progress is not None: + progress.add(len(chunk)) return Path(handle.name) except urllib.error.HTTPError as exc: Path(handle.name).unlink(missing_ok=True) @@ -7083,6 +7100,8 @@ def _fetch_archive(url: str, directory: Path) -> Path: except BaseException: Path(handle.name).unlink(missing_ok=True) raise + if progress is not None and received: + progress.add(-received) if attempt < MAX_RETRIES: time.sleep(_retry_delay(attempt, None)) raise reason if reason else OSError("download failed") @@ -7149,7 +7168,8 @@ def data_directory_state(entry: dict, bios_path: Path, def install_data_directory(entry: dict, bios_path: Path, - state: tuple[Path, dict[str, dict], int] | None = None) -> dict: + state: tuple[Path, dict[str, dict], int] | None = None, + progress: Progress | None = None) -> dict: """Rebuild one data tree from its source archive, file by file verified. state is the tree's data_directory_state when the run already read it: each read hashes every file in place. @@ -7173,7 +7193,7 @@ def install_data_directory(entry: dict, bios_path: Path, # The pack holds the tree where it extracts, already mapped. members = LOCAL.pack.tree(entry.get("dest", "")) else: - archive = _fetch_archive(entry["url"], Path(scratch)) + archive = _fetch_archive(entry["url"], Path(scratch), progress) members = _archive_members(archive, entry) for rel, declared, opener in members: meta = needed.pop(rel, None) @@ -15856,7 +15876,18 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: if writable: print("\nData directories:") for entry, state in writable: - counts = install_data_directory(entry, bios_path, state) + # Its archive is drawn as the BIOS files were, and counted + # in the bytes and time the run ends on: 82 MB came in + # silence and the end said 310.5 KB. + fetching = bool(state[1]) and LOCAL.pack is None + progress = Progress(len(state[1]), 0, term, events=False) if fetching else None + try: + counts = install_data_directory(entry, bios_path, state, progress) + finally: + if progress is not None: + progress.finish() + total_bytes += progress.transferred() + total_seconds += progress.elapsed() total_downloaded += counts["installed"] data_landed += counts["installed"] total_up_to_date += counts["present"] diff --git a/install.sh b/install.sh index 556c6aec4..b085a4cbb 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014" +DEFAULT_INSTALL_SHA256="34fd006cc0456c61b9a621e52f35cee6d3fd55ff14bbc6cea207ddc7bc57d858" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index 3cba41420..358ee41c9 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1101457, - "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", + "size": 1103111, + "sha256": "34fd006cc0456c61b9a621e52f35cee6d3fd55ff14bbc6cea207ddc7bc57d858", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1155084, - "sha256": "41b72bf029de9d855312e472cc9a10046f71692a55e02c4a959efdf4201505ad" + "size": 1156738, + "sha256": "35c0920008baadca997d0f778e99ce46d702bbe3d3f0d33104d7158422b292aa" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1101457, - "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", + "size": 1103111, + "sha256": "34fd006cc0456c61b9a621e52f35cee6d3fd55ff14bbc6cea207ddc7bc57d858", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1101457, - "sha256": "c8cf4b65474279c30c2e1781028d3e05f195e26dd759a98a37db3477b6dd3014", + "size": 1103111, + "sha256": "34fd006cc0456c61b9a621e52f35cee6d3fd55ff14bbc6cea207ddc7bc57d858", "executable": false }, { diff --git a/scripts/generate_installer_doc.py b/scripts/generate_installer_doc.py index ee2973261..7fd134d65 100644 --- a/scripts/generate_installer_doc.py +++ b/scripts/generate_installer_doc.py @@ -362,7 +362,8 @@ def _child(spec: dict) -> int: def held(files: list[dict], _bios: Path, **_kwargs: object) -> tuple: return [], list(files), [] - def tree_landed(entry: dict, _bios: Path, state: object = None) -> dict: + def tree_landed(entry: dict, _bios: Path, state: object = None, + _progress: object = None) -> dict: return {"present": 0, "installed": len(entry["files"]), "changed": 0, "absent": 0, "error": "", "not_kept": []} diff --git a/tests/test_install.py b/tests/test_install.py index b86e1744c..e51432718 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -3707,13 +3707,74 @@ class DataDirectoriesAreInstalled(unittest.TestCase): }, } + def test_the_archive_is_drawn_and_counted(self): + """82 MB of archives came with no progress line, and the run ended + on "310.5 KB downloaded", the BIOS files alone.""" + work = Path(_tempdir(self)) + body = self._zip(work).read_bytes() + attempts: list[int] = [] + + class Response(io.BytesIO): + headers = {"Content-Length": str(len(body))} + + def __enter__(self): + return self + + def __exit__(self, *exc): + return False + + def urlopen(_url, timeout=None): + attempts.append(1) + if len(attempts) == 1: + class Cut(Response): + def read(self, size=-1): + if self.tell(): + raise ConnectionResetError("cut") + return super().read(5) + return Cut(body) + return Response(body) + + progress = install.Progress(1, 0, install.Terminal(io.StringIO()), events=False) + with unittest.mock.patch.object(install.urllib.request, "urlopen", urlopen), \ + unittest.mock.patch.object(install, "_network_allowed", lambda url: None), \ + unittest.mock.patch.object(install, "_retry_delay", lambda *a: 0), \ + unittest.mock.patch.object(install.EVENTS, "emit") as emit: + path = install._fetch_archive("https://example.invalid/D.zip", work, progress) + self.assertEqual(path.read_bytes(), body) + self.assertEqual(len(attempts), 2) + # The cut attempt's five bytes are taken back. + self.assertEqual((progress.transferred(), progress.expected_bytes), + (len(body), len(body))) + emit.assert_not_called() + + def test_the_run_ends_on_the_archive_bytes_too(self): + from test_install_selection import FakeRepository # noqa: PLC0415 + + member = os.urandom(300_000) + with FakeRepository() as repo: + with zipfile.ZipFile(repo.root / "tree.zip", "w") as zf: + zf.writestr("Sys/big.bin", member) + archive = (repo.root / "tree.zip").stat().st_size + listed = json.loads((repo.root / "install" / "retroarch.json").read_text()) + listed["data_directories"] = [{ + "ref": "tree", "dest": "tree", "type": "zip", + "url": f"http://127.0.0.1:{repo.httpd.server_address[1]}/tree.zip", + "systems": ["nintendo-gba"], + "files": {"Sys/big.bin": {"sha1": hashlib.sha1(member).hexdigest(), + "size": len(member)}}}] + (repo.root / "install" / "retroarch.json").write_text(json.dumps(listed)) + proc = repo.run("--no-input") + bios = sum(len(payload) for payload, *_ in FakeRepository.PAYLOADS.values()) + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertIn(f"{install.format_size(bios + archive)} downloaded in", proc.stdout) + def test_verified_members_land_the_rest_are_said(self): work = Path(_tempdir(self)) archive = self._zip(work) bios = work / "system" bios.mkdir() - def fetch(url, directory): + def fetch(url, directory, progress=None): copy = Path(directory) / "a.zip" shutil.copy(archive, copy) return copy @@ -3750,7 +3811,7 @@ class DataDirectoriesAreInstalled(unittest.TestCase): yield "Sys/GC/font.bin", 4, lambda: io.BufferedReader(Endless()) with unittest.mock.patch.object(install, "_fetch_archive", - lambda url, d: Path(d) / "a"), \ + lambda url, d, progress=None: Path(d) / "a"), \ unittest.mock.patch.object(install, "_archive_members", members): counts = install.install_data_directory(entry, work) self.assertEqual(counts["changed"], 1) @@ -3778,7 +3839,7 @@ class DataDirectoriesAreInstalled(unittest.TestCase): yield "Sys/GC/font.bin", 4, lambda: io.BufferedReader(Broken()) with unittest.mock.patch.object(install, "_fetch_archive", - lambda url, d: Path(d) / "a"), \ + lambda url, d, progress=None: Path(d) / "a"), \ unittest.mock.patch.object(install, "_archive_members", members): counts = install.install_data_directory(entry, work) self.assertTrue(counts["error"]) @@ -6458,7 +6519,7 @@ class AFileYouHadIsKept(unittest.TestCase): "type": "zip", "files": {"Sys/a.ini": { "sha1": hashlib.sha1(self.NEW).hexdigest(), "size": len(self.NEW)}}} - def fetch(url, directory): + def fetch(url, directory, progress=None): copy = Path(directory) / "a.zip" shutil.copy(archive, copy) return copy diff --git a/wiki/installer.md b/wiki/installer.md index af2339730..dea79b4bd 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -342,7 +342,9 @@ file list is downloaded once and handed to each run. [Copy from an old card](#copy-from-an-old-card). 6. Downloads what is still missing or wrong, up to 8 files at a time. At a terminal one line shows the progress, the speed and the time left, while in a - log each finished file gets its own line. In an interactive run, a + log each finished file gets its own line. A data tree's archive gets the + same line at a terminal, and the bytes and time the run ends on count + it with the files. In an interactive run, a download of 1 GB or more is confirmed first (`--yes` skips the question). 7. Verifies each download against the declared size, SHA-256 and SHA-1 before it touches the destination, then moves it into place with `os.replace` so From 422de84ac8f6030c208dff5526b66a6daf4eb9d0 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 03:51:54 +0100 Subject: [PATCH 6/6] chore: ask for the Lakka card in the platform menu The manual platform menu test expected /storage/system for Lakka on a computer. Lakka is a card setup now, so the menu finds its card's STORAGE part: the default-folder case uses RetroPie, and a Lakka case checks the card. --- tests/test_install.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/test_install.py b/tests/test_install.py index e51432718..f36389a1e 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1863,12 +1863,28 @@ class TestManualPlatformPrompt(unittest.TestCase): self.assertEqual(chosen, [("batocera", Path("~/my bios").expanduser())]) def test_default_directory_comes_from_the_table(self): - answers = iter(["lakka", ""]) + answers = iter(["retropie", ""]) with unittest.mock.patch("builtins.input", lambda _prompt="": next(answers)), \ unittest.mock.patch.object(install, "_mounted_cards", return_value=[]), \ contextlib.redirect_stdout(io.StringIO()): chosen = install._prompt_manual_platform("linux") - self.assertEqual(chosen, [("lakka", install.DEFAULT_DESTS["lakka"])]) + self.assertEqual(chosen, [("retropie", install.DEFAULT_DESTS["retropie"])]) + + def test_lakka_on_a_computer_asks_for_its_card(self): + """/storage/system, a folder only the Lakka machine has, was taken + on a computer: Lakka keeps its BIOS on its card's STORAGE part.""" + card = Path(_tempdir(self)) + (card / ".config" / "retroarch").mkdir(parents=True) + (card / ".config" / "retroarch" / "retroarch.cfg").write_text( + 'system_directory = "/tmp/system"\n') + answers = iter(["lakka"]) + out = io.StringIO() + with unittest.mock.patch("builtins.input", lambda _prompt="": next(answers)), \ + unittest.mock.patch.object(install, "_mounted_cards", return_value=[card]), \ + contextlib.redirect_stdout(out): + chosen = install._prompt_manual_platform("linux") + self.assertEqual(chosen, [("lakka", card / "system")]) + self.assertIn("Lakka card found", out.getvalue()) def test_batocera_on_a_computer_gets_no_default(self): """/userdata/bios, a folder only the Batocera