diff options
author | 2016-08-02 07:01:29 -0400 | |
---|---|---|
committer | 2016-08-02 17:40:49 -0400 | |
commit | f9db568146503c253230295ace2deba8433f6754 (patch) | |
tree | 57a1b43f5c967e17f0461f9d5be9abf88c2e27ae | |
parent | 159b73a708fb67ca2d39e1d4f8cee9987fdc3f8b (diff) |
Redo of split of src/emu/softlist.[cpp|h]
This is a redo of the split first submitted in #137, with the following differences:
* The newly refactored rom_entry data structure is used
* I've kept the refactored softlist code in src/emu, in order to defer the mechanical process of moving it
* I've kept includes of softlist[_dev].h out of diimage.h, so that changes to either do not trigger an emu.h recompilation
* Obviously, this goes against the latest master
79 files changed, 1028 insertions, 828 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua index 2302811a058..78b61d03d54 100644 --- a/scripts/src/emu.lua +++ b/scripts/src/emu.lua @@ -158,6 +158,8 @@ files { MAME_DIR .. "src/emu/screen.h", MAME_DIR .. "src/emu/softlist.cpp", MAME_DIR .. "src/emu/softlist.h", + MAME_DIR .. "src/emu/softlist_dev.cpp", + MAME_DIR .. "src/emu/softlist_dev.h", MAME_DIR .. "src/emu/sound.cpp", MAME_DIR .. "src/emu/sound.h", MAME_DIR .. "src/emu/speaker.cpp", diff --git a/src/devices/bus/a7800/a78_slot.h b/src/devices/bus/a7800/a78_slot.h index d6a635b1a82..0f4fd9d2e92 100644 --- a/src/devices/bus/a7800/a78_slot.h +++ b/src/devices/bus/a7800/a78_slot.h @@ -3,6 +3,8 @@ #ifndef __A78_SLOT_H #define __A78_SLOT_H +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS diff --git a/src/devices/bus/a800/a800_slot.h b/src/devices/bus/a800/a800_slot.h index 0d1bf674bd5..d1cf620bdc4 100644 --- a/src/devices/bus/a800/a800_slot.h +++ b/src/devices/bus/a800/a800_slot.h @@ -3,6 +3,8 @@ #ifndef __A800_SLOT_H #define __A800_SLOT_H +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS diff --git a/src/devices/bus/adam/exp.h b/src/devices/bus/adam/exp.h index c7bd5abc12a..f1b004d67a8 100644 --- a/src/devices/bus/adam/exp.h +++ b/src/devices/bus/adam/exp.h @@ -12,7 +12,7 @@ #define __ADAM_EXPANSION_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/apf/slot.h b/src/devices/bus/apf/slot.h index 076759e18b3..c2dba02fc08 100644 --- a/src/devices/bus/apf/slot.h +++ b/src/devices/bus/apf/slot.h @@ -3,6 +3,8 @@ #ifndef __APF_SLOT_H #define __APF_SLOT_H +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/arcadia/slot.h b/src/devices/bus/arcadia/slot.h index abc95db625f..2f7f2dbc67a 100644 --- a/src/devices/bus/arcadia/slot.h +++ b/src/devices/bus/arcadia/slot.h @@ -3,6 +3,9 @@ #ifndef __ARCADIA_SLOT_H #define __ARCADIA_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/astrocde/slot.h b/src/devices/bus/astrocde/slot.h index 6866f787655..edd94af5ca1 100644 --- a/src/devices/bus/astrocde/slot.h +++ b/src/devices/bus/astrocde/slot.h @@ -3,6 +3,9 @@ #ifndef __ASTROCADE_SLOT_H #define __ASTROCADE_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/c64/exp.h b/src/devices/bus/c64/exp.h index 3522942e823..4e4555173fa 100644 --- a/src/devices/bus/c64/exp.h +++ b/src/devices/bus/c64/exp.h @@ -37,6 +37,7 @@ #define __C64_EXPANSION_SLOT__ #include "emu.h" +#include "softlist_dev.h" #include "formats/cbm_crt.h" diff --git a/src/devices/bus/cbm2/exp.h b/src/devices/bus/cbm2/exp.h index 2a9fa80d051..ad66454a746 100644 --- a/src/devices/bus/cbm2/exp.h +++ b/src/devices/bus/cbm2/exp.h @@ -30,6 +30,7 @@ #define __CBM2_EXPANSION_SLOT__ #include "emu.h" +#include "softlist_dev.h" diff --git a/src/devices/bus/chanf/slot.h b/src/devices/bus/chanf/slot.h index 68599ffad1c..f1d3f0d2c88 100644 --- a/src/devices/bus/chanf/slot.h +++ b/src/devices/bus/chanf/slot.h @@ -3,6 +3,9 @@ #ifndef __CHANF_SLOT_H #define __CHANF_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/coco/cococart.h b/src/devices/bus/coco/cococart.h index 7ba1e301d50..9415b5956c8 100644 --- a/src/devices/bus/coco/cococart.h +++ b/src/devices/bus/coco/cococart.h @@ -11,6 +11,8 @@ #ifndef __COCOCART_H__ #define __COCOCART_H__ +#include "softlist_dev.h" + /*************************************************************************** CONSTANTS diff --git a/src/devices/bus/coleco/exp.h b/src/devices/bus/coleco/exp.h index 25f503b378e..19fa5b5e69c 100644 --- a/src/devices/bus/coleco/exp.h +++ b/src/devices/bus/coleco/exp.h @@ -31,7 +31,7 @@ #define __COLECOVISION_CARTRIDGE_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/crvision/slot.h b/src/devices/bus/crvision/slot.h index 47fed8c1583..7643ca7fb1b 100644 --- a/src/devices/bus/crvision/slot.h +++ b/src/devices/bus/crvision/slot.h @@ -3,6 +3,9 @@ #ifndef __CRVISION_SLOT_H #define __CRVISION_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/gameboy/gb_slot.h b/src/devices/bus/gameboy/gb_slot.h index 67db3cda7f0..75a8b4e7cde 100644 --- a/src/devices/bus/gameboy/gb_slot.h +++ b/src/devices/bus/gameboy/gb_slot.h @@ -3,6 +3,9 @@ #ifndef __GB_SLOT_H #define __GB_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/gba/gba_slot.h b/src/devices/bus/gba/gba_slot.h index 5cbc103e8dc..f9918744d97 100644 --- a/src/devices/bus/gba/gba_slot.h +++ b/src/devices/bus/gba/gba_slot.h @@ -3,6 +3,9 @@ #ifndef __GBA_SLOT_H #define __GBA_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/generic/slot.h b/src/devices/bus/generic/slot.h index 6ba2e1a1fd5..a3e07f68ef4 100644 --- a/src/devices/bus/generic/slot.h +++ b/src/devices/bus/generic/slot.h @@ -3,6 +3,9 @@ #ifndef __GENERIC_SLOT_H #define __GENERIC_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/hp_optroms/hp_optrom.h b/src/devices/bus/hp_optroms/hp_optrom.h index d82f8962f4f..6ca5440cce5 100644 --- a/src/devices/bus/hp_optroms/hp_optrom.h +++ b/src/devices/bus/hp_optroms/hp_optrom.h @@ -14,6 +14,8 @@ #define _HP_OPTROM_H_ #include "emu.h" +#include "softlist_dev.h" + class hp_optrom_cart_device : public device_t, public device_slot_card_interface diff --git a/src/devices/bus/intv/slot.h b/src/devices/bus/intv/slot.h index ced41e71fd0..11d88aed25c 100644 --- a/src/devices/bus/intv/slot.h +++ b/src/devices/bus/intv/slot.h @@ -3,6 +3,9 @@ #ifndef __INTV_SLOT_H #define __INTV_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/iq151/iq151.h b/src/devices/bus/iq151/iq151.h index 1c75ff6c9a0..684aa00b8fd 100644 --- a/src/devices/bus/iq151/iq151.h +++ b/src/devices/bus/iq151/iq151.h @@ -45,6 +45,8 @@ #ifndef __IQ151CART_H__ #define __IQ151CART_H__ +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/isa/sc499.h b/src/devices/bus/isa/sc499.h index 7bbdaedfb8b..ad536a66df0 100644 --- a/src/devices/bus/isa/sc499.h +++ b/src/devices/bus/isa/sc499.h @@ -15,6 +15,8 @@ #include "emu.h" #include "bus/isa/isa.h" +#include "softlist_dev.h" + //************************************************************************** // TYPE DEFINITIONS diff --git a/src/devices/bus/kc/kc.h b/src/devices/bus/kc/kc.h index 7f9ed65f7d0..6f5e30f4943 100644 --- a/src/devices/bus/kc/kc.h +++ b/src/devices/bus/kc/kc.h @@ -11,6 +11,8 @@ #ifndef __KCEXP_H__ #define __KCEXP_H__ +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/m5/slot.h b/src/devices/bus/m5/slot.h index cd12d43f3a8..27345e34a99 100644 --- a/src/devices/bus/m5/slot.h +++ b/src/devices/bus/m5/slot.h @@ -3,6 +3,9 @@ #ifndef __M5_SLOT_H #define __M5_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/megadrive/md_slot.h b/src/devices/bus/megadrive/md_slot.h index 4a86749d991..008ae917fb5 100644 --- a/src/devices/bus/megadrive/md_slot.h +++ b/src/devices/bus/megadrive/md_slot.h @@ -3,6 +3,8 @@ #ifndef __MD_SLOT_H #define __MD_SLOT_H +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/msx_slot/cartridge.h b/src/devices/bus/msx_slot/cartridge.h index b9e1ca5e4f7..63530699b2b 100644 --- a/src/devices/bus/msx_slot/cartridge.h +++ b/src/devices/bus/msx_slot/cartridge.h @@ -5,6 +5,7 @@ #include "slot.h" #include "bus/msx_cart/cartridge.h" +#include "softlist_dev.h" extern const device_type MSX_SLOT_CARTRIDGE; diff --git a/src/devices/bus/neogeo/slot.h b/src/devices/bus/neogeo/slot.h index 158ff77e706..83de22b0a4b 100644 --- a/src/devices/bus/neogeo/slot.h +++ b/src/devices/bus/neogeo/slot.h @@ -4,6 +4,8 @@ #define __NEOGEO_SLOT_H #include "emu.h" +#include "softlist_dev.h" + /* PCB */ enum diff --git a/src/devices/bus/nes/aladdin.h b/src/devices/bus/nes/aladdin.h index b49ecbf964e..1ef34502618 100644 --- a/src/devices/bus/nes/aladdin.h +++ b/src/devices/bus/nes/aladdin.h @@ -4,6 +4,7 @@ #define __NES_ALADDIN_H #include "nxrom.h" +#include "softlist_dev.h" //---------------------------------- diff --git a/src/devices/bus/nes/datach.h b/src/devices/bus/nes/datach.h index 80157a83a5c..980be7a6492 100644 --- a/src/devices/bus/nes/datach.h +++ b/src/devices/bus/nes/datach.h @@ -4,6 +4,7 @@ #define __NES_DATACH_H #include "bandai.h" +#include "softlist_dev.h" #include "machine/i2cmem.h" #include "machine/bcreader.h" diff --git a/src/devices/bus/nes/karastudio.h b/src/devices/bus/nes/karastudio.h index e2b5ef874b5..8af386d9e33 100644 --- a/src/devices/bus/nes/karastudio.h +++ b/src/devices/bus/nes/karastudio.h @@ -4,6 +4,7 @@ #define __NES_KARASTUDIO_H #include "nxrom.h" +#include "softlist_dev.h" //----------------------------------------- diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index d9b64cfa30a..27790c208e0 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -3,6 +3,9 @@ #ifndef __NES_SLOT_H__ #define __NES_SLOT_H__ +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/nes/sunsoft_dcs.h b/src/devices/bus/nes/sunsoft_dcs.h index 04f8011d29a..bc56a5a2079 100644 --- a/src/devices/bus/nes/sunsoft_dcs.h +++ b/src/devices/bus/nes/sunsoft_dcs.h @@ -4,6 +4,7 @@ #define __NES_SUNSOFT_DCS_H #include "sunsoft.h" +#include "softlist_dev.h" //----------------------------------------------- diff --git a/src/devices/bus/odyssey2/slot.h b/src/devices/bus/odyssey2/slot.h index 88dde833dca..50f04e74b7e 100644 --- a/src/devices/bus/odyssey2/slot.h +++ b/src/devices/bus/odyssey2/slot.h @@ -3,6 +3,9 @@ #ifndef __O2_SLOT_H #define __O2_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/pce/pce_slot.h b/src/devices/bus/pce/pce_slot.h index c6cb11096e1..579945229bf 100644 --- a/src/devices/bus/pce/pce_slot.h +++ b/src/devices/bus/pce/pce_slot.h @@ -3,6 +3,9 @@ #ifndef __PCE_SLOT_H #define __PCE_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/plus4/exp.h b/src/devices/bus/plus4/exp.h index c63d2b618f1..2d18efaa207 100644 --- a/src/devices/bus/plus4/exp.h +++ b/src/devices/bus/plus4/exp.h @@ -40,7 +40,7 @@ #define __PLUS4_EXPANSION_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/ql/rom.h b/src/devices/bus/ql/rom.h index 606ffe4e67b..5649804df66 100644 --- a/src/devices/bus/ql/rom.h +++ b/src/devices/bus/ql/rom.h @@ -31,7 +31,7 @@ #define __QL_ROM_CARTRIDGE_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/saturn/sat_slot.h b/src/devices/bus/saturn/sat_slot.h index af16ecbdeaa..f87ce9bf0d3 100644 --- a/src/devices/bus/saturn/sat_slot.h +++ b/src/devices/bus/saturn/sat_slot.h @@ -3,6 +3,9 @@ #ifndef __SAT_SLOT_H #define __SAT_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/scv/slot.h b/src/devices/bus/scv/slot.h index 1d921f8d607..cbf87dd7d06 100644 --- a/src/devices/bus/scv/slot.h +++ b/src/devices/bus/scv/slot.h @@ -3,6 +3,9 @@ #ifndef __SCV_SLOT_H #define __SCV_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/sega8/sega8_slot.h b/src/devices/bus/sega8/sega8_slot.h index d27e993f0f7..5a0ce0af010 100644 --- a/src/devices/bus/sega8/sega8_slot.h +++ b/src/devices/bus/sega8/sega8_slot.h @@ -3,6 +3,9 @@ #ifndef __SEGA8_SLOT_H #define __SEGA8_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/snes/snes_slot.h b/src/devices/bus/snes/snes_slot.h index 7ebfefaa7f2..f6d4208eb1c 100644 --- a/src/devices/bus/snes/snes_slot.h +++ b/src/devices/bus/snes/snes_slot.h @@ -3,6 +3,9 @@ #ifndef __SNS_SLOT_H #define __SNS_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/ti99x/gromport.h b/src/devices/bus/ti99x/gromport.h index 81fa024f995..11727076ffb 100644 --- a/src/devices/bus/ti99x/gromport.h +++ b/src/devices/bus/ti99x/gromport.h @@ -12,6 +12,8 @@ #include "emu.h" #include "ti99defs.h" #include "machine/tmc0430.h" +#include "softlist_dev.h" + extern const device_type GROMPORT; diff --git a/src/devices/bus/vboy/slot.h b/src/devices/bus/vboy/slot.h index cf031e75f85..71adadd6a2a 100644 --- a/src/devices/bus/vboy/slot.h +++ b/src/devices/bus/vboy/slot.h @@ -3,6 +3,9 @@ #ifndef __VBOY_SLOT_H #define __VBOY_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/vc4000/slot.h b/src/devices/bus/vc4000/slot.h index 069593208bc..ed3425d0ddc 100644 --- a/src/devices/bus/vc4000/slot.h +++ b/src/devices/bus/vc4000/slot.h @@ -3,6 +3,9 @@ #ifndef __VC4000_SLOT_H #define __VC4000_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/vcs/vcs_slot.h b/src/devices/bus/vcs/vcs_slot.h index 142c30f9622..b8532dc216d 100755 --- a/src/devices/bus/vcs/vcs_slot.h +++ b/src/devices/bus/vcs/vcs_slot.h @@ -3,6 +3,8 @@ #ifndef __VCS_SLOT_H #define __VCS_SLOT_H +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS diff --git a/src/devices/bus/vectrex/slot.h b/src/devices/bus/vectrex/slot.h index 5c0183327ae..261574556cd 100644 --- a/src/devices/bus/vectrex/slot.h +++ b/src/devices/bus/vectrex/slot.h @@ -3,6 +3,9 @@ #ifndef __VECTREX_SLOT_H #define __VECTREX_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/vic10/exp.h b/src/devices/bus/vic10/exp.h index 4221991e124..a3ff118c891 100644 --- a/src/devices/bus/vic10/exp.h +++ b/src/devices/bus/vic10/exp.h @@ -37,10 +37,10 @@ #define __VIC10_EXPANSION_SLOT__ #include "emu.h" +#include "softlist_dev.h" #include "formats/cbm_crt.h" - //************************************************************************** // CONSTANTS //************************************************************************** diff --git a/src/devices/bus/vic20/exp.h b/src/devices/bus/vic20/exp.h index 1bd6092e400..9f161fb5c28 100644 --- a/src/devices/bus/vic20/exp.h +++ b/src/devices/bus/vic20/exp.h @@ -37,7 +37,7 @@ #define __VIC20_EXPANSION_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/vidbrain/exp.h b/src/devices/bus/vidbrain/exp.h index f662dd7cfa7..c9cd6677b55 100644 --- a/src/devices/bus/vidbrain/exp.h +++ b/src/devices/bus/vidbrain/exp.h @@ -40,7 +40,7 @@ #define __VIDEOBRAIN_EXPANSION_SLOT__ #include "emu.h" - +#include "softlist_dev.h" //************************************************************************** diff --git a/src/devices/bus/wswan/slot.h b/src/devices/bus/wswan/slot.h index 72036eab9ca..bd9d74fbe85 100644 --- a/src/devices/bus/wswan/slot.h +++ b/src/devices/bus/wswan/slot.h @@ -3,6 +3,9 @@ #ifndef __WS_SLOT_H #define __WS_SLOT_H +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/bus/z88/z88.h b/src/devices/bus/z88/z88.h index 60dfa2f924c..73d64575976 100644 --- a/src/devices/bus/z88/z88.h +++ b/src/devices/bus/z88/z88.h @@ -54,6 +54,9 @@ #ifndef __Z88CART_H__ #define __Z88CART_H__ +#include "softlist_dev.h" + + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/devices/imagedev/cassette.h b/src/devices/imagedev/cassette.h index 1e6198ddeed..036fc77c534 100644 --- a/src/devices/imagedev/cassette.h +++ b/src/devices/imagedev/cassette.h @@ -12,6 +12,7 @@ #define CASSETTE_H #include "formats/cassimg.h" +#include "softlist_dev.h" enum cassette_state diff --git a/src/devices/imagedev/chd_cd.h b/src/devices/imagedev/chd_cd.h index 02d39071604..9e2ec9f9a29 100644 --- a/src/devices/imagedev/chd_cd.h +++ b/src/devices/imagedev/chd_cd.h @@ -12,6 +12,7 @@ #define CHD_CD_H #include "cdrom.h" +#include "softlist_dev.h" /*************************************************************************** TYPE DEFINITIONS diff --git a/src/devices/imagedev/diablo.h b/src/devices/imagedev/diablo.h index 806a825a1fe..8ab2ac1addc 100644 --- a/src/devices/imagedev/diablo.h +++ b/src/devices/imagedev/diablo.h @@ -8,6 +8,7 @@ #define _IMAGEDEV_DIABLO_H_ #include "harddisk.h" +#include "softlist_dev.h" #define DIABLO_TAG(_id) "diablo"#_id diff --git a/src/devices/imagedev/flopdrv.h b/src/devices/imagedev/flopdrv.h index 9d571c9f390..34e54100364 100644 --- a/src/devices/imagedev/flopdrv.h +++ b/src/devices/imagedev/flopdrv.h @@ -7,6 +7,7 @@ #define __FLOPDRV_H__ #include "formats/flopimg.h" +#include "softlist_dev.h" #define FLOPPY_TYPE_REGULAR 0 #define FLOPPY_TYPE_APPLE 1 diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h index ec5e4b983e2..5e93da56c69 100644 --- a/src/devices/imagedev/floppy.h +++ b/src/devices/imagedev/floppy.h @@ -20,6 +20,7 @@ #include "formats/cqm_dsk.h" #include "formats/dsk_dsk.h" #include "sound/samples.h" +#include "softlist_dev.h" #define MCFG_FLOPPY_DRIVE_ADD(_tag, _slot_intf, _def_slot, _formats) \ MCFG_DEVICE_ADD(_tag, FLOPPY_CONNECTOR, 0) \ diff --git a/src/devices/imagedev/harddriv.h b/src/devices/imagedev/harddriv.h index 583a5f53e9f..d2ce6aeaef9 100644 --- a/src/devices/imagedev/harddriv.h +++ b/src/devices/imagedev/harddriv.h @@ -12,6 +12,7 @@ #define HARDDRIV_H #include "harddisk.h" +#include "softlist_dev.h" /*************************************************************************** TYPE DEFINITIONS diff --git a/src/devices/imagedev/snapquik.h b/src/devices/imagedev/snapquik.h index e14b1d6da6a..1c1a9a3b3df 100644 --- a/src/devices/imagedev/snapquik.h +++ b/src/devices/imagedev/snapquik.h @@ -11,6 +11,8 @@ #ifndef __SNAPQUIK_H__ #define __SNAPQUIK_H__ +#include "softlist_dev.h" + typedef delegate<image_init_result (device_image_interface &,const char *, int)> snapquick_load_delegate; // ======================> snapshot_image_device diff --git a/src/devices/machine/smartmed.h b/src/devices/machine/smartmed.h index 0b69fd05886..f1da965c4e9 100644 --- a/src/devices/machine/smartmed.h +++ b/src/devices/machine/smartmed.h @@ -8,6 +8,7 @@ #define __SMARTMEDIA_H__ #include "formats/imageutl.h" +#include "softlist_dev.h" //#define SMARTMEDIA_IMAGE_SAVE diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index 34a64ddf0f8..8e3d6d04da3 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -15,6 +15,7 @@ #include "ui/uimain.h" #include "zippath.h" #include "softlist.h" +#include "softlist_dev.h" #include "formats/ioprocs.h" #include <regex> @@ -840,9 +841,9 @@ bool device_image_interface::load_software(software_list_device &swlist, const c UINT32 supported = swinfo->supported(); if (supported == SOFTWARE_SUPPORTED_PARTIAL) - osd_printf_error("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist.list_name()); + osd_printf_error("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist.list_name().c_str()); if (supported == SOFTWARE_SUPPORTED_NO) - osd_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name()); + osd_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name().c_str()); // attempt reading up the chain through the parents and create a locationtag std::string in the format // " swlist % clonename % parentname " @@ -1036,7 +1037,8 @@ image_init_result device_image_interface::load_software(const std::string &softl m_is_loading = true; // Check if there's a software list defined for this device and use that if we're not creating an image - bool softload = load_software_part(softlist_name.c_str(), m_software_part_ptr); + std::string list_name; + bool softload = load_software_part(softlist_name.c_str(), m_software_part_ptr, &list_name); if (!softload) { m_is_loading = false; @@ -1045,8 +1047,8 @@ image_init_result device_image_interface::load_software(const std::string &softl // set up softlist stuff m_software_info_ptr = &m_software_part_ptr->info(); - m_software_list_name.assign(m_software_info_ptr->list().list_name()); - m_full_software_name.assign(m_software_part_ptr->info().shortname()); + m_software_list_name = std::move(list_name); + m_full_software_name = m_software_part_ptr->info().shortname(); // specify image name with softlist-derived names m_image_name = m_full_software_name; @@ -1301,7 +1303,11 @@ void device_image_interface::software_name_split(const char *swlist_swname, std: } -const software_part *device_image_interface::find_software_item(const char *path, bool restrict_to_interface) const +//------------------------------------------------- +// find_software_item +//------------------------------------------------- + +const software_part *device_image_interface::find_software_item(const char *path, bool restrict_to_interface, software_list_device **dev) const { // split full software name into software list name and short software name std::string swlist_name, swinfo_name, swpart_name; @@ -1322,7 +1328,11 @@ const software_part *device_image_interface::find_software_item(const char *path { const software_part *part = info->find_part(swpart_name.c_str(), interface); if (part != nullptr) + { + if (dev != nullptr) + *dev = &swlistdev; return part; + } } } @@ -1337,17 +1347,33 @@ const software_part *device_image_interface::find_software_item(const char *path { const software_part *part = info->find_part(nullptr, interface); if (part != nullptr) + { + if (dev != nullptr) + *dev = &swlistdev; return part; + } } } } // if explicitly specified and not found, just error here + if (dev != nullptr) + *dev = nullptr; return nullptr; } //------------------------------------------------- +// get_software_list_loader +//------------------------------------------------- + +const software_list_loader &device_image_interface::get_software_list_loader() const +{ + return false_software_list_loader::instance(); +} + + +//------------------------------------------------- // load_software_part // // Load a software part for a device. The part to @@ -1360,10 +1386,11 @@ const software_part *device_image_interface::find_software_item(const char *path // sw_info and sw_part are also set. //------------------------------------------------- -bool device_image_interface::load_software_part(const char *path, const software_part *&swpart) +bool device_image_interface::load_software_part(const char *path, const software_part *&swpart, std::string *list_name) { // if no match has been found, we suggest similar shortnames - swpart = find_software_item(path, true); + software_list_device *swlist; + swpart = find_software_item(path, true, &swlist); if (swpart == nullptr) { software_list_device::display_matches(device().machine().config(), image_interface(), path); @@ -1371,11 +1398,10 @@ bool device_image_interface::load_software_part(const char *path, const software } // Load the software part - software_list_device &swlist = swpart->info().list(); const char *swname = swpart->info().shortname().c_str(); - const rom_entry *start_entry = swpart->romdata(); + const rom_entry *start_entry = swpart->romdata().data(); const software_list_loader &loader = get_software_list_loader(); - bool result = loader.load_software(*this, swlist, swname, start_entry); + bool result = loader.load_software(*this, *swlist, swname, start_entry); #ifdef UNUSED_VARIABLE // Tell the world which part we actually loaded @@ -1383,17 +1409,17 @@ bool device_image_interface::load_software_part(const char *path, const software #endif // check compatibility - switch (swpart->is_compatible(swlist)) + switch (swlist->is_compatible(*swpart)) { case SOFTWARE_IS_COMPATIBLE: break; case SOFTWARE_IS_INCOMPATIBLE: - swlist.popmessage("WARNING! the set %s might not work on this system due to incompatible filter(s) '%s'\n", swpart->info().shortname(), swlist.filter()); + swlist->popmessage("WARNING! the set %s might not work on this system due to incompatible filter(s) '%s'\n", swpart->info().shortname(), swlist->filter()); break; case SOFTWARE_NOT_COMPATIBLE: - swlist.popmessage("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n", swpart->info().shortname(), swlist.filter()); + swlist->popmessage("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n", swpart->info().shortname(), swlist->filter()); break; } @@ -1404,7 +1430,7 @@ bool device_image_interface::load_software_part(const char *path, const software const software_part *req_swpart = find_software_item(requirement, false); if (req_swpart != nullptr) { - device_image_interface *req_image = req_swpart->find_mountable_image(device().mconfig()); + device_image_interface *req_image = software_list_device::find_mountable_image(device().mconfig(), *req_swpart); if (req_image != nullptr) { req_image->set_init_phase(); @@ -1412,6 +1438,8 @@ bool device_image_interface::load_software_part(const char *path, const software } } } + if (list_name != nullptr) + *list_name = swlist->list_name(); return result; } diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 1d066527b49..0f12c2169ba 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -21,8 +21,6 @@ #include <string> #include <vector> -#include "softlist.h" - //************************************************************************** // TYPE DEFINITIONS @@ -31,6 +29,7 @@ extern struct io_procs image_ioprocs; class software_list; +class software_list_loader; enum iodevice_t { @@ -252,7 +251,7 @@ public: bool user_loadable() const { return m_user_loadable; } protected: - virtual const software_list_loader &get_software_list_loader() const { return false_software_list_loader::instance(); } + virtual const software_list_loader &get_software_list_loader() const; image_init_result load_internal(const std::string &path, bool is_create, int create_format, util::option_resolution *create_args, bool just_load); void determine_open_plan(int is_create, UINT32 *open_plan); @@ -273,8 +272,8 @@ protected: void image_checkhash(); void update_names(const device_type device_type = nullptr, const char *inst = nullptr, const char *brief = nullptr); - const software_part *find_software_item(const char *path, bool restrict_to_interface) const; - bool load_software_part(const char *path, const software_part *&swpart); + const software_part *find_software_item(const char *path, bool restrict_to_interface, software_list_device **device = nullptr) const; + bool load_software_part(const char *path, const software_part *&swpart, std::string *list_name = nullptr); std::string software_get_default_slot(const char *default_card_slot) const; void add_format(std::unique_ptr<image_device_format> &&format); diff --git a/src/emu/drivenum.cpp b/src/emu/drivenum.cpp index 1d2f6d79f06..450790eb55a 100644 --- a/src/emu/drivenum.cpp +++ b/src/emu/drivenum.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /*************************************************************************** - drivenum.c + drivenum.cpp Driver enumeration helpers. @@ -10,7 +10,7 @@ #include "emu.h" #include "drivenum.h" -#include "softlist.h" +#include "softlist_dev.h" #include <ctype.h> diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp index 989539259cc..0a54658c926 100644 --- a/src/emu/romload.cpp +++ b/src/emu/romload.cpp @@ -2,7 +2,7 @@ // copyright-holders:Nicola Salmoria,Paul Priest,Aaron Giles /********************************************************************* - romload.c + romload.cpp ROM loading functions. *********************************************************************/ @@ -10,7 +10,7 @@ #include "emu.h" #include "emuopts.h" #include "drivenum.h" -#include "softlist.h" +#include "softlist_dev.h" #include "ui/uimain.h" diff --git a/src/emu/softlist.cpp b/src/emu/softlist.cpp index 2d6793db3af..67178a1b4bb 100644 --- a/src/emu/softlist.cpp +++ b/src/emu/softlist.cpp @@ -2,137 +2,16 @@ // copyright-holders:Wilbert Pol /*************************************************************************** - softlist.c + softlist.cpp Software list construction helpers. ***************************************************************************/ -#include "emu.h" -#include "emuopts.h" #include "softlist.h" -#include "validity.h" +#include "hash.h" #include "expat.h" -#include <ctype.h> - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -typedef std::unordered_map<std::string,const software_info *> softlist_map; - - -// ======================> softlist_parser - -class softlist_parser -{ -public: - // construction (== execution) - softlist_parser(software_list_device &list, std::ostringstream &errors); - -private: - enum parse_position - { - POS_ROOT, - POS_MAIN, - POS_SOFT, - POS_PART, - POS_DATA - }; - - // internal parsing helpers - const char *filename() const { return m_list.filename(); } - const char *infoname() const { return (m_current_info != nullptr) ? m_current_info->shortname().c_str() : "???"; } - int line() const { return XML_GetCurrentLineNumber(m_parser); } - int column() const { return XML_GetCurrentColumnNumber(m_parser); } - const char *parser_error() const { return XML_ErrorString(XML_GetErrorCode(m_parser)); } - - // internal error helpers - template <typename Format, typename... Params> void parse_error(Format &&fmt, Params &&... args); - void unknown_tag(const char *tagname) { parse_error("Unknown tag: %s", tagname); } - void unknown_attribute(const char *attrname) { parse_error("Unknown attribute: %s", attrname); } - - // internal helpers - template <typename T> std::vector<std::string> parse_attributes(const char **attributes, const T &attrlist); - bool parse_name_and_value(const char **attributes, std::string &name, std::string &value); - void add_rom_entry(std::string &&name, std::string &&hashdata, UINT32 offset, UINT32 length, UINT32 flags); - - // expat callbacks - static void start_handler(void *data, const char *tagname, const char **attributes); - static void data_handler(void *data, const XML_Char *s, int len); - static void end_handler(void *data, const char *name); - - // internal parsing - void parse_root_start(const char *tagname, const char **attributes); - void parse_main_start(const char *tagname, const char **attributes); - void parse_soft_start(const char *tagname, const char **attributes); - void parse_part_start(const char *tagname, const char **attributes); - void parse_data_start(const char *tagname, const char **attributes); - void parse_soft_end(const char *name); - - // internal parsing state - software_list_device & m_list; - std::ostringstream & m_errors; - XML_Parser m_parser; - bool m_done; - bool m_data_accum_expected; - std::string m_data_accum; - software_info * m_current_info; - software_part * m_current_part; - parse_position m_pos; -}; - - - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -// device type definition -const device_type SOFTWARE_LIST = &device_creator<software_list_device>; -false_software_list_loader false_software_list_loader::s_instance; -rom_software_list_loader rom_software_list_loader::s_instance; -image_software_list_loader image_software_list_loader::s_instance; - - - -//************************************************************************** -// SOFTWARE LIST LOADER -//************************************************************************** - -//------------------------------------------------- -// false_software_list_loader::load_software -//------------------------------------------------- - -bool false_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const -{ - return false; -} - - -//------------------------------------------------- -// rom_software_list_loader::load_software -//------------------------------------------------- - -bool rom_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const -{ - swlist.machine().rom_load().load_software_part_region(device, swlist, swname, start_entry); - return true; -} - - -//------------------------------------------------- -// image_software_list_loader::load_software -//------------------------------------------------- - -bool image_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const -{ - return device.load_software(swlist, swname, start_entry); -} - - //************************************************************************** // FEATURE LIST ITEM //************************************************************************** @@ -195,56 +74,6 @@ const char *software_part::feature(const std::string &feature_name) const //------------------------------------------------- -// is_compatible - determine if we are compatible -// with the given software_list_device -//------------------------------------------------- - -software_compatibility software_part::is_compatible(const software_list_device &swlistdev) const -{ - // get the softlist filter; if null, assume compatible - const char *filter = swlistdev.filter(); - if (filter == nullptr) - return SOFTWARE_IS_COMPATIBLE; - - // copy the comma-delimited string and ensure it ends with a final comma - std::string filt = std::string(filter).append(","); - - // get the incompatibility filter and test against it first if it exists - const char *incompatibility = feature("incompatibility"); - if (incompatibility != nullptr) - { - // copy the comma-delimited string and ensure it ends with a final comma - std::string incomp = std::string(incompatibility).append(","); - - // iterate over filter items and see if they exist in the list; if so, it's incompatible - for (int start = 0, end = filt.find_first_of(',',start); end != -1; start = end + 1, end = filt.find_first_of(',', start)) - { - std::string token(filt, start, end - start + 1); - if (incomp.find(token) != -1) - return SOFTWARE_IS_INCOMPATIBLE; - } - } - - // get the compatibility feature; if null, assume compatible - const char *compatibility = feature("compatibility"); - if (compatibility == nullptr) - return SOFTWARE_IS_COMPATIBLE; - - // copy the comma-delimited string and ensure it ends with a final comma - std::string comp = std::string(compatibility).append(","); - - // iterate over filter items and see if they exist in the compatibility list; if so, it's compatible - for (int start = 0, end = filt.find_first_of(',',start); end != -1; start = end + 1, end = filt.find_first_of(',', start)) - { - std::string token(filt, start, end - start + 1); - if (comp.find(token) != -1) - return SOFTWARE_IS_COMPATIBLE; - } - return SOFTWARE_NOT_COMPATIBLE; -} - - -//------------------------------------------------- // matches_interface - determine if we match // an interface in the provided list //------------------------------------------------- @@ -264,35 +93,6 @@ bool software_part::matches_interface(const char *interface_list) const } -//------------------------------------------------- -// find_mountable_image - find an image interface -// that can automatically mount this software part -//------------------------------------------------- - -device_image_interface *software_part::find_mountable_image(const machine_config &mconfig) const -{ - // if automount="no", don't bother - const char *mount = feature("automount"); - if (mount != nullptr && strcmp(mount, "no") == 0) - return nullptr; - - for (device_image_interface &image : image_interface_iterator(mconfig.root_device())) - { - const char *interface = image.image_interface(); - if (interface != nullptr && matches_interface(interface)) - { - // mount only if not already mounted - const char *option = mconfig.options().value(image.brief_instance_name()); - if (*option == '\0' && !image.filename()) - - return ℑ - } - } - return nullptr; -} - - - //************************************************************************** // SOFTWARE INFO //************************************************************************** @@ -301,9 +101,8 @@ device_image_interface *software_part::find_mountable_image(const machine_config // software_info - constructor //------------------------------------------------- -software_info::software_info(software_list_device &list, std::string &&name, std::string &&parent, const char *supported) +software_info::software_info(std::string &&name, std::string &&parent, const char *supported) : m_next(nullptr), - m_list(list), m_supported(SOFTWARE_SUPPORTED_YES), m_shortname(std::move(name)), m_parentname(std::move(parent)) @@ -365,383 +164,6 @@ bool software_info::has_multiple_parts(const char *interface) const } - -//************************************************************************** -// SOFTWARE LIST DEVICE -//************************************************************************** - -//------------------------------------------------- -// software_list_device - constructor -//------------------------------------------------- - -software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, SOFTWARE_LIST, "Software list", tag, owner, clock, "software_list", __FILE__), - m_list_type(SOFTWARE_LIST_ORIGINAL_SYSTEM), - m_filter(nullptr), - m_parsed(false), - m_file(mconfig.options().hash_path(), OPEN_FLAG_READ), - m_description("") -{ -} - - -//------------------------------------------------- -// static_set_type - configuration helper -// to set the list type -//------------------------------------------------- - -void software_list_device::static_set_type(device_t &device, const char *list, softlist_type list_type) -{ - software_list_device &swlistdev = downcast<software_list_device &>(device); - swlistdev.m_list_name.assign(list); - swlistdev.m_list_type = list_type; -} - - -//------------------------------------------------- -// static_set_custom_handler - configuration -// helper to set a custom callback -//------------------------------------------------- - -void software_list_device::static_set_filter(device_t &device, const char *filter) -{ - downcast<software_list_device &>(device).m_filter = filter; -} - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void software_list_device::device_start() -{ -} - - -//------------------------------------------------- -// find_approx_matches - search ourselves for -// a list of possible matches of the given name -// and optional interface -//------------------------------------------------- - -void software_list_device::find_approx_matches(const char *name, int matches, const software_info **list, const char *interface) -{ - // if no name, return - if (name == nullptr || name[0] == 0) - return; - - // initialize everyone's states - std::vector<int> penalty(matches); - for (int matchnum = 0; matchnum < matches; matchnum++) - { - penalty[matchnum] = 9999; - list[matchnum] = nullptr; - } - - // iterate over our info (will cause a parse if needed) - for (const software_info &swinfo : get_info()) - { - const software_part &part = swinfo.parts().front(); - if ((interface == nullptr || part.matches_interface(interface)) && part.is_compatible(*this) == SOFTWARE_IS_COMPATIBLE) - { - // pick the best match between driver name and description - int longpenalty = driver_list::penalty_compare(name, swinfo.longname().c_str()); - int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname().c_str()); - int curpenalty = std::min(longpenalty, shortpenalty); - - // insert into the sorted table of matches - for (int matchnum = matches - 1; matchnum >= 0; matchnum--) - { - // stop if we're worse than the current entry - if (curpenalty >= penalty[matchnum]) - break; - - // as long as this isn't the last entry, bump this one down - if (matchnum < matches - 1) - { - penalty[matchnum + 1] = penalty[matchnum]; - list[matchnum + 1] = list[matchnum]; - } - list[matchnum] = &swinfo; - penalty[matchnum] = curpenalty; - } - } - } -} - - -//------------------------------------------------- -// release - reset to a pre-parsed state -//------------------------------------------------- - -void software_list_device::release() -{ - osd_printf_verbose("Resetting %s\n", m_file.filename()); - m_parsed = false; - m_description.clear(); - m_errors.clear(); - m_infolist.clear(); -} - - -//------------------------------------------------- -// find_by_name - find a software list by name -// across all software list devices -//------------------------------------------------- - -software_list_device *software_list_device::find_by_name(const machine_config &config, const char *name) -{ - // iterate over each device in the system and find a match - for (software_list_device &swlistdev : software_list_device_iterator(config.root_device())) - if (strcmp(swlistdev.list_name(), name) == 0) - return &swlistdev; - return nullptr; -} - - -//------------------------------------------------- -// software_display_matches - display a list of -// possible matches in the system to the given -// name, across all software list devices -//------------------------------------------------- - -void software_list_device::display_matches(const machine_config &config, const char *interface, const char *name) -{ - // check if there is at least one software list - software_list_device_iterator deviter(config.root_device()); - if (deviter.first() != nullptr) - osd_printf_error("\n\"%s\" approximately matches the following\n" - "supported software items (best match first):\n\n", name); - - // iterate through lists - for (software_list_device &swlistdev : deviter) - { - // get the top 16 approximate matches for the selected device interface (i.e. only carts for cartslot, etc.) - const software_info *matches[16] = { nullptr }; - swlistdev.find_approx_matches(name, ARRAY_LENGTH(matches), matches, interface); - - // if we found some, print them - if (matches[0] != nullptr) - { - // different output depending on original system or compatible - if (swlistdev.list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) - osd_printf_error("* Software list \"%s\" (%s) matches: \n", swlistdev.list_name(), swlistdev.description()); - else - osd_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlistdev.list_name(), swlistdev.description()); - - // print them out - for (auto &match : matches) - { - if (match != nullptr) - osd_printf_error("%-18s%s\n", match->shortname().c_str(), match->longname().c_str()); - } - - osd_printf_error("\n"); - } - } -} - - -//------------------------------------------------- -// find - find an item by name in the software -// list, using wildcards and optionally starting -// from an intermediate point -//------------------------------------------------- - -const software_info *software_list_device::find(const char *look_for) -{ - // nullptr search returns nothing - if (look_for == nullptr) - return nullptr; - - bool iswild = strchr(look_for, '*') != nullptr || strchr(look_for, '?'); - - // find a match (will cause a parse if needed when calling get_info) - const auto &info_list = get_info(); - auto iter = std::find_if( - info_list.begin(), - info_list.end(), - [&](const software_info &info) - { - const char *shortname = info.shortname().c_str(); - return (iswild && core_strwildcmp(look_for, shortname) == 0) - || core_stricmp(look_for, shortname) == 0; - }); - - return iter != info_list.end() - ? &*iter - : nullptr; -} - - -//------------------------------------------------- -// parse - parse our softlist file -//------------------------------------------------- - -void software_list_device::parse() -{ - // skip if done - if (m_parsed) - return; - - // reset the errors - m_errors.clear(); - - // attempt to open the file - osd_file::error filerr = m_file.open(m_list_name.c_str(), ".xml"); - if (filerr == osd_file::error::NONE) - { - // parse if no error - std::ostringstream errs; - softlist_parser parser(*this, errs); - m_file.close(); - m_errors = errs.str(); - } - else - m_errors = string_format("Error opening file: %s\n", filename()); - - // indicate that we've been parsed - m_parsed = true; -} - - -//------------------------------------------------- -// device_validity_check - validate the device -// configuration -//------------------------------------------------- - -void software_list_device::device_validity_check(validity_checker &valid) const -{ - // add to the global map whenever we check a list so we don't re-check - // it in the future - if (valid.already_checked(std::string("softlist/").append(m_list_name).c_str())) - return; - - // do device validation only in case of validate command - if (!valid.validate_all()) - return; - - // actually do the validate - const_cast<software_list_device *>(this)->internal_validity_check(valid); -} - - -//------------------------------------------------- -// internal_validity_check - internal helper to -// check the list -//------------------------------------------------- - -void software_list_device::internal_validity_check(validity_checker &valid) -{ - enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; - - softlist_map names; - softlist_map descriptions; - for (const software_info &swinfo : get_info()) - { - // first parse and output core errors if any - if (m_errors.length() > 0) - { - osd_printf_error("%s: Errors parsing software list:\n%s", filename(), errors_string()); - break; - } - - // Now check if the xml data is valid: - - // Did we lost any description? - if (swinfo.longname().empty()) - { - osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname().c_str()); - break; - } - - // Did we lost any year? - if (swinfo.year().empty()) - { - osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname().c_str()); - break; - } - - // Did we lost any publisher? - if (swinfo.publisher().empty()) - { - osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname().c_str()); - break; - } - - // Did we lost the software parts? - if (swinfo.parts().empty()) - { - osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname().c_str()); - break; - } - - // Second, since the xml is fine, run additional checks: - - // check for duplicate names - if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) - { - const software_info *match = names.find(swinfo.shortname())->second; - osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname().c_str(), match->shortname().c_str()); - } - - // check for duplicate descriptions - std::string longname = std::string(swinfo.longname()); - if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) - osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname().c_str(), swinfo.shortname().c_str()); - - bool is_clone = false; - if (!swinfo.parentname().empty()) - { - is_clone = true; - if (swinfo.parentname() == swinfo.shortname()) - { - osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname().c_str()); - break; - } - - // make sure the parent exists - const software_info *swinfo2 = find(swinfo.parentname().c_str()); - - if (swinfo2 == nullptr) - osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname().c_str(), swinfo.shortname().c_str()); - else if (!swinfo2->parentname().empty()) - osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname().c_str()); - } - - // make sure the driver name is 8 chars or less - if ((is_clone && swinfo.shortname().length() > NAME_LEN_CLONE) || (!is_clone && swinfo.shortname().length() > NAME_LEN_PARENT)) - osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname().c_str(), - is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); - - // make sure the year is only digits, '?' or '+' - for (const char *s = swinfo.year().c_str(); *s != 0; s++) - if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') - { - osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname().c_str(), swinfo.year().c_str()); - break; - } - - softlist_map part_names; - for (const software_part &part : swinfo.parts()) - { - if (part.interface().empty()) - osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); - - if (part.romdata() == nullptr) - osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); - - if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) - osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); - } - } - - // release all the memory - release(); -} - - - //************************************************************************** // SOFTWARE LIST PARSER //************************************************************************** @@ -750,8 +172,10 @@ void software_list_device::internal_validity_check(validity_checker &valid) // softlist_parser - constructor //------------------------------------------------- -softlist_parser::softlist_parser(software_list_device &list, std::ostringstream &errors) - : m_list(list), +softlist_parser::softlist_parser(util::core_file &file, const std::string &filename, std::list<software_info> &infolist, std::ostringstream &errors) + : m_file(file), + m_filename(filename), + m_infolist(infolist), m_errors(errors), m_done(false), m_data_accum_expected(false), @@ -759,8 +183,6 @@ softlist_parser::softlist_parser(software_list_device &list, std::ostringstream m_current_part(nullptr), m_pos(POS_ROOT) { - osd_printf_verbose("Parsing %s\n", m_list.m_file.filename()); - // create the parser m_parser = XML_ParserCreate_MM(nullptr, nullptr, nullptr); if (m_parser == nullptr) @@ -772,12 +194,12 @@ softlist_parser::softlist_parser(software_list_device &list, std::ostringstream XML_SetCharacterDataHandler(m_parser, &softlist_parser::data_handler); // parse the file contents - m_list.m_file.seek(0, SEEK_SET); + m_file.seek(0, SEEK_SET); char buffer[1024]; while (!m_done) { - UINT32 length = m_list.m_file.read(buffer, sizeof(buffer)); - m_done = m_list.m_file.eof(); + UINT32 length = m_file.read(buffer, sizeof(buffer)); + m_done = m_file.eof(); if (XML_Parse(m_parser, buffer, length, m_done) == XML_STATUS_ERROR) { parse_error("%s", parser_error()); @@ -787,9 +209,39 @@ softlist_parser::softlist_parser(software_list_device &list, std::ostringstream // free the parser XML_ParserFree(m_parser); - osd_printf_verbose("Parsing complete\n"); } + +//------------------------------------------------- +// line +//------------------------------------------------- + +int softlist_parser::line() const +{ + return XML_GetCurrentLineNumber(m_parser); +} + + +//------------------------------------------------- +// column +//------------------------------------------------- + +int softlist_parser::column() const +{ + return XML_GetCurrentColumnNumber(m_parser); +} + + +//------------------------------------------------- +// parser_error +//------------------------------------------------- + +const char *softlist_parser::parser_error() const +{ + return XML_ErrorString(XML_GetErrorCode(m_parser)); +} + + //------------------------------------------------- // parse_error - append a parsing error with // filename, line and column information @@ -799,7 +251,7 @@ template <typename Format, typename... Params> inline void softlist_parser::parse_error(Format &&fmt, Params &&... args) { // always start with filename(line.column): - util::stream_format(m_errors, "%s(%d.%d): ", filename(), line(), column()); + util::stream_format(m_errors, "%s(%d.%d): ", m_filename, line(), column()); // append the remainder of the string util::stream_format(m_errors, std::forward<Format>(fmt), std::forward<Params>(args)...); @@ -894,17 +346,13 @@ void softlist_parser::add_rom_entry(std::string &&name, std::string &&hashdata, // make sure we don't add duplicate regions if (!name.empty() && (flags & ROMENTRY_TYPEMASK) == ROMENTRYTYPE_REGION) + { for (auto &elem : m_current_part->m_romdata) - if (!elem.name().empty() && elem.name() == name) + if (elem.name() == name) parse_error("Duplicated dataarea %s in software %s", name, infoname()); + } - // create the new entry and append it - m_current_part->m_romdata.emplace_back( - std::move(name), - std::move(hashdata), - offset, - length, - flags); + m_current_part->m_romdata.emplace_back(std::move(name), std::move(hashdata), offset, length, flags); } @@ -986,7 +434,7 @@ void softlist_parser::end_handler(void *data, const char *name) // data_handler - expat data handler //------------------------------------------------- -void softlist_parser::data_handler(void *data, const XML_Char *s, int len) +void softlist_parser::data_handler(void *data, const char *s, int len) { softlist_parser *state = reinterpret_cast<softlist_parser *>(data); @@ -1018,7 +466,7 @@ void softlist_parser::parse_root_start(const char *tagname, const char **attribu const auto attrvalues = parse_attributes(attributes, attrnames); if (!attrvalues[1].empty()) - m_list.m_description = attrvalues[1]; + m_description = attrvalues[1]; } else unknown_tag(tagname); @@ -1040,8 +488,8 @@ void softlist_parser::parse_main_start(const char *tagname, const char **attribu if (!attrvalues[0].empty()) { - m_list.m_infolist.emplace_back(m_list, std::move(attrvalues[0]), std::move(attrvalues[1]), attrvalues[2].c_str()); - m_current_info = &m_list.m_infolist.back(); + m_infolist.emplace_back(std::move(attrvalues[0]), std::move(attrvalues[1]), attrvalues[2].c_str()); + m_current_info = &m_infolist.back(); } else parse_error("No name defined for item"); @@ -1354,7 +802,7 @@ void softlist_parser::parse_soft_end(const char *tagname) return; // was any dataarea/rom information encountered? if so, add a terminator - if (m_current_part->romdata() != nullptr) + if (!m_current_part->m_romdata.empty()) add_rom_entry("", "", 0, 0, ROMENTRYTYPE_END); // get the info; if present, copy shared data (we assume name/value strings live @@ -1364,3 +812,4 @@ void softlist_parser::parse_soft_end(const char *tagname) m_current_part->m_featurelist.emplace_back(item.name(), item.value()); } } + diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 9b6cfd829bf..19ebc73e973 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -4,15 +4,16 @@ softlist.h - Software and software list information. + Software list file format. *********************************************************************/ #ifndef __SOFTLIST_H_ #define __SOFTLIST_H_ -#include "cstrpool.h" - +#include <list> +#include "romentry.h" +#include "corefile.h" //************************************************************************** @@ -23,108 +24,13 @@ #define SOFTWARE_SUPPORTED_PARTIAL 1 #define SOFTWARE_SUPPORTED_NO 2 -enum softlist_type -{ - SOFTWARE_LIST_ORIGINAL_SYSTEM, - SOFTWARE_LIST_COMPATIBLE_SYSTEM -}; - -enum software_compatibility -{ - SOFTWARE_IS_COMPATIBLE, - SOFTWARE_IS_INCOMPATIBLE, - SOFTWARE_NOT_COMPATIBLE -}; - - -//************************************************************************** -// MACROS -//************************************************************************** - -#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \ - software_list_device::static_set_type(*device, _list, _list_type); - -#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \ - MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) - -#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \ - MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) - -#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) - -#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) - -#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - software_list_device::static_set_filter(*device, _filter); - -#define MCFG_SOFTWARE_LIST_REMOVE( _tag ) \ - MCFG_DEVICE_REMOVE( _tag ) - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -class rom_entry; +struct XML_ParserStruct; class software_info; -class device_image_interface; -class software_list_device; - -// ======================> software_list_loader - -class software_list_loader -{ -public: - virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const = 0; -}; - - -// ======================> false_software_list_loader - -class false_software_list_loader : public software_list_loader -{ -public: - virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; - static const software_list_loader &instance() { return s_instance; } - -private: - static false_software_list_loader s_instance; -}; - - -// ======================> rom_software_list_loader - -class rom_software_list_loader : public software_list_loader -{ -public: - virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; - static const software_list_loader &instance() { return s_instance; } - -private: - static rom_software_list_loader s_instance; -}; - - -// ======================> image_software_list_loader - -class image_software_list_loader : public software_list_loader -{ -public: - virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; - static const software_list_loader &instance() { return s_instance; } - -private: - static image_software_list_loader s_instance; -}; - // ======================> feature_list_item @@ -174,13 +80,11 @@ public: const std::string &name() const { return m_name; } const std::string &interface() const { return m_interface; } const std::list<feature_list_item> &featurelist() const { return m_featurelist; } - const rom_entry *romdata(unsigned int index = 0) const { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; } + const std::vector<rom_entry> &romdata() const { return m_romdata; } // helpers - software_compatibility is_compatible(const software_list_device &swlist) const; bool matches_interface(const char *interface) const; const char *feature(const std::string &feature_name) const; - device_image_interface *find_mountable_image(const machine_config &mconfig) const; private: // internal state @@ -202,7 +106,7 @@ class software_info public: // construction/destruction - software_info(software_list_device &list, std::string &&name, std::string &&parent, const char *supported); + software_info(std::string &&name, std::string &&parent, const char *supported); software_info(software_info const &) = delete; software_info(software_info &&) = delete; software_info& operator=(software_info const &) = delete; @@ -210,7 +114,6 @@ public: // getters software_info *next() const { return m_next; } - software_list_device &list() const { return m_list; } const std::string &shortname() const { return m_shortname; } const std::string &longname() const { return m_longname; } const std::string &parentname() const { return m_parentname; } @@ -228,7 +131,6 @@ public: private: // internal state software_info * m_next; - software_list_device & m_list; UINT32 m_supported; std::string m_shortname; std::string m_longname; @@ -242,74 +144,68 @@ private: }; -// ======================> software_list_device +// ======================> softlist_parser -// device representing a software list -class software_list_device : public device_t +class softlist_parser { - friend class softlist_parser; - public: - // construction/destruction - software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + // construction (== execution) + softlist_parser(util::core_file &file, const std::string &filename, std::list<software_info> &infolist, std::ostringstream &errors); - // inline configuration helpers - static void static_set_type(device_t &device, const char *list, softlist_type list_type); - static void static_set_filter(device_t &device, const char *filter); +private: + enum parse_position + { + POS_ROOT, + POS_MAIN, + POS_SOFT, + POS_PART, + POS_DATA + }; + + // internal parsing helpers + const char *infoname() const { return (m_current_info != nullptr) ? m_current_info->shortname().c_str() : "???"; } + int line() const; + int column() const; + const char *parser_error() const; + + // internal error helpers + template <typename Format, typename... Params> void parse_error(Format &&fmt, Params &&... args); + void unknown_tag(const char *tagname) { parse_error("Unknown tag: %s", tagname); } + void unknown_attribute(const char *attrname) { parse_error("Unknown attribute: %s", attrname); } - // getters - const char *list_name() const { return m_list_name.c_str(); } - softlist_type list_type() const { return m_list_type; } - const char *filter() const { return m_filter; } - const char *filename() { return m_file.filename(); } - - // getters that may trigger a parse - const char *description() { if (!m_parsed) parse(); return m_description.c_str(); } - bool valid() { if (!m_parsed) parse(); return !m_infolist.empty(); } - const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); } - const std::list<software_info> &get_info() { if (!m_parsed) parse(); return m_infolist; } - - // operations - const software_info *find(const char *look_for); - void find_approx_matches(const char *name, int matches, const software_info **list, const char *interface); - void release(); - - // string pool helpers - const char *add_string(const char *string) { return m_stringpool.add(string); } - - // static helpers - static software_list_device *find_by_name(const machine_config &mconfig, const char *name); - static void display_matches(const machine_config &config, const char *interface, const char *name); - -protected: // internal helpers - void parse(); - void internal_validity_check(validity_checker &valid) ATTR_COLD; - - // device-level overrides - virtual void device_start() override; - virtual void device_validity_check(validity_checker &valid) const override ATTR_COLD; - - // configuration state - std::string m_list_name; - softlist_type m_list_type; - const char * m_filter; - - // internal state - bool m_parsed; - emu_file m_file; - std::string m_description; - std::string m_errors; - std::list<software_info> m_infolist; - const_string_pool m_stringpool; + template <typename T> std::vector<std::string> parse_attributes(const char **attributes, const T &attrlist); + bool parse_name_and_value(const char **attributes, std::string &name, std::string &value); + void add_rom_entry(std::string &&name, std::string &&hashdata, UINT32 offset, UINT32 length, UINT32 flags); + + // expat callbacks + static void start_handler(void *data, const char *tagname, const char **attributes); + static void data_handler(void *data, const char *s, int len); + static void end_handler(void *data, const char *name); + + // internal parsing + void parse_root_start(const char *tagname, const char **attributes); + void parse_main_start(const char *tagname, const char **attributes); + void parse_soft_start(const char *tagname, const char **attributes); + void parse_part_start(const char *tagname, const char **attributes); + void parse_data_start(const char *tagname, const char **attributes); + void parse_soft_end(const char *name); + + // internal parsing state + util::core_file & m_file; + const std::string & m_filename; + std::list<software_info> & m_infolist; + std::ostringstream & m_errors; + struct XML_ParserStruct * m_parser; + bool m_done; + std::string m_description; + bool m_data_accum_expected; + std::string m_data_accum; + software_info * m_current_info; + software_part * m_current_part; + parse_position m_pos; }; -// device type definition -extern const device_type SOFTWARE_LIST; - -// device type iterator -typedef device_type_iterator<&device_creator<software_list_device>, software_list_device> software_list_device_iterator; - +#endif // __SOFTLIST_H_ -#endif diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp new file mode 100644 index 00000000000..eac92c08939 --- /dev/null +++ b/src/emu/softlist_dev.cpp @@ -0,0 +1,523 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/*************************************************************************** + + softlist_dev.cpp + + Software list construction helpers. + +***************************************************************************/ + +#include "emu.h" +#include "emuopts.h" +#include "diimage.h" +#include "softlist_dev.h" +#include "validity.h" + +#include <ctype.h> + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +typedef std::unordered_map<std::string, const software_info *> softlist_map; + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +const device_type SOFTWARE_LIST = &device_creator<software_list_device>; +false_software_list_loader false_software_list_loader::s_instance; +rom_software_list_loader rom_software_list_loader::s_instance; +image_software_list_loader image_software_list_loader::s_instance; + + +//************************************************************************** +// SOFTWARE LIST LOADER +//************************************************************************** + +//------------------------------------------------- +// false_software_list_loader::load_software +//------------------------------------------------- + +bool false_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const +{ + return false; +} + + +//------------------------------------------------- +// rom_software_list_loader::load_software +//------------------------------------------------- + +bool rom_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const +{ + swlist.machine().rom_load().load_software_part_region(device, swlist, swname, start_entry); + return true; +} + + +//------------------------------------------------- +// image_software_list_loader::load_software +//------------------------------------------------- + +bool image_software_list_loader::load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const +{ + return device.load_software(swlist, swname, start_entry); +} + + +//************************************************************************** +// SOFTWARE LIST DEVICE +//************************************************************************** + +//------------------------------------------------- +// software_list_device - constructor +//------------------------------------------------- + +software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SOFTWARE_LIST, "Software list", tag, owner, clock, "software_list", __FILE__), + m_list_type(SOFTWARE_LIST_ORIGINAL_SYSTEM), + m_filter(nullptr), + m_parsed(false), + m_file(mconfig.options().hash_path(), OPEN_FLAG_READ), + m_description("") +{ +} + + +//------------------------------------------------- +// static_set_type - configuration helper +// to set the list type +//------------------------------------------------- + +void software_list_device::static_set_type(device_t &device, const char *list, softlist_type list_type) +{ + software_list_device &swlistdev = downcast<software_list_device &>(device); + swlistdev.m_list_name.assign(list); + swlistdev.m_list_type = list_type; +} + + +//------------------------------------------------- +// static_set_custom_handler - configuration +// helper to set a custom callback +//------------------------------------------------- + +void software_list_device::static_set_filter(device_t &device, const char *filter) +{ + downcast<software_list_device &>(device).m_filter = filter; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void software_list_device::device_start() +{ +} + + +//------------------------------------------------- +// find_approx_matches - search ourselves for +// a list of possible matches of the given name +// and optional interface +//------------------------------------------------- + +void software_list_device::find_approx_matches(const char *name, int matches, const software_info **list, const char *interface) +{ + // if no name, return + if (name == nullptr || name[0] == 0) + return; + + // initialize everyone's states + std::vector<int> penalty(matches); + for (int matchnum = 0; matchnum < matches; matchnum++) + { + penalty[matchnum] = 9999; + list[matchnum] = nullptr; + } + + // iterate over our info (will cause a parse if needed) + for (const software_info &swinfo : get_info()) + { + const software_part &part = swinfo.parts().front(); + if ((interface == nullptr || part.matches_interface(interface)) && is_compatible(part) == SOFTWARE_IS_COMPATIBLE) + { + // pick the best match between driver name and description + int longpenalty = driver_list::penalty_compare(name, swinfo.longname().c_str()); + int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname().c_str()); + int curpenalty = std::min(longpenalty, shortpenalty); + + // insert into the sorted table of matches + for (int matchnum = matches - 1; matchnum >= 0; matchnum--) + { + // stop if we're worse than the current entry + if (curpenalty >= penalty[matchnum]) + break; + + // as long as this isn't the last entry, bump this one down + if (matchnum < matches - 1) + { + penalty[matchnum + 1] = penalty[matchnum]; + list[matchnum + 1] = list[matchnum]; + } + list[matchnum] = &swinfo; + penalty[matchnum] = curpenalty; + } + } + } +} + + +//------------------------------------------------- +// release - reset to a pre-parsed state +//------------------------------------------------- + +void software_list_device::release() +{ + osd_printf_verbose("Resetting %s\n", m_file.filename()); + m_parsed = false; + m_description.clear(); + m_errors.clear(); + m_infolist.clear(); +} + + +//------------------------------------------------- +// find_by_name - find a software list by name +// across all software list devices +//------------------------------------------------- + +software_list_device *software_list_device::find_by_name(const machine_config &config, const std::string &name) +{ + // iterate over each device in the system and find a match + for (software_list_device &swlistdev : software_list_device_iterator(config.root_device())) + if (swlistdev.list_name() == name) + return &swlistdev; + return nullptr; +} + + +//------------------------------------------------- +// software_display_matches - display a list of +// possible matches in the system to the given +// name, across all software list devices +//------------------------------------------------- + +void software_list_device::display_matches(const machine_config &config, const char *interface, const char *name) +{ + // check if there is at least one software list + software_list_device_iterator deviter(config.root_device()); + if (deviter.first() != nullptr) + osd_printf_error("\n\"%s\" approximately matches the following\n" + "supported software items (best match first):\n\n", name); + + // iterate through lists + for (software_list_device &swlistdev : deviter) + { + // get the top 16 approximate matches for the selected device interface (i.e. only carts for cartslot, etc.) + const software_info *matches[16] = { nullptr }; + swlistdev.find_approx_matches(name, ARRAY_LENGTH(matches), matches, interface); + + // if we found some, print them + if (matches[0] != nullptr) + { + // different output depending on original system or compatible + if (swlistdev.list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) + osd_printf_error("* Software list \"%s\" (%s) matches: \n", swlistdev.list_name().c_str(), swlistdev.description()); + else + osd_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlistdev.list_name().c_str(), swlistdev.description()); + + // print them out + for (auto &match : matches) + { + if (match != nullptr) + osd_printf_error("%-18s%s\n", match->shortname().c_str(), match->longname().c_str()); + } + + osd_printf_error("\n"); + } + } +} + + +//------------------------------------------------- +// find - find an item by name in the software +// list, using wildcards and optionally starting +// from an intermediate point +//------------------------------------------------- + +const software_info *software_list_device::find(const char *look_for) +{ + // nullptr search returns nothing + if (look_for == nullptr) + return nullptr; + + bool iswild = strchr(look_for, '*') != nullptr || strchr(look_for, '?'); + + // find a match (will cause a parse if needed when calling get_info) + const auto &info_list = get_info(); + auto iter = std::find_if( + info_list.begin(), + info_list.end(), + [&](const software_info &info) + { + const char *shortname = info.shortname().c_str(); + return (iswild && core_strwildcmp(look_for, shortname) == 0) + || core_stricmp(look_for, shortname) == 0; + }); + + return iter != info_list.end() + ? &*iter + : nullptr; +} + + +//------------------------------------------------- +// parse - parse our softlist file +//------------------------------------------------- + +void software_list_device::parse() +{ + // skip if done + if (m_parsed) + return; + + // reset the errors + m_errors.clear(); + + // attempt to open the file + osd_file::error filerr = m_file.open(m_list_name.c_str(), ".xml"); + if (filerr == osd_file::error::NONE) + { + // parse if no error + std::ostringstream errs; + softlist_parser parser(m_file, m_description, m_infolist, errs); + m_file.close(); + m_errors = errs.str(); + } + else + m_errors = string_format("Error opening file: %s\n", filename()); + + // indicate that we've been parsed + m_parsed = true; +} + + +//------------------------------------------------- +// is_compatible - determine if we are compatible +// with the given software_list_device +//------------------------------------------------- + +software_compatibility software_list_device::is_compatible(const software_part &swpart) const +{ + // get the softlist filter; if null, assume compatible + if (m_filter == nullptr) + return SOFTWARE_IS_COMPATIBLE; + + // copy the comma-delimited string and ensure it ends with a final comma + std::string filt = std::string(m_filter).append(","); + + // get the incompatibility filter and test against it first if it exists + const char *incompatibility = swpart.feature("incompatibility"); + if (incompatibility != nullptr) + { + // copy the comma-delimited string and ensure it ends with a final comma + std::string incomp = std::string(incompatibility).append(","); + + // iterate over filter items and see if they exist in the list; if so, it's incompatible + for (int start = 0, end = filt.find_first_of(',', start); end != -1; start = end + 1, end = filt.find_first_of(',', start)) + { + std::string token(filt, start, end - start + 1); + if (incomp.find(token) != -1) + return SOFTWARE_IS_INCOMPATIBLE; + } + } + + // get the compatibility feature; if null, assume compatible + const char *compatibility = swpart.feature("compatibility"); + if (compatibility == nullptr) + return SOFTWARE_IS_COMPATIBLE; + + // copy the comma-delimited string and ensure it ends with a final comma + std::string comp = std::string(compatibility).append(","); + + // iterate over filter items and see if they exist in the compatibility list; if so, it's compatible + for (int start = 0, end = filt.find_first_of(',', start); end != -1; start = end + 1, end = filt.find_first_of(',', start)) + { + std::string token(filt, start, end - start + 1); + if (comp.find(token) != -1) + return SOFTWARE_IS_COMPATIBLE; + } + return SOFTWARE_NOT_COMPATIBLE; +} + + +//------------------------------------------------- +// find_mountable_image - find an image interface +// that can automatically mount this software part +//------------------------------------------------- + +device_image_interface *software_list_device::find_mountable_image(const machine_config &mconfig, const software_part &part) +{ + // if automount="no", don't bother + const char *mount = part.feature("automount"); + if (mount != nullptr && strcmp(mount, "no") == 0) + return nullptr; + + for (device_image_interface &image : image_interface_iterator(mconfig.root_device())) + { + const char *interface = image.image_interface(); + if (interface != nullptr && part.matches_interface(interface)) + { + // mount only if not already mounted + const char *option = mconfig.options().value(image.brief_instance_name()); + if (*option == '\0' && !image.filename()) + return ℑ + } + } + return nullptr; +} + + +//------------------------------------------------- +// device_validity_check - validate the device +// configuration +//------------------------------------------------- + +void software_list_device::device_validity_check(validity_checker &valid) const +{ + // add to the global map whenever we check a list so we don't re-check + // it in the future + if (valid.already_checked(std::string("softlist/").append(m_list_name).c_str())) + return; + + // do device validation only in case of validate command + if (!valid.validate_all()) + return; + + // actually do the validate + const_cast<software_list_device *>(this)->internal_validity_check(valid); +} + + +//------------------------------------------------- +// internal_validity_check - internal helper to +// check the list +//------------------------------------------------- + +void software_list_device::internal_validity_check(validity_checker &valid) +{ + enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; + + softlist_map names; + softlist_map descriptions; + for (const software_info &swinfo : get_info()) + { + // first parse and output core errors if any + if (m_errors.length() > 0) + { + osd_printf_error("%s: Errors parsing software list:\n%s", filename(), errors_string()); + break; + } + + // Now check if the xml data is valid: + + // Did we lost any description? + if (swinfo.longname().empty()) + { + osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname().c_str()); + break; + } + + // Did we lost any year? + if (swinfo.year().empty()) + { + osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname().c_str()); + break; + } + + // Did we lost any publisher? + if (swinfo.publisher().empty()) + { + osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname().c_str()); + break; + } + + // Did we lost the software parts? + if (swinfo.parts().empty()) + { + osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname().c_str()); + break; + } + + // Second, since the xml is fine, run additional checks: + + // check for duplicate names + if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) + { + const software_info *match = names.find(swinfo.shortname())->second; + osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname().c_str(), match->shortname().c_str()); + } + + // check for duplicate descriptions + std::string longname = std::string(swinfo.longname()); + if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) + osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname().c_str(), swinfo.shortname().c_str()); + + bool is_clone = false; + if (!swinfo.parentname().empty()) + { + is_clone = true; + if (swinfo.parentname() == swinfo.shortname()) + { + osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname().c_str()); + break; + } + + // make sure the parent exists + const software_info *swinfo2 = find(swinfo.parentname().c_str()); + + if (swinfo2 == nullptr) + osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname().c_str(), swinfo.shortname().c_str()); + else if (!swinfo2->parentname().empty()) + osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname().c_str()); + } + + // make sure the driver name is 8 chars or less + if ((is_clone && swinfo.shortname().length() > NAME_LEN_CLONE) || (!is_clone && swinfo.shortname().length() > NAME_LEN_PARENT)) + osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname().c_str(), + is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); + + // make sure the year is only digits, '?' or '+' + for (const char *s = swinfo.year().c_str(); *s != 0; s++) + if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') + { + osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname().c_str(), swinfo.year().c_str()); + break; + } + + softlist_map part_names; + for (const software_part &part : swinfo.parts()) + { + if (part.interface().empty()) + osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); + + if (part.romdata().empty()) + osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); + + if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) + osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname().c_str(), part.name().c_str()); + } + } + + // release all the memory + release(); +} + + diff --git a/src/emu/softlist_dev.h b/src/emu/softlist_dev.h new file mode 100644 index 00000000000..49ab4fad1ff --- /dev/null +++ b/src/emu/softlist_dev.h @@ -0,0 +1,195 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/********************************************************************* + + softlist_dev.h + + Software and software list information. + +*********************************************************************/ + +#ifndef __SOFTLIST_DEV_H_ +#define __SOFTLIST_DEV_H_ + +#include "softlist.h" + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +#define SOFTWARE_SUPPORTED_YES 0 +#define SOFTWARE_SUPPORTED_PARTIAL 1 +#define SOFTWARE_SUPPORTED_NO 2 + +enum softlist_type +{ + SOFTWARE_LIST_ORIGINAL_SYSTEM, + SOFTWARE_LIST_COMPATIBLE_SYSTEM +}; + +enum software_compatibility +{ + SOFTWARE_IS_COMPATIBLE, + SOFTWARE_IS_INCOMPATIBLE, + SOFTWARE_NOT_COMPATIBLE +}; + + +//************************************************************************** +// MACROS +//************************************************************************** + +#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \ + software_list_device::static_set_type(*device, _list, _list_type); + +#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \ + MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) + +#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \ + MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) + +#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) + +#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) + +#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + software_list_device::static_set_filter(*device, _filter); + +#define MCFG_SOFTWARE_LIST_REMOVE( _tag ) \ + MCFG_DEVICE_REMOVE( _tag ) + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class device_image_interface; +class software_list_device; + + +// ======================> software_list_loader + +class software_list_loader +{ +public: + virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const = 0; +}; + + +// ======================> false_software_list_loader + +class false_software_list_loader : public software_list_loader +{ +public: + virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; + static const software_list_loader &instance() { return s_instance; } + +private: + static false_software_list_loader s_instance; +}; + + +// ======================> rom_software_list_loader + +class rom_software_list_loader : public software_list_loader +{ +public: + virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; + static const software_list_loader &instance() { return s_instance; } + +private: + static rom_software_list_loader s_instance; +}; + + +// ======================> image_software_list_loader + +class image_software_list_loader : public software_list_loader +{ +public: + virtual bool load_software(device_image_interface &device, software_list_device &swlist, const char *swname, const rom_entry *start_entry) const override; + static const software_list_loader &instance() { return s_instance; } + +private: + static image_software_list_loader s_instance; +}; + + +// ======================> software_list_device + +// device representing a software list +class software_list_device : public device_t +{ + friend class softlist_parser; + +public: + // construction/destruction + software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // inline configuration helpers + static void static_set_type(device_t &device, const char *list, softlist_type list_type); + static void static_set_filter(device_t &device, const char *filter); + + // getters + const std::string &list_name() const { return m_list_name; } + softlist_type list_type() const { return m_list_type; } + const char *filter() const { return m_filter; } + const char *filename() { return m_file.filename(); } + + // getters that may trigger a parse + const char *description() { if (!m_parsed) parse(); return m_description.c_str(); } + bool valid() { if (!m_parsed) parse(); return !m_infolist.empty(); } + const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); } + const std::list<software_info> &get_info() { if (!m_parsed) parse(); return m_infolist; } + + // operations + const software_info *find(const char *look_for); + void find_approx_matches(const char *name, int matches, const software_info **list, const char *interface); + void release(); + software_compatibility is_compatible(const software_part &part) const; + + // static helpers + static software_list_device *find_by_name(const machine_config &mconfig, const std::string &name); + static void display_matches(const machine_config &config, const char *interface, const char *name); + static device_image_interface *find_mountable_image(const machine_config &mconfig, const software_part &part); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_validity_check(validity_checker &valid) const override ATTR_COLD; + +private: + // internal helpers + void parse(); + void internal_validity_check(validity_checker &valid) ATTR_COLD; + + // configuration state + std::string m_list_name; + softlist_type m_list_type; + const char * m_filter; + + // internal state + bool m_parsed; + emu_file m_file; + std::string m_description; + std::string m_errors; + std::list<software_info> m_infolist; +}; + + +// device type definition +extern const device_type SOFTWARE_LIST; + +// device type iterator +typedef device_type_iterator<&device_creator<software_list_device>, software_list_device> software_list_device_iterator; + + +#endif // __SOFTLIST_DEV_H_ diff --git a/src/frontend/mame/audit.cpp b/src/frontend/mame/audit.cpp index 9dfc99940f2..6adb5539747 100644 --- a/src/frontend/mame/audit.cpp +++ b/src/frontend/mame/audit.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /*************************************************************************** - audit.c + audit.cpp ROM set auditing functions. @@ -14,7 +14,8 @@ #include "chd.h" #include "drivenum.h" #include "sound/samples.h" -#include "softlist.h" +#include "softlist_dev.h" + //************************************************************************** // CORE FUNCTIONS @@ -149,7 +150,7 @@ media_auditor::summary media_auditor::audit_device(device_t &device, const char //------------------------------------------------- // audit_software //------------------------------------------------- -media_auditor::summary media_auditor::audit_software(const char *list_name, const software_info *swinfo, const char *validation) +media_auditor::summary media_auditor::audit_software(const std::string &list_name, const software_info *swinfo, const char *validation) { // start fresh m_record_list.clear(); @@ -171,7 +172,7 @@ media_auditor::summary media_auditor::audit_software(const char *list_name, cons // now iterate over software parts for (const software_part &part : swinfo->parts()) - audit_regions(part.romdata(), locationtag.c_str(), found, required); + audit_regions(part.romdata().data(), locationtag.c_str(), found, required); if ((found == 0) && (required > 0)) { @@ -180,7 +181,7 @@ media_auditor::summary media_auditor::audit_software(const char *list_name, cons } // return a summary - return summarize(list_name); + return summarize(list_name.c_str()); } diff --git a/src/frontend/mame/audit.h b/src/frontend/mame/audit.h index 1999fb229fa..9e0e131e2ca 100644 --- a/src/frontend/mame/audit.h +++ b/src/frontend/mame/audit.h @@ -158,7 +158,7 @@ public: // audit operations summary audit_media(const char *validation = AUDIT_VALIDATE_FULL); summary audit_device(device_t &device, const char *validation = AUDIT_VALIDATE_FULL); - summary audit_software(const char *list_name, const software_info *swinfo, const char *validation = AUDIT_VALIDATE_FULL); + summary audit_software(const std::string &list_name, const software_info *swinfo, const char *validation = AUDIT_VALIDATE_FULL); summary audit_samples(); summary summarize(const char *name, std::ostream *output = nullptr) const; diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp index 2ce5a6a5581..bc98768242a 100644 --- a/src/frontend/mame/clifront.cpp +++ b/src/frontend/mame/clifront.cpp @@ -25,7 +25,7 @@ #include "drivenum.h" #include "osdepend.h" -#include "softlist.h" +#include "softlist_dev.h" #include "ui/moptions.h" #include "language.h" @@ -374,7 +374,7 @@ int media_identifier::find_by_hash(const util::hash_collection &hashes, int leng { for (const software_info &swinfo : swlistdev.get_info()) for (const software_part &part : swinfo.parts()) - for (const rom_entry *region = part.romdata(); region != nullptr; region = rom_next_region(region)) + for (const rom_entry *region = part.romdata().data(); region != nullptr; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) { util::hash_collection romhashes(ROM_GETHASHDATA(rom)); @@ -385,7 +385,7 @@ int media_identifier::find_by_hash(const util::hash_collection &hashes, int leng // output information about the match if (found) osd_printf_info(" "); - osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev.list_name(), swinfo.shortname().c_str(), swinfo.longname().c_str()); + osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev.list_name().c_str(), swinfo.shortname().c_str(), swinfo.longname().c_str()); found++; } } @@ -527,9 +527,9 @@ int cli_frontend::execute(int argc, char **argv) for (const software_part &swpart : swinfo->parts()) { // only load compatible software this way - if (swpart.is_compatible(swlistdev) == SOFTWARE_IS_COMPATIBLE) + if (swlistdev.is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE) { - device_image_interface *image = swpart.find_mountable_image(config); + device_image_interface *image = software_list_device::find_mountable_image(config, swpart); if (image != nullptr) { std::string val = string_format("%s:%s:%s", swlistdev.list_name(), m_options.software_name(), swpart.name()); @@ -1387,7 +1387,7 @@ void cli_frontend::verifysamples(const char *gamename) void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlistdev) { - fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), xml_normalize_string(swlistdev.description())); + fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name().c_str(), xml_normalize_string(swlistdev.description())); for (const software_info &swinfo : swlistdev.get_info()) { fprintf(out, "\t\t<software name=\"%s\"", swinfo.shortname().c_str()); @@ -1417,7 +1417,7 @@ void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlis fprintf(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name().c_str(), xml_normalize_string(flist.value().c_str())); /* TODO: display rom region information */ - for (const rom_entry *region = part.romdata(); region; region = rom_next_region(region)) + for (const rom_entry *region = part.romdata().data(); region; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); @@ -1626,7 +1626,7 @@ void cli_frontend::getsoftlist(const char *gamename) while (drivlist.next()) { for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config().root_device())) - if (core_strwildcmp(gamename, swlistdev.list_name()) == 0 && list_map.insert(swlistdev.list_name()).second) + if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second) if (!swlistdev.get_info().empty()) { if (isfirst) { fprintf( out, SOFTLIST_XML_BEGIN); isfirst = false; } @@ -1660,7 +1660,7 @@ void cli_frontend::verifysoftlist(const char *gamename) { for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config().root_device())) { - if (core_strwildcmp(gamename, swlistdev.list_name()) == 0 && list_map.insert(swlistdev.list_name()).second) + if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second) { if (!swlistdev.get_info().empty()) { diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp index 918cd07f673..a278288defb 100644 --- a/src/frontend/mame/info.cpp +++ b/src/frontend/mame/info.cpp @@ -16,7 +16,7 @@ #include "xmlfile.h" #include "config.h" #include "drivenum.h" -#include "softlist.h" +#include "softlist_dev.h" #include <ctype.h> @@ -1561,7 +1561,7 @@ void info_xml_creator::output_software_list() { for (const software_list_device &swlist : software_list_device_iterator(m_drivlist.config().root_device())) { - fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist.list_name()); + fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist.list_name().c_str()); fprintf(m_output, "status=\"%s\" ", (swlist.list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible"); if (swlist.filter()) fprintf(m_output, "filter=\"%s\" ", swlist.filter()); diff --git a/src/frontend/mame/mameopts.cpp b/src/frontend/mame/mameopts.cpp index c64b8fd7ebc..9b1150a9590 100644 --- a/src/frontend/mame/mameopts.cpp +++ b/src/frontend/mame/mameopts.cpp @@ -11,7 +11,7 @@ #include "emu.h" #include "mameopts.h" #include "drivenum.h" -#include "softlist.h" +#include "softlist_dev.h" #include <ctype.h> diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index b046acbe66c..a0ab3a99359 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -20,7 +20,7 @@ #include "audit.h" #include "drivenum.h" #include "emuopts.h" -#include "softlist.h" +#include "softlist_dev.h" #include "zippath.h" diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp index fd93bb6d1f7..fc56ca18dc4 100644 --- a/src/frontend/mame/ui/inifile.cpp +++ b/src/frontend/mame/ui/inifile.cpp @@ -11,7 +11,7 @@ #include "emu.h" #include "ui/moptions.h" #include "ui/inifile.h" -#include "softlist.h" +#include "softlist_dev.h" #include "drivenum.h" //------------------------------------------------- diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp index 3019bff9d0f..9fa2e466360 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -31,7 +31,7 @@ #include "mame.h" #include "rendfont.h" #include "rendutil.h" -#include "softlist.h" +#include "softlist_dev.h" #include "uiinput.h" extern const char UI_VERSION_TAG[]; diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp index 1a6b6842df5..e3848e31691 100644 --- a/src/frontend/mame/ui/selsoft.cpp +++ b/src/frontend/mame/ui/selsoft.cpp @@ -24,7 +24,7 @@ #include "mame.h" #include "rendfont.h" #include "rendutil.h" -#include "softlist.h" +#include "softlist_dev.h" #include "uiinput.h" @@ -528,7 +528,7 @@ void menu_select_software::build_software_list() for (const software_info &swinfo : swlist.get_info()) { const software_part &part = swinfo.parts().front(); - if (part.is_compatible(swlist) == SOFTWARE_IS_COMPATIBLE) + if (swlist.is_compatible(part) == SOFTWARE_IS_COMPATIBLE) { const char *instance_name = nullptr; const char *type_name = nullptr; @@ -560,7 +560,7 @@ void menu_select_software::build_software_list() tmpmatches.supported = swinfo.supported(); tmpmatches.part = part.name(); tmpmatches.driver = m_driver; - tmpmatches.listname = strensure(swlist.list_name()); + tmpmatches.listname = swlist.list_name(); tmpmatches.interface = part.interface(); tmpmatches.startempty = 0; tmpmatches.parentlongname.clear(); diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp index b9a25a18535..4ac67f607dd 100644 --- a/src/frontend/mame/ui/swlist.cpp +++ b/src/frontend/mame/ui/swlist.cpp @@ -13,7 +13,7 @@ #include "ui/ui.h" #include "ui/swlist.h" -#include "softlist.h" +#include "softlist_dev.h" namespace ui { @@ -173,7 +173,7 @@ void menu_software_list::append_software_entry(const software_info &swinfo) // check if at least one of the parts has the correct interface and add a menu entry only in this case for (const software_part &swpart : swinfo.parts()) { - if (swpart.matches_interface(m_interface) && swpart.is_compatible(*m_swlist) == SOFTWARE_IS_COMPATIBLE) + if (swpart.matches_interface(m_interface) && m_swlist->is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE) { entry_updated = true; entry.short_name.assign(swinfo.shortname()); diff --git a/src/mame/drivers/c65.cpp b/src/mame/drivers/c65.cpp index fb9f882ead7..1f007bd15f0 100644 --- a/src/mame/drivers/c65.cpp +++ b/src/mame/drivers/c65.cpp @@ -21,7 +21,7 @@ Note: #include "emu.h" #include "cpu/m6502/m4510.h" #include "machine/mos6526.h" -#include "softlist.h" +#include "softlist_dev.h" #define MAIN_CLOCK XTAL_3_5MHz diff --git a/src/mame/drivers/sega_sawatte.cpp b/src/mame/drivers/sega_sawatte.cpp index 9ef349c81e4..04dd9fa432e 100644 --- a/src/mame/drivers/sega_sawatte.cpp +++ b/src/mame/drivers/sega_sawatte.cpp @@ -25,7 +25,7 @@ http://mamedev.emulab.it/haze/reference/sawatte/cartridge_example.jpg */ #include "emu.h" -#include "softlist.h" +#include "softlist_dev.h" class sawatte_state : public driver_device diff --git a/src/mame/machine/at.cpp b/src/mame/machine/at.cpp index 8096b50e289..14508efb797 100644 --- a/src/mame/machine/at.cpp +++ b/src/mame/machine/at.cpp @@ -12,6 +12,7 @@ #include "machine/at_keybc.h" #include "bus/pc_kbd/pc_kbdc.h" #include "sound/dac.h" +#include "softlist_dev.h" #define LOG_PORT80 0 diff --git a/src/mame/machine/microdrv.h b/src/mame/machine/microdrv.h index 5e1547b9dc5..e7d98d8e838 100644 --- a/src/mame/machine/microdrv.h +++ b/src/mame/machine/microdrv.h @@ -13,6 +13,7 @@ #ifndef __MICRODRV__ #define __MICRODRV__ +#include "softlist_dev.h" //************************************************************************** diff --git a/src/mame/machine/psion_pack.h b/src/mame/machine/psion_pack.h index 1c0cd8189d8..f0358844e93 100644 --- a/src/mame/machine/psion_pack.h +++ b/src/mame/machine/psion_pack.h @@ -9,6 +9,8 @@ #ifndef __PSION_PACK_H__ #define __PSION_PACK_H__ +#include "softlist_dev.h" + /*************************************************************************** TYPE DEFINITIONS |