mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 01:53:56 -06:00
chore: merge main
This commit is contained in:
commit
8ba0a8c3f6
18 files changed
+929
-59
No files matched your search
@@ -34,6 +34,7 @@ systems:
|
||||
- zn1-tecmo
|
||||
- zn1-video-system
|
||||
- zn1-acclaim
|
||||
- namco-system11
|
||||
- arcade
|
||||
|
||||
notes: |
|
||||
@@ -272,4 +273,17 @@ files:
|
||||
note: "Acclaim PSX BIOS (PS1-based). NOT_WORKING"
|
||||
source_ref: "src/drivers/zn.c:1925"
|
||||
|
||||
- name: namcoc76.zip
|
||||
required: false
|
||||
category: bios_zip
|
||||
system: namco-system11
|
||||
note: "Namco C76 sound MCU BIOS, parent of the Tekken sets. Each game also loads c76.bin as ROM_LOAD_OPTIONAL from its own archive"
|
||||
source_ref: "src/drivers/namcos11.c:1604-1607, 1609-1610, 1427"
|
||||
contents:
|
||||
- name: "c76.bin"
|
||||
description: C76 internal BIOS
|
||||
size: 16384
|
||||
crc32: "399faac7"
|
||||
sha1: "ceb184ef0486caf715dd997101999785f67a40b8"
|
||||
|
||||
# psarc95.zip and atpsx.zip have NO_DUMP BIOS ROMs (coh1002e.bin, coh1000t.bin)
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"astrocde":["280zzap","adssm","amazmaze","artiduel","artiduelp1","artiduelp2","artiduelp3","astrobat","ballypin","baseball","biorhy","blckjack","bowling","brckyard","bstdroid","buylove","candyman","checkers","claim","colbook","conan","conanp","cosmicrd","cosmicrd35","cosmicrd36","cosmicrda","cosmicrdb","dealdemo","dogpatch","eightday","fawn","fawna","feelfine","football","galactic","galacticp","golddig","golddiga","golddigb","grandprx","hardday","icbmatk","icbmatkp","letitbe","life","lttrmtch","matk","mazeman","mazemanp","mlangman","mscandy","muncher","musicmak","musicmakp","musicmakp2","nodie","pacmaze","paperbck","pirate","rainbow2","seadevil","seawolf","sheloves","sloshed","sneaky","soccer","soccera","soccera2","soccera3","soccera4","soccerp","solarcnq","solarcnqp","solarcnqp28","solarcnqp39","songs","songsa","songsu","spacefrt","spacefrtp","spaceinv","spaceinva","spaceinvf","spaceinvj","spaceinvp","spaceinvt","spedmath","sslope","starbttl","stweek","tests","treasure","treasurep","vidstory","war","wizard","yesternv","yesterv","ziggyjx","ziggymo"],"atarisy1":["indytemp","indytemp2","indytemp3","indytemp4","indytempc","indytempd","marble","marble2","marble3","marble4","marble5","peterpak","reliefs1","roadblst","roadblst1","roadblst2","roadblst3","roadblstc","roadblstc1","roadblstcg","roadblstg","roadblstg1","roadblstg2","roadblstgu","roadblstj","roadblstp","roadrunn","roadrunn1","roadrunn2"],"bubsys":["bs_gradius","bs_gwarrior","bs_rf2","bs_twinbee"],"cchip":["bonzeadv","bonzeadvo","bonzeadvp","bonzeadvp2","bonzeadvu","jigkmgri","jigkmgria","jumping","jumpinga","jumpingi","megablst","megablstj","megablstu","opwolf","opwolfa","opwolfb","opwolfj","opwolfjsc","opwolfu","rbisland","rbislandb","rbislande","rbislando","rbislands","superman","supermanj","supermanp","supermans","supermanu","volfied","volfiedj","volfiedjo","volfiedo","volfiedu","volfieduo"],"channelf":["alieninv","backgamm","builtin","casinop","clrorgan","democrt1","democrt2","dodgeit","dragrace","drawpkr","dsrtfox","hangman","lightsout","magicnum","maze","mazea","memory","mthquiz1","mthquiz2","muehle","multicrt","multicrto","ordtvlng","pfootbll","pinbacvbyred","pinball","pinballa","ratmal","robotwar","robotwarp","schach","slotmchn","sonrsrch","spacewar","spitfire","spitfirep","tctactoe","vblckjck","werbetxt","whizball","wrdlf"],"coleco":["1942sgm","1on1","2010","2010p","421","advisland","ae","aerial","alcazar","alpharoid","alphazoo","amazing","amzsnake","antarct","antarcta","antarctj","antarctk","antarctp","antiair","apshai","aquatack","aquatacka","arkadion","armagedn","arnodash","artduel","ascend","asteroids","astrododge","astroinv","awass","aztecchal","bankbuild","bankpanic","barbarricade","barnbuster","battlot","bbears","bcquest","bcquest2","bcquest2ca","bcquesta","bcquestca","bdash","bdashp","beachead","beamridr","bejeweled","bigcatch","blackonyx","blockrun","bloktris","bofhoth","bokosukawars","bombking","bomblast","bomblast2","boomingboy","boothill","bootskell","bosconian","bountybob","boxxle","brainstr","breakout","breakout23j","breakout23r","buckrogsgm","bugsbots","bullmighty","bustabobble","bustabobble2","bustinout0","bustinout1","bustinout2","bustinout3","cabbage","cabbagep1","cabbagep2","cabbagepk","cabbshow","cacorm","camknights","camknightsb","campaign","canamini","caosbgns","carfight","castelo","castle","castleex","castlek","castlet","catsos","caverns","cavfight","cavit","ccharlie","ccredux","ccrisis","chackpop","challenger","chesschal","chprowres","chucknor","cicehockey","cix","clock","coco","coldblood","coltennis","comicbakery","comicbakeryo","comspace","cotn","crackpots","cracky","crazychickyjr","crazychickyjr2","cso","csok","csot","cure","cvjoytest","cye","dacman","dacman2","dacmana","dambust","dambustca","dangrtower","datrolls","dbreakout","ddash","ddash2","deathrace","decathln","deepdngadv","deflektor","demoattackna","demonattack","desolator","destruct","destructsce","digdugsgm","dkarcade","dkjrarcade","dkongarcade","dkongjrsgm","dkongsgm","dlairsgm","dncfntsy","donuts","drgnfire","drol","drolk","drolt","drseuss","eaclassics","easterbunny","ed2083","eggerland","elecquart","elevaction","elevactionsgm","enerquiz","evolutio","explodingfoot","eyebrawls","f2ffootball","f2fhockey","f2fsoccer","facemakr","fallguy","fantasy","fathom","ffactory","ffreddy","finaltst","fireman","flapbrd","flipslip","flora","flux","fortune","fracfevr","frantic","frogfeast","frogger2","frontlinsgm","frostbite","fruitpanic","fuzzywomp","gamepack1","gamepack2","gamester81","gamewatch","gblaster","gerbils","ggarden","ghost","ghostbst","ghostbst1","ghostbsts","ghostbstse","ghostrap","gnz","golgo13","golgo13c","golgo13sc","goonies","gooniesa","gooniesb","gooniesc","gooniesoc","gooniesttc","gpvic20","gpworld","gpworlda","gpworldt","guardic","guardica","gulkave","gulkavea","gulkavek","gunfright","guntus","gustbust","hamsterww","hamurabi","hardhatmack","hazzard","hchumy","heist","helifire","heroesar","holeone","hopman","hrally","huojiche","icemuncher","iceLine truncated
|
||||
{"bios":{"astrocde":["astro_280zzap","astro_adssm","astro_amazmaze","astro_artiduel","astro_artiduelp1","astro_artiduelp2","astro_artiduelp3","astro_astrobat","astro_ballypin","astro_baseball","astro_biorhy","astro_blckjack","astro_bowling","astro_brckyard","astro_bstdroid","astro_buylove","astro_candyman","astro_cclimber","astro_checkers","astro_claim","astro_colbook","astro_conan","astro_conanp","astro_cosmicrd","astro_cosmicrd35","astro_cosmicrd36","astro_cosmicrda","astro_cosmicrdb","astro_dealdemo","astro_dogpatch","astro_eightday","astro_fawn","astro_fawna","astro_feelfine","astro_football","astro_galactic","astro_galaxian","astro_golddig","astro_golddiga","astro_golddigb","astro_grandprx","astro_hardday","astro_icbmatk","astro_icbmatkp","astro_letitbe","astro_life","astro_lttrmtch","astro_matk","astro_mazeman","astro_mazemanp","astro_mlangman","astro_mscandy","astro_muncher","astro_musicmak","astro_musicmakp","astro_musicmakp2","astro_nodie","astro_pacman","astro_pacmana","astro_pacmaze","astro_paperbck","astro_pirate","astro_rainbow2","astro_redbaron","astro_seadevil","astro_seawolf","astro_sheloves","astro_sloshed","astro_sneaky","astro_soccer","astro_soccera","astro_soccera2","astro_soccera3","astro_soccera4","astro_soccerp","astro_solarcnq","astro_solarcnqp","astro_solarcnqp28","astro_solarcnqp39","astro_songs","astro_songsa","astro_songsu","astro_spacefrt","astro_spacefrtp","astro_spaceinv","astro_spaceinvp","astro_spedmath","astro_sslope","astro_starbttl","astro_stweek","astro_tests","astro_treasure","astro_treasurep","astro_vidstory","astro_war","astro_wizard","astro_yesternv","astro_yesterv","astro_ziggyjx","astro_ziggymo"],"atarisy1":["indytemp","indytemp2","indytemp3","indytemp4","indytempc","indytempd","marble","marble2","marble3","marble4","marble5","peterpak","reliefs1","roadblst","roadblst1","roadblst2","roadblst3","roadblstc","roadblstc1","roadblstcg","roadblstg","roadblstg1","roadblstg2","roadblstgu","roadrunn","roadrunn1","roadrunn2"],"bubsys":["bs_gradius","bs_gwarrior","bs_rf2","bs_twinbee"],"cchip":["bonzeadv","bonzeadvo","bonzeadvp","bonzeadvp2","bonzeadvu","jigkmgri","jigkmgria","jumping","jumpinga","jumpingi","megablst","megablstj","megablstu","opwolf","opwolfa","opwolfb","opwolfj","opwolfjsc","opwolfu","rbisland","rbislande","rbislando","superman","supermanj","supermanu","volfied","volfiedj","volfiedjo","volfiedo","volfiedu","volfieduo"],"channelf":["chf_alieninv","chf_backgamm","chf_baseball","chf_bowling","chf_builtin","chf_casinop","chf_checkers","chf_clrorgan","chf_democrt1","chf_democrt2","chf_dodgeit","chf_dragrace","chf_drawpkr","chf_dsrtfox","chf_football","chf_galactic","chf_galacticp","chf_hangman","chf_lightsout","chf_magicnum","chf_maze","chf_mazea","chf_memory","chf_mthquiz1","chf_mthquiz2","chf_muehle","chf_multicrt","chf_multicrto","chf_ordtvlng","chf_pacman","chf_pacmanv2","chf_pfootbll","chf_pinball","chf_pinballa","chf_ratmal","chf_robotwar","chf_robotwarp","chf_schach","chf_slotmchn","chf_sonrsrch","chf_spacewar","chf_spitfire","chf_spitfirep","chf_tctactoe","chf_tetris","chf_vblckjck","chf_werbetxt","chf_whizball","chf_wrdlf"],"coleco":["cv_1942sgm","cv_1on1","cv_2010","cv_2010p","cv_421","cv_advisland","cv_ae","cv_aerial","cv_alcazar","cv_alpharoid","cv_alphazoo","cv_amazing","cv_amidar","cv_amzsnake","cv_antarct","cv_antarctp","cv_antiair","cv_apshai","cv_aquatack","cv_aquatacka","cv_arabian","cv_arkadion","cv_arkanoid","cv_armagedn","cv_arnodash","cv_artduel","cv_ascend","cv_asteroids","cv_astorm","cv_astrododge","cv_astroinv","cv_awass","cv_aztecchal","cv_bagman","cv_bankbuild","cv_bankpanic","cv_barbarricade","cv_barnbuster","cv_battlot","cv_bbears","cv_bcquest","cv_bcquest2","cv_bcquest2ca","cv_bcquestca","cv_bdash","cv_bdashp","cv_beachead","cv_beamridr","cv_bejeweled","cv_berzerk","cv_bigcatch","cv_blackonyx","cv_blockrun","cv_bloktris","cv_bnj","cv_bnjp","cv_bofhoth","cv_boggy84","cv_bokosukawars","cv_bombjack","cv_bombking","cv_bomblast","cv_bomblast2","cv_boomingboy","cv_boothill","cv_bootskell","cv_bosconian","cv_bountybob","cv_boxxle","cv_brainstr","cv_breakout","cv_breakout23j","cv_breakout23r","cv_brubber","cv_btime","cv_btimem","cv_bubbles","cv_buckrog","cv_buckrogsgm","cv_bugsbots","cv_bullmighty","cv_bustabobble","cv_bustabobble2","cv_bustinout0","cv_bustinout1","cv_bustinout2","cv_bustinout3","cv_cabbage","cv_cabbagep1","cv_cabbagep2","cv_cabbagepk","cv_cabbshow","cv_cacorm","cv_camknights","cv_camknightsb","cv_campaign","cv_canamini","cv_caosbgns","cv_carfight","cv_carnival","cv_castelo","cv_castle","cv_castleex","cv_catsos","cv_cavenger","cv_cavengera","cv_caverns","cv_cavfight","cv_cavit","cv_ccharlie","cv_ccredux","cv_ccrisis","cv_centiped","cv_chackpop","cv_challenger","cv_chesschal","cv_choplift","cv_chprowres","cv_chucknor","cv_cicehockey","cv_circus","cv_cix","cv_clock","cv_coco","cv_coldblood","cv_coltennis","cv_comicbakery","cv_comicbakeryo","cv_comspace","cv_congo","cv_cotn","cv_crackpots","cv_cracky","cv_crazychickyjr","cv_crLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"3dobios":["orbatak"],"airlbios":["alpilot"],"aleck64":["11beat","doncdoon","hipai","hipai2","kurufev","mayjin3","mtetrisc","srmvs","srmvsa","starsldr","twrshaft","vivdolls"],"alg3do":["md23do","sht3do"],"alg_bios":["aplatoon","crimep2","crimep2_11","crimepat","crimepat_10","crimepat_12","crimepat_14","fastdraw","fastdraw_130","gallgall","gallgall_21","lastbh","lastbh_006","maddog","maddog2","maddog2_100","maddog2_110","maddog2_202","maddog_202","maddoga","marvice","marvice100hz","spacepir","spacepir_14","tierras100hz","wsjr","wsjr_15","zortonbr","zortonbr_100"],"allied":["circa33","disco79","erosone","foathens","heartspd","hoedown","royclark","starshot","suprpick","takefive","thndbolt"],"ar_bios":["ar_airh","ar_airh2","ar_argh","ar_blast","ar_bowl","ar_dart","ar_dart2","ar_dlta","ar_fast","ar_fasta","ar_ldrb","ar_ldrba","ar_ldrbb","ar_ninj","ar_ninj2","ar_pm","ar_rdwr","ar_sdwr","ar_sdwr2","ar_socc","ar_spot","ar_sprg","ar_xeon"],"aristmk5":["adonis","adonisa","adonisce","adonisu","alchemst","baddog","blackpnt","bootsctn","bootsctnu","bootsctnua","bootsctnub","bparty","bpartya","bumblbug","bumblbugql","bumblbugu","bumblbugua","buttdeli","canrose","cashcat","cashcata","cashcatnz","cashcham","cashchama","cashchamnz","cashchamu","cashcra5","cashcra5a","chariotc","chariotcv","checkma5","chickna5","chickna5ql","chickna5u","chickna5ua","chickna5v","coralrc2","cuckoo","cuckoou","diamdest","diamdove","dimtouch","dmdfever","dolphntr","dolphntra","dolphntrb","dolphntrce","dolphntrcea","dolphntrceb","dolphntrql","dolphntru","dreamwv","drgneye","dstbloom","dstblooma","dynajack","dynajacku","eforsta5","eforsta5ce","eforsta5cea","eforsta5u","eforsta5ua","eldorda5","fastfort","fortellr","fortfvr","gambler","geisha","genmagi","glizrdce","gnomeatw","goldenra","goldpyr","goldpyra","goldpyrb","hnktonku","honeypot","incasun","incasunnz","incasunsp","incasunu","incasunua","incasunv","indrema5","indrema5ql","jumpbean","jumpjoey","jungjuic","kgalah","kgalaha","kgalahce","kgbirda5","koalamnt","kookabuk","kyhatonu","locoloot","locoloota","locolootnz","locolootu","lonewolf","luckyclo","magimask","magimaska","magimaskb","magtcha5","magtcha5a","mammothm","marmagic","marmagicu","marmagicua","mgarden","minemine","minemineu","minemineua","monmouse","monmousea","montree","mountmon","mountmona","mountmonce","mountmonu","mountmonua","multidrw","mystgard","one4all","orchidms","orchidmsa","orchidmsnz","oscara5","oscara5a","pantmag","pantmaga","partygrs","partygrsa","partygrsb","peaflut","peafluta","pengpay","pengpaya","pengpayb","pengpayc","pengpayce","pengpayd","pengpayu","pengpayua","pengpayub","pengpuck","penpir","penpir2","penpira","petshop","petshopa","phantpay","phantpyc","przfight","qcash","qnile","qnilea","qnileb","qnilebr","qnilec","qnilece","qnilecea","qnileceb","qniled","qnilefl","qnilemax","qnilenl","qnilenz","qnileql","qnileu","qnileua","qnilev","qtbird","rainwarr","rainwarrce","reelpwr","reelrock","reelrockql","retrsam","retrsama","retrsamb","rushrst","sbuk2","sbuk2a","sbuk3","sbuk3a","sldeluxe","slvrwolf","snowcat","sumospin","swhr2","swhr2a","swhr2u","swhr2v","thndh","thndha","thor","topbana","toutango","toutangonl","tritreat","trojhors","trpdlght","trpdlghtu","trstrove","unicornd","unicornda","unicorndnz","unicorndu","venicea5","wafricau","wamazon","wamazona","wamazonv","wcougar","wcougaru","wcougarua","wcougarub","wcougaruc","wcoyote","wikwin","wildbill","wizways","wldangel","wnpost","wthing","wthinga","wtiger","yukongl5"],"aristmk6":["100lions","100lionsa","15lions","50lionrr","50lions","50lionsa","50lionsu","5drag","5draga","5dragce","5dragnz","5dragsp","5koi","5koia","adonisa6","aduskcm","afterhrs","alchemy","amzqueen","amztempl","antcleo","antcleoa","apocof","arabnga6","arabnga6a","arabnga6u","arish","arwincm","asnprinc","atkgld","beavbuk","betzoo","bigben","bigbena","bigbenb","bigbenq","bigheart","bigred","bigred2","bigreda","blkbrum","blkmust","bluetigr","bmbugs","bobdolly","brazil","brazila","bucaneer","bucaneera","bucaneeru","buckstop","buffalo","buffaloa","buffalou","bushrngr","cactusco","callwld","calyking","canaryrc","centrion","cinhell","cmtonig","corrida","cryspri","cryspria","cryspriu","csd","csda","csdce","csdjc","csdq","csdsp","csret","dblagent","dbldolph","dbldolphq","deepfrz","deepfrzu","deltabel","deltaqn","di4ever","diamhrts","dimeye","dimeyece","dimeyeu","dinosa6","doltra6","doltra6nz","drgnlord","drgnmgic","drmcatch","drmcatcha","drmred","dstgold","eaglrock","eastland","efce","eggsrccm","enchantr","encspell","eott","estrike","firednc","firednca","flamolce","flamoljc","followst","fortath","fortking","frogwld","gambjack","gbmoney","geishaa6","geishaa6a","geishaa6b","geishajc","gldgong","gldgongq","gldgongu","gldnflc","goape","gogreen","gogreena","goldarch","goldinc","goldincu","goldpya6","goldpym","goldsam","grizzly","gwnn","heartgld","heartglda","heartveg","highnoon","hlntroy","hlntroya","hlntroyb","hlntroyc","hlntroyu","holdrma6","holdrma6a","househrt","househrta","incachf","indgldcm","indprnLine truncated
|
||||
{"bios":{"3dobios":["orbatak"],"airlbios":["alpilot"],"aleck64":["11beat","doncdoon","hipai","hipai2","kurufev","mayjin3","mtetrisc","srmvs","srmvsa","starsldr","twrshaft","vivdolls"],"alg3do":["md23do","sht3do"],"alg_bios":["aplatoon","crimep2","crimep2_11","crimepat","crimepat_10","crimepat_12","crimepat_14","fastdraw","fastdraw_130","gallgall","gallgall_21","lastbh","lastbh_006","maddog","maddog2","maddog2_100","maddog2_110","maddog2_202","maddog_202","maddoga","marvice","marvice100hz","spacepir","spacepir_14","tierras100hz","wsjr","wsjr_15","zortonbr","zortonbr_100"],"allied":["circa33","disco79","erosone","foathens","heartspd","hoedown","royclark","starshot","suprpick","takefive","thndbolt"],"ar_bios":["ar_airh","ar_airh2","ar_argh","ar_blast","ar_bowl","ar_dart","ar_dart2","ar_dlta","ar_fast","ar_fasta","ar_ldrb","ar_ldrba","ar_ldrbb","ar_ninj","ar_ninj2","ar_pm","ar_rdwr","ar_sdwr","ar_sdwr2","ar_socc","ar_spot","ar_sprg","ar_xeon"],"aristmk5":["adonis","adonisa","adonisce","adonisu","alchemst","baddog","blackpnt","bootsctn","bootsctnu","bootsctnua","bootsctnub","bparty","bpartya","bumblbug","bumblbugql","bumblbugu","bumblbugua","buttdeli","canrose","cashcat","cashcata","cashcatnz","cashcham","cashchama","cashchamnz","cashchamu","cashcra5","cashcra5a","chariotc","chariotcv","checkma5","chickna5","chickna5ql","chickna5u","chickna5ua","chickna5v","coralrc2","cuckoo","cuckoou","diamdest","diamdove","dimtouch","dmdfever","dolphntr","dolphntra","dolphntrb","dolphntrce","dolphntrcea","dolphntrceb","dolphntrql","dolphntru","dreamwv","drgneye","dstbloom","dstblooma","dynajack","dynajacku","eforsta5","eforsta5ce","eforsta5cea","eforsta5u","eforsta5ua","eldorda5","fastfort","fortellr","fortfvr","gambler","geisha","genmagi","glizrdce","gnomeatw","goldenra","goldpyr","goldpyra","goldpyrb","hnktonku","honeypot","incasun","incasunnz","incasunsp","incasunu","incasunua","incasunv","indrema5","indrema5ql","jumpbean","jumpjoey","jungjuic","kgalah","kgalaha","kgalahce","kgbirda5","koalamnt","kookabuk","kyhatonu","locoloot","locoloota","locolootnz","locolootu","lonewolf","luckyclo","magimask","magimaska","magimaskb","magtcha5","magtcha5a","mammothm","marmagic","marmagicu","marmagicua","mgarden","minemine","minemineu","minemineua","monmouse","monmousea","montree","mountmon","mountmona","mountmonce","mountmonu","mountmonua","multidrw","mystgard","one4all","orchidms","orchidmsa","orchidmsnz","oscara5","oscara5a","pantmag","pantmaga","partygrs","partygrsa","partygrsb","peaflut","peafluta","pengpay","pengpaya","pengpayb","pengpayc","pengpayce","pengpayd","pengpayu","pengpayua","pengpayub","pengpuck","penpir","penpir2","penpira","petshop","petshopa","phantpay","phantpyc","przfight","qcash","qnile","qnilea","qnileb","qnilebr","qnilec","qnilece","qnilecea","qnileceb","qniled","qnilefl","qnilemax","qnilenl","qnilenz","qnileql","qnileu","qnileua","qnilev","qtbird","rainwarr","rainwarrce","reelpwr","reelrock","reelrockql","retrsam","retrsama","retrsamb","rushrst","sbuk2","sbuk2a","sbuk3","sbuk3a","sldeluxe","slvrwolf","snowcat","sumospin","swhr2","swhr2a","swhr2u","swhr2v","thndh","thndha","thor","topbana","toutango","toutangonl","tritreat","trojhors","trpdlght","trpdlghtu","trstrove","unicornd","unicornda","unicorndnz","unicorndu","venicea5","wafricau","wamazon","wamazona","wamazonv","wcougar","wcougaru","wcougarua","wcougarub","wcougaruc","wcoyote","wikwin","wildbill","wizways","wldangel","wnpost","wthing","wthinga","wtiger","yukongl5"],"aristmk6":["100lions","100lionsa","15lions","50lionrr","50lions","50lionsa","50lionsu","5drag","5draga","5dragce","5dragnz","5dragsp","5koi","5koia","adonisa6","aduskcm","afterhrs","alchemy","amzqueen","amztempl","antcleo","antcleoa","apocof","arabnga6","arabnga6a","arabnga6u","arish","arwincm","asnprinc","atkgld","beavbuk","betzoo","bigben","bigbena","bigbenb","bigbenq","bigheart","bigred","bigred2","bigreda","blkbrum","blkmust","bluetigr","bmbugs","bobdolly","brazil","brazila","bucaneer","bucaneera","bucaneeru","buckstop","buffalo","buffaloa","buffalou","bushrngr","cactusco","callwld","calyking","canaryrc","centrion","cinhell","cmtonig","corrida","cryspri","cryspria","cryspriu","csd","csda","csdce","csdjc","csdq","csdsp","csret","dblagent","dbldolph","dbldolphq","deepfrz","deepfrzu","deltabel","deltaqn","di4ever","diamhrts","dimeye","dimeyece","dimeyeu","dinosa6","doltra6","doltra6nz","drgnlord","drgnmgic","drmcatch","drmcatcha","drmred","dstgold","eaglrock","eastland","efce","eggsrccm","enchantr","encspell","eott","estrike","firednc","firednca","flamolce","flamoljc","followst","fortath","fortking","frogwld","gambjack","gbmoney","geishaa6","geishaa6a","geishaa6b","geishajc","gldgong","gldgongq","gldgongu","gldnflc","goape","gogreen","gogreena","goldarch","goldinc","goldincu","goldpya6","goldpym","goldsam","grizzly","gwnn","heartgld","heartglda","heartveg","highnoon","hlntroy","hlntroya","hlntroyb","hlntroyc","hlntroyu","holdrma6","holdrma6a","househrt","househrta","incachf","indgldcm","indprnLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","cyberlip","doubledr","eightman","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","flipshot","galaxyfg","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof94","kof95","kof96","kof97","kof98","kotm","kotm2","lastblad","lastbld2","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","overtop","panicbom","pbobble","pgoal","popbounc","pspikes2","pulstar","puzbobb","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbffspec","ridhero","roboarmy","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh2","wh2j","whp","wjammers","zedblade"]},"bios_sets":["neogeo"],"chd":[],"core_version":"0.37b5","counts":{"bios_roots_used":1,"bios_sets":1,"chd_games":0,"games":2240,"games_with_bios":128,"games_with_devices":0,"missing_parents":0,"sets":2241},"devices":{},"missing_parents":{},"no_bios":["005","1941","1941j","1942","1942a","1942b","1943","1943j","1943kai","280zzzap","3stooges","3wonders","4dwarrio","600","64streej","64street","720","720b","800fath","88games","99lstwar","99lstwra","aafb","aafbb","aafbd2p","abaseb","abaseb2","actfanc1","actfancj","actfancr","aeroboto","aerofgt","aerofgtb","aerofgtc","airbustr","airduel","airwolf","ajax","ajaxj","alcon","alexkida","alexkidd","alibaba","alieninv","aliens","aliens2","aliensj","aliensu","aliensya","aliensyb","aliensyj","aliensyn","alleymas","alpine","alpinea","altbeas2","altbeast","ambush","amidar","amidaro","amidars","amidaru","amigo","anteater","apb","apb2","appoooh","arabian","arabiana","arbalest","arcadecl","archriv2","archrivl","area88","ark2jp","ark2us","arkangc","arkanoi2","arkanoid","arkarea","arkatayt","arkatour","arkbl2","arkbloc2","arknoidj","arknoidu","armedf","armora","armorca2","armorcar","armwrest","ashura","ashurau","aso","assault","assaultj","assaultp","astdelu1","astdelux","asteroi1","asteroib","asteroid","astinvad","astorm","astorm2p","astormbl","astrob","astrob1","astrob2","astrof","astrof2","astrof3","astyanax","atarifb","atarifb1","atarifb4","ataxx","ataxxa","ataxxj","atetckt2","atetcktl","atetris","atetrisa","atetrisb","athena","atlantis","atlants2","atomicp","aurail","auraila","avalnche","avenger2","avengers","avspirit","aztarac","azurian","baddudes","badlands","bagman","bagmans","bagmans2","bagnard","ballbomb","baluba","bandido","bankp","baraduke","barrier","basebal2","batman","batsugun","battlan2","battlan3","battlane","battlera","battlntj","battlnts","battroad","bayrouta","bayroute","bayrtbl1","bayrtbl2","bbros","bchopper","beastf","berabohm","berlwall","berlwalt","bermudaa","bermudaj","bermudat","berzerk","berzerk1","bigprowr","bigstrik","billiard","bioatack","bionicc","bionicc2","bjtwin","bking2","bktigerb","bladestl","bladstle","blandia","blasted","blaster","blasto","blastoff","blazer","blckgalb","blckout2","bldwolf","blkdrgnb","blkdrgon","blkhole","blktiger","block","blockade","blockbl","blocken","blockgal","blockhl","blockj","blockout","bloodbro","blsthead","blstroi2","blstroid","blswhstl","blueprnj","blueprnt","blueshrk","bmaster","bnj","boblbobl","bodyslam","bogeyman","bombbee","bombjac2","bombjack","bootcamp","boothill","bosco","boscomd","boscomdo","boscoo","boscoo2","bottom9","bottom9n","bouldash","bowler","bowlrama","boxingb","brain","breywood","brix","brkthru","brkthruj","brubber","brutforc","bsktball","btime","btime2","btimem","btlfield","bubbles","bubblesr","bubbobr1","bublbobl","bublbobr","bullfgtj","burnforc","bwidow","bzone","bzone2","cabal","cabal2","cabalbl","cachat","calibr50","calipso","cameltru","cameltry","canbprot","canyon","capbowl","capbowl2","captcomj","captcomm","captcomu","caractn","carnival","carnvckt","cavenger","cawing","cawingj","cbasebal","cbuster","cbusterj","cbusterw","ccastle2","ccastles","ccboot","ccboot2","cchasm","cchasm1","cclimber","cclimbr2","cclimbrj","centipb2","centipd2","centipdb","centiped","cerberus","challeng","champbas","champbb2","champbbj","champwr","champwrj","champwru","changes","checkmaj","checkman","checkmat","cheekyms","chelnov","chelnovj","cheyenne","chikij","chiller","chimerab","chopper","chplft","chplftb","chplftbl","chukatai","circus","circusc","circusc2","circuscc","circusce","cischeat","citycon","citycona","ckong","ckonga","ckongalc","ckongjeu","ckongo","ckongs","claypign","clbowl","cloak","cloud9","clowns","cninja","cninja0","cninjLine truncated
|
||||
{"bios":{"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","cyberlip","doubledr","eightman","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","flipshot","galaxyfg","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof94","kof95","kof96","kof97","kof98","kotm","kotm2","lastblad","lastbld2","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","overtop","panicbom","pbobble","pgoal","popbounc","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbffspec","ridhero","roboarmy","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh2","wh2j","whp","wjammers","zedblade"]},"bios_sets":["neogeo"],"chd":[],"core_version":"0.37b5","counts":{"bios_roots_used":1,"bios_sets":1,"chd_games":0,"games":2271,"games_with_bios":127,"games_with_devices":0,"missing_parents":0,"sets":2272},"devices":{},"missing_parents":{},"no_bios":["005","1941","1941j","1942","1942a","1942b","1943","1943j","1943kai","280zzzap","3stooges","3wonders","4dwarrio","600","64streej","64street","720","720b","800fath","88games","99lstwar","99lstwra","aafb","aafbb","aafbd2p","abaseb","abaseb2","actfanc1","actfancj","actfancr","aeroboto","aerofgt","aerofgtb","aerofgtc","airbustr","airduel","airwolf","ajax","ajaxj","alcon","alexkida","alexkidd","alibaba","alieninv","aliens","aliens2","aliensj","aliensu","aliensya","aliensyb","aliensyj","aliensyn","alleymas","alpine","alpinea","altbeas2","altbeast","ambush","amidar","amidaro","amidars","amidaru","amigo","anteater","apb","apb2","appoooh","arabian","arabiana","arbalest","arcadecl","archriv2","archrivl","area88","argus","ark2jp","ark2us","arkangc","arkanoi2","arkanoid","arkarea","arkatayt","arkatour","arkbl2","arkbloc2","arknoidj","arknoidu","armedf","armora","armorca2","armorcar","armwrest","ashura","ashurau","aso","assault","assaultj","assaultp","astdelu1","astdelux","asteroi1","asteroib","asteroid","astinvad","astorm","astorm2p","astormbl","astrob","astrob1","astrob2","astrof","astrof2","astrof3","astyanax","atarifb","atarifb1","atarifb4","ataxx","ataxxa","ataxxj","atetckt2","atetcktl","atetris","atetrisa","atetrisb","athena","atlantis","atlants2","atomicp","aurail","auraila","avalnche","avenger2","avengers","avspirit","aztarac","azurian","baddudes","badlands","bagman","bagmans","bagmans2","bagnard","ballbomb","baluba","bandido","bankp","baraduke","barrier","basebal2","batman","batsugun","battlan2","battlan3","battlane","battlera","battlntj","battlnts","battroad","batugnsp","bayrouta","bayroute","bayrtbl1","bayrtbl2","bbros","bchopper","beastf","berabohm","berlwall","berlwalt","bermudaa","bermudaj","bermudat","berzerk","berzerk1","bigkarnk","bigprowr","bigstrik","billiard","bioatack","biomtoy","bionicc","bionicc2","bjtwin","bking2","bktigerb","bladestl","bladstle","blandia","blasted","blaster","blasto","blastoff","blazer","blckgalb","blckout2","bldwolf","blkdrgnb","blkdrgon","blkhole","blktiger","block","blockade","blockbl","blocken","blockgal","blockhl","blockj","blockout","bloodbro","blsthead","blstroi2","blstroid","blswhstl","blueprnj","blueprnt","blueshrk","bmaster","bnj","boblbobl","bodyslam","bogeyman","bombbee","bombjac2","bombjack","bootcamp","boothill","bosco","boscomd","boscomdo","boscoo","boscoo2","bottom9","bottom9n","bouldash","bowler","bowlrama","boxingb","brain","breywood","brix","brkthru","brkthruj","brubber","brutforc","bsktball","btime","btime2","btimem","btlfield","bubbles","bubblesr","bubbobr1","bublbobl","bublbobr","bullfgtj","burnforc","butasan","bwidow","bzone","bzone2","cabal","cabal2","cabalbl","cachat","calibr50","calipso","cameltru","cameltry","canbprot","canyon","capbowl","capbowl2","captcomj","captcomm","captcomu","caractn","carnival","carnvckt","cavenger","cawing","cawingj","cbasebal","cbuster","cbusterj","cbusterw","ccastle2","ccastles","ccboot","ccboot2","cchasm","cchasm1","cclimber","cclimbr2","cclimbrj","centipb2","centipd2","centipdb","centiped","cerberus","challeng","champbas","champbb2","champbbj","champwr","champwrj","champwru","changes","checkmaj","checkman","checkmat","cheekyms","chelnov","chelnovj","cheyenne","chikij","chiller","chimerab","chopper","chplft","chplftb","chplftbl","chukatai","circus","circusc","circusc2","circuscc","circusce","cischeat","citycon","citycona","ckong","ckonga","ckongalc","ckongjeu","ckongo","ckongs","claypign","clbowl","cloak","clLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"acpsx":["jdredd","jdreddb","nbajamex"],"cpzn1":["glpracr","jgakuen","rvschool","sfex","sfexj","sfexp","sfexpj","starglad","tgmj","ts2","ts2j"],"cpzn2":["kikaioh","sfex2","sfex2p","sg2j","shiryu2","strider2","stridr2a","techromn"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmissnx","cnights2","cnightst","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_gaxe2","mp_sonic"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","ctomaday","cyberlip","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof2000","kof2000n","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof98","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mslug3","mslug3n","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","s1945p","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","zedblade"],"nss":["nss_actr","nss_adam","nss_aten","nss_con3","nss_fzer","nss_lwep","nss_ncaa","nss_rob3","nss_skin","nss_smw","nss_ssoc","nss_sten"],"pgm":["dragwld2","kov","kov115","kovplus","kovsh","orlegend","orlegndc","orlegnde","photoy2k"],"playch10":["pc_1942","pc_bball","pc_bfght","pc_bstar","pc_cntra","pc_cshwk","pc_cvnia","pc_dbldr","pc_ddrgn","pc_drmro","pc_duckh","pc_ebike","pc_ftqst","pc_gntlt","pc_golf","pc_goons","pc_grdue","pc_grdus","pc_hgaly","pc_kngfu","pc_mario","pc_miket","pc_mman3","pc_moglf","pc_mtoid","pc_ngai2","pc_ngai3","pc_ngaid","pc_pinbt","pc_pwbld","pc_pwrst","pc_radr2","pc_radrc","pc_rcpam","pc_rkats","pc_rnatk","pc_rrngr","pc_rygar","pc_sjetm","pc_smb","pc_smb2","pc_smb3","pc_suprc","pc_tbowl","pc_tenis","pc_tkfld","pc_tmnt","pc_tmnt2","pc_trjan","pc_vball","pc_wcup","pc_wgnmn","pc_ynoid"],"skns":["cyvern","galpani4","galpanis","galpans2","gutsn","jjparad2","jjparads","panicstr","puzloopj","puzloopu","puzzloop","ryouran","sarukani","sengekij","sengekis","senknow","teljan","vblokbrk"],"stvbios":["astrass","bakubaku","batmanfr","colmns97","cotton2","cottonbm","danchih","decathlt","diehard","dnmtdeka","ejihon","elandore","ffreveng","fhboxers","findlove","finlarch","gaxeduel","grdforce","groovef","hanagumi","introdon","kiwames","maruchan","mausuke","myfairld","othellos","pblbeach","prikura","puyosun","rsgun","sandor","sassisu","seabass","shanhigw","shienryu","sleague","sokyugrt","sss","suikoenb","thunt","twcup98","vfkids","vfremix","vmahjong","winterht","znpwfv"],"taitofx1":["beastrzb","ftimpcta","gdarius","gdarius2","mgcldate","mgcldtea","psyforce","raystorm","sfchamp"],"tps":["doapp","glprac2j","glprac2l","glpracr2","tondemo"]},"bios_sets":["acpsx","cpzn1","cpzn2","cvs","decocass","konamigx","megaplay","megatech","neogeo","nss","pgm","playch10","skns","stvbios","taitofx1","tps"],"chd":["a51mxr3k","area51","area51mx","biofreak","blitz","blitz2k","blitz99","bm1stmix","bm2ndmix","bm2ndmxaLine truncated
|
||||
{"bios":{"acpsx":["jdredd","jdreddb","nbajamex"],"cpzn1":["glpracr","jgakuen","rvschool","sfex","sfexj","sfexp","sfexpj","starglad","tgmj","ts2","ts2j"],"cpzn2":["kikaioh","sfex2","sfex2p","sg2j","shiryu2","strider2","stridr2a","techromn"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmissnx","cnights2","cnightst","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_gaxe2","mp_sonic"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"namcoc76":["tekken","tekken2","tekken2a","tekken2b","tekkena","tekkenb"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","ctomaday","cyberlip","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof2000","kof2000n","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof98","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mslug3","mslug3n","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","s1945p","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","zedblade"],"nss":["nss_actr","nss_adam","nss_aten","nss_con3","nss_fzer","nss_lwep","nss_ncaa","nss_rob3","nss_skin","nss_smw","nss_ssoc","nss_sten"],"pgm":["dragwld2","kov","kov115","kovplus","kovsh","orlegend","orlegndc","orlegnde","photoy2k"],"playch10":["pc_1942","pc_bball","pc_bfght","pc_bstar","pc_cntra","pc_cshwk","pc_cvnia","pc_dbldr","pc_ddrgn","pc_drmro","pc_duckh","pc_ebike","pc_ftqst","pc_gntlt","pc_golf","pc_goons","pc_grdue","pc_grdus","pc_hgaly","pc_kngfu","pc_mario","pc_miket","pc_mman3","pc_moglf","pc_mtoid","pc_ngai2","pc_ngai3","pc_ngaid","pc_pinbt","pc_pwbld","pc_pwrst","pc_radr2","pc_radrc","pc_rcpam","pc_rkats","pc_rnatk","pc_rrngr","pc_rygar","pc_sjetm","pc_smb","pc_smb2","pc_smb3","pc_suprc","pc_tbowl","pc_tenis","pc_tkfld","pc_tmnt","pc_tmnt2","pc_trjan","pc_vball","pc_wcup","pc_wgnmn","pc_ynoid"],"skns":["cyvern","galpani4","galpanis","galpans2","gutsn","jjparad2","jjparads","panicstr","puzloopj","puzloopu","puzzloop","ryouran","sarukani","sengekij","sengekis","senknow","teljan","vblokbrk"],"stvbios":["astrass","bakubaku","batmanfr","colmns97","cotton2","cottonbm","danchih","decathlt","diehard","dnmtdeka","ejihon","elandore","ffreveng","fhboxers","findlove","finlarch","gaxeduel","grdforce","groovef","hanagumi","introdon","kiwames","maruchan","mausuke","myfairld","othellos","pblbeach","prikura","puyosun","rsgun","sandor","sassisu","seabass","shanhigw","shienryu","sleague","sokyugrt","sss","suikoenb","thunt","twcup98","vfkids","vfremix","vmahjong","winterht","znpwfv"],"taitofx1":["beastrzb","ftimpcta","gdarius","gdarius2","mgcldate","mgcldtea","psyforce","raystorm","sfchamp"],"tps":["doapp","glprac2j","glprac2l","glpracr2","tondemo"]},"bios_sets":["acpsx","cpzn1","cpzn2","cvs","decocass","konamigx","megaplay","megatech","namcoc76","neogeo","nss","pgm","playch10","psarc95","skns","stvbios","taitofx1","tps"],"chd":["a51mxLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"acpsx":["nbajamex"],"coh1000a":["jdredd","jdreddb"],"coh1000c":["glpracr","glpracrj","sfex","sfexa","sfexj","sfexp","sfexpj","sfexpj1","sfexpu1","sfexu","starglad","stargladj","ts2","ts2j","ts2ja","ts2u","ts2ua"],"coh1000t":["ftimpact","ftimpactj","ftimpactu","ftimpcta","gdarius","gdarius2","gdariusj","gdariusu","mgcldate","mgcldtex","psyforce","psyforcej","psyforcex","raystorm","raystormj","raystormo","raystormu","sfchamp","sfchampj","sfchampo","sfchampu"],"coh1002m":["1on1gov","brvblade","brvbladea","brvbladej","brvbladeu","cbaj","cbajbl","doapp","doappk","flamegun","flamegunj","glpracr2","glpracr2j","glpracr2l","glpracr3","glpracr3j","lpadv","mfjump","shngmtkb","tblkkuzu","tondemo","twcupmil"],"coh3002c":["jgakuen","jgakuen1","kikaioh","plsmaswd","plsmaswda","rvschool","rvschoola","rvschoolu","sfex2","sfex2a","sfex2h","sfex2j","sfex2p","sfex2pa","sfex2ph","sfex2pj","sfex2pu","sfex2u","sfex2u1","shiryu2","stargld2","strider2","strider2a","strider2u","techromn","techromna","techromnu","tgmj"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","diggerc","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["cadanglr","castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cfishing","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmanhat","cmissnx","cnights2","cnightst","coozumou","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csdtenis","cskater","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoona","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","sexyparoa","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_addams","mp_bio","mp_col3","mp_gaxe2","mp_gslam","mp_gunhe","mp_mazin","mp_shnb3","mp_soni2","mp_sonic","mp_sor2","mp_twc"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"namcoc76":["danceyes","danceyesj","danceyesu","dunkmnia","dunkmniajc","myangel3","pocketrc","primglex","souledge","souledgea","souledgeja","souledgeua","souledgeuc","starswep","starswepj","tekken","tekken2","tekken2a","tekken2b","tekken2jb","tekken2jc","tekken2ua","tekken2ub","tekken2ud","tekkenac","tekkenb","tekkenjb","xevi3dg","xevi3dga","xevi3dgj"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","b2b","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","captainbarrel","crswd2bl","crsword","ct2k3sp","cthd2003","ctomaday","cyberlip","cyborgforce","doubled1","doubled1a","doubled1b","doubled1c","doubled1d","doubled1e","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","ghostlop","gladmort","goalx3","gowcaizr","gpilots","gururin","hypernoid","ironclad","irrmaze","janshin","joyjoy","kabukikl","karnovr","kf10thep","kf2k2mp","kf2k2mp2","kf2k2pla","kf2k2pls","kf2k3bl","kf2k3bla","kf2k3pl","kf2k3upl","kf2k5uni","kizuna","knightsch","kof10th","kof2000","kof2000n","kof2001","kof2001h","kof2002","kof2003","kof2003d","kof2k4se","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof97pls","kof98","kof98k","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kog","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lasthope","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","matrim","miexchng","minasan","mosyougi","mslug","mslug2","mslug2t","mslug3","mslug3n","mslug4","mslug5","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","pnyaa","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","rotd","s1945p","samsh5sp","samsho","samsho2","samsho3","samsho4","samsho5","savagere","sdodgeb","sengokh","sengoku","sengoku2","sengoku3","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","svc","svcboot","svcplus","svcplusa","svcsplus","teot","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","xeno","zedblade","zintrckb","zupapa"],"nss":["nss_actr","nss_Line truncated
|
||||
{"bios":{"coh1000a":["jdredd","jdreddb","nbajamex","nbajamexa"],"coh1000c":["glpracr","glpracrj","sfex","sfexa","sfexj","sfexp","sfexpj","sfexpj1","sfexpu1","sfexu","starglad","stargladj","ts2","ts2j","ts2ja","ts2u","ts2ua"],"coh1000t":["ftimpact","ftimpactj","ftimpactu","ftimpcta","gdarius","gdarius2","gdariusj","gdariusu","mgcldate","mgcldtex","psyforce","psyforcej","psyforcex","raystorm","raystormj","raystormo","raystormu","sfchamp","sfchampj","sfchampo","sfchampu"],"coh1000w":["primrag2"],"coh1001l":["hvnsgate"],"coh1002e":["beastrzr","beastrzra","beastrzrb","bldyroar","bldyror2","bldyror2a","bldyror2j","bldyror2u"],"coh1002m":["1on1gov","brvblade","brvbladea","brvbladej","brvbladeu","cbaj","cbajbl","doapp","doappk","flamegun","flamegunj","glpracr2","glpracr2j","glpracr2l","glpracr3","glpracr3j","lpadv","mfjump","shngmtkb","tblkkuzu","tondemo","twcupmil"],"coh1002t":["mawasunda"],"coh1002v":["aerofgts","aerofgtst","sncwgltd"],"coh3002c":["jgakuen","jgakuen1","kikaioh","plsmaswd","plsmaswda","rvschool","rvschoola","rvschoolu","sfex2","sfex2a","sfex2h","sfex2j","sfex2p","sfex2pa","sfex2ph","sfex2pj","sfex2pu","sfex2u","sfex2u1","shiryu2","stargld2","strider2","strider2a","strider2u","techromn","techromna","techromnu","tgmj"],"coh3002t":["aerofgtsg","brvbladeg","chaoshea","chaosheaj","flamegung","flipmaze","ftimpactg","gdariusg","gobyrc","kollon","kollonc","mahjngoh","nightrai","otenamhf","otenamih","otenki","psyvaria","psyvarij","psyvarrv","raycris","raycrisj","raystormg","rcdego","shanghss","shangtou","shikigam","shikigama","shngmtkbg","sianniv","soutenry","spuzbobl","spuzboblj","tblkkuzug","usagi","xiistag","zokuoten","zokuotena","zooo"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","diggerc","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["cadanglr","castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cfishing","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmanhat","cmissnx","cnights2","cnightst","coozumou","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csdtenis","cskater","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoona","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","sexyparoa","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_addams","mp_bio","mp_col3","mp_gaxe2","mp_gslam","mp_gunhe","mp_mazin","mp_shnb3","mp_soni2","mp_sonic","mp_sor2","mp_twc"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"model1io":["daytona","daytona93","daytonagtx","daytonam","daytonas","daytonase","daytonat","daytonata","desert"],"model1io2":["vcop","vcopa"],"namcoc76":["danceyes","danceyesj","danceyesu","dunkmnia","dunkmniajc","gunbarl","gunbarla","myangel3","pocketrc","primglex","ptblank2","ptblank2a","ptblank2b","ptblank2c","ptblank2ua","souledge","souledgea","souledgeja","souledgeua","souledgeuc","starswep","starswepj","tekken","tekken2","tekken2a","tekken2b","tekken2jb","tekken2jc","tekken2ua","tekken2ub","tekken2ud","tekkenac","tekkenb","tekkenjb","xevi3dg","xevi3dga","xevi3dgj"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","b2b","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","captainbarrel","crswd2bl","crsword","ct2k3sp","cthd2003","ctomaday","cyberlip","cyborgforce","doubled1","doubled1a","doubled1b","doubled1c","doubled1d","doubled1e","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","ghostlop","gladmort","goalx3","gowcaizr","gpilots","gururin","hypernoid","ironclad","irrmaze","janshin","joyjoy","kabukikl","karnovr","kf10thep","kf2k2mp","kf2k2mp2","kf2k2pla","kf2k2pls","kf2k3bl","kf2k3bla","kf2k3pl","kf2k3upl","kf2k5uni","kizuna","knightsch","kof10th","kof2000","kof2000n","kof2001","kof2001h","kof2002","kof2003","kof2003d","kof2k4se","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof97pls","kof98","kof98k","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kog","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lasthope","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","matrim","miexchng","minasan","mosyougi","mslug","mslug2","mslug2t","mslug3","mslug3n","mslug4","mslug5","mslugx","mutnat","nam1Line truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"astrocde":["280zzap","adssm","amazmaze","artiduel","artiduelp1","artiduelp2","artiduelp3","astrobat","ballypin","baseball","biorhy","blckjack","bowling","brckyard","bstdroid","buylove","candyman","checkers","claim","colbook","conan","conanp","cosmicrd","cosmicrd35","cosmicrd36","cosmicrda","cosmicrdb","dealdemo","dogpatch","eightday","fawn","fawna","feelfine","football","galactic","galacticp","golddig","golddiga","golddigb","grandprx","hardday","icbmatk","icbmatkp","letitbe","life","lttrmtch","matk","mazeman","mazemanp","mlangman","mscandy","muncher","musicmak","musicmakp","musicmakp2","nodie","pacmaze","paperbck","pirate","rainbow2","seadevil","seawolf","sheloves","sloshed","sneaky","soccer","soccera","soccera2","soccera3","soccera4","soccerp","solarcnq","solarcnqp","solarcnqp28","solarcnqp39","songs","songsa","songsu","spacefrt","spacefrtp","spaceinv","spaceinva","spaceinvf","spaceinvj","spaceinvp","spaceinvt","spedmath","sslope","starbttl","stweek","tests","treasure","treasurep","vidstory","war","wizard","yesternv","yesterv","ziggyjx","ziggymo"],"atarisy1":["indytemp","indytemp2","indytemp3","indytemp4","indytempc","indytempd","marble","marble2","marble3","marble4","marble5","peterpak","reliefs1","roadblst","roadblst1","roadblst2","roadblst3","roadblstc","roadblstc1","roadblstcg","roadblstg","roadblstg1","roadblstg2","roadblstgu","roadblstj","roadblstp","roadrunn","roadrunn1","roadrunn2"],"bubsys":["bs_gradius","bs_gwarrior","bs_rf2","bs_twinbee"],"cchip":["bonzeadv","bonzeadvo","bonzeadvp","bonzeadvp2","bonzeadvu","jigkmgri","jigkmgria","jumping","jumpinga","jumpingi","megablst","megablstj","megablstu","opwolf","opwolfa","opwolfb","opwolfj","opwolfjsc","opwolfu","rbisland","rbislandb","rbislande","rbislando","rbislands","superman","supermanj","supermanp","supermans","supermanu","volfied","volfiedj","volfiedjo","volfiedo","volfiedu","volfieduo"],"channelf":["alieninv","backgamm","builtin","casinop","clrorgan","democrt1","democrt2","dodgeit","dragrace","drawpkr","dsrtfox","hangman","lightsout","magicnum","maze","mazea","memory","mthquiz1","mthquiz2","muehle","multicrt","multicrto","ordtvlng","pfootbll","pinbacvbyred","pinball","pinballa","ratmal","robotwar","robotwarp","schach","slotmchn","sonrsrch","spacewar","spitfire","spitfirep","tctactoe","vblckjck","werbetxt","whizball","wrdlf"],"coleco":["1942sgm","1on1","2010","2010p","421","advisland","ae","aerial","alcazar","alpharoid","alphazoo","amazing","amzsnake","antarct","antarcta","antarctj","antarctk","antarctp","antiair","apshai","aquatack","aquatacka","arkadion","armagedn","arnodash","artduel","ascend","asteroids","astrododge","astroinv","awass","aztecchal","bankbuild","bankpanic","barbarricade","barnbuster","battlot","bbears","bcquest","bcquest2","bcquest2ca","bcquesta","bcquestca","bdash","bdashp","beachead","beamridr","bejeweled","bigcatch","blackonyx","blockrun","bloktris","bofhoth","bokosukawars","bombking","bomblast","bomblast2","boomingboy","boothill","bootskell","bosconian","bountybob","boxxle","brainstr","breakout","breakout23j","breakout23r","buckrogsgm","bugsbots","bullmighty","bustabobble","bustabobble2","bustinout0","bustinout1","bustinout2","bustinout3","cabbage","cabbagep1","cabbagep2","cabbagepk","cabbshow","cacorm","camknights","camknightsb","campaign","canamini","caosbgns","carfight","castelo","castle","castleex","castlek","castlet","catsos","caverns","cavfight","cavit","ccharlie","ccredux","ccrisis","chackpop","challenger","chesschal","chprowres","chucknor","cicehockey","cix","clock","coco","coldblood","coltennis","comicbakery","comicbakeryo","comspace","cotn","crackpots","cracky","crazychickyjr","crazychickyjr2","cso","csok","csot","cure","cvjoytest","cye","dacman","dacman2","dacmana","dambust","dambustca","dangrtower","datrolls","dbreakout","ddash","ddash2","deathrace","decathln","deepdngadv","deflektor","demoattackna","demonattack","desolator","destruct","destructsce","digdugsgm","dkarcade","dkjrarcade","dkongarcade","dkongjrsgm","dkongsgm","dlairsgm","dncfntsy","donuts","drgnfire","drol","drolk","drolt","drseuss","eaclassics","easterbunny","ed2083","eggerland","elecquart","elevaction","elevactionsgm","enerquiz","evolutio","explodingfoot","eyebrawls","f2ffootball","f2fhockey","f2fsoccer","facemakr","fallguy","fantasy","fathom","ffactory","ffreddy","finaltst","fireman","flapbrd","flipslip","flora","flux","fortune","fracfevr","frantic","frogfeast","frogger2","frontlinsgm","frostbite","fruitpanic","fuzzywomp","gamepack1","gamepack2","gamester81","gamewatch","gblaster","gerbils","ggarden","ghost","ghostbst","ghostbst1","ghostbsts","ghostbstse","ghostrap","gnz","golgo13","golgo13c","golgo13sc","goonies","gooniesa","gooniesb","gooniesc","gooniesoc","gooniesttc","gpvic20","gpworld","gpworlda","gpworldt","guardic","guardica","gulkave","gulkavea","gulkavek","gunfright","guntus","gustbust","hamsterww","hamurabi","hardhatmack","hazzard","hchumy","heist","helifire","heroesar","holeone","hopman","hrally","huojiche","icemuncher","iceLine truncated
|
||||
{"bios":{"astrocde":["astro_280zzap","astro_adssm","astro_amazmaze","astro_artiduel","astro_artiduelp1","astro_artiduelp2","astro_artiduelp3","astro_astrobat","astro_ballypin","astro_baseball","astro_biorhy","astro_blckjack","astro_bowling","astro_brckyard","astro_bstdroid","astro_buylove","astro_candyman","astro_cclimber","astro_checkers","astro_claim","astro_colbook","astro_conan","astro_conanp","astro_cosmicrd","astro_cosmicrd35","astro_cosmicrd36","astro_cosmicrda","astro_cosmicrdb","astro_dealdemo","astro_dogpatch","astro_eightday","astro_fawn","astro_fawna","astro_feelfine","astro_football","astro_galactic","astro_galaxian","astro_golddig","astro_golddiga","astro_golddigb","astro_grandprx","astro_hardday","astro_icbmatk","astro_icbmatkp","astro_letitbe","astro_life","astro_lttrmtch","astro_matk","astro_mazeman","astro_mazemanp","astro_mlangman","astro_mscandy","astro_muncher","astro_musicmak","astro_musicmakp","astro_musicmakp2","astro_nodie","astro_pacman","astro_pacmana","astro_pacmaze","astro_paperbck","astro_pirate","astro_rainbow2","astro_redbaron","astro_seadevil","astro_seawolf","astro_sheloves","astro_sloshed","astro_sneaky","astro_soccer","astro_soccera","astro_soccera2","astro_soccera3","astro_soccera4","astro_soccerp","astro_solarcnq","astro_solarcnqp","astro_solarcnqp28","astro_solarcnqp39","astro_songs","astro_songsa","astro_songsu","astro_spacefrt","astro_spacefrtp","astro_spaceinv","astro_spaceinvp","astro_spedmath","astro_sslope","astro_starbttl","astro_stweek","astro_tests","astro_treasure","astro_treasurep","astro_vidstory","astro_war","astro_wizard","astro_yesternv","astro_yesterv","astro_ziggyjx","astro_ziggymo"],"atarisy1":["indytemp","indytemp2","indytemp3","indytemp4","indytempc","indytempd","marble","marble2","marble3","marble4","marble5","peterpak","reliefs1","roadblst","roadblst1","roadblst2","roadblst3","roadblstc","roadblstc1","roadblstcg","roadblstg","roadblstg1","roadblstg2","roadblstgu","roadrunn","roadrunn1","roadrunn2"],"bubsys":["bs_gradius","bs_gwarrior","bs_rf2","bs_twinbee"],"cchip":["bonzeadv","bonzeadvo","bonzeadvp","bonzeadvp2","bonzeadvu","jigkmgri","jigkmgria","jumping","jumpinga","jumpingi","megablst","megablstj","megablstu","opwolf","opwolfa","opwolfb","opwolfj","opwolfjsc","opwolfu","rbisland","rbislande","rbislando","superman","supermanj","supermanu","volfied","volfiedj","volfiedjo","volfiedo","volfiedu","volfieduo"],"channelf":["chf_alieninv","chf_backgamm","chf_baseball","chf_bowling","chf_builtin","chf_casinop","chf_checkers","chf_clrorgan","chf_democrt1","chf_democrt2","chf_dodgeit","chf_dragrace","chf_drawpkr","chf_dsrtfox","chf_football","chf_galactic","chf_galacticp","chf_hangman","chf_lightsout","chf_magicnum","chf_maze","chf_mazea","chf_memory","chf_mthquiz1","chf_mthquiz2","chf_muehle","chf_multicrt","chf_multicrto","chf_ordtvlng","chf_pacman","chf_pacmanv2","chf_pfootbll","chf_pinball","chf_pinballa","chf_ratmal","chf_robotwar","chf_robotwarp","chf_schach","chf_slotmchn","chf_sonrsrch","chf_spacewar","chf_spitfire","chf_spitfirep","chf_tctactoe","chf_tetris","chf_vblckjck","chf_werbetxt","chf_whizball","chf_wrdlf"],"coleco":["cv_1942sgm","cv_1on1","cv_2010","cv_2010p","cv_421","cv_advisland","cv_ae","cv_aerial","cv_alcazar","cv_alpharoid","cv_alphazoo","cv_amazing","cv_amidar","cv_amzsnake","cv_antarct","cv_antarctp","cv_antiair","cv_apshai","cv_aquatack","cv_aquatacka","cv_arabian","cv_arkadion","cv_arkanoid","cv_armagedn","cv_arnodash","cv_artduel","cv_ascend","cv_asteroids","cv_astorm","cv_astrododge","cv_astroinv","cv_awass","cv_aztecchal","cv_bagman","cv_bankbuild","cv_bankpanic","cv_barbarricade","cv_barnbuster","cv_battlot","cv_bbears","cv_bcquest","cv_bcquest2","cv_bcquest2ca","cv_bcquestca","cv_bdash","cv_bdashp","cv_beachead","cv_beamridr","cv_bejeweled","cv_berzerk","cv_bigcatch","cv_blackonyx","cv_blockrun","cv_bloktris","cv_bnj","cv_bnjp","cv_bofhoth","cv_boggy84","cv_bokosukawars","cv_bombjack","cv_bombking","cv_bomblast","cv_bomblast2","cv_boomingboy","cv_boothill","cv_bootskell","cv_bosconian","cv_bountybob","cv_boxxle","cv_brainstr","cv_breakout","cv_breakout23j","cv_breakout23r","cv_brubber","cv_btime","cv_btimem","cv_bubbles","cv_buckrog","cv_buckrogsgm","cv_bugsbots","cv_bullmighty","cv_bustabobble","cv_bustabobble2","cv_bustinout0","cv_bustinout1","cv_bustinout2","cv_bustinout3","cv_cabbage","cv_cabbagep1","cv_cabbagep2","cv_cabbagepk","cv_cabbshow","cv_cacorm","cv_camknights","cv_camknightsb","cv_campaign","cv_canamini","cv_caosbgns","cv_carfight","cv_carnival","cv_castelo","cv_castle","cv_castleex","cv_catsos","cv_cavenger","cv_cavengera","cv_caverns","cv_cavfight","cv_cavit","cv_ccharlie","cv_ccredux","cv_ccrisis","cv_centiped","cv_chackpop","cv_challenger","cv_chesschal","cv_choplift","cv_chprowres","cv_chucknor","cv_cicehockey","cv_circus","cv_cix","cv_clock","cv_coco","cv_coldblood","cv_coltennis","cv_comicbakery","cv_comicbakeryo","cv_comspace","cv_congo","cv_cotn","cv_crackpots","cv_cracky","cv_crazychickyjr","cv_crLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"3dobios":["orbatak"],"airlbios":["alpilot"],"aleck64":["11beat","doncdoon","hipai","hipai2","kurufev","mayjin3","mtetrisc","srmvs","srmvsa","starsldr","twrshaft","vivdolls"],"alg3do":["md23do","sht3do"],"alg_bios":["aplatoon","crimep2","crimep2_11","crimepat","crimepat_10","crimepat_12","crimepat_14","fastdraw","fastdraw_130","gallgall","gallgall_21","lastbh","lastbh_006","maddog","maddog2","maddog2_100","maddog2_110","maddog2_202","maddog_202","maddoga","marvice","marvice100hz","spacepir","spacepir_14","tierras100hz","wsjr","wsjr_15","zortonbr","zortonbr_100"],"allied":["circa33","disco79","erosone","foathens","heartspd","hoedown","royclark","starshot","suprpick","takefive","thndbolt"],"ar_bios":["ar_airh","ar_airh2","ar_argh","ar_blast","ar_bowl","ar_dart","ar_dart2","ar_dlta","ar_fast","ar_fasta","ar_ldrb","ar_ldrba","ar_ldrbb","ar_ninj","ar_ninj2","ar_pm","ar_rdwr","ar_sdwr","ar_sdwr2","ar_socc","ar_spot","ar_sprg","ar_xeon"],"aristmk5":["adonis","adonisa","adonisce","adonisu","alchemst","baddog","blackpnt","bootsctn","bootsctnu","bootsctnua","bootsctnub","bparty","bpartya","bumblbug","bumblbugql","bumblbugu","bumblbugua","buttdeli","canrose","cashcat","cashcata","cashcatnz","cashcham","cashchama","cashchamnz","cashchamu","cashcra5","cashcra5a","chariotc","chariotcv","checkma5","chickna5","chickna5ql","chickna5u","chickna5ua","chickna5v","coralrc2","cuckoo","cuckoou","diamdest","diamdove","dimtouch","dmdfever","dolphntr","dolphntra","dolphntrb","dolphntrce","dolphntrcea","dolphntrceb","dolphntrql","dolphntru","dreamwv","drgneye","dstbloom","dstblooma","dynajack","dynajacku","eforsta5","eforsta5ce","eforsta5cea","eforsta5u","eforsta5ua","eldorda5","fastfort","fortellr","fortfvr","gambler","geisha","genmagi","glizrdce","gnomeatw","goldenra","goldpyr","goldpyra","goldpyrb","hnktonku","honeypot","incasun","incasunnz","incasunsp","incasunu","incasunua","incasunv","indrema5","indrema5ql","jumpbean","jumpjoey","jungjuic","kgalah","kgalaha","kgalahce","kgbirda5","koalamnt","kookabuk","kyhatonu","locoloot","locoloota","locolootnz","locolootu","lonewolf","luckyclo","magimask","magimaska","magimaskb","magtcha5","magtcha5a","mammothm","marmagic","marmagicu","marmagicua","mgarden","minemine","minemineu","minemineua","monmouse","monmousea","montree","mountmon","mountmona","mountmonce","mountmonu","mountmonua","multidrw","mystgard","one4all","orchidms","orchidmsa","orchidmsnz","oscara5","oscara5a","pantmag","pantmaga","partygrs","partygrsa","partygrsb","peaflut","peafluta","pengpay","pengpaya","pengpayb","pengpayc","pengpayce","pengpayd","pengpayu","pengpayua","pengpayub","pengpuck","penpir","penpir2","penpira","petshop","petshopa","phantpay","phantpyc","przfight","qcash","qnile","qnilea","qnileb","qnilebr","qnilec","qnilece","qnilecea","qnileceb","qniled","qnilefl","qnilemax","qnilenl","qnilenz","qnileql","qnileu","qnileua","qnilev","qtbird","rainwarr","rainwarrce","reelpwr","reelrock","reelrockql","retrsam","retrsama","retrsamb","rushrst","sbuk2","sbuk2a","sbuk3","sbuk3a","sldeluxe","slvrwolf","snowcat","sumospin","swhr2","swhr2a","swhr2u","swhr2v","thndh","thndha","thor","topbana","toutango","toutangonl","tritreat","trojhors","trpdlght","trpdlghtu","trstrove","unicornd","unicornda","unicorndnz","unicorndu","venicea5","wafricau","wamazon","wamazona","wamazonv","wcougar","wcougaru","wcougarua","wcougarub","wcougaruc","wcoyote","wikwin","wildbill","wizways","wldangel","wnpost","wthing","wthinga","wtiger","yukongl5"],"aristmk6":["100lions","100lionsa","15lions","50lionrr","50lions","50lionsa","50lionsu","5drag","5draga","5dragce","5dragnz","5dragsp","5koi","5koia","adonisa6","aduskcm","afterhrs","alchemy","amzqueen","amztempl","antcleo","antcleoa","apocof","arabnga6","arabnga6a","arabnga6u","arish","arwincm","asnprinc","atkgld","beavbuk","betzoo","bigben","bigbena","bigbenb","bigbenq","bigheart","bigred","bigred2","bigreda","blkbrum","blkmust","bluetigr","bmbugs","bobdolly","brazil","brazila","bucaneer","bucaneera","bucaneeru","buckstop","buffalo","buffaloa","buffalou","bushrngr","cactusco","callwld","calyking","canaryrc","centrion","cinhell","cmtonig","corrida","cryspri","cryspria","cryspriu","csd","csda","csdce","csdjc","csdq","csdsp","csret","dblagent","dbldolph","dbldolphq","deepfrz","deepfrzu","deltabel","deltaqn","di4ever","diamhrts","dimeye","dimeyece","dimeyeu","dinosa6","doltra6","doltra6nz","drgnlord","drgnmgic","drmcatch","drmcatcha","drmred","dstgold","eaglrock","eastland","efce","eggsrccm","enchantr","encspell","eott","estrike","firednc","firednca","flamolce","flamoljc","followst","fortath","fortking","frogwld","gambjack","gbmoney","geishaa6","geishaa6a","geishaa6b","geishajc","gldgong","gldgongq","gldgongu","gldnflc","goape","gogreen","gogreena","goldarch","goldinc","goldincu","goldpya6","goldpym","goldsam","grizzly","gwnn","heartgld","heartglda","heartveg","highnoon","hlntroy","hlntroya","hlntroyb","hlntroyc","hlntroyu","holdrma6","holdrma6a","househrt","househrta","incachf","indgldcm","indprnLine truncated
|
||||
{"bios":{"3dobios":["orbatak"],"airlbios":["alpilot"],"aleck64":["11beat","doncdoon","hipai","hipai2","kurufev","mayjin3","mtetrisc","srmvs","srmvsa","starsldr","twrshaft","vivdolls"],"alg3do":["md23do","sht3do"],"alg_bios":["aplatoon","crimep2","crimep2_11","crimepat","crimepat_10","crimepat_12","crimepat_14","fastdraw","fastdraw_130","gallgall","gallgall_21","lastbh","lastbh_006","maddog","maddog2","maddog2_100","maddog2_110","maddog2_202","maddog_202","maddoga","marvice","marvice100hz","spacepir","spacepir_14","tierras100hz","wsjr","wsjr_15","zortonbr","zortonbr_100"],"allied":["circa33","disco79","erosone","foathens","heartspd","hoedown","royclark","starshot","suprpick","takefive","thndbolt"],"ar_bios":["ar_airh","ar_airh2","ar_argh","ar_blast","ar_bowl","ar_dart","ar_dart2","ar_dlta","ar_fast","ar_fasta","ar_ldrb","ar_ldrba","ar_ldrbb","ar_ninj","ar_ninj2","ar_pm","ar_rdwr","ar_sdwr","ar_sdwr2","ar_socc","ar_spot","ar_sprg","ar_xeon"],"aristmk5":["adonis","adonisa","adonisce","adonisu","alchemst","baddog","blackpnt","bootsctn","bootsctnu","bootsctnua","bootsctnub","bparty","bpartya","bumblbug","bumblbugql","bumblbugu","bumblbugua","buttdeli","canrose","cashcat","cashcata","cashcatnz","cashcham","cashchama","cashchamnz","cashchamu","cashcra5","cashcra5a","chariotc","chariotcv","checkma5","chickna5","chickna5ql","chickna5u","chickna5ua","chickna5v","coralrc2","cuckoo","cuckoou","diamdest","diamdove","dimtouch","dmdfever","dolphntr","dolphntra","dolphntrb","dolphntrce","dolphntrcea","dolphntrceb","dolphntrql","dolphntru","dreamwv","drgneye","dstbloom","dstblooma","dynajack","dynajacku","eforsta5","eforsta5ce","eforsta5cea","eforsta5u","eforsta5ua","eldorda5","fastfort","fortellr","fortfvr","gambler","geisha","genmagi","glizrdce","gnomeatw","goldenra","goldpyr","goldpyra","goldpyrb","hnktonku","honeypot","incasun","incasunnz","incasunsp","incasunu","incasunua","incasunv","indrema5","indrema5ql","jumpbean","jumpjoey","jungjuic","kgalah","kgalaha","kgalahce","kgbirda5","koalamnt","kookabuk","kyhatonu","locoloot","locoloota","locolootnz","locolootu","lonewolf","luckyclo","magimask","magimaska","magimaskb","magtcha5","magtcha5a","mammothm","marmagic","marmagicu","marmagicua","mgarden","minemine","minemineu","minemineua","monmouse","monmousea","montree","mountmon","mountmona","mountmonce","mountmonu","mountmonua","multidrw","mystgard","one4all","orchidms","orchidmsa","orchidmsnz","oscara5","oscara5a","pantmag","pantmaga","partygrs","partygrsa","partygrsb","peaflut","peafluta","pengpay","pengpaya","pengpayb","pengpayc","pengpayce","pengpayd","pengpayu","pengpayua","pengpayub","pengpuck","penpir","penpir2","penpira","petshop","petshopa","phantpay","phantpyc","przfight","qcash","qnile","qnilea","qnileb","qnilebr","qnilec","qnilece","qnilecea","qnileceb","qniled","qnilefl","qnilemax","qnilenl","qnilenz","qnileql","qnileu","qnileua","qnilev","qtbird","rainwarr","rainwarrce","reelpwr","reelrock","reelrockql","retrsam","retrsama","retrsamb","rushrst","sbuk2","sbuk2a","sbuk3","sbuk3a","sldeluxe","slvrwolf","snowcat","sumospin","swhr2","swhr2a","swhr2u","swhr2v","thndh","thndha","thor","topbana","toutango","toutangonl","tritreat","trojhors","trpdlght","trpdlghtu","trstrove","unicornd","unicornda","unicorndnz","unicorndu","venicea5","wafricau","wamazon","wamazona","wamazonv","wcougar","wcougaru","wcougarua","wcougarub","wcougaruc","wcoyote","wikwin","wildbill","wizways","wldangel","wnpost","wthing","wthinga","wtiger","yukongl5"],"aristmk6":["100lions","100lionsa","15lions","50lionrr","50lions","50lionsa","50lionsu","5drag","5draga","5dragce","5dragnz","5dragsp","5koi","5koia","adonisa6","aduskcm","afterhrs","alchemy","amzqueen","amztempl","antcleo","antcleoa","apocof","arabnga6","arabnga6a","arabnga6u","arish","arwincm","asnprinc","atkgld","beavbuk","betzoo","bigben","bigbena","bigbenb","bigbenq","bigheart","bigred","bigred2","bigreda","blkbrum","blkmust","bluetigr","bmbugs","bobdolly","brazil","brazila","bucaneer","bucaneera","bucaneeru","buckstop","buffalo","buffaloa","buffalou","bushrngr","cactusco","callwld","calyking","canaryrc","centrion","cinhell","cmtonig","corrida","cryspri","cryspria","cryspriu","csd","csda","csdce","csdjc","csdq","csdsp","csret","dblagent","dbldolph","dbldolphq","deepfrz","deepfrzu","deltabel","deltaqn","di4ever","diamhrts","dimeye","dimeyece","dimeyeu","dinosa6","doltra6","doltra6nz","drgnlord","drgnmgic","drmcatch","drmcatcha","drmred","dstgold","eaglrock","eastland","efce","eggsrccm","enchantr","encspell","eott","estrike","firednc","firednca","flamolce","flamoljc","followst","fortath","fortking","frogwld","gambjack","gbmoney","geishaa6","geishaa6a","geishaa6b","geishajc","gldgong","gldgongq","gldgongu","gldnflc","goape","gogreen","gogreena","goldarch","goldinc","goldincu","goldpya6","goldpym","goldsam","grizzly","gwnn","heartgld","heartglda","heartveg","highnoon","hlntroy","hlntroya","hlntroyb","hlntroyc","hlntroyu","holdrma6","holdrma6a","househrt","househrta","incachf","indgldcm","indprnLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","cyberlip","doubledr","eightman","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","flipshot","galaxyfg","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof94","kof95","kof96","kof97","kof98","kotm","kotm2","lastblad","lastbld2","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","overtop","panicbom","pbobble","pgoal","popbounc","pspikes2","pulstar","puzbobb","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbffspec","ridhero","roboarmy","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh2","wh2j","whp","wjammers","zedblade"]},"bios_sets":["neogeo"],"chd":[],"core_version":"0.37b5","counts":{"bios_roots_used":1,"bios_sets":1,"chd_games":0,"games":2240,"games_with_bios":128,"games_with_devices":0,"missing_parents":0,"sets":2241},"devices":{},"missing_parents":{},"no_bios":["005","1941","1941j","1942","1942a","1942b","1943","1943j","1943kai","280zzzap","3stooges","3wonders","4dwarrio","600","64streej","64street","720","720b","800fath","88games","99lstwar","99lstwra","aafb","aafbb","aafbd2p","abaseb","abaseb2","actfanc1","actfancj","actfancr","aeroboto","aerofgt","aerofgtb","aerofgtc","airbustr","airduel","airwolf","ajax","ajaxj","alcon","alexkida","alexkidd","alibaba","alieninv","aliens","aliens2","aliensj","aliensu","aliensya","aliensyb","aliensyj","aliensyn","alleymas","alpine","alpinea","altbeas2","altbeast","ambush","amidar","amidaro","amidars","amidaru","amigo","anteater","apb","apb2","appoooh","arabian","arabiana","arbalest","arcadecl","archriv2","archrivl","area88","ark2jp","ark2us","arkangc","arkanoi2","arkanoid","arkarea","arkatayt","arkatour","arkbl2","arkbloc2","arknoidj","arknoidu","armedf","armora","armorca2","armorcar","armwrest","ashura","ashurau","aso","assault","assaultj","assaultp","astdelu1","astdelux","asteroi1","asteroib","asteroid","astinvad","astorm","astorm2p","astormbl","astrob","astrob1","astrob2","astrof","astrof2","astrof3","astyanax","atarifb","atarifb1","atarifb4","ataxx","ataxxa","ataxxj","atetckt2","atetcktl","atetris","atetrisa","atetrisb","athena","atlantis","atlants2","atomicp","aurail","auraila","avalnche","avenger2","avengers","avspirit","aztarac","azurian","baddudes","badlands","bagman","bagmans","bagmans2","bagnard","ballbomb","baluba","bandido","bankp","baraduke","barrier","basebal2","batman","batsugun","battlan2","battlan3","battlane","battlera","battlntj","battlnts","battroad","bayrouta","bayroute","bayrtbl1","bayrtbl2","bbros","bchopper","beastf","berabohm","berlwall","berlwalt","bermudaa","bermudaj","bermudat","berzerk","berzerk1","bigprowr","bigstrik","billiard","bioatack","bionicc","bionicc2","bjtwin","bking2","bktigerb","bladestl","bladstle","blandia","blasted","blaster","blasto","blastoff","blazer","blckgalb","blckout2","bldwolf","blkdrgnb","blkdrgon","blkhole","blktiger","block","blockade","blockbl","blocken","blockgal","blockhl","blockj","blockout","bloodbro","blsthead","blstroi2","blstroid","blswhstl","blueprnj","blueprnt","blueshrk","bmaster","bnj","boblbobl","bodyslam","bogeyman","bombbee","bombjac2","bombjack","bootcamp","boothill","bosco","boscomd","boscomdo","boscoo","boscoo2","bottom9","bottom9n","bouldash","bowler","bowlrama","boxingb","brain","breywood","brix","brkthru","brkthruj","brubber","brutforc","bsktball","btime","btime2","btimem","btlfield","bubbles","bubblesr","bubbobr1","bublbobl","bublbobr","bullfgtj","burnforc","bwidow","bzone","bzone2","cabal","cabal2","cabalbl","cachat","calibr50","calipso","cameltru","cameltry","canbprot","canyon","capbowl","capbowl2","captcomj","captcomm","captcomu","caractn","carnival","carnvckt","cavenger","cawing","cawingj","cbasebal","cbuster","cbusterj","cbusterw","ccastle2","ccastles","ccboot","ccboot2","cchasm","cchasm1","cclimber","cclimbr2","cclimbrj","centipb2","centipd2","centipdb","centiped","cerberus","challeng","champbas","champbb2","champbbj","champwr","champwrj","champwru","changes","checkmaj","checkman","checkmat","cheekyms","chelnov","chelnovj","cheyenne","chikij","chiller","chimerab","chopper","chplft","chplftb","chplftbl","chukatai","circus","circusc","circusc2","circuscc","circusce","cischeat","citycon","citycona","ckong","ckonga","ckongalc","ckongjeu","ckongo","ckongs","claypign","clbowl","cloak","cloud9","clowns","cninja","cninja0","cninjLine truncated
|
||||
{"bios":{"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","cyberlip","doubledr","eightman","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","flipshot","galaxyfg","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof94","kof95","kof96","kof97","kof98","kotm","kotm2","lastblad","lastbld2","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","overtop","panicbom","pbobble","pgoal","popbounc","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbffspec","ridhero","roboarmy","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh2","wh2j","whp","wjammers","zedblade"]},"bios_sets":["neogeo"],"chd":[],"core_version":"0.37b5","counts":{"bios_roots_used":1,"bios_sets":1,"chd_games":0,"games":2271,"games_with_bios":127,"games_with_devices":0,"missing_parents":0,"sets":2272},"devices":{},"missing_parents":{},"no_bios":["005","1941","1941j","1942","1942a","1942b","1943","1943j","1943kai","280zzzap","3stooges","3wonders","4dwarrio","600","64streej","64street","720","720b","800fath","88games","99lstwar","99lstwra","aafb","aafbb","aafbd2p","abaseb","abaseb2","actfanc1","actfancj","actfancr","aeroboto","aerofgt","aerofgtb","aerofgtc","airbustr","airduel","airwolf","ajax","ajaxj","alcon","alexkida","alexkidd","alibaba","alieninv","aliens","aliens2","aliensj","aliensu","aliensya","aliensyb","aliensyj","aliensyn","alleymas","alpine","alpinea","altbeas2","altbeast","ambush","amidar","amidaro","amidars","amidaru","amigo","anteater","apb","apb2","appoooh","arabian","arabiana","arbalest","arcadecl","archriv2","archrivl","area88","argus","ark2jp","ark2us","arkangc","arkanoi2","arkanoid","arkarea","arkatayt","arkatour","arkbl2","arkbloc2","arknoidj","arknoidu","armedf","armora","armorca2","armorcar","armwrest","ashura","ashurau","aso","assault","assaultj","assaultp","astdelu1","astdelux","asteroi1","asteroib","asteroid","astinvad","astorm","astorm2p","astormbl","astrob","astrob1","astrob2","astrof","astrof2","astrof3","astyanax","atarifb","atarifb1","atarifb4","ataxx","ataxxa","ataxxj","atetckt2","atetcktl","atetris","atetrisa","atetrisb","athena","atlantis","atlants2","atomicp","aurail","auraila","avalnche","avenger2","avengers","avspirit","aztarac","azurian","baddudes","badlands","bagman","bagmans","bagmans2","bagnard","ballbomb","baluba","bandido","bankp","baraduke","barrier","basebal2","batman","batsugun","battlan2","battlan3","battlane","battlera","battlntj","battlnts","battroad","batugnsp","bayrouta","bayroute","bayrtbl1","bayrtbl2","bbros","bchopper","beastf","berabohm","berlwall","berlwalt","bermudaa","bermudaj","bermudat","berzerk","berzerk1","bigkarnk","bigprowr","bigstrik","billiard","bioatack","biomtoy","bionicc","bionicc2","bjtwin","bking2","bktigerb","bladestl","bladstle","blandia","blasted","blaster","blasto","blastoff","blazer","blckgalb","blckout2","bldwolf","blkdrgnb","blkdrgon","blkhole","blktiger","block","blockade","blockbl","blocken","blockgal","blockhl","blockj","blockout","bloodbro","blsthead","blstroi2","blstroid","blswhstl","blueprnj","blueprnt","blueshrk","bmaster","bnj","boblbobl","bodyslam","bogeyman","bombbee","bombjac2","bombjack","bootcamp","boothill","bosco","boscomd","boscomdo","boscoo","boscoo2","bottom9","bottom9n","bouldash","bowler","bowlrama","boxingb","brain","breywood","brix","brkthru","brkthruj","brubber","brutforc","bsktball","btime","btime2","btimem","btlfield","bubbles","bubblesr","bubbobr1","bublbobl","bublbobr","bullfgtj","burnforc","butasan","bwidow","bzone","bzone2","cabal","cabal2","cabalbl","cachat","calibr50","calipso","cameltru","cameltry","canbprot","canyon","capbowl","capbowl2","captcomj","captcomm","captcomu","caractn","carnival","carnvckt","cavenger","cawing","cawingj","cbasebal","cbuster","cbusterj","cbusterw","ccastle2","ccastles","ccboot","ccboot2","cchasm","cchasm1","cclimber","cclimbr2","cclimbrj","centipb2","centipd2","centipdb","centiped","cerberus","challeng","champbas","champbb2","champbbj","champwr","champwrj","champwru","changes","checkmaj","checkman","checkmat","cheekyms","chelnov","chelnovj","cheyenne","chikij","chiller","chimerab","chopper","chplft","chplftb","chplftbl","chukatai","circus","circusc","circusc2","circuscc","circusce","cischeat","citycon","citycona","ckong","ckonga","ckongalc","ckongjeu","ckongo","ckongs","claypign","clbowl","cloak","clLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"acpsx":["jdredd","jdreddb","nbajamex"],"cpzn1":["glpracr","jgakuen","rvschool","sfex","sfexj","sfexp","sfexpj","starglad","tgmj","ts2","ts2j"],"cpzn2":["kikaioh","sfex2","sfex2p","sg2j","shiryu2","strider2","stridr2a","techromn"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmissnx","cnights2","cnightst","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_gaxe2","mp_sonic"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","ctomaday","cyberlip","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof2000","kof2000n","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof98","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mslug3","mslug3n","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","s1945p","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","zedblade"],"nss":["nss_actr","nss_adam","nss_aten","nss_con3","nss_fzer","nss_lwep","nss_ncaa","nss_rob3","nss_skin","nss_smw","nss_ssoc","nss_sten"],"pgm":["dragwld2","kov","kov115","kovplus","kovsh","orlegend","orlegndc","orlegnde","photoy2k"],"playch10":["pc_1942","pc_bball","pc_bfght","pc_bstar","pc_cntra","pc_cshwk","pc_cvnia","pc_dbldr","pc_ddrgn","pc_drmro","pc_duckh","pc_ebike","pc_ftqst","pc_gntlt","pc_golf","pc_goons","pc_grdue","pc_grdus","pc_hgaly","pc_kngfu","pc_mario","pc_miket","pc_mman3","pc_moglf","pc_mtoid","pc_ngai2","pc_ngai3","pc_ngaid","pc_pinbt","pc_pwbld","pc_pwrst","pc_radr2","pc_radrc","pc_rcpam","pc_rkats","pc_rnatk","pc_rrngr","pc_rygar","pc_sjetm","pc_smb","pc_smb2","pc_smb3","pc_suprc","pc_tbowl","pc_tenis","pc_tkfld","pc_tmnt","pc_tmnt2","pc_trjan","pc_vball","pc_wcup","pc_wgnmn","pc_ynoid"],"skns":["cyvern","galpani4","galpanis","galpans2","gutsn","jjparad2","jjparads","panicstr","puzloopj","puzloopu","puzzloop","ryouran","sarukani","sengekij","sengekis","senknow","teljan","vblokbrk"],"stvbios":["astrass","bakubaku","batmanfr","colmns97","cotton2","cottonbm","danchih","decathlt","diehard","dnmtdeka","ejihon","elandore","ffreveng","fhboxers","findlove","finlarch","gaxeduel","grdforce","groovef","hanagumi","introdon","kiwames","maruchan","mausuke","myfairld","othellos","pblbeach","prikura","puyosun","rsgun","sandor","sassisu","seabass","shanhigw","shienryu","sleague","sokyugrt","sss","suikoenb","thunt","twcup98","vfkids","vfremix","vmahjong","winterht","znpwfv"],"taitofx1":["beastrzb","ftimpcta","gdarius","gdarius2","mgcldate","mgcldtea","psyforce","raystorm","sfchamp"],"tps":["doapp","glprac2j","glprac2l","glpracr2","tondemo"]},"bios_sets":["acpsx","cpzn1","cpzn2","cvs","decocass","konamigx","megaplay","megatech","neogeo","nss","pgm","playch10","skns","stvbios","taitofx1","tps"],"chd":["a51mxr3k","area51","area51mx","biofreak","blitz","blitz2k","blitz99","bm1stmix","bm2ndmix","bm2ndmxaLine truncated
|
||||
{"bios":{"acpsx":["jdredd","jdreddb","nbajamex"],"cpzn1":["glpracr","jgakuen","rvschool","sfex","sfexj","sfexp","sfexpj","starglad","tgmj","ts2","ts2j"],"cpzn2":["kikaioh","sfex2","sfex2p","sg2j","shiryu2","strider2","stridr2a","techromn"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmissnx","cnights2","cnightst","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_gaxe2","mp_sonic"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"namcoc76":["tekken","tekken2","tekken2a","tekken2b","tekkena","tekkenb"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","crsword","ctomaday","cyberlip","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","goalx3","gowcaizr","gpilots","gururin","irrmaze","janshin","joyjoy","kabukikl","karnovr","kizuna","kof2000","kof2000n","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof98","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","miexchng","minasan","mosyougi","mslug","mslug2","mslug3","mslug3n","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","s1945p","samsho","samsho2","samsho3","samsho4","savagere","sdodgeb","sengokh","sengoku","sengoku2","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","zedblade"],"nss":["nss_actr","nss_adam","nss_aten","nss_con3","nss_fzer","nss_lwep","nss_ncaa","nss_rob3","nss_skin","nss_smw","nss_ssoc","nss_sten"],"pgm":["dragwld2","kov","kov115","kovplus","kovsh","orlegend","orlegndc","orlegnde","photoy2k"],"playch10":["pc_1942","pc_bball","pc_bfght","pc_bstar","pc_cntra","pc_cshwk","pc_cvnia","pc_dbldr","pc_ddrgn","pc_drmro","pc_duckh","pc_ebike","pc_ftqst","pc_gntlt","pc_golf","pc_goons","pc_grdue","pc_grdus","pc_hgaly","pc_kngfu","pc_mario","pc_miket","pc_mman3","pc_moglf","pc_mtoid","pc_ngai2","pc_ngai3","pc_ngaid","pc_pinbt","pc_pwbld","pc_pwrst","pc_radr2","pc_radrc","pc_rcpam","pc_rkats","pc_rnatk","pc_rrngr","pc_rygar","pc_sjetm","pc_smb","pc_smb2","pc_smb3","pc_suprc","pc_tbowl","pc_tenis","pc_tkfld","pc_tmnt","pc_tmnt2","pc_trjan","pc_vball","pc_wcup","pc_wgnmn","pc_ynoid"],"skns":["cyvern","galpani4","galpanis","galpans2","gutsn","jjparad2","jjparads","panicstr","puzloopj","puzloopu","puzzloop","ryouran","sarukani","sengekij","sengekis","senknow","teljan","vblokbrk"],"stvbios":["astrass","bakubaku","batmanfr","colmns97","cotton2","cottonbm","danchih","decathlt","diehard","dnmtdeka","ejihon","elandore","ffreveng","fhboxers","findlove","finlarch","gaxeduel","grdforce","groovef","hanagumi","introdon","kiwames","maruchan","mausuke","myfairld","othellos","pblbeach","prikura","puyosun","rsgun","sandor","sassisu","seabass","shanhigw","shienryu","sleague","sokyugrt","sss","suikoenb","thunt","twcup98","vfkids","vfremix","vmahjong","winterht","znpwfv"],"taitofx1":["beastrzb","ftimpcta","gdarius","gdarius2","mgcldate","mgcldtea","psyforce","raystorm","sfchamp"],"tps":["doapp","glprac2j","glprac2l","glpracr2","tondemo"]},"bios_sets":["acpsx","cpzn1","cpzn2","cvs","decocass","konamigx","megaplay","megatech","namcoc76","neogeo","nss","pgm","playch10","psarc95","skns","stvbios","taitofx1","tps"],"chd":["a51mxLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"bios":{"acpsx":["nbajamex"],"coh1000a":["jdredd","jdreddb"],"coh1000c":["glpracr","glpracrj","sfex","sfexa","sfexj","sfexp","sfexpj","sfexpj1","sfexpu1","sfexu","starglad","stargladj","ts2","ts2j","ts2ja","ts2u","ts2ua"],"coh1000t":["ftimpact","ftimpactj","ftimpactu","ftimpcta","gdarius","gdarius2","gdariusj","gdariusu","mgcldate","mgcldtex","psyforce","psyforcej","psyforcex","raystorm","raystormj","raystormo","raystormu","sfchamp","sfchampj","sfchampo","sfchampu"],"coh1002m":["1on1gov","brvblade","brvbladea","brvbladej","brvbladeu","cbaj","cbajbl","doapp","doappk","flamegun","flamegunj","glpracr2","glpracr2j","glpracr2l","glpracr3","glpracr3j","lpadv","mfjump","shngmtkb","tblkkuzu","tondemo","twcupmil"],"coh3002c":["jgakuen","jgakuen1","kikaioh","plsmaswd","plsmaswda","rvschool","rvschoola","rvschoolu","sfex2","sfex2a","sfex2h","sfex2j","sfex2p","sfex2pa","sfex2ph","sfex2pj","sfex2pu","sfex2u","sfex2u1","shiryu2","stargld2","strider2","strider2a","strider2u","techromn","techromna","techromnu","tgmj"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","diggerc","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["cadanglr","castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cfishing","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmanhat","cmissnx","cnights2","cnightst","coozumou","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csdtenis","cskater","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoona","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","sexyparoa","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_addams","mp_bio","mp_col3","mp_gaxe2","mp_gslam","mp_gunhe","mp_mazin","mp_shnb3","mp_soni2","mp_sonic","mp_sor2","mp_twc"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"namcoc76":["danceyes","danceyesj","danceyesu","dunkmnia","dunkmniajc","myangel3","pocketrc","primglex","souledge","souledgea","souledgeja","souledgeua","souledgeuc","starswep","starswepj","tekken","tekken2","tekken2a","tekken2b","tekken2jb","tekken2jc","tekken2ua","tekken2ub","tekken2ud","tekkenac","tekkenb","tekkenjb","xevi3dg","xevi3dga","xevi3dgj"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","b2b","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","captainbarrel","crswd2bl","crsword","ct2k3sp","cthd2003","ctomaday","cyberlip","cyborgforce","doubled1","doubled1a","doubled1b","doubled1c","doubled1d","doubled1e","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","ghostlop","gladmort","goalx3","gowcaizr","gpilots","gururin","hypernoid","ironclad","irrmaze","janshin","joyjoy","kabukikl","karnovr","kf10thep","kf2k2mp","kf2k2mp2","kf2k2pla","kf2k2pls","kf2k3bl","kf2k3bla","kf2k3pl","kf2k3upl","kf2k5uni","kizuna","knightsch","kof10th","kof2000","kof2000n","kof2001","kof2001h","kof2002","kof2003","kof2003d","kof2k4se","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof97pls","kof98","kof98k","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kog","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lasthope","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","matrim","miexchng","minasan","mosyougi","mslug","mslug2","mslug2t","mslug3","mslug3n","mslug4","mslug5","mslugx","mutnat","nam1975","ncombat","ncommand","neobombe","neocup98","neodrift","neomrdo","ninjamas","nitd","overtop","panicbom","pbobbl2n","pbobblen","pbobblna","pgoal","pnyaa","popbounc","preisle2","pspikes2","pulstar","puzzldpr","puzzledp","quizdai2","quizdais","quizkof","ragnagrd","rbff1","rbff2","rbff2a","rbffspec","ridhero","ridheroh","roboarmy","rotd","s1945p","samsh5sp","samsho","samsho2","samsho3","samsho4","samsho5","savagere","sdodgeb","sengokh","sengoku","sengoku2","sengoku3","shocktr2","shocktra","shocktro","socbrawl","sonicwi2","sonicwi3","spinmast","ssideki","ssideki2","ssideki3","ssideki4","stakwin","stakwin2","strhoop","superspy","svc","svcboot","svcplus","svcplusa","svcsplus","teot","tophuntr","tpgolf","trally","turfmast","twinspri","tws96","viewpoin","wakuwak7","wh1","wh1h","wh2","wh2j","whp","wjammers","xeno","zedblade","zintrckb","zupapa"],"nss":["nss_actr","nss_Line truncated
|
||||
{"bios":{"coh1000a":["jdredd","jdreddb","nbajamex","nbajamexa"],"coh1000c":["glpracr","glpracrj","sfex","sfexa","sfexj","sfexp","sfexpj","sfexpj1","sfexpu1","sfexu","starglad","stargladj","ts2","ts2j","ts2ja","ts2u","ts2ua"],"coh1000t":["ftimpact","ftimpactj","ftimpactu","ftimpcta","gdarius","gdarius2","gdariusj","gdariusu","mgcldate","mgcldtex","psyforce","psyforcej","psyforcex","raystorm","raystormj","raystormo","raystormu","sfchamp","sfchampj","sfchampo","sfchampu"],"coh1000w":["primrag2"],"coh1001l":["hvnsgate"],"coh1002e":["beastrzr","beastrzra","beastrzrb","bldyroar","bldyror2","bldyror2a","bldyror2j","bldyror2u"],"coh1002m":["1on1gov","brvblade","brvbladea","brvbladej","brvbladeu","cbaj","cbajbl","doapp","doappk","flamegun","flamegunj","glpracr2","glpracr2j","glpracr2l","glpracr3","glpracr3j","lpadv","mfjump","shngmtkb","tblkkuzu","tondemo","twcupmil"],"coh1002t":["mawasunda"],"coh1002v":["aerofgts","aerofgtst","sncwgltd"],"coh3002c":["jgakuen","jgakuen1","kikaioh","plsmaswd","plsmaswda","rvschool","rvschoola","rvschoolu","sfex2","sfex2a","sfex2h","sfex2j","sfex2p","sfex2pa","sfex2ph","sfex2pj","sfex2pu","sfex2u","sfex2u1","shiryu2","stargld2","strider2","strider2a","strider2u","techromn","techromna","techromnu","tgmj"],"coh3002t":["aerofgtsg","brvbladeg","chaoshea","chaosheaj","flamegung","flipmaze","ftimpactg","gdariusg","gobyrc","kollon","kollonc","mahjngoh","nightrai","otenamhf","otenamih","otenki","psyvaria","psyvarij","psyvarrv","raycris","raycrisj","raystormg","rcdego","shanghss","shangtou","shikigam","shikigama","shngmtkbg","sianniv","soutenry","spuzbobl","spuzboblj","tblkkuzug","usagi","xiistag","zokuoten","zokuotena","zooo"],"cvs":["8ball","8ball1","cosmos","darkwar","dazzler","diggerc","goldbug","heartatk","herbiedk","hero","herodk","herodku","hunchbak","hunchbkd","hunchbks","huncholy","logger","outline","radarzn1","radarznt","radarzon","sbdk","spacefrt","superbik","wallst"],"decocass":["cadanglr","castfant","cbdash","cbnj","cbtime","cburnrb2","cburnrub","cdiscon1","cexplore","cfghtice","cfishing","cflyball","cgraplop","cgraplp2","chwy","clapapa","clapapa2","clocknch","cluckypo","cmanhat","cmissnx","cnights2","cnightst","coozumou","cppicf","cppicf2","cprobowl","cprogolf","cprosocc","cptennis","cscrtry","cscrtry2","csdtenis","cskater","csuperas","csweetht","cterrani","ctisland","ctislnd2","ctislnd3","ctornado","ctsttape","czeroize"],"konamigx":["daiskiss","dragoona","dragoonj","fantjour","ggreats2","gokuparo","le2","le2u","opengolf","puzldama","racinfrc","rungun2","rushhero","salmndr2","sexyparo","sexyparoa","slamdnk2","soccerss","tbyahhoo","tkmmpzdm","tokkae","vsnetscr","winspike"],"megaplay":["mp_addams","mp_bio","mp_col3","mp_gaxe2","mp_gslam","mp_gunhe","mp_mazin","mp_shnb3","mp_soni2","mp_sonic","mp_sor2","mp_twc"],"megatech":["mt_aftrb","mt_astro","mt_bbros","mt_beast","mt_eswat","mt_fshrk","mt_gaxe","mt_gaxe2","mt_ggolf","mt_gng","mt_gsocr","mt_kcham","mt_lastb","mt_mwalk","mt_mystd","mt_parlg","mt_revsh","mt_shar2","mt_shnbi","mt_smgp","mt_sonic","mt_stbld","mt_tetri","mt_tfor2","mt_tgolf","mt_tlbba","mt_wcsoc"],"model1io":["daytona","daytona93","daytonagtx","daytonam","daytonas","daytonase","daytonat","daytonata","desert"],"model1io2":["vcop","vcopa"],"namcoc76":["danceyes","danceyesj","danceyesu","dunkmnia","dunkmniajc","gunbarl","gunbarla","myangel3","pocketrc","primglex","ptblank2","ptblank2a","ptblank2b","ptblank2c","ptblank2ua","souledge","souledgea","souledgeja","souledgeua","souledgeuc","starswep","starswepj","tekken","tekken2","tekken2a","tekken2b","tekken2jb","tekken2jc","tekken2ua","tekken2ub","tekken2ud","tekkenac","tekkenb","tekkenjb","xevi3dg","xevi3dga","xevi3dgj"],"neogeo":["2020bb","2020bbh","3countb","alpham2","androdun","aodk","aof","aof2","aof3","b2b","bakatono","bangbead","bjourney","blazstar","breakers","breakrev","bstars","bstars2","burningf","burningh","captainbarrel","crswd2bl","crsword","ct2k3sp","cthd2003","ctomaday","cyberlip","cyborgforce","doubled1","doubled1a","doubled1b","doubled1c","doubled1d","doubled1e","doubledr","eightman","fatfursa","fatfursp","fatfury1","fatfury2","fatfury3","fbfrenzy","fightfev","fightfva","flipshot","galaxyfg","ganryu","garou","garouo","garoup","ghostlop","gladmort","goalx3","gowcaizr","gpilots","gururin","hypernoid","ironclad","irrmaze","janshin","joyjoy","kabukikl","karnovr","kf10thep","kf2k2mp","kf2k2mp2","kf2k2pla","kf2k2pls","kf2k3bl","kf2k3bla","kf2k3pl","kf2k3upl","kf2k5uni","kizuna","knightsch","kof10th","kof2000","kof2000n","kof2001","kof2001h","kof2002","kof2003","kof2003d","kof2k4se","kof94","kof95","kof95a","kof96","kof96h","kof97","kof97a","kof97pls","kof98","kof98k","kof98n","kof99","kof99a","kof99e","kof99n","kof99p","kog","kotm","kotm2","kotmh","lastblad","lastbld2","lastblda","lasthope","lbowling","legendos","lresort","magdrop2","magdrop3","maglord","maglordh","mahretsu","marukodq","matrim","miexchng","minasan","mosyougi","mslug","mslug2","mslug2t","mslug3","mslug3n","mslug4","mslug5","mslugx","mutnat","nam1Line truncated
|
||||
@@ -1 +1 @@
|
||||
{"arcade":{"fbneo":{"file":"arcade/fbneo.json","gzip_size":97826,"sha256":"fe2dd891c254c0ed4897389ef182dd1acd0c01995b7005356ae29bf2fcaf7d95","size":310093},"flycast":{"file":"arcade/flycast.json","gzip_size":1841,"sha256":"957189a6e993fda08e21c90ffc6ad94aed9ca9e6dd9ed8c7724e29db036791cb","size":5441},"mame":{"file":"arcade/mame.json","gzip_size":154527,"sha256":"b12010301293a218ecfac45706d81a26c3ac0c27eebeca7409bc8f6ce0163e9e","size":604648},"mame0258":{"file":"arcade/mame0258.json","gzip_size":141146,"sha256":"670695cf67d6bc4a180c59e90419db89162423381c3d66abadddd1683728d89e","size":556069},"mame0278":{"file":"arcade/mame0278.json","gzip_size":148595,"sha256":"7881e3516f451ec83e886aaf41ebac9d60f497e1f954f49749d52890d7955cbf","size":582797},"mame2000":{"file":"arcade/mame2000.json","gzip_size":8529,"sha256":"908f5fde3f979008f686e161060496fe6c8a58bcb64db1eacc4c0bcc8c59e9a8","size":23020},"mame2003":{"file":"arcade/mame2003.json","gzip_size":17453,"sha256":"ed840078d1e0967ed730a8061d6951bb3c5d427c28c17fd4b363b2745256b60f","size":48932},"mame2003_plus":{"file":"arcade/mame2003_plus.json","gzip_size":20506,"sha256":"de6728cddea960fa25282cdab32463597992025485d0d743837d95750d98153e","size":60222},"mame2010":{"file":"arcade/mame2010.json","gzip_size":30869,"sha256":"50b1b381b4b07463f69f1f4c512dd1c98a78d4d0e9c3aeaf49b7b1b007b42152","size":96528},"mame2015":{"file":"arcade/mame2015.json","gzip_size":86990,"sha256":"afeb8c32f651421f74c6de057b0c0b837acd14c533b5160bb31f4411e0afffec","size":360117},"mame2016":{"file":"arcade/mame2016.json","gzip_size":101249,"sha256":"1f75147977d9d082a38b8f8e47a02b301f3d6e6db97c9b9282f3e7f27f26ee47","size":406190}},"containers":{"7z":{"description":"Per-file CRCs and sizes sit in the header at the end of the archive, LZMA-compressed by default (kEncodedHeader). One LZMA decode of the header, independent of the archive size, gives them. Python's lzma is an optional module.","re_read":true,"signature":{"bytes_hex":"377abcaf271c","offset":0},"source_ref":"ip7z/7zip@b88c6bc0 DOC/7zFormat.txt:171-189, DOC/7zFormat.txt:318-334, CPP/7zip/Archive/7z/7zHandlerOut.cpp:859"},"cd-sector":{"description":"User data of a CD sector. In a 2048-byte image (.iso) sector N starts at N * 2048. In a raw 2352-byte image it starts at N * 2352 plus 16 for Mode 1 and plus 24 for Mode 2 Form 1 (12 sync bytes, a 4-byte header, and for Mode 2 an 8-byte subheader).","re_read":true,"sector_size":{"iso":2048,"raw":2352},"source_ref":"stenzek/duckstation@526b4a12 src/util/iso_reader.cpp:157-171, src/util/cd_image.h:28-34","user_data_offset":{"mode1":16,"mode2":24}},"chd-v5":{"description":"MAME compressed hunks, big-endian. The header holds sizes, codecs and hashes only, never the system or the region. The overall SHA-1 is what MAME software lists record. Neither SHA-1 equals a Redump track hash: chdman hashes 2448-byte frames (subcode included, zero-filled), pads each track to 4 frames and byte-swaps audio, all tracks in one stream.","fields":{"compressors":{"encoding":"fourcc4","length":16,"offset":16},"header_length":{"encoding":"u32be","length":4,"offset":8,"value":124},"hunk_bytes":{"encoding":"u32be","length":4,"offset":56},"logical_bytes":{"encoding":"u64be","length":8,"offset":32},"map_offset":{"encoding":"u64be","length":8,"offset":40},"metadata_offset":{"encoding":"u64be","length":8,"offset":48},"overall_sha1":{"encoding":"hex","length":20,"offset":84},"parent_sha1":{"encoding":"hex","length":20,"offset":104},"raw_sha1":{"encoding":"hex","length":20,"offset":64},"unit_bytes":{"encoding":"u32be","length":4,"offset":60},"version":{"encoding":"u32be","length":4,"offset":12,"value":5}},"magic":{"bytes":"MComprHD","offset":0},"media_tags":{"CHCD":"cd","CHGD":"gd-rom","CHGT":"gd-rom","CHT2":"cd","CHTR":"cd","DVD ":"dvd","GDDD":"hard-disk"},"metadata_entry":{"description":"16-byte entry header, payload follows. Linked list from metadata_offset.","flags":{"encoding":"u8","length":1,"offset":4},"length":{"encoding":"u24be","length":3,"offset":5},"next":{"encoding":"u64be","length":8,"offset":8},"tag":{"encoding":"ascii","length":4,"offset":0}},"re_read":true,"source_ref":"mamedev/mame@f34f0250 src/lib/util/chd.h:148-162, src/lib/util/chd.cpp:2021-2061, src/lib/util/chd.cpp:2822-2831, src/lib/util/chd.h:212-235, src/lib/util/chd.cpp:1709-1749, src/tools/chdman.cpp:443-445, src/tools/chdman.cpp:2195-2203, src/lib/util/cdrom.cpp:2669-2672, src/emu/romload.cpp:1211"},"gamecube-disc":{"description":"Where disc offset 0 sits inside each container Dolphin opens.","formats":{"ciso":{"disc_header_at":32768,"magic":"CISO"},"gcz":{"disc_header_at":null,"magic_u32le":2970337281,"note":"block 0 is zlib unless bit 63 of its pointer is set"},"iso":{"disc_header_at":0,"magic":null},"rvz":{"disc_header_at":88,"magic":"RVZ\u0001","note":"first 0x80 disc bytes copied into header 2"},"wbfs":{"disc_header_at":null,"magic":"WBFS","note":"disc offset 0 at wlba[0] << wbfs_sector_shift"},"wia":{"disc_header_at":88,"magic":"WIA\u0001","note":"Line truncated
|
||||
{"arcade":{"fbneo":{"file":"arcade/fbneo.json","gzip_size":115955,"sha256":"88961c9a6be804772baa767f6ee3a9162478c30c60fe55c8363d8fe4fbc909da","size":423362},"flycast":{"file":"arcade/flycast.json","gzip_size":1841,"sha256":"957189a6e993fda08e21c90ffc6ad94aed9ca9e6dd9ed8c7724e29db036791cb","size":5441},"mame":{"file":"arcade/mame.json","gzip_size":154527,"sha256":"b12010301293a218ecfac45706d81a26c3ac0c27eebeca7409bc8f6ce0163e9e","size":604648},"mame0258":{"file":"arcade/mame0258.json","gzip_size":141151,"sha256":"7ecff1979ed2ac123ea3ba4825dde6e2c31906415165fabefc9af93fa48a6de4","size":556059},"mame0278":{"file":"arcade/mame0278.json","gzip_size":148595,"sha256":"7881e3516f451ec83e886aaf41ebac9d60f497e1f954f49749d52890d7955cbf","size":582797},"mame2000":{"file":"arcade/mame2000.json","gzip_size":8624,"sha256":"f0d69b0872ecfc2845eeb7304543e5b17c11db82060b5514c206b6962ed08263","size":23316},"mame2003":{"file":"arcade/mame2003.json","gzip_size":17456,"sha256":"3b44e2a92c80a8f104b7781fcc1c776d025ad2cf4986638efa3ea041baa9a56d","size":48929},"mame2003_plus":{"file":"arcade/mame2003_plus.json","gzip_size":21077,"sha256":"2857283556fa49c20d8160ed113465bf0c2e643ed0b8acd2d38266a78be8e25e","size":62373},"mame2010":{"file":"arcade/mame2010.json","gzip_size":30869,"sha256":"50b1b381b4b07463f69f1f4c512dd1c98a78d4d0e9c3aeaf49b7b1b007b42152","size":96528},"mame2015":{"file":"arcade/mame2015.json","gzip_size":86990,"sha256":"afeb8c32f651421f74c6de057b0c0b837acd14c533b5160bb31f4411e0afffec","size":360117},"mame2016":{"file":"arcade/mame2016.json","gzip_size":101249,"sha256":"1f75147977d9d082a38b8f8e47a02b301f3d6e6db97c9b9282f3e7f27f26ee47","size":406190}},"containers":{"7z":{"description":"Per-file CRCs and sizes sit in the header at the end of the archive, LZMA-compressed by default (kEncodedHeader). One LZMA decode of the header, independent of the archive size, gives them. Python's lzma is an optional module.","re_read":true,"signature":{"bytes_hex":"377abcaf271c","offset":0},"source_ref":"ip7z/7zip@b88c6bc0 DOC/7zFormat.txt:171-189, DOC/7zFormat.txt:318-334, CPP/7zip/Archive/7z/7zHandlerOut.cpp:859"},"cd-sector":{"description":"User data of a CD sector. In a 2048-byte image (.iso) sector N starts at N * 2048. In a raw 2352-byte image it starts at N * 2352 plus 16 for Mode 1 and plus 24 for Mode 2 Form 1 (12 sync bytes, a 4-byte header, and for Mode 2 an 8-byte subheader).","re_read":true,"sector_size":{"iso":2048,"raw":2352},"source_ref":"stenzek/duckstation@526b4a12 src/util/iso_reader.cpp:157-171, src/util/cd_image.h:28-34","user_data_offset":{"mode1":16,"mode2":24}},"chd-v5":{"description":"MAME compressed hunks, big-endian. The header holds sizes, codecs and hashes only, never the system or the region. The overall SHA-1 is what MAME software lists record. Neither SHA-1 equals a Redump track hash: chdman hashes 2448-byte frames (subcode included, zero-filled), pads each track to 4 frames and byte-swaps audio, all tracks in one stream.","fields":{"compressors":{"encoding":"fourcc4","length":16,"offset":16},"header_length":{"encoding":"u32be","length":4,"offset":8,"value":124},"hunk_bytes":{"encoding":"u32be","length":4,"offset":56},"logical_bytes":{"encoding":"u64be","length":8,"offset":32},"map_offset":{"encoding":"u64be","length":8,"offset":40},"metadata_offset":{"encoding":"u64be","length":8,"offset":48},"overall_sha1":{"encoding":"hex","length":20,"offset":84},"parent_sha1":{"encoding":"hex","length":20,"offset":104},"raw_sha1":{"encoding":"hex","length":20,"offset":64},"unit_bytes":{"encoding":"u32be","length":4,"offset":60},"version":{"encoding":"u32be","length":4,"offset":12,"value":5}},"magic":{"bytes":"MComprHD","offset":0},"media_tags":{"CHCD":"cd","CHGD":"gd-rom","CHGT":"gd-rom","CHT2":"cd","CHTR":"cd","DVD ":"dvd","GDDD":"hard-disk"},"metadata_entry":{"description":"16-byte entry header, payload follows. Linked list from metadata_offset.","flags":{"encoding":"u8","length":1,"offset":4},"length":{"encoding":"u24be","length":3,"offset":5},"next":{"encoding":"u64be","length":8,"offset":8},"tag":{"encoding":"ascii","length":4,"offset":0}},"re_read":true,"source_ref":"mamedev/mame@f34f0250 src/lib/util/chd.h:148-162, src/lib/util/chd.cpp:2021-2061, src/lib/util/chd.cpp:2822-2831, src/lib/util/chd.h:212-235, src/lib/util/chd.cpp:1709-1749, src/tools/chdman.cpp:443-445, src/tools/chdman.cpp:2195-2203, src/lib/util/cdrom.cpp:2669-2672, src/emu/romload.cpp:1211"},"gamecube-disc":{"description":"Where disc offset 0 sits inside each container Dolphin opens.","formats":{"ciso":{"disc_header_at":32768,"magic":"CISO"},"gcz":{"disc_header_at":null,"magic_u32le":2970337281,"note":"block 0 is zlib unless bit 63 of its pointer is set"},"iso":{"disc_header_at":0,"magic":null},"rvz":{"disc_header_at":88,"magic":"RVZ\u0001","note":"first 0x80 disc bytes copied into header 2"},"wbfs":{"disc_header_at":null,"magic":"WBFS","note":"disc offset 0 at wlba[0] << wbfs_sector_shift"},"wia":{"disc_header_at":88,"magic":"WIA\u0001","note":Line truncated
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://abdess.github.io/retrobios/api/v1/schemas/arcade-parents.schema.json",
|
||||
"title": "RetroBIOS arcade parent index of one core version",
|
||||
"description": "games/arcade/<profile>.json, written by python -m scripts.scraper.arcade_parent_importer from the DAT the profile pins. A game set needs every BIOS set it is listed under (the romof chain read to its end) and, for the MAME family, every device set with ROMs it is listed under.",
|
||||
"description": "games/arcade/<profile>.json, written by python -m scripts.scraper.arcade_parent_importer from the DAT or the driver code the profile pins. A game set needs every BIOS set it is listed under (the romof chain read to its end) and, for the MAME family, every device set with ROMs it is listed under.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema", "profile", "core_version", "source", "bios", "devices", "chd", "missing_parents", "no_bios", "bios_sets", "counts"],
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Files of a repository at a commit, each with its git blob sha.",
|
||||
"description": "Files or directories of a repository at a commit, each with its git blob or tree sha.",
|
||||
"additionalProperties": false,
|
||||
"required": ["repo", "commit", "files"],
|
||||
"properties": {
|
||||
|
||||
@@ -5,30 +5,38 @@ and the chain ends at a BIOS set (``neogeo``, ``naomi``, ``pgm``). The archive
|
||||
the installer has to provide for a game on the card is every BIOS set on that
|
||||
chain, plus, for the MAME family, the device sets with ROMs the machine
|
||||
instantiates (``device_ref``), which a split or merged romset reads from their
|
||||
own archive. The DAT that answers is the one of the core version that runs
|
||||
the game, read at the revision its profile pins:
|
||||
own archive. The answer is read at the revision the profile pins, from the
|
||||
DAT of the core version that runs the game where that DAT is the code's own
|
||||
output, and from the driver code where it is not:
|
||||
|
||||
python -m scripts.scraper.arcade_parent_importer --all
|
||||
python -m scripts.scraper.arcade_parent_importer --profile mame2003_plus
|
||||
python -m scripts.scraper.arcade_parent_importer --all --offline
|
||||
|
||||
A BIOS set is ``isbios="yes"`` (MAME 0.139 and later, FBNeo) or, in the
|
||||
MAME 0.78 lineage (mame2003, mame2003-plus), which has no such attribute, a
|
||||
set marked ``runnable="no"``. flycast keeps its NAOMI and Atomiswave table in
|
||||
code: ``Games[].bios`` names the BIOS, ``naomi`` when it is null
|
||||
(core/hw/naomi/naomi_cart.cpp:195-197), and ``BIOS[].filename`` the archive
|
||||
when it differs from the name (naomi_cart.cpp:75).
|
||||
A BIOS set is ``isbios="yes"`` (MAME 0.139 and later, FBNeo). mame2000,
|
||||
mame2003 and mame2003-plus carry a DAT in metadata/ that their code has
|
||||
moved past (mame2003-plus: 186 compiled sets absent, nbajamex under a BIOS
|
||||
set the code no longer declares), so they are read from src/driver.c and
|
||||
src/drivers/: the parent is the GAME macro's PARENT argument and a BIOS set
|
||||
is flagged NOT_A_DRIVER. Their DAT is still read, to report where it
|
||||
disagrees. FBNeo's DATs are read one at a time, a console set keyed by its
|
||||
driver (``msx_1942``): the Arcade, MSX and NES DATs each carry a ``1942``.
|
||||
flycast keeps its NAOMI and Atomiswave table in code: ``Games[].bios`` names
|
||||
the BIOS, ``naomi`` when it is null (core/hw/naomi/naomi_cart.cpp:195-197),
|
||||
and ``BIOS[].filename`` the archive when it differs from the name
|
||||
(naomi_cart.cpp:75).
|
||||
|
||||
Output: games/arcade/<profile>.json. CHD games are listed, not resolved: a
|
||||
CHD is game content. A ``romof`` pointing outside the DAT is listed with its
|
||||
target, never guessed. The games that load no BIOS set (``no_bios``) and
|
||||
every BIOS set (``bios_sets``) are listed too: a set name on a card that
|
||||
none of the lists holds is one the core's DAT does not know.
|
||||
CHD is game content. A ``romof`` pointing outside the sets read is listed
|
||||
with its target, never guessed. The games that load no BIOS set
|
||||
(``no_bios``) and every BIOS set (``bios_sets``) are listed too: a set name
|
||||
on a card that none of the lists holds is one the core does not know.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
@@ -36,6 +44,7 @@ import re
|
||||
import sys
|
||||
import urllib.parse
|
||||
import zipfile
|
||||
from collections import Counter
|
||||
from collections.abc import Callable, Iterator
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
@@ -60,8 +69,11 @@ DEFAULT_CACHE = Path(".cache") / "dats"
|
||||
# How each profile's DAT is found. "listxml": the -listxml release asset of
|
||||
# the MAME version core_version names. "fbneo": every DAT of libretro/FBNeo's
|
||||
# dats/ at source_commit. "repo": files of the profile's source repository at
|
||||
# source_commit (a ZIP member when the file is an archive). "flycast": the
|
||||
# BIOS and Games tables of naomi_roms.cpp at source_commit.
|
||||
# source_commit (a ZIP member when the file is an archive). "source": the
|
||||
# driver code itself at source_commit (src/driver.c and src/drivers/), for the
|
||||
# cores whose committed DAT contradicts their code; "paths" then names that
|
||||
# DAT, read only to report where it disagrees. "flycast": the BIOS and Games
|
||||
# tables of naomi_roms.cpp at source_commit.
|
||||
PROFILES: dict[str, dict] = {
|
||||
"mame": {"kind": "listxml", "marker": "isbios"},
|
||||
"mame0258": {"kind": "listxml", "marker": "isbios"},
|
||||
@@ -74,9 +86,9 @@ PROFILES: dict[str, dict] = {
|
||||
},
|
||||
"mame2015": {"kind": "repo", "marker": "isbios", "paths": ["metadata/mame2014-xml.zip"]},
|
||||
"mame2010": {"kind": "repo", "marker": "isbios", "paths": ["metadata/mame2010.xml"]},
|
||||
"mame2003_plus": {"kind": "repo", "marker": "runnable", "paths": ["metadata/mame2003-plus.xml"]},
|
||||
"mame2003": {"kind": "repo", "marker": "runnable", "paths": ["metadata/mame2003.xml"]},
|
||||
"mame2000": {"kind": "repo", "marker": "isbios", "paths": ["metadata/MAME 0.37b5 XML.dat"]},
|
||||
"mame2003_plus": {"kind": "source", "marker": "runnable", "paths": ["metadata/mame2003-plus.xml"]},
|
||||
"mame2003": {"kind": "source", "marker": "runnable", "paths": ["metadata/mame2003.xml"]},
|
||||
"mame2000": {"kind": "source", "marker": "isbios", "paths": ["metadata/MAME 0.37b5 XML.dat"]},
|
||||
"flycast": {"kind": "flycast", "paths": ["core/hw/naomi/naomi_roms.cpp"]},
|
||||
}
|
||||
|
||||
@@ -109,6 +121,7 @@ class SetEntry:
|
||||
has_roms: bool = False
|
||||
disks: bool = False
|
||||
devices: list[str] = field(default_factory=list)
|
||||
source: str | None = None
|
||||
|
||||
|
||||
_ELEMENT = re.compile(rb"<(machine|game)\b([^>]*)>")
|
||||
@@ -159,6 +172,7 @@ def iter_sets(stream: io.BufferedIOBase) -> Iterator[SetEntry]:
|
||||
has_roms=bool(_machine_roms(body)),
|
||||
disks=any(d.get("status") != "nodump" for d in disks),
|
||||
devices=[d.decode() for d in _DEVICE_REF.findall(body)],
|
||||
source=attrs.get("sourcefile"),
|
||||
)
|
||||
position = end + len(closing)
|
||||
keep_from = max(position, len(buffer) - _TAG_TAIL)
|
||||
@@ -173,8 +187,16 @@ def is_bios(entry: SetEntry, marker: str) -> bool:
|
||||
return marker == "runnable" and not entry.runnable and not entry.isdevice
|
||||
|
||||
|
||||
def build_index(sets: dict[str, SetEntry], marker: str) -> dict:
|
||||
"""BIOS sets per game, device sets per game, CHD games, broken chains."""
|
||||
def build_index(
|
||||
sets: dict[str, SetEntry], marker: str, archives: dict[str, str] | None = None
|
||||
) -> dict:
|
||||
"""BIOS sets per game, device sets per game, CHD games, broken chains.
|
||||
|
||||
A BIOS set none of whose ROMs was dumped is passed over: its archive holds
|
||||
nothing, and the loader only warns about a ROM without a dump. *archives*
|
||||
names the archive of a set whose name is not its archive's (an FBNeo
|
||||
console driver)."""
|
||||
archive = (archives or {}).get
|
||||
bios_names = {n for n, e in sets.items() if is_bios(e, marker)}
|
||||
device_roms = {n for n, e in sets.items() if e.isdevice and e.has_roms}
|
||||
games = {
|
||||
@@ -191,10 +213,10 @@ def build_index(sets: dict[str, SetEntry], marker: str) -> dict:
|
||||
seen.add(current)
|
||||
parent = sets.get(current)
|
||||
if parent is None:
|
||||
missing[name] = current
|
||||
missing[name] = archive(current, current)
|
||||
break
|
||||
if current in bios_names:
|
||||
bios.setdefault(current, set()).add(name)
|
||||
if current in bios_names and parent.has_roms:
|
||||
bios.setdefault(archive(current, current), set()).add(name)
|
||||
current = parent.romof
|
||||
for device in set(entry.devices) & device_roms:
|
||||
devices.setdefault(device, set()).add(name)
|
||||
@@ -219,6 +241,87 @@ def build_index(sets: dict[str, SetEntry], marker: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
# --- FBNeo: one namespace per DAT ---------------------------------------------
|
||||
|
||||
# Generated at build time from every driver and committed: the set name and the
|
||||
# source file of each driver.
|
||||
FBNEO_DRIVERLIST = "src/dep/generated/driverlist.h"
|
||||
_FBNEO_DRIVER = re.compile(r'\{\s*"([^"]+)",\s*"([^"]+\.cpp)"\s*\}')
|
||||
|
||||
|
||||
def fbneo_drivers(listing: str) -> dict[str, set[str]]:
|
||||
"""Driver names per source file, from driverlist.h."""
|
||||
names: dict[str, set[str]] = {}
|
||||
for name, path in _FBNEO_DRIVER.findall(listing):
|
||||
names.setdefault(path, set()).add(name)
|
||||
if not names:
|
||||
raise ValueError(f"{FBNEO_DRIVERLIST} lists no driver")
|
||||
return names
|
||||
|
||||
|
||||
def _fbneo_candidates(entry: SetEntry, names: dict[str, set[str]]) -> list[str]:
|
||||
"""The drivers a DAT set can be. A console DAT writes the archive name,
|
||||
which the driver's GetZipName() takes by cutting the system prefix:
|
||||
``1942`` in the MSX DAT is the driver ``msx_1942``."""
|
||||
drivers = names.get(entry.source or "", set())
|
||||
if entry.name in drivers:
|
||||
return [entry.name]
|
||||
return sorted(n for n in drivers if "_" in n and n.split("_", 1)[1] == entry.name)
|
||||
|
||||
|
||||
def _fbneo_driver_names(entries: list[SetEntry], names: dict[str, set[str]]) -> dict[str, str]:
|
||||
"""Driver name per set of one DAT. Where a source file holds two systems
|
||||
(d_nes.cpp builds the NES and the FDS drivers), the prefix the rest of
|
||||
the DAT carries decides."""
|
||||
candidates = {e.name: _fbneo_candidates(e, names) for e in entries}
|
||||
prefixes = Counter(
|
||||
found[0].split("_", 1)[0]
|
||||
for name, found in candidates.items()
|
||||
if len(found) == 1 and found[0] != name
|
||||
)
|
||||
driver: dict[str, str] = {}
|
||||
for entry in entries:
|
||||
found = candidates[entry.name]
|
||||
if len(found) > 1 and prefixes:
|
||||
dominant = prefixes.most_common(1)[0][0]
|
||||
found = [n for n in found if n.split("_", 1)[0] == dominant]
|
||||
if len(found) != 1:
|
||||
raise ValueError(f"{entry.source}: {entry.name} matches drivers {found}")
|
||||
driver[entry.name] = found[0]
|
||||
return driver
|
||||
|
||||
|
||||
def fbneo_sets(
|
||||
openers: list[Callable[[], io.BufferedIOBase]], names: dict[str, set[str]]
|
||||
) -> tuple[dict[str, SetEntry], dict[str, str]]:
|
||||
"""Every set of FBNeo's DATs keyed by its driver, and the archive of each
|
||||
set whose driver name is not its archive name.
|
||||
|
||||
Each DAT is its own namespace: the Arcade, MSX, NES and ZX Spectrum DATs
|
||||
all carry a ``1942``, and a ``romof`` inside a DAT names a set of that DAT.
|
||||
Merged by archive name, the MSX ``1942`` that needs msx.zip was the
|
||||
arcade one, which needs nothing. The Arcade and Neo Geo DATs both carry
|
||||
the Neo Geo drivers: a driver read twice keeps its first reading.
|
||||
"""
|
||||
sets: dict[str, SetEntry] = {}
|
||||
archives: dict[str, str] = {}
|
||||
for opener in openers:
|
||||
with opener() as stream:
|
||||
entries = [e for e in iter_sets(stream) if e.name]
|
||||
driver = _fbneo_driver_names(entries, names)
|
||||
for entry in entries:
|
||||
name = driver[entry.name]
|
||||
if name in sets:
|
||||
continue
|
||||
if name != entry.name:
|
||||
archives[name] = entry.name
|
||||
if entry.romof:
|
||||
entry.romof = driver.get(entry.romof, entry.romof)
|
||||
entry.name = name
|
||||
sets[name] = entry
|
||||
return sets, archives
|
||||
|
||||
|
||||
# --- C table reader (flycast naomi_roms.cpp) ---------------------------------
|
||||
|
||||
_TOKEN = re.compile(r'"(?:\\.|[^"\\])*"|[{},]|[^\s{},"]+')
|
||||
@@ -340,6 +443,475 @@ def flycast_index(source: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
# --- MAME 0.37 and 0.78 driver source (mame2000, mame2003, mame2003-plus) ----
|
||||
|
||||
# driver.h at each pin: NAME is argument 1 and PARENT argument 2 in every
|
||||
# form, and a BIOS set carries NOT_A_DRIVER in its flags.
|
||||
_GAME_MACRO = re.compile(r"\b(GAME|GAMEX|GAMEC|GAMECX|GAMEB|GAMEBX)\s*\(")
|
||||
_DRIVER_ENTRY = re.compile(r"\bDRIVER\s*\(\s*(\w+)\s*\)")
|
||||
_ROM_START = re.compile(r"\bROM_START\s*\(\s*(\w+)\s*\)(.*?)\bROM_END\b", re.S)
|
||||
_ROM_LOAD = re.compile(r"\bROMX?_LOAD\w*\s*\(")
|
||||
_DISK_IMAGE = re.compile(r"\bDISK_IMAGE\w*\s*\(")
|
||||
_ROM_START_HEAD = re.compile(r"\bROM_START\s*\(")
|
||||
_DIRECTIVE = re.compile(r"^[ \t]*#[ \t]*(\w+)[ \t]*(.*)$")
|
||||
_MACRO_HEAD = re.compile(r"(\w+)(\([^)]*\))?[ \t]*(.*)")
|
||||
_CONDITION_TOKEN = re.compile(
|
||||
r"\s*(?:(0[xX][0-9a-fA-F]+|\d+)[uUlL]*|(defined)|([A-Za-z_]\w*)"
|
||||
r"|(&&|\|\||==|!=|<=|>=|<<|>>|[!<>()+\-*/%~&|^]))"
|
||||
)
|
||||
_IDENTIFIER = re.compile(r"\b[A-Za-z_]\w*\b")
|
||||
_INCLUDE = re.compile(r'"([^"]+)"')
|
||||
|
||||
|
||||
class DriverSourceError(ValueError):
|
||||
"""The driver source does not have the shape the reader knows."""
|
||||
|
||||
|
||||
def _call_args(text: str, start: int) -> list[str]:
|
||||
"""Top-level arguments of the call whose opening parenthesis ends at
|
||||
*start*, string literals kept whole."""
|
||||
return _call_span(text, start)[0]
|
||||
|
||||
|
||||
def _call_span(text: str, start: int) -> tuple[list[str], int]:
|
||||
"""The arguments of a call and the offset just past its parenthesis."""
|
||||
args: list[str] = []
|
||||
current: list[str] = []
|
||||
depth, i, n = 1, start, len(text)
|
||||
while i < n:
|
||||
c = text[i]
|
||||
if c == '"':
|
||||
j = i + 1
|
||||
while j < n and text[j] != '"':
|
||||
j += 2 if text[j] == "\\" else 1
|
||||
current.append(text[i : j + 1])
|
||||
i = j + 1
|
||||
continue
|
||||
if c == "(":
|
||||
depth += 1
|
||||
elif c == ")":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
args.append("".join(current).strip())
|
||||
return args, i + 1
|
||||
elif c == "," and depth == 1:
|
||||
args.append("".join(current).strip())
|
||||
current = []
|
||||
i += 1
|
||||
continue
|
||||
current.append(c)
|
||||
i += 1
|
||||
raise DriverSourceError("unterminated macro call")
|
||||
|
||||
|
||||
def _condition_value(expr: str, defines: dict[str, str], depth: int = 0) -> int:
|
||||
"""An ``#if`` expression the way the C preprocessor reads it: a name not
|
||||
defined is 0, a defined name is its value."""
|
||||
python: list[str] = []
|
||||
position = 0
|
||||
expr = expr.strip()
|
||||
while position < len(expr):
|
||||
match = _CONDITION_TOKEN.match(expr, position)
|
||||
if not match:
|
||||
raise DriverSourceError(f"#if {expr}: cannot read")
|
||||
number, defined, name, operator = match.groups()
|
||||
position = match.end()
|
||||
if number:
|
||||
python.append(str(int(number, 0)))
|
||||
elif defined:
|
||||
target = re.match(r"\s*\(?\s*(\w+)\s*\)?", expr[position:])
|
||||
if not target:
|
||||
raise DriverSourceError(f"#if {expr}: defined without a name")
|
||||
python.append("1" if target.group(1) in defines else "0")
|
||||
position += target.end()
|
||||
elif name:
|
||||
value = defines.get(name, "0").strip() or "1"
|
||||
if depth > 8:
|
||||
raise DriverSourceError(f"#if {expr}: {name} does not resolve")
|
||||
python.append(str(_condition_value(value, defines, depth + 1)))
|
||||
else:
|
||||
python.append(
|
||||
{"&&": " and ", "||": " or ", "!": " not ", "/": "//"}.get(operator, operator)
|
||||
)
|
||||
try:
|
||||
return int(_arithmetic(ast.parse("".join(python).strip(), mode="eval").body))
|
||||
except (SyntaxError, ZeroDivisionError, TypeError) as exc:
|
||||
raise DriverSourceError(f"#if {expr}: {exc}") from exc
|
||||
|
||||
|
||||
_BINARY = {
|
||||
ast.Add: lambda a, b: a + b, ast.Sub: lambda a, b: a - b,
|
||||
ast.Mult: lambda a, b: a * b, ast.FloorDiv: lambda a, b: a // b,
|
||||
ast.Mod: lambda a, b: a % b, ast.LShift: lambda a, b: a << b,
|
||||
ast.RShift: lambda a, b: a >> b, ast.BitAnd: lambda a, b: a & b,
|
||||
ast.BitOr: lambda a, b: a | b, ast.BitXor: lambda a, b: a ^ b,
|
||||
}
|
||||
_COMPARE = {
|
||||
ast.Eq: lambda a, b: a == b, ast.NotEq: lambda a, b: a != b,
|
||||
ast.Lt: lambda a, b: a < b, ast.LtE: lambda a, b: a <= b,
|
||||
ast.Gt: lambda a, b: a > b, ast.GtE: lambda a, b: a >= b,
|
||||
}
|
||||
|
||||
|
||||
def _arithmetic(node: ast.AST) -> int:
|
||||
"""Integer arithmetic of an ``#if``, nothing else evaluated."""
|
||||
if isinstance(node, ast.Constant) and isinstance(node.value, int):
|
||||
return node.value
|
||||
if isinstance(node, ast.UnaryOp):
|
||||
value = _arithmetic(node.operand)
|
||||
if isinstance(node.op, ast.Not):
|
||||
return int(not value)
|
||||
if isinstance(node.op, ast.USub):
|
||||
return -value
|
||||
if isinstance(node.op, ast.UAdd):
|
||||
return value
|
||||
if isinstance(node.op, ast.Invert):
|
||||
return ~value
|
||||
if isinstance(node, ast.BoolOp):
|
||||
values = [_arithmetic(v) for v in node.values]
|
||||
return int(all(values) if isinstance(node.op, ast.And) else any(values))
|
||||
if isinstance(node, ast.BinOp) and type(node.op) in _BINARY:
|
||||
return _BINARY[type(node.op)](_arithmetic(node.left), _arithmetic(node.right))
|
||||
if isinstance(node, ast.Compare):
|
||||
left = _arithmetic(node.left)
|
||||
for op, right_node in zip(node.ops, node.comparators):
|
||||
right = _arithmetic(right_node)
|
||||
if type(op) not in _COMPARE or not _COMPARE[type(op)](left, right):
|
||||
return 0
|
||||
left = right
|
||||
return 1
|
||||
raise TypeError(f"{type(node).__name__} in a condition")
|
||||
|
||||
|
||||
class _Preprocessor:
|
||||
"""Conditional compilation over src/, enough to tell which GAME and
|
||||
ROM_START a build compiles. Headers are read for their definitions."""
|
||||
|
||||
def __init__(self, headers: dict[str, str]) -> None:
|
||||
self.headers = headers
|
||||
self._by_basename: dict[str, list[str]] = {}
|
||||
for path in headers:
|
||||
self._by_basename.setdefault(path.rsplit("/", 1)[-1], []).append(path)
|
||||
|
||||
def _resolve(self, name: str, including: str) -> str | None:
|
||||
folder = including.rsplit("/", 1)[0]
|
||||
for candidate in (f"{folder}/{name}", f"src/{name}", f"src/includes/{name}"):
|
||||
if candidate in self.headers:
|
||||
return candidate
|
||||
found = self._by_basename.get(name.rsplit("/", 1)[-1], [])
|
||||
return found[0] if len(found) == 1 else None
|
||||
|
||||
def run(
|
||||
self, path: str, text: str, defines: dict[str, str],
|
||||
local: dict[str, tuple[list[str] | None, str]] | None, seen: set[str],
|
||||
) -> str:
|
||||
text = _strip_comments(text).replace("\\\r\n", " ").replace("\\\n", " ")
|
||||
out: list[str] = []
|
||||
# Each level: (enclosing level active, a branch already taken, this branch active).
|
||||
stack: list[tuple[bool, bool, bool]] = []
|
||||
active = True
|
||||
for line in text.splitlines():
|
||||
directive = _DIRECTIVE.match(line)
|
||||
if not directive:
|
||||
if active:
|
||||
out.append(line)
|
||||
continue
|
||||
word, rest = directive.groups()
|
||||
if word in ("if", "ifdef", "ifndef"):
|
||||
if not active:
|
||||
stack.append((False, True, False))
|
||||
continue
|
||||
if word == "if":
|
||||
value = bool(_condition_value(rest, defines))
|
||||
else:
|
||||
value = (rest.split()[0] in defines) == (word == "ifdef")
|
||||
stack.append((True, value, value))
|
||||
active = value
|
||||
elif word in ("elif", "else"):
|
||||
if not stack:
|
||||
raise DriverSourceError(f"{path}: #{word} without #if")
|
||||
outer, taken, _ = stack[-1]
|
||||
value = (
|
||||
outer and not taken
|
||||
and (word == "else" or bool(_condition_value(rest, defines)))
|
||||
)
|
||||
stack[-1] = (outer, taken or value, value)
|
||||
active = value
|
||||
elif word == "endif":
|
||||
if not stack:
|
||||
raise DriverSourceError(f"{path}: #endif without #if")
|
||||
stack.pop()
|
||||
active = stack[-1][2] if stack else True
|
||||
elif not active:
|
||||
continue
|
||||
elif word == "define":
|
||||
head = _MACRO_HEAD.match(rest)
|
||||
if head:
|
||||
defines[head.group(1)] = head.group(3)
|
||||
if local is not None:
|
||||
params = head.group(2)
|
||||
local[head.group(1)] = (
|
||||
[a.strip() for a in params[1:-1].split(",")] if params else None,
|
||||
head.group(3),
|
||||
)
|
||||
elif word == "undef":
|
||||
defines.pop(rest.strip(), None)
|
||||
elif word == "include":
|
||||
target = _INCLUDE.match(rest)
|
||||
header = self._resolve(target.group(1), path) if target else None
|
||||
if header and header not in seen:
|
||||
seen.add(header)
|
||||
self.run(header, self.headers[header], defines, None, seen)
|
||||
if stack:
|
||||
raise DriverSourceError(f"{path}: #if without #endif")
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def _dumped(args: list[str]) -> bool:
|
||||
"""A ROM_LOAD whose ROM was dumped: 0.78 writes ``NO_DUMP`` in the hash
|
||||
argument, 0.37 a zero CRC."""
|
||||
if any("NO_DUMP" in a for a in args):
|
||||
return False
|
||||
crc = args[3] if len(args) > 3 else ""
|
||||
return not re.fullmatch(r"0[xX]0+|0", crc.strip())
|
||||
|
||||
|
||||
def _expand_declarations(text: str, local: dict[str, tuple[list[str] | None, str]]) -> str:
|
||||
"""Calls of a file's own function-like macros that write a ROM_START or a
|
||||
GAME line, expanded (pgm.c builds every DoDonPachi II set through
|
||||
``DDP2_SET(name, program, asic)``)."""
|
||||
writers = {
|
||||
name: (params, body)
|
||||
for name, (params, body) in local.items()
|
||||
if params is not None and (_ROM_START_HEAD.search(body) or _GAME_MACRO.search(body))
|
||||
}
|
||||
if not writers:
|
||||
return text
|
||||
call = re.compile(r"\b(" + "|".join(map(re.escape, writers)) + r")\s*\(")
|
||||
out: list[str] = []
|
||||
position = 0
|
||||
for match in call.finditer(text):
|
||||
if match.start() < position:
|
||||
continue
|
||||
params, body = writers[match.group(1)]
|
||||
args, end = _call_span(text, match.end())
|
||||
if len(args) != len(params):
|
||||
raise DriverSourceError(f"{match.group(1)} called with {len(args)} arguments")
|
||||
values = dict(zip(params, args))
|
||||
out.append(text[position : match.start()])
|
||||
out.append(_IDENTIFIER.sub(lambda m: values.get(m.group(0), m.group(0)), body))
|
||||
position = end
|
||||
out.append(text[position:])
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def compiled_drivers(driver_c: str, preprocessor: _Preprocessor) -> list[str]:
|
||||
"""The DRIVER() entries driver.c compiles into the driver list."""
|
||||
# driver.c is read twice by the build, the second time with
|
||||
# DRIVER_RECURSIVE defined: that pass is the list.
|
||||
text = preprocessor.run(
|
||||
"src/driver.c", driver_c, {"DRIVER_RECURSIVE": "", "DRIVER": ""}, None, set()
|
||||
)
|
||||
return [n for n in _DRIVER_ENTRY.findall(text) if n != "NAME"]
|
||||
|
||||
|
||||
def driver_source_sets(
|
||||
driver_c: str, drivers: dict[str, str], headers: dict[str, str]
|
||||
) -> dict[str, SetEntry]:
|
||||
"""Every compiled set and every set on its parent chain, from the source.
|
||||
|
||||
*drivers* maps each path under src/drivers/ to its text and *headers*
|
||||
every header under src/. A set is declared by a GAME-family macro whose
|
||||
ROMs are ``ROM_START(name)``, and a set flagged ``NOT_A_DRIVER`` is a BIOS
|
||||
set, the flag the 0.37 and 0.78 info.c use to tell a resource from a game.
|
||||
"""
|
||||
preprocessor = _Preprocessor(headers)
|
||||
declared: dict[str, tuple[str | None, bool]] = {}
|
||||
roms: dict[str, tuple[bool, bool]] = {}
|
||||
for path, source in sorted(drivers.items()):
|
||||
local: dict[str, tuple[list[str] | None, str]] = {}
|
||||
text = _expand_declarations(preprocessor.run(path, source, {}, local, set()), local)
|
||||
known: dict[str, bool] = {}
|
||||
|
||||
def holds_roms(body: str, seen: frozenset[str] = frozenset()) -> bool:
|
||||
for match in _ROM_LOAD.finditer(body):
|
||||
if _dumped(_call_args(body, match.end())):
|
||||
return True
|
||||
# A ROM list shared through a macro of the same file (a BIOS
|
||||
# block every game of the board pulls in).
|
||||
for word in set(_IDENTIFIER.findall(body)) - seen:
|
||||
if word in local:
|
||||
if word not in known:
|
||||
known[word] = holds_roms(local[word][1], seen | {word})
|
||||
if known[word]:
|
||||
return True
|
||||
return False
|
||||
|
||||
for match in _ROM_START.finditer(text):
|
||||
body = match.group(2)
|
||||
roms.setdefault(match.group(1), (holds_roms(body), bool(_DISK_IMAGE.search(body))))
|
||||
for match in _GAME_MACRO.finditer(text):
|
||||
args = _call_args(text, match.end())
|
||||
if len(args) < 9:
|
||||
raise DriverSourceError(f"{path}: {match.group(1)} with {len(args)} arguments")
|
||||
name, parent = args[1], args[2]
|
||||
if name in declared:
|
||||
raise DriverSourceError(f"{path}: {name} declared twice")
|
||||
declared[name] = (
|
||||
None if parent == "0" else parent,
|
||||
any("NOT_A_DRIVER" in a for a in args[3:]),
|
||||
)
|
||||
compiled = compiled_drivers(driver_c, preprocessor)
|
||||
undeclared = [n for n in compiled if n not in declared]
|
||||
if undeclared:
|
||||
raise DriverSourceError(f"driver.c lists undeclared sets: {', '.join(undeclared[:10])}")
|
||||
sets: dict[str, SetEntry] = {}
|
||||
pending = list(compiled)
|
||||
while pending:
|
||||
name = pending.pop()
|
||||
if name in sets or name not in declared:
|
||||
continue
|
||||
parent, bios = declared[name]
|
||||
has_roms, disks = roms.get(name, (False, False))
|
||||
sets[name] = SetEntry(
|
||||
name=name, romof=parent, isbios=bios, runnable=not bios,
|
||||
has_roms=has_roms, disks=disks,
|
||||
)
|
||||
if parent:
|
||||
pending.append(parent)
|
||||
return sets
|
||||
|
||||
|
||||
def git_tree_sha(entries: dict[str, tuple[str, str]]) -> str:
|
||||
"""The sha git gives a directory, from ``{path: (mode, blob sha)}`` of
|
||||
every file under it, paths relative to it."""
|
||||
children: dict[str, dict[str, tuple[str, str]]] = {}
|
||||
rows: list[tuple[str, str, str]] = []
|
||||
for path, (mode, sha) in entries.items():
|
||||
head, sep, tail = path.partition("/")
|
||||
if sep:
|
||||
children.setdefault(head, {})[tail] = (mode, sha)
|
||||
else:
|
||||
rows.append((head, mode, sha))
|
||||
rows += [(name, "40000", git_tree_sha(sub)) for name, sub in children.items()]
|
||||
# git orders a tree by name, a directory compared as if it ended in "/".
|
||||
rows.sort(key=lambda row: row[0].encode() + (b"/" if row[1] == "40000" else b""))
|
||||
body = b"".join(
|
||||
mode.encode() + b" " + name.encode() + b"\0" + bytes.fromhex(sha)
|
||||
for name, mode, sha in rows
|
||||
)
|
||||
return hashlib.sha1(f"tree {len(body)}\0".encode() + body).hexdigest()
|
||||
|
||||
|
||||
@dataclass
|
||||
class DriverSource:
|
||||
"""What the reader needs from src/ at one commit, and the tree sha of
|
||||
src/ computed from every file of it."""
|
||||
|
||||
driver_c: str
|
||||
drivers: dict[str, str]
|
||||
headers: dict[str, str]
|
||||
tree: str
|
||||
|
||||
|
||||
def read_driver_source(tarball: Path) -> DriverSource:
|
||||
"""src/ of a GitHub tarball: the texts the reader needs, and the git
|
||||
tree sha of the whole directory."""
|
||||
import tarfile
|
||||
|
||||
entries: dict[str, tuple[str, str]] = {}
|
||||
texts: dict[str, str] = {}
|
||||
with tarfile.open(tarball, "r:gz") as archive:
|
||||
for member in archive:
|
||||
parts = member.name.split("/", 1)
|
||||
if len(parts) < 2 or not parts[1].startswith("src/"):
|
||||
continue
|
||||
path = parts[1]
|
||||
if member.issym():
|
||||
entries[path[4:]] = ("120000", git_blob_sha(member.linkname.encode()))
|
||||
elif member.isfile():
|
||||
handle = archive.extractfile(member)
|
||||
data = handle.read() if handle else b""
|
||||
mode = "100755" if member.mode & 0o111 else "100644"
|
||||
entries[path[4:]] = (mode, git_blob_sha(data))
|
||||
if path == "src/driver.c" or path.endswith(".h") or (
|
||||
path.startswith("src/drivers/") and path.endswith(".c")
|
||||
):
|
||||
texts[path] = data.decode("latin-1")
|
||||
if "src/driver.c" not in texts:
|
||||
raise FileNotFoundError(f"{tarball} has no src/driver.c")
|
||||
return DriverSource(
|
||||
driver_c=texts["src/driver.c"],
|
||||
drivers={p: t for p, t in texts.items() if p.startswith("src/drivers/") and p.endswith(".c")},
|
||||
headers={p: t for p, t in texts.items() if p.endswith(".h")},
|
||||
tree=git_tree_sha(entries),
|
||||
)
|
||||
|
||||
|
||||
def fetch_driver_source(
|
||||
slug: str, commit: str, cache_dir: Path, offline: bool = False
|
||||
) -> DriverSource:
|
||||
"""src/ at a commit, its tree sha checked against the repository's own
|
||||
when online."""
|
||||
tarball = cache_dir / "src" / slug / f"{commit}.tar.gz"
|
||||
if offline:
|
||||
if not tarball.is_file():
|
||||
raise FileNotFoundError(f"{tarball} is not cached")
|
||||
else:
|
||||
_download(f"https://codeload.github.com/{slug}/tar.gz/{commit}", tarball)
|
||||
source = read_driver_source(tarball)
|
||||
if not offline:
|
||||
listing = _api_json(f"https://api.github.com/repos/{slug}/git/trees/{commit}")
|
||||
listed = next(
|
||||
(
|
||||
item.get("sha")
|
||||
for item in (listing.get("tree", []) if isinstance(listing, dict) else [])
|
||||
if item.get("path") == "src"
|
||||
),
|
||||
None,
|
||||
)
|
||||
if listed != source.tree:
|
||||
tarball.unlink()
|
||||
raise BlobMismatchError(f"{slug}@{commit[:8]}:src is tree {listed}, not {source.tree}")
|
||||
return source
|
||||
|
||||
|
||||
def dat_gaps(code: dict[str, SetEntry], dat: dict[str, SetEntry], marker: str) -> dict:
|
||||
"""Where the DAT a repository carries contradicts its own code."""
|
||||
both = code.keys() & dat.keys()
|
||||
return {
|
||||
"code_only": sorted(code.keys() - dat.keys()),
|
||||
"dat_only": sorted(dat.keys() - code.keys()),
|
||||
"romof": sorted(n for n in both if code[n].romof != dat[n].romof),
|
||||
"bios": sorted(n for n in both if is_bios(code[n], marker) != is_bios(dat[n], marker)),
|
||||
}
|
||||
|
||||
|
||||
def _dat_cross_check(
|
||||
spec: dict, slug: str, commit: str, cache_dir: Path, offline: bool,
|
||||
code: dict[str, SetEntry],
|
||||
) -> dict | None:
|
||||
"""dat_gaps against the DAT the repository carries, None when the DAT
|
||||
is not cached and the run is offline."""
|
||||
paths: list[Path] = []
|
||||
for path in spec.get("paths", []):
|
||||
try:
|
||||
local, _ = (
|
||||
_cached_repo_file(slug, commit, path, cache_dir)
|
||||
if offline
|
||||
else fetch_repo_file(slug, commit, path, cache_dir)
|
||||
)
|
||||
except FileNotFoundError:
|
||||
if offline:
|
||||
return None
|
||||
raise
|
||||
paths.append(local)
|
||||
if not paths:
|
||||
return None
|
||||
dat = read_sets([opener for p in paths for opener in _xml_streams(p)])
|
||||
return dat_gaps(code, dat, spec["marker"])
|
||||
|
||||
|
||||
# --- Fetching ----------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -425,9 +997,12 @@ def _sha256(path: Path) -> str:
|
||||
|
||||
|
||||
def import_profile(
|
||||
profile: str, data: dict, cache_dir: Path, offline: bool = False
|
||||
profile: str, data: dict, cache_dir: Path, offline: bool = False,
|
||||
report: dict | None = None,
|
||||
) -> dict:
|
||||
"""The index document for one profile, from the DAT its pin names."""
|
||||
"""The index document for one profile, from the DAT or the code its pin
|
||||
names. *report* receives, for a profile read from its code, where the DAT
|
||||
the repository carries disagrees with that code."""
|
||||
spec = PROFILES[profile]
|
||||
commit = str(data.get("source_commit") or "")
|
||||
source_url = str(data.get("source") or "")
|
||||
@@ -454,15 +1029,33 @@ def import_profile(
|
||||
raise FileNotFoundError(f"{folder} is not cached")
|
||||
else:
|
||||
folder, blobs = fetch_pack("fbneo", commit, cache_dir)
|
||||
slug = _repo_slug(source_url)
|
||||
listing, listing_sha = (
|
||||
_cached_repo_file(slug, commit, FBNEO_DRIVERLIST, cache_dir)
|
||||
if offline
|
||||
else fetch_repo_file(slug, commit, FBNEO_DRIVERLIST, cache_dir)
|
||||
)
|
||||
source = {
|
||||
"repo": source_url,
|
||||
"commit": commit,
|
||||
"files": {f"dats/{name}": sha for name, sha in sorted(blobs.items())},
|
||||
"files": {
|
||||
**{f"dats/{name}": sha for name, sha in sorted(blobs.items())},
|
||||
FBNEO_DRIVERLIST: listing_sha,
|
||||
},
|
||||
}
|
||||
openers = [
|
||||
(lambda p=folder / name: p.open("rb")) for name in sorted(blobs)
|
||||
]
|
||||
index = build_index(read_sets(openers), spec["marker"])
|
||||
sets, archives = fbneo_sets(openers, fbneo_drivers(listing.read_text(encoding="utf-8")))
|
||||
index = build_index(sets, spec["marker"], archives)
|
||||
elif kind == "source":
|
||||
slug = _repo_slug(source_url)
|
||||
tree = fetch_driver_source(slug, commit, cache_dir, offline)
|
||||
sets = driver_source_sets(tree.driver_c, tree.drivers, tree.headers)
|
||||
source = {"repo": source_url, "commit": commit, "files": {"src": tree.tree}}
|
||||
index = build_index(sets, spec["marker"])
|
||||
if report is not None:
|
||||
report["dat_gaps"] = _dat_cross_check(spec, slug, commit, cache_dir, offline, sets)
|
||||
else:
|
||||
slug = _repo_slug(source_url)
|
||||
files: dict[str, str] = {}
|
||||
@@ -552,7 +1145,10 @@ def main() -> int:
|
||||
failed = True
|
||||
continue
|
||||
try:
|
||||
doc = import_profile(profile, profiles[profile], args.cache_dir, args.offline)
|
||||
report: dict = {}
|
||||
doc = import_profile(
|
||||
profile, profiles[profile], args.cache_dir, args.offline, report
|
||||
)
|
||||
except (OSError, ValueError, KeyError) as exc:
|
||||
print(f"FAIL {profile}: {exc}", file=sys.stderr)
|
||||
failed = True
|
||||
@@ -566,8 +1162,22 @@ def main() -> int:
|
||||
f"{profile}: {counts['games']} games, {counts['games_with_bios']} with a BIOS set, "
|
||||
f"{counts['bios_roots_used']} BIOS sets used, "
|
||||
f"{counts['games_with_devices']} with device sets, {counts['chd_games']} CHD, "
|
||||
f"{counts['missing_parents']} parents absent from the DAT"
|
||||
f"{counts['missing_parents']} parents absent"
|
||||
)
|
||||
if PROFILES[profile]["kind"] == "source":
|
||||
gaps = report.get("dat_gaps")
|
||||
if gaps is None:
|
||||
print(" read from the code, the committed DAT is not cached for the cross-check")
|
||||
else:
|
||||
print(
|
||||
f" read from the code, the committed DAT disagrees: "
|
||||
f"{len(gaps['code_only'])} sets only in the code, "
|
||||
f"{len(gaps['dat_only'])} only in the DAT, "
|
||||
f"{len(gaps['romof'])} parents and {len(gaps['bios'])} BIOS flags differ"
|
||||
)
|
||||
for key in ("dat_only", "romof", "bios"):
|
||||
if gaps[key]:
|
||||
print(f" {key}: {', '.join(gaps[key][:20])}")
|
||||
if absent:
|
||||
print(f" BIOS sets absent from the collection: {', '.join(absent)}")
|
||||
if undeclared:
|
||||
|
||||
@@ -200,20 +200,22 @@ def _scan_listxml(
|
||||
and those holding one of *targets*.
|
||||
|
||||
The document is 311 MB for MAME 0.289, so it is never held whole: the
|
||||
reader keeps a sliding window just large enough to close the element it
|
||||
is in the middle of.
|
||||
window keeps the element still open from its start tag, and grows until
|
||||
that element closes, whatever its size.
|
||||
"""
|
||||
found: dict[str, tuple[str | None, list[dict]]] = {}
|
||||
buffer = b""
|
||||
while chunk := stream.read(LISTXML_CHUNK):
|
||||
buffer += chunk
|
||||
position = 0
|
||||
keep_from = None
|
||||
while True:
|
||||
match = _MACHINE.search(buffer, position)
|
||||
if not match:
|
||||
break
|
||||
end = buffer.find(b"</machine>", match.end())
|
||||
if end == -1:
|
||||
keep_from = match.start()
|
||||
break
|
||||
name = match.group(1).decode()
|
||||
wanted = selector(name)
|
||||
@@ -223,7 +225,12 @@ def _scan_listxml(
|
||||
parent = _ROMOF.search(match.group(2).decode())
|
||||
found[name] = (parent.group(1) if parent else None, roms)
|
||||
position = end + len(b"</machine>")
|
||||
buffer = buffer[position:] if position else buffer[-(2 * LISTXML_CHUNK) :]
|
||||
if keep_from is None:
|
||||
# No element open: only a start tag cut by the read can follow.
|
||||
start = buffer.rfind(b"<machine", position)
|
||||
tail = max(position, len(buffer) - len(b"<machine"))
|
||||
keep_from = start if start != -1 else tail
|
||||
buffer = buffer[keep_from:]
|
||||
return found
|
||||
|
||||
|
||||
|
||||
+233
-14
@@ -108,27 +108,27 @@ class OfflineImport(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.temp = tempfile.TemporaryDirectory(dir=TMP_ROOT)
|
||||
self.cache = Path(self.temp.name)
|
||||
dat = self.cache / "repo" / "libretro" / "mame2003-libretro" / COMMIT / "metadata"
|
||||
dat = self.cache / "repo" / "libretro" / "mame2010-libretro" / COMMIT / "metadata"
|
||||
dat.mkdir(parents=True)
|
||||
(dat / "mame2003.xml").write_bytes((FIXTURES / "runnable_no.dat").read_bytes())
|
||||
(dat / "mame2010.xml").write_bytes((FIXTURES / "listxml.xml").read_bytes())
|
||||
with zipfile.ZipFile(self.cache / "mame0000lx.zip", "w") as archive:
|
||||
archive.write(FIXTURES / "listxml.xml", "mame0000.xml")
|
||||
self.profile = {
|
||||
"source": "https://github.com/libretro/mame2010-libretro",
|
||||
"source_commit": COMMIT,
|
||||
"core_version": "0.139",
|
||||
}
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.temp.cleanup()
|
||||
|
||||
def test_repo_profile_is_deterministic(self) -> None:
|
||||
profile = {
|
||||
"source": "https://github.com/libretro/mame2003-libretro",
|
||||
"source_commit": COMMIT,
|
||||
"core_version": "0.78",
|
||||
}
|
||||
first = api.dump(api.import_profile("mame2003", profile, self.cache, offline=True))
|
||||
second = api.dump(api.import_profile("mame2003", profile, self.cache, offline=True))
|
||||
first = api.dump(api.import_profile("mame2010", self.profile, self.cache, offline=True))
|
||||
second = api.dump(api.import_profile("mame2010", self.profile, self.cache, offline=True))
|
||||
self.assertEqual(first, second)
|
||||
doc = json.loads(first)
|
||||
self.assertEqual(doc["bios"], {"neogeo": ["kof98"]})
|
||||
self.assertEqual(list(doc["source"]["files"]), ["metadata/mame2003.xml"])
|
||||
self.assertEqual(doc["bios"]["neogeo"], ["mslug", "mslugh"])
|
||||
self.assertEqual(list(doc["source"]["files"]), ["metadata/mame2010.xml"])
|
||||
|
||||
def test_listxml_release_from_the_cache(self) -> None:
|
||||
doc = api.import_profile("mame", {"core_version": "0.000"}, self.cache, offline=True)
|
||||
@@ -137,14 +137,233 @@ class OfflineImport(unittest.TestCase):
|
||||
|
||||
@unittest.skipIf(Draft202012Validator is None, "jsonschema not installed")
|
||||
def test_fixture_output_matches_the_schema(self) -> None:
|
||||
profile = {
|
||||
doc = api.import_profile("mame2010", self.profile, self.cache, offline=True)
|
||||
schema = json.loads((ROOT / "schemas" / "arcade-parents.schema.json").read_text())
|
||||
self.assertEqual(list(Draft202012Validator(schema).iter_errors(doc)), [])
|
||||
|
||||
|
||||
DRIVER_C = """/* driver.c is read twice, the list comes from the second pass */
|
||||
#ifndef DRIVER_RECURSIVE
|
||||
#define DRIVER_RECURSIVE
|
||||
#include "driver.c"
|
||||
#else
|
||||
#ifdef TINY_COMPILE
|
||||
DRIVER( tinyonly )
|
||||
#else
|
||||
DRIVER( game1 )
|
||||
DRIVER( clone1 )
|
||||
DRIVER( game2 )
|
||||
DRIVER( hacked )
|
||||
DRIVER( built1 )
|
||||
DRIVER( diskgame )
|
||||
#endif
|
||||
#endif
|
||||
"""
|
||||
|
||||
DRIVER_FILE = """#include "driver.h"
|
||||
#include "board.h"
|
||||
|
||||
#define BOARD_BIOS \\
|
||||
ROM_REGION( 0x100, REGION_USER1, 0 ) \\
|
||||
ROM_LOAD( "b1.bin", 0, 0x100, CRC(12345678) SHA1(0000000000000000000000000000000000000000) )
|
||||
|
||||
ROM_START( bios1 )
|
||||
BOARD_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( bios2 )
|
||||
ROM_REGION( 0x100, REGION_USER1, 0 )
|
||||
ROM_LOAD( "b2.bin", 0, 0x100, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
ROM_START( game1 )
|
||||
ROM_LOAD( "g1.bin", 0, 0x100, CRC(11111111) SHA1(0000000000000000000000000000000000000000) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( clone1 )
|
||||
ROM_LOAD( "c1.bin", 0, 0x100, CRC(22222222) SHA1(0000000000000000000000000000000000000000) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( game2 )
|
||||
ROM_LOAD( "g2.bin", 0, 0x100, CRC(33333333) SHA1(0000000000000000000000000000000000000000) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( hacked )
|
||||
ROM_LOAD( "h.bin", 0, 0x100, CRC(44444444) SHA1(0000000000000000000000000000000000000000) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( diskgame )
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "disk", 0, MD5(00000000000000000000000000000000) )
|
||||
ROM_END
|
||||
|
||||
#define SET( name, program ) \\
|
||||
ROM_START( name ) \\
|
||||
program \\
|
||||
ROM_END
|
||||
|
||||
#define PROGRAM_A ROM_LOAD( "p.bin", 0, 0x100, CRC(55555555) SHA1(0000000000000000000000000000000000000000) )
|
||||
SET( built1, PROGRAM_A )
|
||||
|
||||
GAMEX( 1995, bios1, 0, m, i, n, ROT0, "Maker", "Board BIOS", NOT_A_DRIVER )
|
||||
GAMEX( 1995, bios2, 0, m, i, n, ROT0, "Maker", "Undumped BIOS", NOT_A_DRIVER )
|
||||
GAMEX( 1995, game1, bios1, m, i, n, ROT0, "Maker", "Game (one, two)", 0 )
|
||||
GAME( 1995, clone1, game1, m, i, n, ROT0, "Maker", "Clone" )
|
||||
GAME( 1995, game2, bios2, m, i, n, ROT0, "Maker", "Game on an undumped BIOS" )
|
||||
#if BOARD_HACK
|
||||
GAME( 1995, hacked, bios1, m, i, n, ROT0, "Maker", "Hacked" )
|
||||
#else
|
||||
GAME( 1995, hacked, 0, m, i, n, ROT0, "Maker", "Not hacked" )
|
||||
#endif
|
||||
GAME( 1995, built1, bios1, m, i, n, ROT0, "Maker", "Built by a macro" )
|
||||
GAME( 1995, diskgame, 0, m, i, n, ROT0, "Maker", "Disk game" )
|
||||
"""
|
||||
|
||||
STALE_DAT = """<?xml version="1.0"?>
|
||||
<mame>
|
||||
<game name="game1" sourcefile="board.c" romof="oldbios">
|
||||
<rom name="g1.bin" size="256" crc="11111111"/>
|
||||
</game>
|
||||
<game runnable="no" name="oldbios">
|
||||
<rom name="o.bin" size="256" crc="77777777"/>
|
||||
</game>
|
||||
</mame>
|
||||
"""
|
||||
|
||||
|
||||
def _write_tarball(path: Path, files: dict[str, str]) -> None:
|
||||
import tarfile
|
||||
|
||||
with tarfile.open(path, "w:gz") as archive:
|
||||
for name, text in files.items():
|
||||
data = text.encode("latin-1")
|
||||
info = tarfile.TarInfo(f"repo-{COMMIT}/{name}")
|
||||
info.size = len(data)
|
||||
info.mode = 0o644
|
||||
archive.addfile(info, io.BytesIO(data))
|
||||
|
||||
|
||||
class DriverSource(unittest.TestCase):
|
||||
"""mame2000, mame2003 and mame2003-plus are read from their driver code:
|
||||
the DATs those repositories carry contradict it."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.temp = tempfile.TemporaryDirectory(dir=TMP_ROOT)
|
||||
self.cache = Path(self.temp.name)
|
||||
slug = "libretro/mame2003-libretro"
|
||||
tarball = self.cache / "src" / slug / f"{COMMIT}.tar.gz"
|
||||
tarball.parent.mkdir(parents=True)
|
||||
_write_tarball(tarball, {
|
||||
"src/driver.c": DRIVER_C,
|
||||
"src/driver.h": "#define NOT_A_DRIVER 0x4000\n",
|
||||
"src/includes/board.h": "#define BOARD_HACK 0\n",
|
||||
"src/drivers/board.c": DRIVER_FILE,
|
||||
})
|
||||
dat = self.cache / "repo" / slug / COMMIT / "metadata"
|
||||
dat.mkdir(parents=True)
|
||||
(dat / "mame2003.xml").write_text(STALE_DAT)
|
||||
self.profile = {
|
||||
"source": "https://github.com/libretro/mame2003-libretro",
|
||||
"source_commit": COMMIT,
|
||||
"core_version": "0.78",
|
||||
}
|
||||
doc = api.import_profile("mame2003", profile, self.cache, offline=True)
|
||||
self.report: dict = {}
|
||||
self.doc = api.import_profile("mame2003", self.profile, self.cache, True, self.report)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.temp.cleanup()
|
||||
|
||||
def test_parents_come_from_the_game_macros(self) -> None:
|
||||
self.assertEqual(self.doc["bios"], {"bios1": ["built1", "clone1", "game1"]})
|
||||
|
||||
def test_a_bios_without_a_dump_needs_no_archive(self) -> None:
|
||||
self.assertNotIn("bios2", self.doc["bios"])
|
||||
self.assertEqual(self.doc["counts"]["bios_sets"], 2)
|
||||
|
||||
def test_the_branch_the_build_compiles(self) -> None:
|
||||
"""BOARD_HACK is 0 in the header the driver includes."""
|
||||
self.assertNotIn("hacked", self.doc["bios"]["bios1"])
|
||||
|
||||
def test_the_tiny_build_list_is_left_out(self) -> None:
|
||||
self.assertEqual(self.doc["counts"]["games"], 6)
|
||||
|
||||
def test_a_disk_image_is_a_chd(self) -> None:
|
||||
self.assertEqual(self.doc["chd"], ["diskgame"])
|
||||
|
||||
def test_the_source_is_named_by_its_tree(self) -> None:
|
||||
tree = self.doc["source"]["files"]["src"]
|
||||
source = api.read_driver_source(self.cache / "src" / "libretro" / "mame2003-libretro" / f"{COMMIT}.tar.gz")
|
||||
self.assertEqual(tree, source.tree)
|
||||
self.assertEqual(list(self.doc["source"]["files"]), ["src"])
|
||||
|
||||
def test_the_committed_dat_is_reported_where_it_disagrees(self) -> None:
|
||||
gaps = self.report["dat_gaps"]
|
||||
self.assertEqual(gaps["romof"], ["game1"])
|
||||
self.assertEqual(gaps["dat_only"], ["oldbios"])
|
||||
self.assertIn("built1", gaps["code_only"])
|
||||
|
||||
def test_an_undeclared_driver_is_refused(self) -> None:
|
||||
with self.assertRaises(api.DriverSourceError):
|
||||
api.driver_source_sets("DRIVER( nosuch )", {"src/drivers/a.c": ""}, {})
|
||||
|
||||
def test_the_empty_tree(self) -> None:
|
||||
self.assertEqual(api.git_tree_sha({}), "4b825dc642cb6eb9a060e54bf8d69288fbee4904")
|
||||
|
||||
@unittest.skipIf(Draft202012Validator is None, "jsonschema not installed")
|
||||
def test_output_matches_the_schema(self) -> None:
|
||||
schema = json.loads((ROOT / "schemas" / "arcade-parents.schema.json").read_text())
|
||||
self.assertEqual(list(Draft202012Validator(schema).iter_errors(doc)), [])
|
||||
self.assertEqual(list(Draft202012Validator(schema).iter_errors(self.doc)), [])
|
||||
|
||||
|
||||
FBNEO_LIST = """\t{ "1942", "pre90s/d_1942.cpp"},
|
||||
\t{ "msx_1942", "msx/d_msx.cpp"},
|
||||
\t{ "msx_msx", "msx/d_msx.cpp"},
|
||||
\t{ "nes_zelda", "nes/d_nes.cpp"},
|
||||
\t{ "fds_zelda", "nes/d_nes.cpp"},
|
||||
\t{ "nes_smb", "nes/d_nes.cpp"},
|
||||
"""
|
||||
|
||||
|
||||
def _dat(*games: str) -> bytes:
|
||||
return ("<datafile>" + "".join(games) + "</datafile>").encode()
|
||||
|
||||
|
||||
def _game(name: str, source: str, romof: str | None = None) -> str:
|
||||
parent = f' romof="{romof}"' if romof else ""
|
||||
return (
|
||||
f'<game name="{name}" sourcefile="{source}"{parent}>'
|
||||
f'<rom name="{name}.bin" size="1" crc="12345678"/></game>'
|
||||
)
|
||||
|
||||
|
||||
class FbneoNamespaces(unittest.TestCase):
|
||||
"""Each FBNeo DAT is its own namespace, a console set is its driver."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
names = api.fbneo_drivers(FBNEO_LIST)
|
||||
arcade = _dat(_game("1942", "pre90s/d_1942.cpp"))
|
||||
msx = _dat(
|
||||
_game("1942", "msx/d_msx.cpp", "msx"),
|
||||
'<game name="msx" sourcefile="msx/d_msx.cpp" isbios="yes">'
|
||||
'<rom name="msx.rom" size="1" crc="87654321"/></game>',
|
||||
)
|
||||
nes = _dat(_game("zelda", "nes/d_nes.cpp"), _game("smb", "nes/d_nes.cpp"))
|
||||
sets, self.archives = api.fbneo_sets(
|
||||
[lambda d=d: io.BytesIO(d) for d in (arcade, msx, nes)], names
|
||||
)
|
||||
self.sets = sets
|
||||
self.index = api.build_index(sets, "isbios", self.archives)
|
||||
|
||||
def test_the_msx_set_needs_the_msx_bios_and_the_arcade_one_does_not(self) -> None:
|
||||
self.assertEqual(self.index["bios"], {"msx": ["msx_1942"]})
|
||||
self.assertIn("1942", self.sets)
|
||||
|
||||
def test_the_bios_is_named_by_its_archive(self) -> None:
|
||||
self.assertEqual(self.archives["msx_msx"], "msx")
|
||||
|
||||
def test_a_shared_source_file_takes_the_prefix_of_its_dat(self) -> None:
|
||||
self.assertIn("nes_zelda", self.sets)
|
||||
self.assertNotIn("fds_zelda", self.sets)
|
||||
|
||||
|
||||
class DeclaredArchives(unittest.TestCase):
|
||||
|
||||
@@ -374,6 +374,26 @@ class ListXmlRecipes(unittest.TestCase):
|
||||
[m["name"] for m in by_name["parentset.zip"]["members"]], ["shared.rom"]
|
||||
)
|
||||
|
||||
def test_a_machine_larger_than_the_window_is_kept(self):
|
||||
"""Each machine here spans several reads: the window grows until the
|
||||
element closes instead of cutting its start tag away."""
|
||||
from scripts.scraper import romset_dat_importer
|
||||
|
||||
expected = listxml_entries(self._opener(self._document()), "MAME 0.289", None)
|
||||
saved = romset_dat_importer.LISTXML_CHUNK
|
||||
try:
|
||||
for window in (1, 7, 16, 64):
|
||||
romset_dat_importer.LISTXML_CHUNK = window
|
||||
entries = listxml_entries(
|
||||
self._opener(self._document()), "MAME 0.289", None
|
||||
)
|
||||
self.assertEqual(entries, expected, window)
|
||||
finally:
|
||||
romset_dat_importer.LISTXML_CHUNK = saved
|
||||
self.assertEqual(
|
||||
[entry["name"] for entry in entries], ["childset.zip", "parentset.zip"]
|
||||
)
|
||||
|
||||
def test_an_undumped_only_set_is_dropped(self):
|
||||
entries = listxml_entries(self._opener(self._document()), "MAME 0.289", None)
|
||||
self.assertNotIn("undumped.zip", {entry["name"] for entry in entries})
|
||||
|
||||
+1
-1
@@ -1634,7 +1634,7 @@ python scripts/generate_games_index.py --check # exit 1 when a publ
|
||||
| `games/catalogs/<source>/<system>.json` | `scraper/game_dat_importer.py` | crc32, size, sha1, region and title per game, disc serials |
|
||||
| `games/headers.yml` | hand, cited | header fields each core reads and the region each value means |
|
||||
| `games/regions.yml`, `games/extras.yml` | hand, cited | region routes, the cases that keep every region, per-game files |
|
||||
| `games/arcade/<profile>.json` | `scraper/arcade_parent_importer.py` | BIOS parent and device sets of each game set |
|
||||
| `games/arcade/<profile>.json` | `scraper/arcade_parent_importer.py` | BIOS parent and device sets of each game set, from the DAT the pin names or, for mame2000, mame2003 and mame2003-plus, from the driver code |
|
||||
|
||||
Folder names resolve to systems through `SYSTEM_ALIASES` and `_norm_system_id`
|
||||
in `common.py`, the one alias table, and core names to profiles through the
|
||||
|
||||
Reference in new issue
Block a user