mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-13 05:23:51 -06:00
chore: merge board rule and installable cores
This commit is contained in:
commit
ceee9ffbe7
27 files changed
+2517
-838
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -321,26 +321,43 @@
|
||||
},
|
||||
"atm7039": {
|
||||
"cores": [
|
||||
"2048",
|
||||
"81",
|
||||
"a5200",
|
||||
"abuse",
|
||||
"arduous",
|
||||
"atari800",
|
||||
"bennugd",
|
||||
"bk",
|
||||
"bluemsx",
|
||||
"bsnes_cplusplus98",
|
||||
"bsnes_mercury_accuracy",
|
||||
"bsnes_mercury_balanced",
|
||||
"bsnes_mercury_performance",
|
||||
"bstone",
|
||||
"cannonball",
|
||||
"cap32",
|
||||
"cdogs",
|
||||
"cgenius",
|
||||
"chailove",
|
||||
"crocods",
|
||||
"devilutionx",
|
||||
"dinothawr",
|
||||
"dosbox_core",
|
||||
"dosbox_pure",
|
||||
"dosbox_staging",
|
||||
"dosbox_svn",
|
||||
"dosbox_svn_ce",
|
||||
"easyrpg",
|
||||
"ecwolf",
|
||||
"emuscv",
|
||||
"fake08",
|
||||
"fallout1-ce",
|
||||
"fallout2-ce",
|
||||
"fbalpha2012",
|
||||
"fbalpha2012_cps1",
|
||||
"fbalpha2012_cps2",
|
||||
"fbalpha2012_neogeo",
|
||||
"fbneo",
|
||||
"fceumm",
|
||||
"flycast",
|
||||
@@ -349,37 +366,56 @@
|
||||
"freeintv",
|
||||
"fuse",
|
||||
"gambatte",
|
||||
"gearboy",
|
||||
"gearsystem",
|
||||
"genesis_plus_gx",
|
||||
"genesisplusgx",
|
||||
"geolith",
|
||||
"gme",
|
||||
"gpsp",
|
||||
"gsplus",
|
||||
"gw",
|
||||
"handy",
|
||||
"hatari",
|
||||
"hcl",
|
||||
"higan_sfc",
|
||||
"higan_sfc_balanced",
|
||||
"holani",
|
||||
"hurrican",
|
||||
"ioquake3",
|
||||
"lowresnx",
|
||||
"lutro",
|
||||
"mame",
|
||||
"mame0139",
|
||||
"mame078plus",
|
||||
"mame2000",
|
||||
"mame2003",
|
||||
"mame2003_plus",
|
||||
"mednafen_gba",
|
||||
"mednafen_lynx",
|
||||
"mednafen_ngp",
|
||||
"mednafen_pce",
|
||||
"mednafen_pce_fast",
|
||||
"mednafen_psx",
|
||||
"mednafen_snes",
|
||||
"mednafen_supergrafx",
|
||||
"mednafen_vb",
|
||||
"mednafen_wswan",
|
||||
"mesen",
|
||||
"mgba",
|
||||
"minivmac",
|
||||
"moonlight",
|
||||
"mrboom",
|
||||
"mu",
|
||||
"mupen64plus",
|
||||
"mupen64plus-next",
|
||||
"nekop2",
|
||||
"neocd",
|
||||
"nestopia",
|
||||
"np2kai",
|
||||
"nxengine",
|
||||
"o2em",
|
||||
"oberon",
|
||||
"openbor",
|
||||
"openbor4432",
|
||||
"openbor6412",
|
||||
@@ -392,6 +428,7 @@
|
||||
"pcfx",
|
||||
"pcsx_rearmed",
|
||||
"picodrive",
|
||||
"pocketcdg",
|
||||
"pokemini",
|
||||
"potator",
|
||||
"ppsspp",
|
||||
@@ -402,22 +439,34 @@
|
||||
"px68k",
|
||||
"pygame",
|
||||
"quasi88",
|
||||
"quicknes",
|
||||
"reminiscence",
|
||||
"remotejoy",
|
||||
"samcoupe",
|
||||
"sameboy",
|
||||
"sameduck",
|
||||
"scummvm",
|
||||
"sdlpop",
|
||||
"smsplus",
|
||||
"snes9x",
|
||||
"snes9x2002",
|
||||
"snes9x2005",
|
||||
"snes9x2005_plus",
|
||||
"snes9x2010",
|
||||
"snes9x_next",
|
||||
"solarus",
|
||||
"sonic2013",
|
||||
"soniccd",
|
||||
"squirreljme",
|
||||
"stella",
|
||||
"stella2014",
|
||||
"superbroswar",
|
||||
"swanstation",
|
||||
"taradino",
|
||||
"test",
|
||||
"tgbdual",
|
||||
"theodore",
|
||||
"thepowdertoy",
|
||||
"tic80",
|
||||
"tyrian",
|
||||
"tyrquake",
|
||||
@@ -425,15 +474,21 @@
|
||||
"uzem",
|
||||
"vb",
|
||||
"vba-m",
|
||||
"vba_next",
|
||||
"vbam",
|
||||
"vecx",
|
||||
"vemulator",
|
||||
"vice",
|
||||
"vice_x128",
|
||||
"vice_x64",
|
||||
"vice_x64sc",
|
||||
"vice_xcbm2",
|
||||
"vice_xcbm5x0",
|
||||
"vice_xpet",
|
||||
"vice_xplus4",
|
||||
"vice_xscpu64",
|
||||
"vice_xvic",
|
||||
"virtualjaguar",
|
||||
"x1",
|
||||
"x128",
|
||||
"x16emu",
|
||||
@@ -620,6 +675,7 @@
|
||||
},
|
||||
"r16": {
|
||||
"cores": [
|
||||
"2048",
|
||||
"81",
|
||||
"a5200",
|
||||
"abuse",
|
||||
@@ -627,20 +683,36 @@
|
||||
"arduous",
|
||||
"atari800",
|
||||
"bennugd",
|
||||
"bk",
|
||||
"bluemsx",
|
||||
"bsnes_cplusplus98",
|
||||
"bsnes_mercury_accuracy",
|
||||
"bsnes_mercury_balanced",
|
||||
"bsnes_mercury_performance",
|
||||
"bstone",
|
||||
"cannonball",
|
||||
"cap32",
|
||||
"cdogs",
|
||||
"cgenius",
|
||||
"chailove",
|
||||
"crocods",
|
||||
"devilutionx",
|
||||
"dinothawr",
|
||||
"dosbox_core",
|
||||
"dosbox_pure",
|
||||
"dosbox_staging",
|
||||
"dosbox_svn",
|
||||
"dosbox_svn_ce",
|
||||
"easyrpg",
|
||||
"ecwolf",
|
||||
"emuscv",
|
||||
"fake08",
|
||||
"fallout1-ce",
|
||||
"fallout2-ce",
|
||||
"fbalpha2012",
|
||||
"fbalpha2012_cps1",
|
||||
"fbalpha2012_cps2",
|
||||
"fbalpha2012_neogeo",
|
||||
"fbneo",
|
||||
"fceumm",
|
||||
"flycast",
|
||||
@@ -649,37 +721,56 @@
|
||||
"freeintv",
|
||||
"fuse",
|
||||
"gambatte",
|
||||
"gearboy",
|
||||
"gearsystem",
|
||||
"genesis_plus_gx",
|
||||
"genesisplusgx",
|
||||
"geolith",
|
||||
"gme",
|
||||
"gpsp",
|
||||
"gsplus",
|
||||
"gw",
|
||||
"handy",
|
||||
"hatari",
|
||||
"hcl",
|
||||
"higan_sfc",
|
||||
"higan_sfc_balanced",
|
||||
"holani",
|
||||
"hurrican",
|
||||
"ioquake3",
|
||||
"lowresnx",
|
||||
"lutro",
|
||||
"mame",
|
||||
"mame0139",
|
||||
"mame078plus",
|
||||
"mame2000",
|
||||
"mame2003",
|
||||
"mame2003_plus",
|
||||
"mednafen_gba",
|
||||
"mednafen_lynx",
|
||||
"mednafen_ngp",
|
||||
"mednafen_pce",
|
||||
"mednafen_pce_fast",
|
||||
"mednafen_psx",
|
||||
"mednafen_snes",
|
||||
"mednafen_supergrafx",
|
||||
"mednafen_vb",
|
||||
"mednafen_wswan",
|
||||
"mesen",
|
||||
"mgba",
|
||||
"minivmac",
|
||||
"moonlight",
|
||||
"mrboom",
|
||||
"mu",
|
||||
"mupen64plus",
|
||||
"mupen64plus-next",
|
||||
"nekop2",
|
||||
"neocd",
|
||||
"nestopia",
|
||||
"np2kai",
|
||||
"nxengine",
|
||||
"o2em",
|
||||
"oberon",
|
||||
"openbor",
|
||||
"openbor4432",
|
||||
"openbor6412",
|
||||
@@ -692,6 +783,7 @@
|
||||
"pcfx",
|
||||
"pcsx_rearmed",
|
||||
"picodrive",
|
||||
"pocketcdg",
|
||||
"pokemini",
|
||||
"potator",
|
||||
"ppsspp",
|
||||
@@ -702,22 +794,34 @@
|
||||
"px68k",
|
||||
"pygame",
|
||||
"quasi88",
|
||||
"quicknes",
|
||||
"reminiscence",
|
||||
"remotejoy",
|
||||
"samcoupe",
|
||||
"sameboy",
|
||||
"sameduck",
|
||||
"scummvm",
|
||||
"sdlpop",
|
||||
"smsplus",
|
||||
"snes9x",
|
||||
"snes9x2002",
|
||||
"snes9x2005",
|
||||
"snes9x2005_plus",
|
||||
"snes9x2010",
|
||||
"snes9x_next",
|
||||
"solarus",
|
||||
"sonic2013",
|
||||
"soniccd",
|
||||
"squirreljme",
|
||||
"stella",
|
||||
"stella2014",
|
||||
"superbroswar",
|
||||
"swanstation",
|
||||
"taradino",
|
||||
"test",
|
||||
"tgbdual",
|
||||
"theodore",
|
||||
"thepowdertoy",
|
||||
"tic80",
|
||||
"tyrian",
|
||||
"tyrquake",
|
||||
@@ -725,15 +829,21 @@
|
||||
"uzem",
|
||||
"vb",
|
||||
"vba-m",
|
||||
"vba_next",
|
||||
"vbam",
|
||||
"vecx",
|
||||
"vemulator",
|
||||
"vice",
|
||||
"vice_x128",
|
||||
"vice_x64",
|
||||
"vice_x64sc",
|
||||
"vice_xcbm2",
|
||||
"vice_xcbm5x0",
|
||||
"vice_xpet",
|
||||
"vice_xplus4",
|
||||
"vice_xscpu64",
|
||||
"vice_xvic",
|
||||
"virtualjaguar",
|
||||
"x1",
|
||||
"x128",
|
||||
"x16emu",
|
||||
@@ -752,6 +862,7 @@
|
||||
},
|
||||
"rk3128": {
|
||||
"cores": [
|
||||
"2048",
|
||||
"81",
|
||||
"a5200",
|
||||
"abuse",
|
||||
@@ -759,21 +870,37 @@
|
||||
"arduous",
|
||||
"atari800",
|
||||
"bennugd",
|
||||
"bk",
|
||||
"bluemsx",
|
||||
"bsnes_cplusplus98",
|
||||
"bsnes_mercury_accuracy",
|
||||
"bsnes_mercury_balanced",
|
||||
"bsnes_mercury_performance",
|
||||
"bstone",
|
||||
"cannonball",
|
||||
"cap32",
|
||||
"cdogs",
|
||||
"cgenius",
|
||||
"chailove",
|
||||
"crocods",
|
||||
"devilutionx",
|
||||
"dinothawr",
|
||||
"dosbox_core",
|
||||
"dosbox_pure",
|
||||
"dosbox_staging",
|
||||
"dosbox_svn",
|
||||
"dosbox_svn_ce",
|
||||
"easyrpg",
|
||||
"ecwolf",
|
||||
"emuscv",
|
||||
"fake08",
|
||||
"fallout1-ce",
|
||||
"fallout2-ce",
|
||||
"fbalpha",
|
||||
"fbalpha2012",
|
||||
"fbalpha2012_cps1",
|
||||
"fbalpha2012_cps2",
|
||||
"fbalpha2012_neogeo",
|
||||
"fbneo",
|
||||
"fceumm",
|
||||
"flycast",
|
||||
@@ -782,37 +909,55 @@
|
||||
"freeintv",
|
||||
"fuse",
|
||||
"gambatte",
|
||||
"gearboy",
|
||||
"gearsystem",
|
||||
"genesis_plus_gx",
|
||||
"genesisplusgx",
|
||||
"geolith",
|
||||
"gme",
|
||||
"gpsp",
|
||||
"gsplus",
|
||||
"gw",
|
||||
"handy",
|
||||
"hatari",
|
||||
"hcl",
|
||||
"higan_sfc",
|
||||
"higan_sfc_balanced",
|
||||
"holani",
|
||||
"hurrican",
|
||||
"lightspark",
|
||||
"lowresnx",
|
||||
"lutro",
|
||||
"mame",
|
||||
"mame0139",
|
||||
"mame078plus",
|
||||
"mame2000",
|
||||
"mame2003",
|
||||
"mame2003_plus",
|
||||
"mednafen_gba",
|
||||
"mednafen_lynx",
|
||||
"mednafen_ngp",
|
||||
"mednafen_pce",
|
||||
"mednafen_pce_fast",
|
||||
"mednafen_psx",
|
||||
"mednafen_snes",
|
||||
"mednafen_supergrafx",
|
||||
"mednafen_vb",
|
||||
"mednafen_wswan",
|
||||
"mesen",
|
||||
"mgba",
|
||||
"minivmac",
|
||||
"mrboom",
|
||||
"mu",
|
||||
"mupen64plus",
|
||||
"mupen64plus-next",
|
||||
"nekop2",
|
||||
"neocd",
|
||||
"nestopia",
|
||||
"np2kai",
|
||||
"nxengine",
|
||||
"o2em",
|
||||
"oberon",
|
||||
"openbor",
|
||||
"openbor4432",
|
||||
"openbor6412",
|
||||
@@ -825,6 +970,7 @@
|
||||
"pcfx",
|
||||
"pcsx_rearmed",
|
||||
"picodrive",
|
||||
"pocketcdg",
|
||||
"pokemini",
|
||||
"potator",
|
||||
"ppsspp",
|
||||
@@ -835,22 +981,34 @@
|
||||
"px68k",
|
||||
"pygame",
|
||||
"quasi88",
|
||||
"quicknes",
|
||||
"reminiscence",
|
||||
"remotejoy",
|
||||
"samcoupe",
|
||||
"sameboy",
|
||||
"sameduck",
|
||||
"scummvm",
|
||||
"sdlpop",
|
||||
"smsplus",
|
||||
"snes9x",
|
||||
"snes9x2002",
|
||||
"snes9x2005",
|
||||
"snes9x2005_plus",
|
||||
"snes9x2010",
|
||||
"snes9x_next",
|
||||
"solarus",
|
||||
"sonic2013",
|
||||
"soniccd",
|
||||
"squirreljme",
|
||||
"stella",
|
||||
"stella2014",
|
||||
"superbroswar",
|
||||
"swanstation",
|
||||
"taradino",
|
||||
"test",
|
||||
"tgbdual",
|
||||
"theodore",
|
||||
"thepowdertoy",
|
||||
"tic80",
|
||||
"tyrian",
|
||||
"tyrquake",
|
||||
@@ -858,15 +1016,21 @@
|
||||
"uzem",
|
||||
"vb",
|
||||
"vba-m",
|
||||
"vba_next",
|
||||
"vbam",
|
||||
"vecx",
|
||||
"vemulator",
|
||||
"vice",
|
||||
"vice_x128",
|
||||
"vice_x64",
|
||||
"vice_x64sc",
|
||||
"vice_xcbm2",
|
||||
"vice_xcbm5x0",
|
||||
"vice_xpet",
|
||||
"vice_xplus4",
|
||||
"vice_xscpu64",
|
||||
"vice_xvic",
|
||||
"virtualjaguar",
|
||||
"x1",
|
||||
"x128",
|
||||
"x16emu",
|
||||
|
||||
+390
-146
File diff suppressed because it is too large.
Load diff
+151
-24
@@ -10,7 +10,6 @@ cores:
|
||||
- a5200
|
||||
- abuse
|
||||
- amiberry
|
||||
- applewin
|
||||
- arduous
|
||||
- atari800
|
||||
- azahar
|
||||
@@ -30,7 +29,6 @@ cores:
|
||||
- cdogs
|
||||
- cemu
|
||||
- cgenius
|
||||
- citron
|
||||
- clk
|
||||
- corsixth
|
||||
- demul
|
||||
@@ -50,7 +48,6 @@ cores:
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- eduke32
|
||||
- eka2l1
|
||||
- emuscv
|
||||
- ep128emu-core
|
||||
- etlegacy
|
||||
@@ -66,7 +63,6 @@ cores:
|
||||
- fmsx
|
||||
- freechaf
|
||||
- freeintv
|
||||
- freej2me
|
||||
- fsuae
|
||||
- fury
|
||||
- fuse
|
||||
@@ -76,7 +72,6 @@ cores:
|
||||
- genesisplusgx
|
||||
- genesisplusgx-expanded
|
||||
- genesisplusgx-wide
|
||||
- gong
|
||||
- gpsp
|
||||
- gsplus
|
||||
- gw
|
||||
@@ -158,7 +153,6 @@ cores:
|
||||
- reminiscence
|
||||
- rpcs3
|
||||
- ruffle
|
||||
- ryujinx
|
||||
- samcoupe
|
||||
- same_cdi
|
||||
- sameduck
|
||||
@@ -173,7 +167,6 @@ cores:
|
||||
- sonic2013
|
||||
- sonic3-air
|
||||
- soniccd
|
||||
- squirreljme
|
||||
- stella
|
||||
- stella2014
|
||||
- superbroswar
|
||||
@@ -192,12 +185,10 @@ cores:
|
||||
- tyrian
|
||||
- tyrquake
|
||||
- uae4arm
|
||||
- uqm
|
||||
- uzem
|
||||
- vb
|
||||
- vba-m
|
||||
- vecx
|
||||
- vemulator
|
||||
- vice
|
||||
- vice_x128
|
||||
- vice_x64
|
||||
@@ -5683,7 +5674,6 @@ systems:
|
||||
standalone_cores:
|
||||
- abuse
|
||||
- amiberry
|
||||
- applewin
|
||||
- azahar
|
||||
- bigpemu
|
||||
- bstone
|
||||
@@ -5692,7 +5682,6 @@ standalone_cores:
|
||||
- cdogs
|
||||
- cemu
|
||||
- cgenius
|
||||
- citron
|
||||
- clk
|
||||
- corsixth
|
||||
- demul
|
||||
@@ -5709,7 +5698,6 @@ standalone_cores:
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- eduke32
|
||||
- eka2l1
|
||||
- etlegacy
|
||||
- fallout1-ce
|
||||
- fallout2-ce
|
||||
@@ -5755,7 +5743,6 @@ standalone_cores:
|
||||
- redream
|
||||
- rpcs3
|
||||
- ruffle
|
||||
- ryujinx
|
||||
- samcoupe
|
||||
- scummvm
|
||||
- sdlpop
|
||||
@@ -5776,7 +5763,6 @@ standalone_cores:
|
||||
- tr2x
|
||||
- tsugaru
|
||||
- tyrian
|
||||
- uqm
|
||||
- vice
|
||||
- vita3k
|
||||
- vkquake
|
||||
@@ -5800,7 +5786,6 @@ standalone_cores:
|
||||
- ymir
|
||||
- yquake2
|
||||
dual_mode_cores:
|
||||
- applewin
|
||||
- dolphin
|
||||
- easyrpg
|
||||
- flycast
|
||||
@@ -5813,6 +5798,157 @@ dual_mode_cores:
|
||||
- scummvm
|
||||
- stella
|
||||
- tic80
|
||||
installable_cores:
|
||||
- "2048"
|
||||
- 3dengine
|
||||
- DoubleCherryGB
|
||||
- amiarcadia
|
||||
- anarch
|
||||
- applewin
|
||||
- ardens
|
||||
- b2
|
||||
- bbkemu
|
||||
- boom3_xp
|
||||
- bsnes-jg
|
||||
- bsnes2014_accuracy
|
||||
- bsnes2014_balanced
|
||||
- bsnes2014_performance
|
||||
- bsnes_cplusplus98
|
||||
- bsnes_hd_beta
|
||||
- bsnes_mercury_accuracy
|
||||
- bsnes_mercury_balanced
|
||||
- bsnes_mercury_performance
|
||||
- cdi2015
|
||||
- chailove
|
||||
- citra
|
||||
- citra2018
|
||||
- clownmdemu
|
||||
- coolbaremu
|
||||
- craft
|
||||
- crocods
|
||||
- desmume2015
|
||||
- dingooemu
|
||||
- dinothawr
|
||||
- dirksimple
|
||||
- dosbox_core
|
||||
- dosbox_svn
|
||||
- dosbox_svn_ce
|
||||
- doukutsu_rs
|
||||
- ep128emu_core
|
||||
- fbalpha2012
|
||||
- fbalpha2012_cps1
|
||||
- fbalpha2012_cps2
|
||||
- fbalpha2012_cps3
|
||||
- fbalpha2012_neogeo
|
||||
- fixgb
|
||||
- fixnes
|
||||
- frodo
|
||||
- galaksija
|
||||
- gam4980
|
||||
- gametank
|
||||
- gearboy
|
||||
- geargrafx
|
||||
- gearlynx
|
||||
- geartowns
|
||||
- genesis_plus_gx
|
||||
- genesis_plus_gx_wide
|
||||
- geolith
|
||||
- gme
|
||||
- gong
|
||||
- hatari2014
|
||||
- hbmame
|
||||
- higan_sfc
|
||||
- higan_sfc_balanced
|
||||
- hyperscanemu
|
||||
- hypseushw
|
||||
- irogb
|
||||
- jaxe
|
||||
- jollycv
|
||||
- jumpnbump
|
||||
- linuxloader
|
||||
- m2000
|
||||
- mame2000
|
||||
- mame2003
|
||||
- mame2003_midway
|
||||
- mame2003_plus
|
||||
- mame2010
|
||||
- mame2015
|
||||
- mame2016
|
||||
- mcsoftserve
|
||||
- mednafen_gba
|
||||
- mednafen_pce
|
||||
- mednafen_pce_fast
|
||||
- mednafen_pcfx
|
||||
- mednafen_psx_hw
|
||||
- mednafen_saturn
|
||||
- mednafen_snes
|
||||
- mednafen_supafaust
|
||||
- mednafen_vb
|
||||
- mesen2
|
||||
- meteor
|
||||
- mojozork
|
||||
- mu
|
||||
- mupen64plus_next
|
||||
- n64emu
|
||||
- native32emu
|
||||
- nekop2
|
||||
- nicaiemu
|
||||
- noods
|
||||
- nside_sfc_balanced
|
||||
- nuance
|
||||
- numero
|
||||
- oberon
|
||||
- odin
|
||||
- omicron
|
||||
- openlara
|
||||
- panda3ds
|
||||
- parallel_dc
|
||||
- pcee2
|
||||
- pcem
|
||||
- piece
|
||||
- playdiaemu
|
||||
- pocketcdg
|
||||
- pokket
|
||||
- pokketstation
|
||||
- qemu
|
||||
- quicknes
|
||||
- race
|
||||
- radio
|
||||
- remotejoy
|
||||
- retro8
|
||||
- romcleaner
|
||||
- rust_dos
|
||||
- rustynes
|
||||
- sameboy
|
||||
- skyemu
|
||||
- snes9x2002
|
||||
- snes9x2005
|
||||
- snes9x2005_plus
|
||||
- snes9x2010
|
||||
- spmp8000emu
|
||||
- squirreljme
|
||||
- stella2023
|
||||
- tamalibretro
|
||||
- test
|
||||
- thepowdertoy
|
||||
- tia
|
||||
- uw8
|
||||
- uzdoom
|
||||
- vaporspec
|
||||
- vba_next
|
||||
- vbam
|
||||
- vemulator
|
||||
- vice_xcbm2
|
||||
- vice_xcbm5x0
|
||||
- video_processor
|
||||
- virtualxt
|
||||
- vitaquake2-rogue
|
||||
- vitaquake2-xatrix
|
||||
- vitaquake2-zaero
|
||||
- vitaquake3
|
||||
- wqxemu
|
||||
- xenia_edge
|
||||
- yabause
|
||||
libretro_systems:
|
||||
"81":
|
||||
- zx81
|
||||
@@ -6624,15 +6760,6 @@ launchers:
|
||||
fails_when_missing: false
|
||||
source_ref: "package/batocera/core/batocera-configgen/configgen/configgen/generators/shadps4/shadps4Generator.py:46,\
|
||||
\ 228"
|
||||
- emulator: citron
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/switch
|
||||
passes_to: "CitronPath::KeysDir in src/common/fs/path_util.cpp returns it, in place\
|
||||
\ of citron_path / KEYS_DIR"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/batocera/emulators/citron/002-adjust-paths.patch:9-10"
|
||||
configs_root:
|
||||
path: /userdata/system/configs
|
||||
from_bios: ../system/configs
|
||||
|
||||
@@ -11,56 +11,38 @@ cores:
|
||||
- "81"
|
||||
- AMIBERRY
|
||||
- AdvanceMame
|
||||
- CGeniusExe
|
||||
- Chocolate-Doom
|
||||
- DOSBOXSDL2
|
||||
- Duckstation
|
||||
- ECWolf
|
||||
- FBNEOSA
|
||||
- GZDoom
|
||||
- HATARISA
|
||||
- HYPSEUS
|
||||
- LZDoom
|
||||
- OPENBOR
|
||||
- OpenJazz
|
||||
- PPSSPPSDL
|
||||
- Pico-8
|
||||
- RigelEngine
|
||||
- SCUMMVMSA
|
||||
- STELLASA
|
||||
- Solarus
|
||||
- VVVVVV
|
||||
- a5200
|
||||
- abuse
|
||||
- atari800
|
||||
- bgdi
|
||||
- bk
|
||||
- bluemsx
|
||||
- bs
|
||||
- bstone
|
||||
- cannonball
|
||||
- cap32
|
||||
- ccleste
|
||||
- cdogs-sdl
|
||||
- daphne
|
||||
- devilutionx
|
||||
- dinothawr
|
||||
- dolphin
|
||||
- dosbox_pure
|
||||
- dosbox_svn
|
||||
- easyrpg
|
||||
- eduke32
|
||||
- fake08
|
||||
- fallout-ce
|
||||
- fallout2-ce
|
||||
- fbalpha2012
|
||||
- fbneo
|
||||
- fceumm
|
||||
- fceumm_mod
|
||||
- fheroes2
|
||||
- flycast
|
||||
- flycast_32b
|
||||
- flycast_dojo
|
||||
- flycastsa
|
||||
- fmsx
|
||||
- freeintv
|
||||
@@ -80,9 +62,6 @@ cores:
|
||||
- gw
|
||||
- handy
|
||||
- hatari
|
||||
- hcl
|
||||
- hode
|
||||
- hurrican
|
||||
- ikemen
|
||||
- jzintv
|
||||
- mame
|
||||
@@ -111,7 +90,6 @@ cores:
|
||||
- np2kai
|
||||
- nxengine
|
||||
- o2em
|
||||
- opentyrian
|
||||
- opera
|
||||
- parallel_n64_32b
|
||||
- pcsx_rearmed
|
||||
@@ -121,7 +99,6 @@ cores:
|
||||
- pokemini
|
||||
- potator
|
||||
- prboom
|
||||
- prince
|
||||
- prosystem
|
||||
- puae
|
||||
- puae2021
|
||||
@@ -131,17 +108,11 @@ cores:
|
||||
- sameboy
|
||||
- sameduck
|
||||
- scummvm
|
||||
- smw
|
||||
- snes9x
|
||||
- snes9x2002
|
||||
- snes9x2005_plus
|
||||
- snes9x2010
|
||||
- sonic2013
|
||||
- soniccd
|
||||
- sonicmania
|
||||
- stella
|
||||
- supertux2
|
||||
- supertuxkart
|
||||
- swanstation
|
||||
- tgbdual
|
||||
- tic80
|
||||
@@ -158,60 +129,29 @@ cores:
|
||||
- vice_xvic
|
||||
- virtualjaguar
|
||||
- x1
|
||||
- xash3d
|
||||
- xrick
|
||||
- yabasanshiro
|
||||
standalone_cores:
|
||||
- AMIBERRY
|
||||
- AdvanceMame
|
||||
- CGeniusExe
|
||||
- Chocolate-Doom
|
||||
- DOSBOXSDL2
|
||||
- Duckstation
|
||||
- ECWolf
|
||||
- FBNEOSA
|
||||
- GZDoom
|
||||
- HATARISA
|
||||
- HYPSEUS
|
||||
- LZDoom
|
||||
- OPENBOR
|
||||
- OpenJazz
|
||||
- PPSSPPSDL
|
||||
- Pico-8
|
||||
- RigelEngine
|
||||
- SCUMMVMSA
|
||||
- STELLASA
|
||||
- Solarus
|
||||
- VVVVVV
|
||||
- abuse
|
||||
- bgdi
|
||||
- bs
|
||||
- bstone
|
||||
- ccleste
|
||||
- cdogs-sdl
|
||||
- devilutionx
|
||||
- dolphin
|
||||
- eduke32
|
||||
- fallout-ce
|
||||
- fallout2-ce
|
||||
- fheroes2
|
||||
- flycast_dojo
|
||||
- flycastsa
|
||||
- hcl
|
||||
- hode
|
||||
- hurrican
|
||||
- ikemen
|
||||
- jzintv
|
||||
- mupen64plussa
|
||||
- opentyrian
|
||||
- prince
|
||||
- smw
|
||||
- sonic2013
|
||||
- soniccd
|
||||
- sonicmania
|
||||
- supertux2
|
||||
- supertuxkart
|
||||
- xash3d
|
||||
- yabasanshiro
|
||||
dual_mode_cores:
|
||||
- FBNEOSA
|
||||
@@ -4412,15 +4352,6 @@ launchers:
|
||||
fails_when_missing: false
|
||||
source_ref: "packages/sx05re/emuelec/bin/emuelecRunEmu.sh:198-200, packages/sx05re/emulators/flycastsa/scripts/flycast.sh:11,\
|
||||
\ 14"
|
||||
- emulator: flycast_dojo
|
||||
build: standalone
|
||||
kind: links
|
||||
names: []
|
||||
search_dir: /storage/roms/bios/dc_dojo
|
||||
passes_to: symlink /storage/.local/share/flycast-dojo -> /storage/roms/bios/dc_dojo
|
||||
fails_when_missing: false
|
||||
source_ref: "packages/sx05re/emuelec/bin/emuelecRunEmu.sh:201-203, packages/sx05re/emulators/flycast-dojo/scripts/flycastdojo.sh:11-12,\
|
||||
\ 28-30"
|
||||
- emulator: amiberry
|
||||
build: standalone
|
||||
kind: links
|
||||
|
||||
+51
-323
@@ -12,55 +12,36 @@ cores:
|
||||
- advanced_drastic
|
||||
- aethersx2
|
||||
- amiberry
|
||||
- applewin
|
||||
- arduous
|
||||
- atari800
|
||||
- azahar
|
||||
- beetle-saturn
|
||||
- bennugd
|
||||
- bigpemu
|
||||
- blastem
|
||||
- bluemsx
|
||||
- boom3
|
||||
- bsnes
|
||||
- bsnes_hd
|
||||
- bstone
|
||||
- cannonball
|
||||
- cap32
|
||||
- catacombgl
|
||||
- cdogs
|
||||
- cemu
|
||||
- cgenius
|
||||
- citra
|
||||
- citron
|
||||
- clk
|
||||
- corsixth
|
||||
- demul
|
||||
- desmume
|
||||
- devilutionx
|
||||
- dhewm3
|
||||
- dice
|
||||
- dolphin
|
||||
- dolphin_triforce
|
||||
- dosbox
|
||||
- dosbox-x
|
||||
- dosbox_pure
|
||||
- dosbox_staging
|
||||
- dosboxx
|
||||
- drastic
|
||||
- duckstation
|
||||
- duckstation-legacy
|
||||
- dxx-rebirth
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- eduke32
|
||||
- eka2l1
|
||||
- emuscv
|
||||
- etlegacy
|
||||
- fake08
|
||||
- fallout1-ce
|
||||
- fallout2-ce
|
||||
- fba2x
|
||||
- fbalpha
|
||||
- fbneo
|
||||
- fceumm
|
||||
@@ -68,20 +49,15 @@ cores:
|
||||
- flycast-xtreme
|
||||
- flycastvl
|
||||
- fmsx
|
||||
- fpinball
|
||||
- freechaf
|
||||
- freeintv
|
||||
- freej2me
|
||||
- fsuae
|
||||
- fury
|
||||
- fuse
|
||||
- gambatte
|
||||
- gearsystem
|
||||
- genesisplusgx
|
||||
- genesisplusgx-expanded
|
||||
- genesisplusgx-wide
|
||||
- geolith
|
||||
- gong
|
||||
- gpsp
|
||||
- gsplus
|
||||
- gw
|
||||
@@ -92,15 +68,9 @@ cores:
|
||||
- hcl
|
||||
- holani
|
||||
- hurrican
|
||||
- hypseus-singe
|
||||
- ikemen
|
||||
- imame4all
|
||||
- ioquake3
|
||||
- iortcw
|
||||
- jazz2-native
|
||||
- kronos
|
||||
- lightspark
|
||||
- lindbergh-loader
|
||||
- lowresnx
|
||||
- lutro
|
||||
- mame
|
||||
@@ -117,7 +87,6 @@ cores:
|
||||
- mesen-s
|
||||
- mgba
|
||||
- minivmac
|
||||
- model2emu
|
||||
- moonlight
|
||||
- mpv
|
||||
- mrboom
|
||||
@@ -134,21 +103,14 @@ cores:
|
||||
- openbor7142
|
||||
- openbor7530
|
||||
- openjazz
|
||||
- openjk
|
||||
- openjkdf2
|
||||
- openlara
|
||||
- openmohaa
|
||||
- openmsx
|
||||
- opera
|
||||
- parallel_n64
|
||||
- pce
|
||||
- pce_fast
|
||||
- pcfx
|
||||
- pcsx2
|
||||
- pcsx_rearmed
|
||||
- picodrive
|
||||
- play
|
||||
- pocketsnes
|
||||
- pokemini
|
||||
- potator
|
||||
- ppsspp
|
||||
@@ -158,20 +120,15 @@ cores:
|
||||
- puae2021
|
||||
- px68k
|
||||
- pygame
|
||||
- pyxel
|
||||
- quasi88
|
||||
- raze
|
||||
- redream
|
||||
- reminiscence
|
||||
- rpcs3
|
||||
- ruffle
|
||||
- ryujinx
|
||||
- samcoupe
|
||||
- same_cdi
|
||||
- sameduck
|
||||
- scummvm
|
||||
- sdlpop
|
||||
- shadps4
|
||||
- smsplus
|
||||
- snes9x
|
||||
- snes9x_next
|
||||
@@ -180,31 +137,21 @@ cores:
|
||||
- sonic2013
|
||||
- sonic3-air
|
||||
- soniccd
|
||||
- squirreljme
|
||||
- stella
|
||||
- stella2014
|
||||
- superbroswar
|
||||
- supermodel
|
||||
- supermodel-legacy
|
||||
- swanstation
|
||||
- taradino
|
||||
- tgbdual
|
||||
- theforceengine
|
||||
- theodore
|
||||
- thextech
|
||||
- tic80
|
||||
- tr1x
|
||||
- tr2x
|
||||
- tsugaru
|
||||
- tyrian
|
||||
- tyrquake
|
||||
- uae4arm
|
||||
- uqm
|
||||
- uzem
|
||||
- vb
|
||||
- vba-m
|
||||
- vecx
|
||||
- vemulator
|
||||
- vice
|
||||
- vice_x128
|
||||
- vice_x64
|
||||
@@ -221,24 +168,18 @@ cores:
|
||||
- vkquake2
|
||||
- vkquake3
|
||||
- vox_official
|
||||
- vpinball
|
||||
- wasm4
|
||||
- x1
|
||||
- x128
|
||||
- x16emu
|
||||
- x64
|
||||
- x64dtv
|
||||
- xash3d_fwgs
|
||||
- xemu
|
||||
- xenia
|
||||
- xenia-canary
|
||||
- xpet
|
||||
- xplus4
|
||||
- xrick
|
||||
- xscpu64
|
||||
- xvic
|
||||
- yabasanshiro
|
||||
- ymir
|
||||
- zc210
|
||||
systems:
|
||||
atari-400-800:
|
||||
@@ -4879,61 +4820,39 @@ standalone_cores:
|
||||
- advanced_drastic
|
||||
- aethersx2
|
||||
- amiberry
|
||||
- applewin
|
||||
- azahar
|
||||
- bigpemu
|
||||
- bstone
|
||||
- cannonball
|
||||
- catacombgl
|
||||
- cdogs
|
||||
- cemu
|
||||
- cgenius
|
||||
- citra
|
||||
- citron
|
||||
- clk
|
||||
- corsixth
|
||||
- demul
|
||||
- devilutionx
|
||||
- dhewm3
|
||||
- dolphin
|
||||
- dolphin_triforce
|
||||
- dosbox
|
||||
- dosbox-x
|
||||
- dosbox_staging
|
||||
- dosboxx
|
||||
- drastic
|
||||
- duckstation
|
||||
- duckstation-legacy
|
||||
- dxx-rebirth
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- eduke32
|
||||
- eka2l1
|
||||
- etlegacy
|
||||
- fallout1-ce
|
||||
- fallout2-ce
|
||||
- fba2x
|
||||
- flycast
|
||||
- fpinball
|
||||
- fsuae
|
||||
- fury
|
||||
- gsplus
|
||||
- gzdoom
|
||||
- hatari
|
||||
- hcl
|
||||
- hurrican
|
||||
- hypseus-singe
|
||||
- ikemen
|
||||
- ioquake3
|
||||
- iortcw
|
||||
- jazz2-native
|
||||
- kodi
|
||||
- lexaloffle
|
||||
- lightspark
|
||||
- lindbergh-loader
|
||||
- mame
|
||||
- melonds
|
||||
- model2emu
|
||||
- moonlight
|
||||
- mpv
|
||||
- mupen64plus
|
||||
@@ -4943,76 +4862,102 @@ standalone_cores:
|
||||
- openbor7142
|
||||
- openbor7530
|
||||
- openjazz
|
||||
- openjk
|
||||
- openjkdf2
|
||||
- openmohaa
|
||||
- openmsx
|
||||
- pcsx2
|
||||
- play
|
||||
- ppsspp
|
||||
- pygame
|
||||
- pyxel
|
||||
- raze
|
||||
- redream
|
||||
- rpcs3
|
||||
- ruffle
|
||||
- ryujinx
|
||||
- samcoupe
|
||||
- scummvm
|
||||
- sdlpop
|
||||
- shadps4
|
||||
- solarus
|
||||
- sonic-mania
|
||||
- sonic2013
|
||||
- sonic3-air
|
||||
- soniccd
|
||||
- stella
|
||||
- supermodel
|
||||
- supermodel-legacy
|
||||
- taradino
|
||||
- theforceengine
|
||||
- thextech
|
||||
- tr1x
|
||||
- tr2x
|
||||
- tsugaru
|
||||
- tyrian
|
||||
- uqm
|
||||
- vice
|
||||
- vita3k
|
||||
- vkquake
|
||||
- vkquake2
|
||||
- vkquake3
|
||||
- vox_official
|
||||
- vpinball
|
||||
- x128
|
||||
- x16emu
|
||||
- x64
|
||||
- x64dtv
|
||||
- xash3d_fwgs
|
||||
- xemu
|
||||
- xenia
|
||||
- xenia-canary
|
||||
- xpet
|
||||
- xplus4
|
||||
- xscpu64
|
||||
- xvic
|
||||
- yabasanshiro
|
||||
- ymir
|
||||
dual_mode_cores:
|
||||
- applewin
|
||||
- citra
|
||||
- dolphin
|
||||
- easyrpg
|
||||
- flycast
|
||||
- hatari
|
||||
- mame
|
||||
- melonds
|
||||
- pcsx2
|
||||
- play
|
||||
- ppsspp
|
||||
- scummvm
|
||||
- stella
|
||||
- yabasanshiro
|
||||
installable_cores:
|
||||
- "2048"
|
||||
- bk
|
||||
- bsnes_cplusplus98
|
||||
- bsnes_mercury_accuracy
|
||||
- bsnes_mercury_balanced
|
||||
- bsnes_mercury_performance
|
||||
- chailove
|
||||
- crocods
|
||||
- dinothawr
|
||||
- dosbox_core
|
||||
- dosbox_svn
|
||||
- dosbox_svn_ce
|
||||
- ecwolf
|
||||
- fbalpha2012
|
||||
- fbalpha2012_cps1
|
||||
- fbalpha2012_cps2
|
||||
- fbalpha2012_neogeo
|
||||
- gearboy
|
||||
- genesis_plus_gx
|
||||
- gme
|
||||
- higan_sfc
|
||||
- higan_sfc_balanced
|
||||
- mame2000
|
||||
- mame2003
|
||||
- mame2003_plus
|
||||
- mednafen_gba
|
||||
- mednafen_pce
|
||||
- mednafen_pce_fast
|
||||
- mednafen_snes
|
||||
- mednafen_vb
|
||||
- mu
|
||||
- nekop2
|
||||
- oberon
|
||||
- pocketcdg
|
||||
- quicknes
|
||||
- remotejoy
|
||||
- sameboy
|
||||
- snes9x2002
|
||||
- snes9x2005
|
||||
- snes9x2005_plus
|
||||
- snes9x2010
|
||||
- squirreljme
|
||||
- stella2014
|
||||
- test
|
||||
- thepowdertoy
|
||||
- vba_next
|
||||
- vbam
|
||||
- vemulator
|
||||
- vice_xcbm2
|
||||
- vice_xcbm5x0
|
||||
libretro_systems:
|
||||
"81":
|
||||
- zx81
|
||||
@@ -5393,129 +5338,6 @@ libretro_systems:
|
||||
zc210:
|
||||
- zc210
|
||||
launchers:
|
||||
- emulator: duckstation
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: NTSCU
|
||||
names:
|
||||
- scph101.bin
|
||||
- scph1001.bin
|
||||
- scph5501.bin
|
||||
- scph7001.bin
|
||||
- scph7501.bin
|
||||
case_insensitive: true
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathNTSCU"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation/duckstationGenerator.py:119-143,\
|
||||
\ 589-611"
|
||||
- emulator: duckstation
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: PAL
|
||||
names:
|
||||
- scph1002.bin
|
||||
- scph5502.bin
|
||||
- scph5552.bin
|
||||
- scph7002.bin
|
||||
- scph7502.bin
|
||||
- scph9002.bin
|
||||
- scph102a.bin
|
||||
- scph102b.bin
|
||||
case_insensitive: true
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathPAL"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation/duckstationGenerator.py:119-143,\
|
||||
\ 589-611"
|
||||
- emulator: duckstation
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: NTSCJ
|
||||
names:
|
||||
- scph100.bin
|
||||
- scph1000.bin
|
||||
- scph3000.bin
|
||||
- scph3500.bin
|
||||
- scph5500.bin
|
||||
- scph7000.bin
|
||||
- scph7003.bin
|
||||
case_insensitive: true
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathNTSCJ"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation/duckstationGenerator.py:119-143,\
|
||||
\ 589-611"
|
||||
- emulator: duckstation
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: Uni
|
||||
names:
|
||||
- psxonpsp660.bin
|
||||
- ps1_rom.bin
|
||||
case_insensitive: true
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathNTSCU, PathPAL, PathNTSCJ"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation/duckstationGenerator.py:119-143,\
|
||||
\ 589-611"
|
||||
- emulator: duckstation-legacy
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: NTSCU
|
||||
names:
|
||||
- scph101.bin
|
||||
- scph1001.bin
|
||||
- scph5501.bin
|
||||
- scph7001.bin
|
||||
- scph7501.bin
|
||||
case_insensitive: false
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathNTSCU"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation_legacy/duckstationLegacyGenerator.py:116-153"
|
||||
- emulator: duckstation-legacy
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: PAL
|
||||
names:
|
||||
- scph1002.bin
|
||||
- scph5502.bin
|
||||
- scph5552.bin
|
||||
- scph7002.bin
|
||||
- scph7502.bin
|
||||
- scph9002.bin
|
||||
- scph102a.bin
|
||||
- scph102b.bin
|
||||
case_insensitive: false
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathPAL"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation_legacy/duckstationLegacyGenerator.py:116-153"
|
||||
- emulator: duckstation-legacy
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
slot: NTSCJ
|
||||
names:
|
||||
- scph100.bin
|
||||
- scph1000.bin
|
||||
- scph3000.bin
|
||||
- scph3500.bin
|
||||
- scph5500.bin
|
||||
- scph7000.bin
|
||||
- scph7003.bin
|
||||
case_insensitive: false
|
||||
search_dir: /userdata/bios
|
||||
passes_to: "[BIOS] PathNTSCJ"
|
||||
fails_when_missing: No PSX1 BIOS found
|
||||
fails_scope: emulator
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/duckstation_legacy/duckstationLegacyGenerator.py:116-153"
|
||||
- emulator: hatari
|
||||
build: standalone
|
||||
kind: names_searched
|
||||
@@ -5683,33 +5505,6 @@ launchers:
|
||||
passes_to: environment FLYCAST_BIOS_PATH
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/flycast/flycastGenerator.py:239"
|
||||
- emulator: shadps4
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/system/configs/shadps4
|
||||
passes_to: working directory of shadps4Generator.py
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/shadps4/shadps4Generator.py:33,\
|
||||
\ 164"
|
||||
- emulator: openmsx
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/Machines
|
||||
passes_to: "written: filepool add -path /userdata/bios/Machines -types system_rom\
|
||||
\ -position 1"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/openmsx/openmsxGenerator.py:95"
|
||||
- emulator: openmsx
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/openmsx
|
||||
passes_to: "written: filepool add -path /userdata/bios/openmsx -types system_rom\
|
||||
\ -position 2"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/openmsx/openmsxGenerator.py:96"
|
||||
- emulator: amiberry
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
@@ -5765,15 +5560,6 @@ launchers:
|
||||
depends_on_option: neocd_bios
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/libretro/libretroOptions.py:2558-2559,\
|
||||
\ 2566-2569"
|
||||
- emulator: pcsx2
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/ps2
|
||||
passes_to: "inis/PCSX2.ini [Folders] Bios = ../../../bios/ps2, relative to /userdata/system/configs/PCSX2"
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/pcsx2/pcsx2Generator.py:92,\
|
||||
\ 176, 213"
|
||||
- emulator: aethersx2
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
@@ -5919,29 +5705,6 @@ launchers:
|
||||
fails_when_missing: false
|
||||
depends_on_option: "Rpcs3Generator.getFirmwareVersion() is None"
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/rpcs3/rpcs3Generator.py:355-358"
|
||||
- emulator: ryujinx
|
||||
build: standalone
|
||||
kind: copies
|
||||
names:
|
||||
- switch/prod.keys
|
||||
case_insensitive: false
|
||||
search_dir: /userdata/bios
|
||||
passes_to: /userdata/system/configs/Ryujinx/system/prod.keys
|
||||
fails_when_missing: false
|
||||
depends_on_option: "ryujinxKeys.exists()"
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/ryujinx/ryujinxGenerator.py:107-109"
|
||||
- emulator: pcsx2
|
||||
build: standalone
|
||||
kind: copies
|
||||
names:
|
||||
- patches.zip
|
||||
case_insensitive: false
|
||||
search_dir: /usr/share/knulli/datainit/bios/ps2
|
||||
passes_to: /userdata/bios/ps2/patches.zip
|
||||
fails_when_missing: false
|
||||
depends_on_option: "not pcsx2Patches.exists()"
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/pcsx2/pcsx2Generator.py:78,\
|
||||
\ 121-122"
|
||||
- emulator: aethersx2
|
||||
build: standalone
|
||||
kind: copies
|
||||
@@ -5962,14 +5725,6 @@ launchers:
|
||||
passes_to: g_cfg_rom_path
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/gsplus/gsplusGenerator.py:106"
|
||||
- emulator: tsugaru
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/fmtowns
|
||||
passes_to: command line argument 1
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/tsugaru/tsugaruGenerator.py:18-19"
|
||||
- emulator: scummvm
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
@@ -5978,14 +5733,6 @@ launchers:
|
||||
passes_to: command line --extrapath
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/scummvm/scummvmGenerator.py:117-123"
|
||||
- emulator: fsuae
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/amiga
|
||||
passes_to: command line --kickstarts_dir
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/fsuae/fsuaeGenerator.py:63-69"
|
||||
- emulator: mame
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
@@ -6039,16 +5786,6 @@ launchers:
|
||||
passes_to: command line -crosshairpath
|
||||
fails_when_missing: false
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/mame/mameGenerator.py:180"
|
||||
- emulator: fpinball
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios
|
||||
passes_to: environment W_CACHE
|
||||
fails_when_missing: false
|
||||
depends_on_option: "not wsh57_done.exists()"
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/fpinball/fpinballGenerator.py:37,\
|
||||
\ 39-43"
|
||||
- emulator: retroarch
|
||||
build: libretro
|
||||
kind: passes_path
|
||||
@@ -6142,15 +5879,6 @@ launchers:
|
||||
depends_on_option: not system.name == 'ti99'
|
||||
source_ref: "package/system/knulli-configgen/configgen/configgen/generators/libretro/libretroMAMEConfig.py:431-432,\
|
||||
\ 435"
|
||||
- emulator: citron
|
||||
build: standalone
|
||||
kind: passes_path
|
||||
names: []
|
||||
search_dir: /userdata/bios/switch
|
||||
passes_to: "CitronPath::KeysDir in src/common/fs/path_util.cpp returns it, in place\
|
||||
\ of citron_path / KEYS_DIR"
|
||||
fails_when_missing: false
|
||||
source_ref: "batocera/package/batocera/emulators/citron/002-adjust-paths.patch:9-10"
|
||||
configs_root:
|
||||
path: /userdata/system/configs
|
||||
from_bios: ../system/configs
|
||||
|
||||
+126
-1
@@ -6,66 +6,191 @@ base_destination: bios
|
||||
hash_type: md5
|
||||
verification_mode: md5
|
||||
cores:
|
||||
- retroarch
|
||||
- "81"
|
||||
- DoubleCherryGB
|
||||
- a5200
|
||||
- amiberry
|
||||
- arduous
|
||||
- ares
|
||||
- ares-sa
|
||||
- armsx2
|
||||
- armsx2-sa
|
||||
- atari800
|
||||
- azahar
|
||||
- azahar-sa
|
||||
- b2
|
||||
- beetle_gba
|
||||
- beetle_lynx
|
||||
- beetle_ngp
|
||||
- beetle_pce
|
||||
- beetle_pce_fast
|
||||
- beetle_pcfx
|
||||
- beetle_psx
|
||||
- beetle_saturn
|
||||
- beetle_supafaust
|
||||
- beetle_supergrafx
|
||||
- beetle_vb
|
||||
- beetle_wswan
|
||||
- bigpemu
|
||||
- bigpemu-sa
|
||||
- bk
|
||||
- bluemsx
|
||||
- boom3
|
||||
- boom3_xp
|
||||
- bsnes
|
||||
- bsnes2014_accuracy
|
||||
- bsnes2014_balanced
|
||||
- bsnes2014_performance
|
||||
- bsnes_hd_beta
|
||||
- bsnes_mercury_accuracy
|
||||
- bsnes_mercury_balanced
|
||||
- bsnes_mercury_performance
|
||||
- cap32
|
||||
- cemu
|
||||
- cemu-sa
|
||||
- crocods
|
||||
- daedalusx64
|
||||
- daedalusx64-sa
|
||||
- daphne
|
||||
- desmume
|
||||
- dolphin
|
||||
- dolphin-sa
|
||||
- dosbox_core
|
||||
- dosbox_pure
|
||||
- drastic
|
||||
- drastic-sa
|
||||
- dsperate
|
||||
- dsperate-sa
|
||||
- duckstation
|
||||
- duckstation-sa
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- emuscv
|
||||
- fake08
|
||||
- fbalpha2012
|
||||
- fbalpha2019
|
||||
- fbneo
|
||||
- fceumm
|
||||
- flycast
|
||||
- flycast-sa
|
||||
- flycast2021
|
||||
- fmsx
|
||||
- freeintv
|
||||
- freej2me
|
||||
- fuse
|
||||
- gambatte
|
||||
- gearboy
|
||||
- gearcoleco
|
||||
- geargrafx
|
||||
- gearlynx
|
||||
- gearsystem
|
||||
- genesis_plus_gx
|
||||
- genesis_plus_gx_wide
|
||||
- geolith
|
||||
- gopher64
|
||||
- gopher64-sa
|
||||
- gpsp
|
||||
- gw
|
||||
- gzdoom
|
||||
- gzdoom-sa
|
||||
- handy
|
||||
- hatari
|
||||
- hatarisa
|
||||
- heroic
|
||||
- hypseus-singe
|
||||
- jaxe
|
||||
- kronos
|
||||
- mame
|
||||
- mame2003_plus
|
||||
- mame2010
|
||||
- mame2015
|
||||
- mednafen
|
||||
- melonds
|
||||
- melonds-sa
|
||||
- melondsds
|
||||
- mesen
|
||||
- mesen-s
|
||||
- mgba
|
||||
- minivmac
|
||||
- mojozork
|
||||
- mu
|
||||
- mupen64plus
|
||||
- mupen64plus-sa
|
||||
- mupen64plus_next
|
||||
- nanoboyadvance
|
||||
- nanoboyadvance-sa
|
||||
- neocd
|
||||
- nestopia
|
||||
- np2kai
|
||||
- o2em
|
||||
- openbor
|
||||
- opera
|
||||
- parallel_n64
|
||||
- pcsx_rearmed
|
||||
- pcsx_rearmed32
|
||||
- pico-8
|
||||
- picodrive
|
||||
- pokemini
|
||||
- potator
|
||||
- ppsspp
|
||||
- ppsspp-sa
|
||||
- prboom
|
||||
- prosystem
|
||||
- puae
|
||||
- puae2021
|
||||
- px68k
|
||||
- quasi88
|
||||
- quicknes
|
||||
- race
|
||||
- rpcs3
|
||||
- rpcs3-sa
|
||||
- same_cdi
|
||||
- sameboy
|
||||
- sameduck
|
||||
- scummvm
|
||||
- scummvm-sa
|
||||
- skyemu
|
||||
- skyemu-sa
|
||||
- smsplus
|
||||
- snes9x
|
||||
- snes9x2002
|
||||
- snes9x2005_plus
|
||||
- snes9x2010
|
||||
- steam
|
||||
- stella
|
||||
- supermodel
|
||||
- supermodel-sa
|
||||
- supersnes9x
|
||||
- swanstation
|
||||
- tgbdual
|
||||
- theodore
|
||||
- tic80
|
||||
- touchhle
|
||||
- touchhle-sa
|
||||
- tyrquake
|
||||
- uae4arm
|
||||
- uzem
|
||||
- vba_next
|
||||
- vbam
|
||||
- vecx
|
||||
- vice
|
||||
- vice-sa
|
||||
- vice_x128
|
||||
- vice_x64
|
||||
- vice_xpet
|
||||
- vice_xplus4
|
||||
- vice_xvic
|
||||
- vircon32
|
||||
- virtualjaguar
|
||||
- vita3k
|
||||
- vita3k-sa
|
||||
- vitaquake2
|
||||
- vitaquake3
|
||||
- wasm4
|
||||
- x1
|
||||
- xemu
|
||||
- xemu-sa
|
||||
- yabadabadoo
|
||||
- yabasanshiro
|
||||
- yabasanshiro-sa
|
||||
standalone_cores:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
platform: batocera
|
||||
source: https://github.com/batocera-linux/batocera.linux/tree/batocera-43.1
|
||||
scraped_at: '2026-11-06T02:18:59Z'
|
||||
scraped_at: '2026-11-09T20:38:15Z'
|
||||
targets:
|
||||
a3gen2:
|
||||
architecture: aarch64
|
||||
@@ -203,6 +203,7 @@ targets:
|
||||
- dosbox_staging
|
||||
- dosboxx
|
||||
- duckstation
|
||||
- dxx-rebirth
|
||||
- easyrpg
|
||||
- ecwolf
|
||||
- eduke32
|
||||
@@ -300,7 +301,9 @@ targets:
|
||||
- snes9x_next
|
||||
- solarus
|
||||
- sonic-mania
|
||||
- sonic2013
|
||||
- sonic3-air
|
||||
- soniccd
|
||||
- stella
|
||||
- superbroswar
|
||||
- supermodel
|
||||
@@ -342,6 +345,7 @@ targets:
|
||||
- xpet
|
||||
- xplus4
|
||||
- xrick
|
||||
- xroar
|
||||
- xscpu64
|
||||
- xvic
|
||||
- yabasanshiro
|
||||
@@ -786,6 +790,7 @@ targets:
|
||||
- xvic
|
||||
- yquake2
|
||||
- zc210
|
||||
downloads: linux-armhf
|
||||
bcm2837:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -1071,6 +1076,7 @@ targets:
|
||||
- orangepi-one
|
||||
- orangepi-pc
|
||||
- orangepi-plus2e
|
||||
downloads: linux-armhf
|
||||
h5:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -2177,6 +2183,7 @@ targets:
|
||||
- xvic
|
||||
- yquake2
|
||||
- zc210
|
||||
downloads: linux-armhf
|
||||
qcs6490:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -2512,6 +2519,7 @@ targets:
|
||||
- powkiddy_a13
|
||||
- ps5000
|
||||
- ps7000
|
||||
downloads: linux-armhf
|
||||
rk3288:
|
||||
architecture: arm
|
||||
cores:
|
||||
@@ -2670,6 +2678,7 @@ targets:
|
||||
images:
|
||||
- miqi
|
||||
- tinkerboard
|
||||
downloads: linux-armhf
|
||||
rk3326:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -3883,6 +3892,7 @@ targets:
|
||||
- xvic
|
||||
- yquake2
|
||||
- zc210
|
||||
downloads: linux-armhf
|
||||
s905:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -5379,6 +5389,7 @@ targets:
|
||||
- model2emu
|
||||
- moonlight
|
||||
- mrboom
|
||||
- mugen
|
||||
- mupen64plus
|
||||
- mupen64plus-next
|
||||
- neocd
|
||||
@@ -5475,6 +5486,8 @@ targets:
|
||||
- vkquake3
|
||||
- vpinball
|
||||
- wasm4
|
||||
- wine
|
||||
- wine-tkg
|
||||
- x1
|
||||
- x128
|
||||
- x16emu
|
||||
@@ -5494,6 +5507,7 @@ targets:
|
||||
- ymir
|
||||
- yquake2
|
||||
- zc210
|
||||
downloads: linux-x86_64
|
||||
zen3:
|
||||
architecture: x86_64
|
||||
cores:
|
||||
@@ -5605,6 +5619,7 @@ targets:
|
||||
- model2emu
|
||||
- moonlight
|
||||
- mrboom
|
||||
- mugen
|
||||
- mupen64plus
|
||||
- mupen64plus-next
|
||||
- neocd
|
||||
@@ -5701,6 +5716,8 @@ targets:
|
||||
- vkquake3
|
||||
- vpinball
|
||||
- wasm4
|
||||
- wine
|
||||
- wine-tkg
|
||||
- x1
|
||||
- x128
|
||||
- x16emu
|
||||
@@ -5722,3 +5739,4 @@ targets:
|
||||
- zc210
|
||||
images:
|
||||
- x86-64-v3
|
||||
downloads: linux-x86_64
|
||||
@@ -1,6 +1,6 @@
|
||||
platform: knulli
|
||||
source: https://github.com/knulli-cfw/knulli-linux/tree/20260511
|
||||
scraped_at: '2026-11-06T02:19:00Z'
|
||||
scraped_at: '2026-11-09T20:38:23Z'
|
||||
targets:
|
||||
a133:
|
||||
architecture: aarch64
|
||||
@@ -472,6 +472,7 @@ targets:
|
||||
- zc210
|
||||
images:
|
||||
- rg35xx
|
||||
downloads: linux-armhf
|
||||
h700:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
@@ -787,6 +788,7 @@ targets:
|
||||
- zc210
|
||||
images:
|
||||
- miyoo-a30
|
||||
downloads: linux-armhf
|
||||
rk3128:
|
||||
architecture: arm
|
||||
cores:
|
||||
@@ -930,6 +932,7 @@ targets:
|
||||
- powkiddy_a13
|
||||
- ps5000
|
||||
- ps7000
|
||||
downloads: linux-armhf
|
||||
rk3326:
|
||||
architecture: aarch64
|
||||
cores:
|
||||
|
||||
+192
-102
File diff suppressed because it is too large.
Load diff
@@ -45,6 +45,14 @@
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"installable_cores": {
|
||||
"description": "Buildbot libretro cores the platform's RetroArch core downloader installs on at least one board, from the RetroArch targets entry of that board's architecture.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"dual_mode_cores": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
+22
-9
@@ -869,11 +869,24 @@ def load_target_config(
|
||||
)
|
||||
)
|
||||
|
||||
declared = (targets[canonical] or {}).get("cores")
|
||||
return _target_core_set(targets[canonical] or {}, overrides, canonical, platforms_dir)
|
||||
|
||||
|
||||
def _target_core_set(
|
||||
entry: dict, overrides: dict, target: str, platforms_dir: str
|
||||
) -> set[str] | None:
|
||||
"""A target's cores: what the board builds, overrides applied, and the
|
||||
buildbot cores its RetroArch core downloader installs (`downloads`, a
|
||||
RetroArch targets entry), which a Batocera x86_64 or armv7 board can
|
||||
fetch from its menu."""
|
||||
declared = entry.get("cores")
|
||||
if declared is None:
|
||||
return None
|
||||
cores = set(str(c) for c in declared)
|
||||
return apply_target_overrides(cores, overrides, canonical)
|
||||
cores = apply_target_overrides({str(c) for c in declared}, overrides, target)
|
||||
downloads = entry.get("downloads")
|
||||
if downloads:
|
||||
cores |= load_target_config("retroarch", str(downloads), platforms_dir) or set()
|
||||
return cores
|
||||
|
||||
|
||||
def apply_target_overrides(
|
||||
@@ -917,12 +930,9 @@ def list_available_targets(
|
||||
result = []
|
||||
for tname, tdata in sorted(data.get("targets", {}).items()):
|
||||
aliases = (overrides.get(tname) or {}).get("aliases", [])
|
||||
declared = (tdata or {}).get("cores")
|
||||
# None: the target runs every core the platform declares.
|
||||
count = (
|
||||
None if declared is None
|
||||
else len(apply_target_overrides({str(c) for c in declared}, overrides, tname))
|
||||
)
|
||||
found = _target_core_set(tdata or {}, overrides, tname, platforms_dir)
|
||||
count = None if found is None else len(found)
|
||||
result.append(
|
||||
{
|
||||
"name": tname,
|
||||
@@ -2533,6 +2543,7 @@ def group_identical_platforms(
|
||||
cores if isinstance(cores, str) else sorted(map(str, cores or [])),
|
||||
sorted(map(str, config.get("standalone_cores") or [])),
|
||||
sorted(map(str, config.get("dual_mode_cores") or [])),
|
||||
sorted(map(str, config.get("installable_cores") or [])),
|
||||
# One archive cannot serve a filesystem that folds case and one
|
||||
# that does not: Lakka keeps bios.col beside BIOS.col.
|
||||
bool(config.get("case_insensitive_fs")),
|
||||
@@ -3218,9 +3229,11 @@ def resolve_platform_cores(
|
||||
# An emulator the platform launches standalone runs there even when
|
||||
# its own list names only the cores: Batocera's es_systems.yml files
|
||||
# lexaloffle and gsplus as standalone emulators and nowhere else.
|
||||
# A core the platform's RetroArch installs from the buildbot runs
|
||||
# there as well (installable_cores, Batocera x86_64 and armv7).
|
||||
core_set = {str(c) for c in cores_config} | {
|
||||
str(c) for c in config.get("standalone_cores") or []
|
||||
}
|
||||
} | {str(c) for c in config.get("installable_cores") or []}
|
||||
index = upstream_profile_index(profiles)
|
||||
platform = str(config.get("_key") or "")
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ import re
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from collections.abc import Callable, Iterable
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
from common import yaml_load
|
||||
from common import load_target_config, yaml_load
|
||||
from hashing import cut_md5_owner
|
||||
from safeparse import yaml_load_upstream
|
||||
|
||||
@@ -30,6 +30,8 @@ from .base_scraper import (
|
||||
requirement_entry,
|
||||
)
|
||||
from .batocera_launchers import Configgen, configs_root, extract_launchers
|
||||
from .targets.batocera_targets_scraper import BuildSelection
|
||||
from .targets.batocera_targets_scraper import Scraper as BoardTargets
|
||||
|
||||
PLATFORM_NAME = "batocera"
|
||||
|
||||
@@ -489,76 +491,51 @@ def configgen_cores(
|
||||
for GameCube). `dropped` names what es_systems.yml files under an
|
||||
emulator without being one.
|
||||
|
||||
A default es_systems.yml does not offer names an emulator the build may
|
||||
lack: KNULLI's defaults pick suyu for the Switch, and no package of its
|
||||
tree, its batocera submodule or its buildroot builds suyu. `built` says
|
||||
whether the build has a standalone emulator (packages_and_programs); a
|
||||
default it answers no for is not run, nor its core.
|
||||
`built` says whether some board builds a name (boards_build). What it
|
||||
answers no for is not run: KNULLI's es_systems lists citron and shadps4,
|
||||
which no KNULLI board selects, and its defaults pick suyu, which no
|
||||
package builds. A default's core follows a standalone emulator the
|
||||
build runs (vox_official is lexaloffle's Voxatron build).
|
||||
"""
|
||||
data = yaml_load_upstream(defaults_text)
|
||||
cores, standalone = es_systems_emulators(es_systems_text)
|
||||
offered = set(cores)
|
||||
libretro = es_systems_libretro(es_systems_text)
|
||||
if not cores:
|
||||
raise RuntimeError("es_systems.yml names no emulator")
|
||||
if built is not None:
|
||||
cores = {name for name in cores if built(name)}
|
||||
standalone &= cores
|
||||
for system, cfg in data.items():
|
||||
if system == "default" or not isinstance(cfg, dict):
|
||||
continue
|
||||
emulator = cfg.get("emulator", "")
|
||||
core = cfg.get("core", "")
|
||||
if (built is not None and emulator and emulator != "libretro"
|
||||
and emulator not in offered and not built(emulator)):
|
||||
continue
|
||||
if core:
|
||||
cores.add(core)
|
||||
if emulator and emulator != "libretro":
|
||||
if built is not None and not built(emulator):
|
||||
continue
|
||||
standalone.add(emulator)
|
||||
if core and core != emulator:
|
||||
standalone.add(core)
|
||||
elif built is not None and core and not built(core):
|
||||
continue
|
||||
if core:
|
||||
cores.add(core)
|
||||
dual = (standalone & libretro) - dropped
|
||||
return sorted(cores - dropped), sorted(standalone - dropped), sorted(dual)
|
||||
|
||||
|
||||
BATOCERA_REPO = "batocera-linux/batocera.linux"
|
||||
def boards_build(selection: BuildSelection, launchers: list[dict]) -> Callable[[str], bool]:
|
||||
"""Whether some board of a build runs an emulator.
|
||||
|
||||
|
||||
def package_names(paths: Iterable[str]) -> set[str]:
|
||||
"""The buildroot packages a tree defines: each folder holding a Config.in."""
|
||||
return {
|
||||
path.rsplit("/", 2)[-2]
|
||||
for path in paths
|
||||
if path.endswith("/Config.in") and path.count("/") >= 1
|
||||
}
|
||||
|
||||
|
||||
def repo_tree(repo: str, ref: str) -> list[str]:
|
||||
"""Every path of a GitHub repository at a revision."""
|
||||
url = f"https://api.github.com/repos/{repo}/git/trees/{ref}?recursive=1"
|
||||
req = urllib.request.Request(url, headers=github_headers())
|
||||
with urllib.request.urlopen(req, timeout=60) as resp:
|
||||
found = json.loads(resp.read().decode("utf-8"))
|
||||
if found.get("truncated"):
|
||||
raise RuntimeError(f"{url}: tree truncated")
|
||||
return [entry["path"] for entry in found.get("tree", [])]
|
||||
|
||||
|
||||
def submodule_revision(repo: str, path: str, ref: str) -> str:
|
||||
"""The commit a repository's submodule at `path` pins at a revision."""
|
||||
url = f"https://api.github.com/repos/{repo}/contents/{path}?ref={ref}"
|
||||
req = urllib.request.Request(url, headers=github_headers())
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
found = json.loads(resp.read().decode("utf-8"))
|
||||
if not isinstance(found, dict) or found.get("type") != "submodule" or not found.get("sha"):
|
||||
raise RuntimeError(f"{url}: {path} is not a submodule")
|
||||
return str(found["sha"])
|
||||
|
||||
|
||||
def packages_and_programs(packages: set[str], launchers: list[dict]) -> Callable[[str], bool]:
|
||||
"""Whether a build has a standalone emulator.
|
||||
|
||||
It does when a package of that name exists, or when its launcher runs a
|
||||
program the user puts in the BIOS folder (Batocera's lexaloffle runs
|
||||
/userdata/bios/pico-8/pico8), which no package builds.
|
||||
es_systems.yml ties each name to the packages that build it
|
||||
(requireAnyOf), and a name it lists is built when a board selects one of
|
||||
them: KNULLI lists citron and shadps4, and its Config.in selects them
|
||||
only on x86_64 boards, which it has none of. A name only
|
||||
configgen-defaults.yml gives is built when a board selects the package
|
||||
of that name: the symbol its Config.in defines, else the one Buildroot
|
||||
derives from the folder (BR2_PACKAGE_<NAME>, package/pkg-generic.mk). A
|
||||
program the launcher runs from the BIOS folder (lexaloffle,
|
||||
/userdata/bios/pico-8/pico8) needs no package.
|
||||
"""
|
||||
supplied = {
|
||||
name.strip()
|
||||
@@ -567,7 +544,42 @@ def packages_and_programs(packages: set[str], launchers: list[dict]) -> Callable
|
||||
and str(record.get("search_dir") or "").startswith("/userdata/bios")
|
||||
for name in str(record.get("emulator", "")).split(",")
|
||||
}
|
||||
return lambda emulator: emulator in packages or emulator in supplied
|
||||
|
||||
def built(name: str) -> bool:
|
||||
if name in selection.emulators or name in supplied:
|
||||
return True
|
||||
if name in selection.listed:
|
||||
return False
|
||||
symbol = selection.packages.get(name) or (
|
||||
"BR2_PACKAGE_" + name.upper().replace("-", "_"))
|
||||
return symbol in selection.symbols
|
||||
|
||||
return built
|
||||
|
||||
|
||||
def installable_cores(selection: BuildSelection, cores: list[str]) -> list[str]:
|
||||
"""Buildbot cores a board's RetroArch core downloader installs, beyond
|
||||
the cores the image builds.
|
||||
|
||||
The targets scraper names, per board, the RetroArch targets entry its
|
||||
downloader reads (`downloads`): a Batocera x86_64 board installs any
|
||||
core of linux-x86_64, an armv7 one any of linux-armhf.
|
||||
"""
|
||||
found: set[str] = set()
|
||||
for entry in selection.targets.values():
|
||||
if entry.get("downloads"):
|
||||
found |= load_target_config("retroarch", entry["downloads"]) or set()
|
||||
return sorted(found - set(cores))
|
||||
|
||||
|
||||
def records_run(launchers: list[dict], built: Callable[[str], bool]) -> list[dict]:
|
||||
"""The launcher records of emulators the build runs.
|
||||
|
||||
configgen keeps the generators of emulators a build does not select
|
||||
(KNULLI's citron, pcsx2, shadps4): what they read is never read on the
|
||||
device, so the records do not describe the platform.
|
||||
"""
|
||||
return [r for r in launchers if any(built(n) for n in str(r["emulator"]).split(", "))]
|
||||
|
||||
|
||||
class Scraper(BaseScraper):
|
||||
@@ -578,20 +590,13 @@ class Scraper(BaseScraper):
|
||||
super().__init__(url=SOURCE_URL.format(tag=self.tag))
|
||||
|
||||
def _fetch_cores(
|
||||
self, launchers: list[dict] | None = None
|
||||
self, built: Callable[[str], bool] | None = None
|
||||
) -> tuple[list[str], list[str], list[str]]:
|
||||
"""Core names, standalone cores and dual-mode cores at the pinned tag.
|
||||
|
||||
A default es_systems.yml does not offer counts when a package of
|
||||
Batocera's tree or its buildroot builds it, or when its launcher
|
||||
runs a program from the BIOS folder.
|
||||
With `built` (boards_build), a name counts when some board builds
|
||||
it or its launcher runs a program from the BIOS folder.
|
||||
"""
|
||||
built = None
|
||||
if launchers is not None:
|
||||
paths = repo_tree(BATOCERA_REPO, self.tag)
|
||||
buildroot = submodule_revision(BATOCERA_REPO, "buildroot", self.tag)
|
||||
paths += repo_tree("batocera-linux/buildroot", buildroot)
|
||||
built = packages_and_programs(package_names(paths), launchers)
|
||||
return configgen_cores(
|
||||
self._fetch_text(CONFIGGEN_DEFAULTS_URL.format(tag=self.tag)),
|
||||
self._fetch_text(ES_SYSTEMS_URL.format(tag=self.tag)),
|
||||
@@ -633,7 +638,11 @@ class Scraper(BaseScraper):
|
||||
launchers = extract_launchers(
|
||||
lambda path: self._fetch_text(f"{_RAW_BASE}/{self.tag}/{path}")
|
||||
)
|
||||
cores, standalone, dual = self._fetch_cores(launchers)
|
||||
selection = BoardTargets().build_selection(self.tag)
|
||||
built = boards_build(selection, launchers)
|
||||
launchers = records_run(launchers, built)
|
||||
cores, standalone, dual = self._fetch_cores(built)
|
||||
installable = installable_cores(selection, cores)
|
||||
libretro_systems = es_systems_libretro_systems(
|
||||
self._fetch_text(ES_SYSTEMS_URL.format(tag=self.tag)), _not_cores()
|
||||
)
|
||||
@@ -653,6 +662,8 @@ class Scraper(BaseScraper):
|
||||
if dual:
|
||||
# Launched both ways: each layout gets its files.
|
||||
result["dual_mode_cores"] = dual
|
||||
if installable:
|
||||
result["installable_cores"] = installable
|
||||
# The systems each libretro core runs for: its save folders.
|
||||
result["libretro_systems"] = libretro_systems
|
||||
result["launchers"] = launchers
|
||||
|
||||
@@ -209,7 +209,18 @@ class Scraper(BaseScraper):
|
||||
)
|
||||
not_cores = _not_cores(PLATFORM_NAME)
|
||||
cores, standalone, dual = es_cores(es_systems, RUNNERS, BUILDS_OF, not_cores)
|
||||
# Each system keeps the list es_systems.json gives it: it says whose
|
||||
# files a platform entry asks for. What runs is what an image carries.
|
||||
attach_system_cores(systems, system_cores(es_systems, RUNNERS, not_cores))
|
||||
built = self._built()
|
||||
unbuilt = {n for n in cores if n not in built}
|
||||
cores, standalone, dual = ([n for n in names if n in built] for names in (cores, standalone, dual))
|
||||
# Runners (retroarch, retrorun) and the launcher's own spellings are
|
||||
# no ES core name: only a record of an emulator no image carries goes.
|
||||
launchers = [
|
||||
r for r in extract_launchers(RepoTree.github(REPO, launcher_revision(self.url)))
|
||||
if not set(str(r["emulator"]).split(", ")) <= unbuilt
|
||||
]
|
||||
return {
|
||||
"platform": "EmuELEC",
|
||||
"version": self.tag.removeprefix("v"),
|
||||
@@ -225,12 +236,26 @@ class Scraper(BaseScraper):
|
||||
"standalone_cores": standalone,
|
||||
"dual_mode_cores": dual,
|
||||
"systems": systems,
|
||||
# Read at the revision the BIOS list comes from.
|
||||
"launchers": extract_launchers(
|
||||
RepoTree.github(REPO, launcher_revision(self.url))
|
||||
),
|
||||
# Read at the revision the BIOS list comes from, for the
|
||||
# emulators an image carries.
|
||||
"launchers": launchers,
|
||||
}
|
||||
|
||||
def _built(self) -> set[str]:
|
||||
"""The cores at least one released device image carries.
|
||||
|
||||
Read by the targets scraper: a device keeps a core when a package it
|
||||
builds installs it and its es_systems.cfg still offers it. The port
|
||||
engines depend on emuelec-ports, which no package of an image
|
||||
depends on, and flycast-dojo is in no device list (UNBUILT there).
|
||||
"""
|
||||
try:
|
||||
from .targets.emuelec_targets_scraper import Scraper as DeviceTargets
|
||||
except ImportError:
|
||||
from scraper.targets.emuelec_targets_scraper import Scraper as DeviceTargets
|
||||
targets = DeviceTargets().device_targets(self.tag)["targets"]
|
||||
return {name for entry in targets.values() for name in entry["cores"]}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from .base_scraper import scraper_cli
|
||||
|
||||
@@ -37,18 +37,18 @@ from .batocera_scraper import (
|
||||
)
|
||||
from .batocera_scraper import (
|
||||
_not_cores,
|
||||
boards_build,
|
||||
configgen_cores,
|
||||
es_systems_by_system,
|
||||
es_systems_libretro_systems,
|
||||
extract_systems_dict,
|
||||
package_names,
|
||||
packages_and_programs,
|
||||
installable_cores,
|
||||
platform_systems,
|
||||
repo_tree,
|
||||
records_run,
|
||||
requirements_from_systems,
|
||||
submodule_revision,
|
||||
)
|
||||
from .es_emulators import attach_system_cores
|
||||
from .targets.knulli_targets_scraper import Scraper as BoardTargets
|
||||
from .batocera_launchers import configs_root
|
||||
from .knulli_launchers import BATOCERA_SUBMODULE, extract_launchers
|
||||
from .knulli_launchers import configgen as knulli_configgen
|
||||
@@ -134,16 +134,14 @@ class Scraper(BaseScraper):
|
||||
lambda path: self._fetch_text(_RAW.format(ref=self.tag) + path),
|
||||
lambda path: self._fetch_text(_BATOCERA_RAW.format(ref=revision) + path),
|
||||
)
|
||||
# The packages KNULLI builds come from its own tree, its batocera
|
||||
# submodule and its buildroot submodule: a default no package of
|
||||
# them builds (suyu) is not run.
|
||||
paths = repo_tree(REPO, self.tag)
|
||||
paths += repo_tree("batocera-linux/batocera.linux", revision)
|
||||
paths += repo_tree(
|
||||
"knulli-cfw/buildroot", submodule_revision(REPO, "buildroot", self.tag)
|
||||
)
|
||||
built = packages_and_programs(package_names(paths), launchers)
|
||||
# What runs is what at least one board builds, read by the targets
|
||||
# scraper from the Kconfig of KNULLI's tree and its batocera and
|
||||
# buildroot submodules (boards_build).
|
||||
selection = BoardTargets().build_selection(self.tag)
|
||||
built = boards_build(selection, launchers)
|
||||
launchers = records_run(launchers, built)
|
||||
cores, standalone, dual = configgen_cores(defaults, es_systems, dropped, built)
|
||||
installable = installable_cores(selection, cores)
|
||||
# Each system's own list (psx, es_systems.yml:640-653: libretro
|
||||
# pcsx_rearmed, swanstation, mednafen_psx, then duckstation and
|
||||
# duckstation-legacy).
|
||||
@@ -165,6 +163,8 @@ class Scraper(BaseScraper):
|
||||
result["standalone_cores"] = standalone
|
||||
if dual:
|
||||
result["dual_mode_cores"] = dual
|
||||
if installable:
|
||||
result["installable_cores"] = installable
|
||||
# configgen hands a libretro core /userdata/saves/<system>, as
|
||||
# Batocera's does: the systems each core runs for are its save folders.
|
||||
result["libretro_systems"] = es_systems_libretro_systems(es_systems, dropped)
|
||||
|
||||
@@ -190,6 +190,25 @@ class Scraper(BaseScraper):
|
||||
self.tag = None if url else fetch_github_latest_version(GITHUB_REPO)
|
||||
super().__init__(url=url or SOURCE_TEMPLATE.format(ref=self.tag))
|
||||
|
||||
def _built_cores(self, standalone: list[str]) -> tuple[list[str], list[str]]:
|
||||
"""(cores, standalone cores) at least one device image carries.
|
||||
|
||||
RetroArch runs the libretro cores the packages of its emulators
|
||||
metapackage install per device
|
||||
(projects/ROCKNIX/packages/virtual/emulators/package.mk), read by
|
||||
the targets scraper, where every libretro profile counted before. A
|
||||
standalone package no device carries is not run either.
|
||||
"""
|
||||
try:
|
||||
from .targets.rocknix_targets_scraper import Scraper as DeviceTargets
|
||||
except ImportError:
|
||||
from scraper.targets.rocknix_targets_scraper import Scraper as DeviceTargets
|
||||
builds = DeviceTargets().device_builds(self.tag or launcher_revision(self.url))
|
||||
libretro = sorted({core for _arch, lr, _sa in builds.values() for core in lr})
|
||||
carried = set(standalone_emulators(sorted({p for *_rest, sa in builds.values() for p in sa})))
|
||||
standalone = [name for name in standalone if name in carried]
|
||||
return sorted({*libretro, *standalone}), standalone
|
||||
|
||||
def _fetch_standalone(self) -> list[str]:
|
||||
"""The packages of projects/ROCKNIX/packages/emulators/standalone."""
|
||||
import json
|
||||
@@ -281,7 +300,7 @@ class Scraper(BaseScraper):
|
||||
)
|
||||
entry["files"].append(requirement_entry(req))
|
||||
|
||||
standalone = self._fetch_standalone()
|
||||
cores, standalone = self._built_cores(self._fetch_standalone())
|
||||
return {
|
||||
"platform": "ROCKNIX",
|
||||
"version": self.tag or fetch_github_latest_version(GITHUB_REPO),
|
||||
@@ -290,9 +309,7 @@ class Scraper(BaseScraper):
|
||||
"base_destination": "bios",
|
||||
"hash_type": "md5",
|
||||
"verification_mode": "md5",
|
||||
# RetroArch with every libretro core, plus the standalone
|
||||
# emulators ROCKNIX packages beside it.
|
||||
"cores": ["retroarch", *standalone],
|
||||
"cores": cores,
|
||||
"standalone_cores": standalone,
|
||||
# Launched both ways only where package.mk also adds the
|
||||
# emulator as a RetroArch core.
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Sources (batocera-linux/batocera.linux):
|
||||
- configs/batocera-*.board -- board definitions, each sets BR2_PACKAGE_BATOCERA_TARGET_*
|
||||
- package/batocera/core/batocera-system/Config.in -- select PACKAGE if CONDITION lines
|
||||
- Config.in and every Kconfig file it sources -- the selects a package
|
||||
declares itself (advanced_drastic selects drastic)
|
||||
- package/batocera/emulationstation/batocera-es-system/es_systems.yml
|
||||
-- emulator requireAnyOf flag mapping
|
||||
Sources (batocera-linux/buildroot, at the submodule commit the tag pins):
|
||||
@@ -19,6 +21,8 @@ import re
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import yaml
|
||||
@@ -79,6 +83,16 @@ def _fetch(url: str, headers: dict | None = None) -> str:
|
||||
raise RuntimeError(f"cannot fetch {url}: {e}") from e
|
||||
|
||||
|
||||
def _fetch_present(url: str) -> str | None:
|
||||
"""A file's text, or None when the server answers that it does not exist."""
|
||||
try:
|
||||
return _fetch(url)
|
||||
except RuntimeError as e:
|
||||
if isinstance(e.__cause__, urllib.error.HTTPError) and e.__cause__.code == 404:
|
||||
return None
|
||||
raise
|
||||
|
||||
|
||||
def _fetch_json(url: str) -> list | dict:
|
||||
text = _fetch(url, headers=github_headers())
|
||||
try:
|
||||
@@ -205,11 +219,14 @@ def _parse_meta_flags(text: str) -> list[tuple[str, str]]:
|
||||
# ("select BR2_PACKAGE_XROAR if BR2_PACKAGE_HAS_LIBGL") reached no board.
|
||||
BUILDROOT_KCONFIG = (
|
||||
"arch/Config.in",
|
||||
# Each armv7-A CPU selects BR2_ARM_CPU_ARMV7A (cortex_a15_a7 included).
|
||||
"arch/Config.in.arm",
|
||||
"package/mesa3d/Config.in",
|
||||
"package/libglvnd/Config.in",
|
||||
)
|
||||
|
||||
_CONFIG_LINE_RE = re.compile(r"^\s*(?:menu)?config\s+(BR2_\w+)")
|
||||
_SOURCE_RE = re.compile(r'^\s*source\s+"\$BR2_EXTERNAL_\w+_PATH/([^"]+)"')
|
||||
_OWNED_SELECT_RE = re.compile(r"^\s+select\s+(BR2_\w+)(?:\s+if\s+([^#]+))?")
|
||||
_BOARD_FLAG_RE = re.compile(r"^(BR2_\w+)=y\s*$", re.MULTILINE)
|
||||
_BOARD_INCLUDE_RE = re.compile(r"^(-?)include\s+(\S+)", re.MULTILINE)
|
||||
@@ -315,6 +332,51 @@ def _parse_es_systems(text: str) -> dict[str, list[str]]:
|
||||
return package_to_emulators
|
||||
|
||||
|
||||
# RetroArch's core downloader fetches from DEFAULT_BUILDBOT_SERVER_URL, which
|
||||
# Linux sets for x86_64, i386 and armv7 hard-float alone, and leaves empty on
|
||||
# aarch64 (config.def.h:1855-1864 at Batocera's 4b74434 and at v1.22.2).
|
||||
def buildbot_target(symbols: set[str] | frozenset[str]) -> str | None:
|
||||
"""The RetroArch targets entry a board's core downloader installs from.
|
||||
|
||||
`symbols` are the board's active symbols. An armv7-A CPU selects
|
||||
BR2_ARM_CPU_ARMV7A (arch/Config.in.arm) and is hard-float unless the
|
||||
board asks for soft-float (BR2_ARM_EABI): Buildroot picks EABIHF for a
|
||||
CPU with a VFP, which every Cortex-A has. armv6 (bcm2835), aarch64 and
|
||||
riscv64 get no buildbot URL.
|
||||
"""
|
||||
if "BR2_x86_64" in symbols:
|
||||
return "linux-x86_64"
|
||||
if "BR2_i386" in symbols:
|
||||
return "linux-x86"
|
||||
if "BR2_ARM_CPU_ARMV7A" in symbols and "BR2_ARM_EABI" not in symbols:
|
||||
return "linux-armhf"
|
||||
return None
|
||||
|
||||
|
||||
# configure options and make variables that compile the downloader out.
|
||||
_NO_DOWNLOADER = ("--disable-update-cores", "--disable-online-updater", "--disable-networking",
|
||||
"HAVE_UPDATE_CORES=0", "HAVE_ONLINE_UPDATER=0", "HAVE_LAKKA=1")
|
||||
_BLANK_CORES_URL = re.compile(r'^\s*core_updater_buildbot_cores_url\s*=\s*""', re.MULTILINE)
|
||||
|
||||
|
||||
def downloader_disabled(retroarch_mk: str, shipped_cfgs: dict[str, str]) -> str | None:
|
||||
"""Why RetroArch's core downloader installs nothing, or None.
|
||||
|
||||
Compiled out by its build options, or left without a URL by a shipped
|
||||
retroarch.cfg. A config that hides the menu entry alone does not stop
|
||||
it: without HAVE_LAKKA, Settings > User Interface offers it back
|
||||
(menu_setting.c). A config that blanks the URL for some boards only is
|
||||
a case this reader does not split, and an error.
|
||||
"""
|
||||
for option in _NO_DOWNLOADER:
|
||||
if option in retroarch_mk:
|
||||
return f"retroarch.mk sets {option}"
|
||||
blank = sorted(path for path, text in shipped_cfgs.items() if _BLANK_CORES_URL.search(text))
|
||||
if blank:
|
||||
raise RuntimeError(f"{', '.join(blank)} blank the core downloader URL: split per board")
|
||||
return None
|
||||
|
||||
|
||||
# Buildroot's architecture choice, as a board sets it (arch/Config.in).
|
||||
_ARCH_SYMBOLS = {
|
||||
"BR2_aarch64": "aarch64",
|
||||
@@ -342,6 +404,44 @@ def _arch_from_flag(flag: str, board_flags: set[str] | frozenset[str] = frozense
|
||||
return "aarch64"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BuildSelection:
|
||||
"""What the boards of a build turn on, read once from its Kconfig.
|
||||
|
||||
`targets` is each board's entry of the targets file, `downloads` naming
|
||||
the RetroArch targets entry its core downloader installs from. `emulators` holds
|
||||
every es_systems name some board builds and `listed` every name
|
||||
es_systems ties to a package, `symbols` every symbol some board ends up
|
||||
with, and `packages` the config symbol each package folder of the tree
|
||||
defines.
|
||||
"""
|
||||
|
||||
targets: dict[str, dict]
|
||||
emulators: frozenset[str]
|
||||
listed: frozenset[str]
|
||||
symbols: frozenset[str]
|
||||
packages: dict[str, str]
|
||||
|
||||
|
||||
def _sourced(text: str) -> list[str]:
|
||||
"""The files a Kconfig file sources, relative to the external tree."""
|
||||
return [m.group(1) for line in text.splitlines() if (m := _SOURCE_RE.match(line))]
|
||||
|
||||
|
||||
def _package_symbols(files: dict[str, str]) -> dict[str, str]:
|
||||
"""package folder -> the first config symbol its Config.in defines."""
|
||||
found: dict[str, str] = {}
|
||||
for path, text in files.items():
|
||||
parts = path.split("/")
|
||||
if len(parts) < 3 or parts[-1] != "Config.in" or "package" not in parts:
|
||||
continue
|
||||
config = next((m.group(1) for line in text.splitlines()
|
||||
if (m := _CONFIG_LINE_RE.match(line))), None)
|
||||
if config:
|
||||
found.setdefault(parts[-2], config)
|
||||
return found
|
||||
|
||||
|
||||
class Scraper(BaseTargetScraper):
|
||||
"""Cross-references Batocera boards, Config.in, and es_systems to build target lists.
|
||||
|
||||
@@ -357,6 +457,10 @@ class Scraper(BaseTargetScraper):
|
||||
ES_SYSTEMS_PATH = "package/batocera/emulationstation/batocera-es-system/es_systems.yml"
|
||||
SYSTEM_SYMBOL = "BR2_PACKAGE_BATOCERA_SYSTEM"
|
||||
BUILDROOT_REPO = "batocera-linux/buildroot"
|
||||
# Path prefix -> repository of a submodule the root Config.in sources
|
||||
# from: KNULLI reads Batocera's packages as batocera/package/...
|
||||
SUBMODULES: dict[str, str] = {}
|
||||
RETROARCH_MK = "package/batocera/emulators/retroarch/retroarch/retroarch.mk"
|
||||
|
||||
def __init__(self, url: str = "") -> None:
|
||||
super().__init__(url=url or f"https://github.com/{self.REPO}")
|
||||
@@ -411,6 +515,62 @@ class Scraper(BaseTargetScraper):
|
||||
pending += [(inc, bool(dash)) for dash, inc in _BOARD_INCLUDE_RE.findall(text)]
|
||||
return target, flags
|
||||
|
||||
def _kconfig_files(self) -> dict[str, str]:
|
||||
"""The root Config.in and every file it sources, recursively.
|
||||
|
||||
The build reads these and nothing else: a package's own Config.in
|
||||
can select another package (advanced_drastic selects drastic), and
|
||||
such a select sits in no system Config.in. A sourced file absent at
|
||||
the pin defines nothing and is named: KNULLI 20260511 sources
|
||||
package/utils/vtree/Config.in, a package its tree gained later.
|
||||
"""
|
||||
bases: list[tuple[str, str]] = []
|
||||
for prefix, repo in self.SUBMODULES.items():
|
||||
pin = _fetch_json(self._api(prefix.rstrip("/")))
|
||||
sha = pin.get("sha") if isinstance(pin, dict) else None
|
||||
if not sha:
|
||||
raise RuntimeError(f"no {prefix.rstrip('/')} submodule commit at {self.tag}")
|
||||
bases.append((prefix, f"https://raw.githubusercontent.com/{repo}/{sha}/"))
|
||||
|
||||
def url(path: str) -> str:
|
||||
for prefix, base in bases:
|
||||
if path.startswith(prefix):
|
||||
return base + path.removeprefix(prefix)
|
||||
return self._raw(path)
|
||||
|
||||
files: dict[str, str] = {}
|
||||
absent: list[str] = []
|
||||
pending = ["Config.in"]
|
||||
with ThreadPoolExecutor(max_workers=8) as pool:
|
||||
while pending:
|
||||
found = dict(zip(pending, pool.map(lambda path: _fetch_present(url(path)), pending)))
|
||||
absent += [path for path, text in found.items() if text is None]
|
||||
files.update((path, text or "") for path, text in found.items())
|
||||
pending = sorted({src for text in found.values() if text
|
||||
for src in _sourced(text)} - set(files))
|
||||
if "Config.in" in absent or len(files) - len(absent) < 2:
|
||||
raise RuntimeError(f"Config.in at {self.tag} sources no readable Kconfig file")
|
||||
for path in absent:
|
||||
print(f" sourced but absent at {self.tag}: {path}", file=sys.stderr)
|
||||
return files
|
||||
|
||||
def _shipped_retroarch_cfgs(self) -> dict[str, str]:
|
||||
"""Every retroarch.cfg the tree ships, its submodules included."""
|
||||
repos = [("", self.REPO, self.tag)]
|
||||
for prefix, repo in self.SUBMODULES.items():
|
||||
pin = _fetch_json(self._api(prefix.rstrip("/")))
|
||||
repos.append((prefix, repo, pin["sha"]))
|
||||
found: dict[str, str] = {}
|
||||
for prefix, repo, ref in repos:
|
||||
listing = _fetch_json(f"https://api.github.com/repos/{repo}/git/trees/{ref}?recursive=1")
|
||||
if not isinstance(listing, dict) or listing.get("truncated"):
|
||||
raise RuntimeError(f"{repo} tree at {ref} is unreadable or truncated")
|
||||
for entry in listing.get("tree", []):
|
||||
if re.search(r"(^|/)retroarch\.cfg$", entry["path"]):
|
||||
raw = f"https://raw.githubusercontent.com/{repo}/{ref}/{entry['path']}"
|
||||
found[prefix + entry["path"]] = _fetch(raw)
|
||||
return found
|
||||
|
||||
def _buildroot_rules(self) -> list[tuple[str, str, str]]:
|
||||
"""Buildroot's selects for the symbols the tree tests, at its pin."""
|
||||
pin = _fetch_json(self._api("buildroot"))
|
||||
@@ -423,26 +583,32 @@ class Scraper(BaseTargetScraper):
|
||||
rules += _parse_owned_selects(_fetch(f"{raw}/{path}"))
|
||||
return rules
|
||||
|
||||
def fetch_targets(self) -> dict:
|
||||
"""Build per-board emulator availability map."""
|
||||
self.tag = self.pinned_revision(self.PLATFORM)
|
||||
def build_selection(self, tag: str | None = None) -> BuildSelection:
|
||||
"""Each board's selection, from the Kconfig the build reads.
|
||||
|
||||
`tag` is the revision to read, by default the one the platform's
|
||||
YAML was scraped at: a platform scraper moving to a new release
|
||||
passes its own.
|
||||
"""
|
||||
self.tag = tag or self.pinned_revision(self.PLATFORM)
|
||||
print(" fetching board list...", file=sys.stderr)
|
||||
boards = self._list_boards()
|
||||
|
||||
print(" fetching Config.in...", file=sys.stderr)
|
||||
config_in_url = self._raw(self.CONFIG_IN_PATH)
|
||||
config_in_text = _fetch(config_in_url)
|
||||
print(" fetching Kconfig files...", file=sys.stderr)
|
||||
files = self._kconfig_files()
|
||||
config_in_text = files.get(self.CONFIG_IN_PATH)
|
||||
if not config_in_text:
|
||||
raise RuntimeError(f"empty Config.in from {config_in_url}")
|
||||
raise RuntimeError(f"Config.in at {self.tag} does not source {self.CONFIG_IN_PATH}")
|
||||
|
||||
meta_rules = _parse_meta_flags(config_in_text)
|
||||
rules = _parse_owned_selects(config_in_text)
|
||||
rules = [rule for text in files.values() for rule in _parse_owned_selects(text)]
|
||||
print(
|
||||
f" parsed {len(meta_rules)} meta-flag rules, {len(rules)} select lines",
|
||||
f" parsed {len(meta_rules)} meta-flag rules, {len(rules)} select lines "
|
||||
f"in {len(files)} Kconfig files",
|
||||
file=sys.stderr,
|
||||
)
|
||||
if not rules:
|
||||
raise RuntimeError(f"no 'select BR2_PACKAGE_*' lines parsed from {config_in_url}")
|
||||
if not _parse_owned_selects(config_in_text):
|
||||
raise RuntimeError(f"no 'select BR2_PACKAGE_*' lines parsed from {self.CONFIG_IN_PATH}")
|
||||
rules += self._buildroot_rules()
|
||||
|
||||
print(" fetching es_systems.yml...", file=sys.stderr)
|
||||
@@ -459,9 +625,14 @@ class Scraper(BaseTargetScraper):
|
||||
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}")
|
||||
raise RuntimeError(f"no target image list parsed from {self.CONFIG_IN_PATH}")
|
||||
disabled = downloader_disabled(_fetch(self._raw(self.RETROARCH_MK)),
|
||||
self._shipped_retroarch_cfgs())
|
||||
if disabled:
|
||||
print(f" core downloader off: {disabled}", file=sys.stderr)
|
||||
|
||||
targets: dict[str, dict] = {}
|
||||
symbols: set[str] = set()
|
||||
for board_name in sorted(boards):
|
||||
target_key = board_name.removeprefix(self.BOARD_PREFIX).removesuffix(".board")
|
||||
print(f" processing {target_key}...", file=sys.stderr)
|
||||
@@ -476,6 +647,7 @@ class Scraper(BaseTargetScraper):
|
||||
if self.SYSTEM_SYMBOL not in selected_packages:
|
||||
print(f" {board_name} builds no system image", file=sys.stderr)
|
||||
continue
|
||||
symbols |= selected_packages
|
||||
|
||||
# Map selected packages to emulator names via es_systems.yml
|
||||
emulators: set[str] = set()
|
||||
@@ -491,16 +663,30 @@ class Scraper(BaseTargetScraper):
|
||||
images = sorted(set(images_by_flag.get(primary_flag, [])))
|
||||
if images and images != [target_key]:
|
||||
targets[target_key]["images"] = images
|
||||
downloads = None if disabled else buildbot_target(selected_packages)
|
||||
if downloads:
|
||||
targets[target_key]["downloads"] = downloads
|
||||
print(
|
||||
f" {len(emulators)} emulators ({len(selected_packages)} packages selected)",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
return BuildSelection(
|
||||
targets=targets,
|
||||
emulators=frozenset(c for entry in targets.values() for c in entry["cores"]),
|
||||
listed=frozenset(n for names in package_to_emulators.values() for n in names),
|
||||
symbols=frozenset(symbols),
|
||||
packages=_package_symbols(files),
|
||||
)
|
||||
|
||||
def fetch_targets(self) -> dict:
|
||||
"""Build per-board emulator availability map."""
|
||||
selection = self.build_selection()
|
||||
return {
|
||||
"platform": self.PLATFORM,
|
||||
"source": f"{self.url}/tree/{self.tag}",
|
||||
"scraped_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"targets": targets,
|
||||
"targets": selection.targets,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -610,7 +610,12 @@ class Scraper(BaseTargetScraper):
|
||||
return fetch_bytes(RAW.format(ref=self.ref, path=path)).decode("utf-8")
|
||||
|
||||
def fetch_targets(self) -> dict:
|
||||
self.ref = self.pinned_revision(PLATFORM_NAME)
|
||||
return self.device_targets()
|
||||
|
||||
def device_targets(self, ref: str | None = None) -> dict:
|
||||
"""The targets file, read at `ref`, by default the revision
|
||||
platforms/emuelec.yml was scraped at."""
|
||||
self.ref = ref or self.pinned_revision(PLATFORM_NAME)
|
||||
release = json.loads(
|
||||
fetch_bytes(RELEASE_API.format(ref=self.ref), headers=github_headers())
|
||||
)
|
||||
|
||||
@@ -9,6 +9,8 @@ the tag platforms/knulli.yml names):
|
||||
the root Config.in in place of Batocera's batocera-system/Config.in
|
||||
- package/emulationstation/knulli-es-system/es_systems.yml
|
||||
-- emulator requireAnyOf flag mapping
|
||||
- Config.in and what it sources, Batocera's packages read from the
|
||||
batocera submodule at the commit the tag pins
|
||||
Sources (knulli-cfw/buildroot, at the submodule commit the tag pins):
|
||||
- arch/Config.in, package/mesa3d/Config.in, package/libglvnd/Config.in
|
||||
|
||||
@@ -32,6 +34,8 @@ class Scraper(BatoceraScraper):
|
||||
ES_SYSTEMS_PATH = "package/emulationstation/knulli-es-system/es_systems.yml"
|
||||
SYSTEM_SYMBOL = "BR2_PACKAGE_KNULLI_SYSTEM"
|
||||
BUILDROOT_REPO = "knulli-cfw/buildroot"
|
||||
SUBMODULES = {"batocera/": "batocera-linux/batocera.linux"}
|
||||
RETROARCH_MK = "package/retroarch/retroarch/retroarch.mk"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
@@ -5,6 +5,8 @@ Sources (ROCKNIX/distribution, at the release tag platforms/rocknix.yml names):
|
||||
image carries, those aarch64 adds, and a `case "${DEVICE}"` block per SoC
|
||||
- projects/ROCKNIX/devices/<DEVICE>/options -- ENABLE_32BIT, which the 32-bit
|
||||
cores of a device depend on (distributions/ROCKNIX/options defaults it on)
|
||||
- each libretro package's package.mk -- the cores its makeinstall_target
|
||||
copies to ${INSTALL}/usr/lib/libretro (vice-lr installs ten of them)
|
||||
|
||||
An H700 or RK3326 handheld carries neither Dolphin nor AetherSX2: without a
|
||||
target list, its pack shipped the PS2, GameCube and PS3 firmware anyway.
|
||||
@@ -13,6 +15,7 @@ target list, its pack shipped the PS2, GameCube and PS3 firmware anyway.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
@@ -89,18 +92,90 @@ def parse_device_cores(
|
||||
return libretro, standalone
|
||||
|
||||
|
||||
def core_names(libretro: list[str], standalone: list[str]) -> list[str]:
|
||||
"""Package names as the profiles' cores: lists spell them.
|
||||
_INSTALL_BODY_RE = re.compile(r"^makeinstall_target\(\)\s*\{\n(.*?)^\}", re.M | re.S)
|
||||
_COPY_RE = re.compile(r"\bcp\s+(.*?)\s+\$\{?INSTALL\}?/usr/lib/libretro(?:/(\S*))?")
|
||||
_CORE_FILE_RE = re.compile(r"([\w+.-]+)_libretro\.(?:so\b|\{[^}]*\bso\b[^}]*\})")
|
||||
_TEST_RE = re.compile(r'\[\s*"\$\{(\w+)\}"\s*=\s*"([^"]*)"\s*\]')
|
||||
|
||||
A libretro package is the core's name with `-lr` (`beetle-psx-lr`,
|
||||
`neocd_lr`), spelled with underscores as the buildbot names it. A
|
||||
standalone package is kept under both spellings, as the platform
|
||||
scraper keeps it: `vice-sa` is the only name vice-standalone answers
|
||||
to, `vice` that of the libretro profile.
|
||||
|
||||
def installed_cores(package_mk: str, arch: str, with_32bit: bool) -> list[str]:
|
||||
"""The cores a libretro package installs on a device.
|
||||
|
||||
The name is that of the file makeinstall_target copies to
|
||||
${INSTALL}/usr/lib/libretro ($INSTALL in some), renamed when the copy names its target:
|
||||
beetle-psx-lr copies mednafen_psx_libretro.so as beetle_psx_libretro.so,
|
||||
vice-lr ten EMUTYPE builds. pcsx_rearmed-lr picks its file by
|
||||
TARGET_ARCH and adds the 32-bit build when ENABLE_32BIT is on, desmume-lr
|
||||
copies the 32-bit build on aarch64 (ARCH). A test on another variable,
|
||||
or a package that installs no core, is an error.
|
||||
"""
|
||||
names = {re.sub(r"[-_]lr$", "", package).replace("-", "_") for package in libretro}
|
||||
names.update(standalone_emulators(standalone))
|
||||
return sorted(names)
|
||||
body = _INSTALL_BODY_RE.search(package_mk)
|
||||
if body is None:
|
||||
raise RuntimeError("package.mk has no makeinstall_target")
|
||||
# config/options:36 sets TARGET_ARCH="${ARCH}".
|
||||
values = {"ARCH": arch, "TARGET_ARCH": arch, "ENABLE_32BIT": "true" if with_32bit else "false"}
|
||||
|
||||
def holds(condition: str) -> bool:
|
||||
tests = _TEST_RE.findall(condition)
|
||||
if not tests or re.sub(_TEST_RE, "", condition).strip(" ;&") not in ("", "then"):
|
||||
raise RuntimeError(f"makeinstall_target tests {condition.strip()!r}")
|
||||
for variable, value in tests:
|
||||
if variable not in values:
|
||||
raise RuntimeError(f"makeinstall_target tests ${{{variable}}}")
|
||||
if values[variable] != value:
|
||||
return False
|
||||
return True
|
||||
|
||||
found: list[str] = []
|
||||
stack: list[bool] = []
|
||||
in_case = False
|
||||
for raw in body.group(1).splitlines():
|
||||
line = raw.strip()
|
||||
if re.match(r"case \$\{TARGET_ARCH\} in$", line):
|
||||
in_case = True
|
||||
stack.append(False)
|
||||
continue
|
||||
if line == "esac":
|
||||
in_case = False
|
||||
stack.pop()
|
||||
continue
|
||||
if in_case and (arm := re.match(r"([\w|*]+)\)\s*(.*)$", line)):
|
||||
stack[-1] = arch in arm.group(1).split("|") or arm.group(1) == "*"
|
||||
line = arm.group(2)
|
||||
if line.startswith("if "):
|
||||
stack.append(holds(line[3:]))
|
||||
continue
|
||||
if line == "else":
|
||||
stack[-1] = not stack[-1]
|
||||
continue
|
||||
if line == "fi":
|
||||
stack.pop()
|
||||
continue
|
||||
if not all(stack):
|
||||
continue
|
||||
for sources, target in _COPY_RE.findall(line):
|
||||
if named := _CORE_FILE_RE.search(target):
|
||||
found.append(named.group(1))
|
||||
continue
|
||||
for source in sources.split():
|
||||
if not source.startswith("-") and (named := _CORE_FILE_RE.search(source.rsplit("/", 1)[-1])):
|
||||
found.append(named.group(1))
|
||||
if not found:
|
||||
raise RuntimeError("makeinstall_target installs no libretro core")
|
||||
return sorted(set(found))
|
||||
|
||||
|
||||
def package_paths(tree: list[str]) -> dict[str, str]:
|
||||
"""package name -> its package.mk, a ROCKNIX project package first.
|
||||
|
||||
The build takes projects/ROCKNIX/packages/<...>/<name> over
|
||||
packages/<...>/<name> when both exist.
|
||||
"""
|
||||
found: dict[str, str] = {}
|
||||
for path in sorted(tree, key=lambda p: not p.startswith("projects/ROCKNIX/")):
|
||||
if path.endswith("/package.mk"):
|
||||
found.setdefault(path.rsplit("/", 2)[-2], path)
|
||||
return found
|
||||
|
||||
|
||||
# A package that builds nothing itself and pulls other cores in. idtech-lr
|
||||
@@ -149,13 +224,40 @@ class Scraper(BaseTargetScraper):
|
||||
raise RuntimeError(f"no device in {DEVICES_DIR} at {self.tag}")
|
||||
return sorted(devices)
|
||||
|
||||
def fetch_targets(self) -> dict:
|
||||
self.tag = self.pinned_revision(PLATFORM_NAME)
|
||||
def _tree(self) -> list[str]:
|
||||
listing = json.loads(fetch_bytes(
|
||||
f"https://api.github.com/repos/ROCKNIX/distribution/git/trees/{self.tag}?recursive=1",
|
||||
headers=github_headers(),
|
||||
))
|
||||
if listing.get("truncated"):
|
||||
raise RuntimeError(f"ROCKNIX tree at {self.tag} is truncated")
|
||||
return [entry["path"] for entry in listing.get("tree", [])]
|
||||
|
||||
def device_builds(self, tag: str | None = None) -> dict[str, tuple[str, list[str], list[str]]]:
|
||||
"""{device: (architecture, libretro cores, standalone packages)}.
|
||||
|
||||
Read at `tag`, by default the revision platforms/rocknix.yml was
|
||||
scraped at: metapackages resolved to the packages they pull in, and
|
||||
each libretro package to the cores it installs on the device.
|
||||
"""
|
||||
self.tag = tag or self.pinned_revision(PLATFORM_NAME)
|
||||
package_mk = self._raw(EMULATORS_MK)
|
||||
if "LIBRETRO_CORES" not in package_mk:
|
||||
raise RuntimeError(f"no LIBRETRO_CORES in {EMULATORS_MK} at {self.tag}")
|
||||
paths = package_paths(self._tree())
|
||||
texts: dict[str, str] = {}
|
||||
|
||||
targets: dict[str, dict] = {}
|
||||
def cores_of(package: str, arch: str, with_32bit: bool) -> list[str]:
|
||||
if package not in paths:
|
||||
raise RuntimeError(f"no package.mk for {package} at {self.tag}")
|
||||
if package not in texts:
|
||||
texts[package] = self._raw(paths[package])
|
||||
try:
|
||||
return installed_cores(texts[package], arch, with_32bit)
|
||||
except RuntimeError as e:
|
||||
raise RuntimeError(f"{paths[package]}: {e}") from e
|
||||
|
||||
builds: dict[str, tuple[str, list[str], list[str]]] = {}
|
||||
for device in self._devices():
|
||||
options = self._raw(f"{DEVICES_DIR}/{device}/options")
|
||||
arch = "x86_64" if device == "AMD64" else "aarch64"
|
||||
@@ -165,9 +267,19 @@ class Scraper(BaseTargetScraper):
|
||||
if meta in libretro:
|
||||
libretro.remove(meta)
|
||||
libretro += metapackage_cores(self._raw(path), arch)
|
||||
cores = core_names(libretro, standalone)
|
||||
targets[device.lower()] = {"architecture": arch, "cores": cores}
|
||||
print(f" {device.lower()} ({arch}): {len(cores)} cores", file=sys.stderr)
|
||||
cores = sorted({c for package in libretro for c in cores_of(package, arch, with_32bit)})
|
||||
builds[device.lower()] = (arch, cores, standalone)
|
||||
return builds
|
||||
|
||||
def fetch_targets(self) -> dict:
|
||||
targets: dict[str, dict] = {}
|
||||
for device, (arch, libretro, standalone) in self.device_builds().items():
|
||||
# A standalone package is kept under both spellings, as the
|
||||
# platform scraper keeps it: vice-sa is the only name
|
||||
# vice-standalone answers to, vice that of the libretro profile.
|
||||
cores = sorted({*libretro, *standalone_emulators(standalone)})
|
||||
targets[device] = {"architecture": arch, "cores": cores}
|
||||
print(f" {device} ({arch}): {len(cores)} cores", file=sys.stderr)
|
||||
|
||||
return {
|
||||
"platform": PLATFORM_NAME,
|
||||
|
||||
@@ -284,7 +284,10 @@ class TheExportKeepsTheirShape(unittest.TestCase):
|
||||
|
||||
class TheCommittedListsAgree(unittest.TestCase):
|
||||
"""A system's cores are a part of the platform's: a name only the system
|
||||
carries would escape every reader of the platform list."""
|
||||
carries would escape every reader of the platform list. A system keeps
|
||||
the list its ES file writes, which says whose files its entries ask for,
|
||||
so the one name it may carry beyond the platform's is one no device
|
||||
image builds (EmuELEC's VVVVVV port engine, KNULLI's duckstation)."""
|
||||
|
||||
def test_system_cores_are_platform_cores(self):
|
||||
import yaml
|
||||
@@ -292,10 +295,14 @@ class TheCommittedListsAgree(unittest.TestCase):
|
||||
for name in ("amberelec", "emuelec", "knulli"):
|
||||
with self.subTest(platform=name):
|
||||
config = yaml.safe_load((REPO_ROOT / "platforms" / f"{name}.yml").read_text())
|
||||
targets = yaml.safe_load(
|
||||
(REPO_ROOT / "platforms" / "targets" / f"{name}.yml").read_text())["targets"]
|
||||
built = {c for entry in targets.values() for c in entry["cores"]}
|
||||
platform = {str(c) for c in config["cores"]}
|
||||
listed = {str(c) for s in config["systems"].values() for c in s.get("cores", [])}
|
||||
self.assertTrue(listed, "no system carries its cores")
|
||||
self.assertEqual(listed - platform, set())
|
||||
self.assertEqual(listed - platform - (listed - built), set())
|
||||
self.assertEqual(platform - built - {"lexaloffle", "mpv", "vox_official"}, set())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -207,6 +207,8 @@ class APlatformEntryTakesNoOtherEmulatorsTree(unittest.TestCase):
|
||||
|
||||
config = load_platform_config("emuelec", str(REPO_ROOT / "platforms"))
|
||||
entry = config["systems"]["vvvvvv"]["files"][0]
|
||||
# No image builds the VVVVVV port engine, but es_systems.json still
|
||||
# names it for the system: its tree is the one the entry asks for.
|
||||
self.assertEqual(entry["platform_cores"], ["VVVVVV"])
|
||||
db = load_database(str(REPO_ROOT / "database.json"))
|
||||
path, _status = resolve_local_file(
|
||||
|
||||
@@ -231,15 +231,20 @@ class APortableUserFolder(unittest.TestCase):
|
||||
|
||||
|
||||
|
||||
class ADefaultTheBuildLacksIsNotRun(unittest.TestCase):
|
||||
"""KNULLI's configgen-defaults.yml picks suyu for the Switch, which its
|
||||
es_systems.yml does not offer and no package builds."""
|
||||
class OnlyWhatABoardBuildsIsRun(unittest.TestCase):
|
||||
"""KNULLI's es_systems.yml lists citron and shadps4, which its Config.in
|
||||
selects only on x86_64 boards (it has none), and its
|
||||
configgen-defaults.yml picks suyu, which no package builds."""
|
||||
|
||||
ES = textwrap.dedent("""\
|
||||
switch:
|
||||
emulators:
|
||||
citron:
|
||||
citron: { requireAnyOf: [BR2_PACKAGE_CITRON] }
|
||||
gba:
|
||||
emulators:
|
||||
libretro:
|
||||
mgba: { requireAnyOf: [BR2_PACKAGE_LIBRETRO_MGBA] }
|
||||
voxatron:
|
||||
emulators: {}
|
||||
""")
|
||||
@@ -253,31 +258,67 @@ class ADefaultTheBuildLacksIsNotRun(unittest.TestCase):
|
||||
kodi:
|
||||
emulator: kodi
|
||||
core: kodi
|
||||
mpv:
|
||||
emulator: mpv
|
||||
core: mpv
|
||||
""")
|
||||
LAUNCHERS = [{"emulator": "lexaloffle", "kind": "fixed_name", "passes_to": "exec",
|
||||
"search_dir": "/userdata/bios"}]
|
||||
|
||||
def test_only_what_a_package_or_the_user_supplies_is_run(self):
|
||||
def selection(self, symbols: set[str]):
|
||||
from scraper.targets.batocera_targets_scraper import BuildSelection
|
||||
|
||||
return BuildSelection(
|
||||
targets={}, emulators=frozenset({"mgba"}),
|
||||
listed=frozenset({"citron", "mgba"}), symbols=frozenset(symbols),
|
||||
packages={"kodi": "BR2_PACKAGE_KODI"},
|
||||
)
|
||||
|
||||
def test_only_what_a_board_builds_or_the_user_supplies_is_run(self):
|
||||
from scraper import batocera_scraper as bs
|
||||
|
||||
paths = ["package/batocera/emulators/citron/Config.in", "package/kodi/Config.in"]
|
||||
built = bs.packages_and_programs(bs.package_names(paths), self.LAUNCHERS)
|
||||
# A board selects kodi's package and buildroot's mpv; citron is
|
||||
# listed by es_systems, so the symbol of a folder of that name does
|
||||
# not count for it.
|
||||
built = bs.boards_build(
|
||||
self.selection({"BR2_PACKAGE_KODI", "BR2_PACKAGE_MPV", "BR2_PACKAGE_CITRON_X"}),
|
||||
self.LAUNCHERS,
|
||||
)
|
||||
cores, standalone, _dual = bs.configgen_cores(self.DEFAULTS, self.ES, set(), built)
|
||||
self.assertEqual(sorted(cores), ["citron", "kodi", "vox_official"])
|
||||
self.assertIn("lexaloffle", standalone)
|
||||
self.assertNotIn("suyu", standalone)
|
||||
self.assertEqual(sorted(cores), ["kodi", "mgba", "mpv", "vox_official"])
|
||||
self.assertEqual(sorted(standalone), ["kodi", "lexaloffle", "mpv", "vox_official"])
|
||||
# Each system keeps the list es_systems.yml writes (whose files its
|
||||
# entries ask for), less a default no package builds.
|
||||
by_system = bs.es_systems_by_system(self.ES, self.DEFAULTS, set(), built)
|
||||
self.assertEqual(by_system["switch"], ["citron"])
|
||||
# Without the packages, every default counts, as before.
|
||||
self.assertEqual(by_system["voxatron"], ["lexaloffle", "vox_official"])
|
||||
self.assertEqual(by_system["gba"], ["mgba"])
|
||||
|
||||
def test_a_listed_name_is_built_only_through_its_packages(self):
|
||||
from scraper import batocera_scraper as bs
|
||||
|
||||
built = bs.boards_build(self.selection({"BR2_PACKAGE_CITRON"}), [])
|
||||
self.assertFalse(built("citron"))
|
||||
self.assertTrue(built("mgba"))
|
||||
self.assertFalse(built("lexaloffle"))
|
||||
# Without a selection, every name counts, as before.
|
||||
self.assertIn("suyu", bs.configgen_cores(self.DEFAULTS, self.ES, set())[0])
|
||||
|
||||
def test_the_real_knulli_list_names_no_suyu(self):
|
||||
def test_the_real_lists_name_only_what_a_board_builds(self):
|
||||
import yaml
|
||||
|
||||
config = yaml.safe_load((REPO_ROOT / "platforms" / "knulli.yml").read_text())
|
||||
self.assertNotIn("suyu", config["cores"])
|
||||
self.assertNotIn("suyu", config.get("standalone_cores") or [])
|
||||
|
||||
for platform, absent in (("knulli", ("suyu", "citron", "shadps4", "pcsx2")),
|
||||
("batocera", ("citron", "ryujinx", "applewin"))):
|
||||
config = yaml.safe_load((REPO_ROOT / "platforms" / f"{platform}.yml").read_text())
|
||||
names = set(config["cores"]) | set(config.get("standalone_cores") or [])
|
||||
targets = yaml.safe_load(
|
||||
(REPO_ROOT / "platforms" / "targets" / f"{platform}.yml").read_text())["targets"]
|
||||
boards = {c for entry in targets.values() for c in entry["cores"]}
|
||||
with self.subTest(platform=platform):
|
||||
self.assertFalse(names & set(absent))
|
||||
# What a board builds and the list once named is still there,
|
||||
# and what no board builds is a program the user supplies.
|
||||
self.assertLessEqual(names - boards, {"kodi", "lexaloffle", "mpv", "vox_official"})
|
||||
|
||||
|
||||
class AUserFolderInTheConfigsFolder(unittest.TestCase):
|
||||
@@ -289,7 +330,8 @@ class AUserFolderInTheConfigsFolder(unittest.TestCase):
|
||||
from common import standalone_set
|
||||
|
||||
profile = load_emulator_profiles(str(REPO_ROOT / "emulators"))["shadps4"]
|
||||
for platform in ("batocera", "knulli"):
|
||||
# KNULLI's generator does the same, but no KNULLI board builds shadps4.
|
||||
for platform in ("batocera",):
|
||||
config = load_platform_config(platform, str(REPO_ROOT / "platforms"))
|
||||
((view, _standalone),) = platform_layouts("shadps4", profile, standalone_set(config))
|
||||
with self.subTest(platform=platform):
|
||||
|
||||
@@ -639,8 +639,10 @@ class PlatformRecords(unittest.TestCase):
|
||||
cls.config = yaml.safe_load((REPO_ROOT / "platforms" / "rocknix.yml").read_text())
|
||||
|
||||
def test_every_emulator_is_one_rocknix_packages(self):
|
||||
# RetroArch itself runs the libretro cores the list names.
|
||||
cores = set(self.config["cores"])
|
||||
self.assertEqual(sorted({r["emulator"] for r in self.config["launchers"]} - cores), [])
|
||||
self.assertEqual(sorted({r["emulator"] for r in self.config["launchers"]} - cores),
|
||||
["retroarch"])
|
||||
|
||||
def test_every_reference_is_in_the_rocknix_project(self):
|
||||
for record in self.config["launchers"]:
|
||||
|
||||
@@ -480,7 +480,10 @@ class RocknixRunsItsStandaloneEmulators(unittest.TestCase):
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
platform = yaml.safe_load((root / "platforms" / "rocknix.yml").read_text())
|
||||
self.assertIn(f"/distribution/{platform['version']}/", platform["source"])
|
||||
self.assertIn("retroarch", platform["cores"])
|
||||
# RetroArch runs the libretro cores some device image installs, not
|
||||
# every libretro profile.
|
||||
self.assertNotIn("retroarch", platform["cores"])
|
||||
self.assertIn("beetle_psx", platform["cores"])
|
||||
registry = yaml.safe_load((root / "platforms" / "_registry.yml").read_text())
|
||||
self.assertNotIn("cores", registry["platforms"]["rocknix"])
|
||||
|
||||
|
||||
@@ -548,12 +548,12 @@ class OpenmsxOnEachPlatform(unittest.TestCase):
|
||||
"""openMSX finds system ROMs by SHA1 in share/systemroms below its user
|
||||
directory and in every filepool entry. RetroBat sets OPENMSX_HOME to
|
||||
bios/openmsx, RetroPie links share/systemroms of its user directory to
|
||||
BIOS/openmsx, Batocera and KNULLI add bios/Machines and bios/openmsx to
|
||||
the filepool and list their own files in bios/openmsx."""
|
||||
BIOS/openmsx, Batocera adds bios/Machines and bios/openmsx to the
|
||||
filepool and lists its own files in bios/openmsx. KNULLI's generator
|
||||
does the same, but no KNULLI board builds openmsx."""
|
||||
|
||||
EXPECTED = {
|
||||
"batocera": {"share/systemroms": ("", "openmsx")},
|
||||
"knulli": {"share/systemroms": ("", "openmsx")},
|
||||
"retrobat": {"": ("", "openmsx")},
|
||||
"retropie": {"share/systemroms": ("", "openmsx")},
|
||||
}
|
||||
|
||||
+142
-24
@@ -97,6 +97,13 @@ class FailedRequestsStopTheScrape(unittest.TestCase):
|
||||
_refuse()
|
||||
return _Body(b"BR2_PACKAGE_BATOCERA_TARGET_X86_64=y\n"
|
||||
b"BR2_PACKAGE_BATOCERA_SYSTEM=y\n")
|
||||
if "/git/trees/" in url:
|
||||
return _Body(b'{"tree": [], "truncated": false}')
|
||||
if url.endswith("retroarch.mk"):
|
||||
return _Body(b"RETROARCH_CONF_OPTS = --enable-networking\n")
|
||||
if url.startswith("https://raw.githubusercontent.com/") and url.count("/") == 6:
|
||||
return _Body(b'source "$BR2_EXTERNAL_BATOCERA_PATH/'
|
||||
b'package/batocera/core/batocera-system/Config.in"\n')
|
||||
if url.endswith("Config.in"):
|
||||
return _Body(b"config BR2_PACKAGE_BATOCERA_SYSTEM\n"
|
||||
b"\tselect BR2_PACKAGE_MGBA\n\n"
|
||||
@@ -240,6 +247,61 @@ class BatoceraDerivedFlags(unittest.TestCase):
|
||||
self.assertIn("BR2_PACKAGE_DUCKSTATION_LEGACY", r16)
|
||||
|
||||
|
||||
class CoreDownloaderReach(unittest.TestCase):
|
||||
"""Batocera and KNULLI build RetroArch with its core downloader, shown in
|
||||
the menu, and its compiled buildbot URL serves Linux x86_64, i386 and
|
||||
armv7 hard-float alone (config.def.h:743-749, 1855-1864): a board of
|
||||
those runs any core of the buildbot list, an aarch64 one none."""
|
||||
|
||||
def test_each_architecture_reads_its_buildbot_list(self):
|
||||
from scraper.targets.batocera_targets_scraper import buildbot_target # noqa: PLC0415
|
||||
|
||||
self.assertEqual(buildbot_target({"BR2_x86_64"}), "linux-x86_64")
|
||||
self.assertEqual(buildbot_target({"BR2_arm", "BR2_ARM_CPU_ARMV7A"}), "linux-armhf")
|
||||
self.assertIsNone(buildbot_target({"BR2_arm", "BR2_ARM_CPU_ARMV7A", "BR2_ARM_EABI"}))
|
||||
self.assertIsNone(buildbot_target({"BR2_arm", "BR2_arm1176jzf_s"}))
|
||||
self.assertIsNone(buildbot_target({"BR2_aarch64"}))
|
||||
|
||||
def test_a_build_or_a_blank_url_turns_it_off(self):
|
||||
from scraper.targets.batocera_targets_scraper import downloader_disabled # noqa: PLC0415
|
||||
|
||||
self.assertIsNone(downloader_disabled("--enable-networking", {
|
||||
"a/retroarch.cfg": 'menu_show_core_updater = "false"\n'}))
|
||||
self.assertIn("HAVE_LAKKA=1", downloader_disabled("make HAVE_LAKKA=1", {}))
|
||||
with self.assertRaises(RuntimeError):
|
||||
downloader_disabled("", {"a/retroarch.cfg": 'core_updater_buildbot_cores_url = ""\n'})
|
||||
|
||||
def test_a_board_that_downloads_gets_the_buildbot_list(self):
|
||||
from common import load_target_config # noqa: PLC0415
|
||||
|
||||
root = str(REPO_ROOT / "platforms")
|
||||
x86 = set(load_target_config("retroarch", "linux-x86_64", root) or ())
|
||||
armhf = set(load_target_config("retroarch", "linux-armhf", root) or ())
|
||||
self.assertLessEqual(x86, set(load_target_config("batocera", "x86_64", root) or ()))
|
||||
self.assertLessEqual(armhf, set(load_target_config("batocera", "rk3288", root) or ()))
|
||||
self.assertFalse(x86 <= set(load_target_config("batocera", "bcm2711", root) or ()))
|
||||
self.assertLessEqual(armhf, set(load_target_config("knulli", "r16", root) or ()))
|
||||
|
||||
def test_the_platform_names_what_its_boards_install(self):
|
||||
import yaml # noqa: PLC0415
|
||||
|
||||
from common import load_target_config # noqa: PLC0415
|
||||
|
||||
root = str(REPO_ROOT / "platforms")
|
||||
for platform in ("batocera", "knulli"):
|
||||
config = yaml.safe_load((REPO_ROOT / "platforms" / f"{platform}.yml").read_text())
|
||||
targets = yaml.safe_load(
|
||||
(REPO_ROOT / "platforms" / "targets" / f"{platform}.yml").read_text())["targets"]
|
||||
fetched = set()
|
||||
for entry in targets.values():
|
||||
if entry.get("downloads"):
|
||||
fetched |= load_target_config("retroarch", entry["downloads"], root) or set()
|
||||
if entry["architecture"] == "aarch64":
|
||||
self.assertNotIn("downloads", entry)
|
||||
with self.subTest(platform=platform):
|
||||
self.assertEqual(set(config["installable_cores"]), fetched - set(config["cores"]))
|
||||
|
||||
|
||||
class KnulliPerBoard(unittest.TestCase):
|
||||
"""KNULLI builds per board on Batocera's model from its own tree:
|
||||
configs/knulli-*.board, package/system/knulli-system/Config.in and
|
||||
@@ -254,7 +316,7 @@ class KnulliPerBoard(unittest.TestCase):
|
||||
"BR2_PACKAGE_BATOCERA_TARGET_H700=y\n"
|
||||
),
|
||||
"configs/knulli-r16.board": (
|
||||
"include knulli-board.common\n\nBR2_arm=y\n"
|
||||
"include knulli-board.common\n\nBR2_arm=y\nBR2_cortex_a7=y\n"
|
||||
"BR2_PACKAGE_BATOCERA_TARGET_SUNXI_R16=y\n"
|
||||
),
|
||||
"configs/knulli-h700_armhf_libs.board": (
|
||||
@@ -262,6 +324,15 @@ class KnulliPerBoard(unittest.TestCase):
|
||||
"BR2_arm=y\nBR2_PACKAGE_BATOCERA_TARGET_H700=y\n"
|
||||
),
|
||||
"configs/knulli-h700_armhf_libs.packages": "BR2_PACKAGE_SDL2=y\n",
|
||||
# The root Config.in sources KNULLI's system and Batocera's packages
|
||||
# from the batocera submodule, where a package selects another.
|
||||
"Config.in": (
|
||||
'source "$BR2_EXTERNAL_KNULLI_PATH/package/system/knulli-system/Config.in"\n'
|
||||
'source "$BR2_EXTERNAL_KNULLI_PATH/batocera/package/batocera/emulators/'
|
||||
'ppsspp/Config.in"\n'
|
||||
'#source "$BR2_EXTERNAL_KNULLI_PATH/package/utils/off/Config.in"\n'
|
||||
'source "$BR2_EXTERNAL_KNULLI_PATH/package/utils/vtree/Config.in"\n'
|
||||
),
|
||||
"package/system/knulli-system/Config.in": (
|
||||
"if BR2_PACKAGE_BATOCERA_TARGET_H700 || \\\n"
|
||||
" BR2_PACKAGE_BATOCERA_TARGET_A133\n"
|
||||
@@ -282,6 +353,8 @@ class KnulliPerBoard(unittest.TestCase):
|
||||
" mgba: {requireAnyOf: [BR2_PACKAGE_LIBRETRO_MGBA]}\n"
|
||||
"psp:\n emulators:\n ppsspp:\n"
|
||||
" ppsspp: {requireAnyOf: [BR2_PACKAGE_PPSSPP]}\n"
|
||||
"pspassets:\n emulators:\n libretro:\n"
|
||||
" assets: {requireAnyOf: [BR2_PACKAGE_PPSSPP_ASSETS]}\n"
|
||||
),
|
||||
}
|
||||
|
||||
@@ -314,6 +387,23 @@ class KnulliPerBoard(unittest.TestCase):
|
||||
return _Body(json.dumps([{"name": n} for n in names]))
|
||||
if url == f"{api}buildroot?ref={pin}":
|
||||
return _Body('{"sha": "c2d7985b"}')
|
||||
if url == f"{api}batocera?ref={pin}":
|
||||
return _Body('{"sha": "487014d9"}')
|
||||
if "/git/trees/" in url:
|
||||
# A board config that hides the downloader leaves its URL.
|
||||
cfg = "board/r16/retroarch.cfg" if "knulli-linux" in url else "x"
|
||||
return _Body(json.dumps({"tree": [{"path": cfg}], "truncated": False}))
|
||||
if url == f"{raw}board/r16/retroarch.cfg":
|
||||
return _Body('menu_show_core_updater = "false"\n')
|
||||
if url == f"{raw}package/retroarch/retroarch/retroarch.mk":
|
||||
return _Body("RETROARCH_CONF_OPTS = --enable-networking\n")
|
||||
if url == ("https://raw.githubusercontent.com/batocera-linux/batocera.linux/"
|
||||
"487014d9/package/batocera/emulators/ppsspp/Config.in"):
|
||||
return _Body("config BR2_PACKAGE_PPSSPP\n\tselect BR2_PACKAGE_PPSSPP_ASSETS\n")
|
||||
if url == f"{raw}package/utils/vtree/Config.in":
|
||||
raise urllib.error.HTTPError(url, 404, "Not Found", {}, None)
|
||||
if url.endswith("/c2d7985b/arch/Config.in.arm"):
|
||||
return _Body("config BR2_cortex_a7\n\tselect BR2_ARM_CPU_ARMV7A\n")
|
||||
if url.startswith("https://raw.githubusercontent.com/knulli-cfw/buildroot/c2d7985b/"):
|
||||
return _Body("config BR2_aarch64\n\tselect BR2_ARCH_IS_64\n")
|
||||
path = url.removeprefix(raw)
|
||||
@@ -330,11 +420,14 @@ class KnulliPerBoard(unittest.TestCase):
|
||||
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": ["assets", "mgba", "ppsspp"],
|
||||
"images": ["rg35xx-plus", "rg35xx-sp"]})
|
||||
# An armv7 hard-float board's RetroArch installs the armhf buildbot list.
|
||||
self.assertEqual(data["targets"]["r16"],
|
||||
{"architecture": "arm", "cores": ["mgba"], "images": ["miyoo-a30"]})
|
||||
self.assertTrue(all(pin in url or "buildroot/c2d7985b" in url for url in seen), seen)
|
||||
{"architecture": "arm", "cores": ["mgba"], "images": ["miyoo-a30"],
|
||||
"downloads": "linux-armhf"})
|
||||
self.assertTrue(all(pin in url or "buildroot/c2d7985b" in url
|
||||
or "487014d9" in url for url in seen), seen)
|
||||
|
||||
|
||||
class RocknixPerDevice(unittest.TestCase):
|
||||
@@ -371,35 +464,60 @@ class RocknixPerDevice(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_each_device_gets_its_own_cores(self):
|
||||
from scraper.targets.rocknix_targets_scraper import ( # noqa: PLC0415
|
||||
core_names,
|
||||
parse_device_cores,
|
||||
)
|
||||
from scraper.targets.rocknix_targets_scraper import parse_device_cores # noqa: PLC0415
|
||||
|
||||
h700 = core_names(*parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", True))
|
||||
self.assertTrue({"drastic", "gpsp", "duckstation", "beetle_psx", "hatari",
|
||||
"81", "neocd"} <= set(h700))
|
||||
self.assertFalse({"aethersx2", "dolphin"} & set(h700))
|
||||
no32 = core_names(*parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", False))
|
||||
self.assertNotIn("gpsp", no32)
|
||||
amd64 = core_names(*parse_device_cores(self.PACKAGE_MK, "AMD64", "x86_64", False))
|
||||
self.assertIn("dolphin", amd64)
|
||||
self.assertNotIn("drastic", amd64)
|
||||
libretro, standalone = parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", True)
|
||||
self.assertTrue({"gpsp-lr", "duckstation-lr", "beetle-psx-lr", "81-lr",
|
||||
"neocd_lr"} <= set(libretro))
|
||||
self.assertTrue({"drastic-sa", "hatarisa"} <= set(standalone))
|
||||
self.assertFalse({"aethersx2-sa", "dolphin-sa"} & set(standalone))
|
||||
libretro, _ = parse_device_cores(self.PACKAGE_MK, "H700", "aarch64", False)
|
||||
self.assertNotIn("gpsp-lr", libretro)
|
||||
_, standalone = parse_device_cores(self.PACKAGE_MK, "AMD64", "x86_64", False)
|
||||
self.assertIn("dolphin-sa", standalone)
|
||||
self.assertNotIn("drastic-sa", standalone)
|
||||
|
||||
def test_a_package_names_the_cores_it_installs(self):
|
||||
"""vice-lr builds ten EMUTYPEs: read as the package name, vice_x64
|
||||
and its siblings reached no ROCKNIX device."""
|
||||
from scraper.targets.rocknix_targets_scraper import installed_cores # noqa: PLC0415
|
||||
|
||||
vice = ("makeinstall_target() {\n mkdir -p ${INSTALL}/usr/lib/libretro\n"
|
||||
" cp -a built/vice_x128_libretro.so ${INSTALL}/usr/lib/libretro\n"
|
||||
" cp -a built/vice_x64_libretro.so ${INSTALL}/usr/lib/libretro\n}\n")
|
||||
self.assertEqual(installed_cores(vice, "aarch64", True), ["vice_x128", "vice_x64"])
|
||||
renamed = ("makeinstall_target() {\n"
|
||||
" cp -a mednafen_psx_libretro.so ${INSTALL}/usr/lib/libretro/beetle_psx_libretro.so\n"
|
||||
" cp -a fake08_libretro.{so,info} $INSTALL/usr/lib/libretro\n}\n")
|
||||
self.assertEqual(installed_cores(renamed, "aarch64", True), ["beetle_psx", "fake08"])
|
||||
pcsx = ("makeinstall_target() {\n"
|
||||
" case ${TARGET_ARCH} in\n"
|
||||
" aarch64|x86_64) cp -a ../pcsx_rearmed_libretro.so ${INSTALL}/usr/lib/libretro ;;\n"
|
||||
" arm) cp -a ../pcsx_rearmed_libretro.so ${INSTALL}/usr/lib/libretro/pcsx_rearmed32_libretro.so ;;\n"
|
||||
" esac\n"
|
||||
' if [ "${TARGET_ARCH}" = "aarch64" ] && [ "${ENABLE_32BIT}" = "true" ]; then\n'
|
||||
" cp -a x/usr/lib/libretro/pcsx_rearmed32_libretro.so ${INSTALL}/usr/lib/libretro\n"
|
||||
" fi\n}\n")
|
||||
self.assertEqual(installed_cores(pcsx, "aarch64", True), ["pcsx_rearmed", "pcsx_rearmed32"])
|
||||
self.assertEqual(installed_cores(pcsx, "aarch64", False), ["pcsx_rearmed"])
|
||||
self.assertEqual(installed_cores(pcsx, "x86_64", True), ["pcsx_rearmed"])
|
||||
with self.assertRaises(RuntimeError):
|
||||
installed_cores('makeinstall_target() {\n if [ "${DEVICE}" = "H700" ]; then\n'
|
||||
" cp a_libretro.so ${INSTALL}/usr/lib/libretro\n fi\n}\n",
|
||||
"aarch64", True)
|
||||
with self.assertRaises(RuntimeError):
|
||||
installed_cores("makeinstall_target() {\n :\n}\n", "aarch64", True)
|
||||
|
||||
def test_a_standalone_package_keeps_both_spellings(self):
|
||||
"""vice-standalone answers to vice-sa only, as scummvm-standalone to
|
||||
scummvm-sa: stripped to vice, every targeted pack left them out
|
||||
while the untargeted one, read from the platform scraper, kept them."""
|
||||
from scraper.rocknix_scraper import standalone_emulators # noqa: PLC0415
|
||||
from scraper.targets.rocknix_targets_scraper import ( # noqa: PLC0415
|
||||
core_names,
|
||||
parse_device_cores,
|
||||
)
|
||||
from scraper.targets.rocknix_targets_scraper import parse_device_cores # noqa: PLC0415
|
||||
|
||||
libretro, standalone = parse_device_cores(self.PACKAGE_MK, "SM8550", "aarch64", False)
|
||||
names = set(core_names(libretro, standalone))
|
||||
_, standalone = parse_device_cores(self.PACKAGE_MK, "SM8550", "aarch64", False)
|
||||
names = set(standalone_emulators(standalone))
|
||||
self.assertTrue({"aethersx2-sa", "aethersx2", "dolphin-sa", "dolphin"} <= names)
|
||||
self.assertTrue(set(standalone_emulators(standalone)) <= names)
|
||||
|
||||
def test_a_metapackage_names_the_cores_it_installs(self):
|
||||
from scraper.targets.rocknix_targets_scraper import metapackage_cores # noqa: PLC0415
|
||||
|
||||
Reference in new issue
Block a user