From cc9b510f9c76edebb38e83e40439a5a75adeb2db Mon Sep 17 00:00:00 2001 From: smf- Date: Mon, 16 Dec 2013 19:31:52 +0000 Subject: [PATCH] Slot options can now be configured inline without creating an array. Legacy support for old configuration uses MCFG_FRAGMENT_ADD, which required changing so the current device could be updated by the fragment. [smf] --- src/emu/clifront.c | 26 +++---- src/emu/device.c | 4 +- src/emu/dislot.c | 131 ++++++++---------------------------- src/emu/dislot.h | 164 +++++++++++++++++++++++++++------------------ src/emu/emu.h | 2 +- src/emu/emuopts.c | 10 +-- src/emu/info.c | 18 +++-- src/emu/mconfig.c | 70 ++++++++----------- src/emu/mconfig.h | 24 +++---- src/emu/uimain.c | 117 ++++++++++++++++++++++---------- src/emu/uimain.h | 3 +- src/emu/validity.c | 7 +- 12 files changed, 277 insertions(+), 299 deletions(-) diff --git a/src/emu/clifront.c b/src/emu/clifront.c index 554900b622f..d81a6a9e25c 100644 --- a/src/emu/clifront.c +++ b/src/emu/clifront.c @@ -664,23 +664,26 @@ void cli_frontend::listslots(const char *gamename) // output the line, up to the list of extensions printf("%-13s%-10s ", first ? drivlist.driver().name : "", slot->device().tag()+1); + bool first_option = true; + // get the options and print them - const slot_interface* intf = slot->get_slot_interfaces(); - for (int i = 0; intf && intf[i].name != NULL; i++) + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) { - if (!intf[i].internal) + if (option->selectable()) { - device_t *dev = (*intf[i].devtype)(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); + device_t *dev = (*option->devtype())(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); dev->config_complete(); - if (i==0) { - printf("%-15s %s\n", intf[i].name,dev->name()); + if (first_option) { + printf("%-15s %s\n", option->name(),dev->name()); } else { - printf("%-23s %-15s %s\n", "",intf[i].name,dev->name()); + printf("%-23s %-15s %s\n", "",option->name(),dev->name()); } global_free(dev); + + first_option = false; } } - if (intf==NULL || (intf!=NULL && intf[0].name == NULL)) + if (first_option) printf("%-15s %s\n", "[none]","No options available"); // end the line printf("\n"); @@ -884,12 +887,11 @@ void cli_frontend::verifyroms(const char *gamename) slot_interface_iterator slotiter(config.root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next()) { - const slot_interface* intf = slot->get_slot_interfaces(); - for (int i = 0; intf && intf[i].name != NULL; i++) + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) { astring temptag("_"); - temptag.cat(intf[i].name); - device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.cstr(), intf[i].devtype, 0); + temptag.cat(option->name()); + device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.cstr(), option->devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); diff --git a/src/emu/device.c b/src/emu/device.c index 6f9aa39e0ed..d34ec6ce28c 100644 --- a/src/emu/device.c +++ b/src/emu/device.c @@ -774,7 +774,7 @@ device_t *device_t::add_subdevice(device_type type, const char *tag, UINT32 cloc // apply any machine configuration owned by the device now machine_config_constructor additions = device->machine_config_additions(); if (additions != NULL) - (*additions)(const_cast(mconfig()), device); + (*additions)(const_cast(mconfig()), device, NULL); return device; } @@ -798,7 +798,7 @@ device_t *device_t::replace_subdevice(device_t &old, device_type type, const cha // apply any machine configuration owned by the device now machine_config_constructor additions = device->machine_config_additions(); if (additions != NULL) - (*additions)(const_cast(mconfig()), device); + (*additions)(const_cast(mconfig()), device, NULL); return device; } diff --git a/src/emu/dislot.c b/src/emu/dislot.c index c14f89525e9..9ed9fa46b1f 100644 --- a/src/emu/dislot.c +++ b/src/emu/dislot.c @@ -11,8 +11,7 @@ device_slot_interface::device_slot_interface(const machine_config &mconfig, device_t &device) : device_interface(device), - m_slot_interfaces(NULL), - m_default_card(NULL), + m_default_option(NULL), m_fixed(false) { } @@ -21,94 +20,46 @@ device_slot_interface::~device_slot_interface() { } -void device_slot_interface::static_set_slot_info(device_t &device, const slot_interface *slots_info, const char *default_card, bool fixed) +device_slot_option::device_slot_option(const char *name, const device_type &devtype): + m_name(name), + m_devtype(devtype), + m_selectable(true), + m_default_bios(NULL), + m_machine_config(NULL), + m_input_device_defaults(NULL), + m_config(NULL), + m_clock(0) { - device_slot_interface *slot; - if (!device.interface(slot)) - throw emu_fatalerror("set_default_slot_card called on device '%s' with no slot interface", device.tag()); - - slot->m_slot_interfaces = slots_info; - slot->m_default_card = default_card; - slot->m_fixed = fixed; } -device_card_options *device_slot_interface::static_alloc_card_options(device_t &device, const char *card) +void device_slot_interface::static_option_reset(device_t &device) { device_slot_interface &intf = dynamic_cast(device); - device_card_options *options = intf.m_card_options.find(card); - if (options == NULL) - { - options = pool_alloc(intf.m_card_options.pool(), device_card_options()); - intf.m_card_options.append(card, *options); - } - - return options; + intf.m_options.reset(); } -void device_slot_interface::static_set_card_default_bios(device_t &device, const char *card, const char *default_bios) +void device_slot_interface::static_option_add(device_t &device, const char *name, const device_type &devtype) { - static_alloc_card_options(device, card)->m_default_bios = default_bios; + device_slot_interface &intf = dynamic_cast(device); + device_slot_option *option = intf.option(name); + + if (option != NULL) + throw emu_fatalerror("slot '%s' duplicate option '%s\n", device.tag(), name); + + option = pool_alloc(intf.m_options.pool(), device_slot_option(name, devtype)); + intf.m_options.append(name, *option); } -void device_slot_interface::static_set_card_machine_config(device_t &device, const char *card, const machine_config_constructor machine_config) +device_slot_option *device_slot_interface::static_option(device_t &device, const char *name) { - static_alloc_card_options(device, card)->m_machine_config = machine_config; -} + device_slot_interface &intf = dynamic_cast(device); + device_slot_option *option = intf.option(name); -void device_slot_interface::static_set_card_device_input_defaults(device_t &device, const char *card, const input_device_default *input_device_defaults) -{ - static_alloc_card_options(device, card)->m_input_device_defaults = input_device_defaults; -} + if (option == NULL) + throw emu_fatalerror("slot '%s' has no option '%s\n", device.tag(), name); -void device_slot_interface::static_set_card_config(device_t &device, const char *card, const void *config) -{ - static_alloc_card_options(device, card)->m_config = config; -} - -void device_slot_interface::static_set_card_clock(device_t &device, const char *card, UINT32 clock) -{ - static_alloc_card_options(device, card)->m_clock = clock; -} - -const char *device_slot_interface::card_default_bios(const char *card) const -{ - device_card_options *options = m_card_options.find(card); - if (options != NULL) - return options->m_default_bios; - return NULL; -} - -const machine_config_constructor device_slot_interface::card_machine_config(const char *card) const -{ - device_card_options *options = m_card_options.find(card); - if (options != NULL) - return options->m_machine_config; - return NULL; -} - -const input_device_default *device_slot_interface::card_input_device_defaults(const char *card) const -{ - device_card_options *options = m_card_options.find(card); - if (options != NULL) - return options->m_input_device_defaults; - return NULL; -} - -const void *device_slot_interface::card_config(const char *card) const -{ - device_card_options *options = m_card_options.find(card); - if (options != NULL) - return options->m_config; - return NULL; -} - -const UINT32 device_slot_interface::card_clock(const char *card) const -{ - device_card_options *options = m_card_options.find(card); - if (options != NULL) - return options->m_clock; - return 0; + return option; } device_t* device_slot_interface::get_card_device() @@ -117,7 +68,7 @@ device_t* device_slot_interface::get_card_device() device_t *dev = NULL; astring temp; if (!device().mconfig().options().exists(device().tag()+1)) { - subtag = m_default_card; + subtag = m_default_option; } else { subtag = device().mconfig().options().main_value(temp,device().tag()+1); } @@ -130,32 +81,6 @@ device_t* device_slot_interface::get_card_device() return dev; } -const bool device_slot_interface::all_internal() const -{ - for (int i = 0; m_slot_interfaces && m_slot_interfaces[i].name != NULL; i++) - if (!m_slot_interfaces[i].internal) - return FALSE; - return TRUE; -} - - -bool device_slot_interface::is_internal_option(const char *option) const -{ - if ( !option ) - { - return false; - } - - for (int i = 0; m_slot_interfaces && m_slot_interfaces[i].name != NULL; i++) - { - if ( !strcmp(m_slot_interfaces[i].name, option) ) - { - return m_slot_interfaces[i].internal; - } - } - return false; -} - device_slot_card_interface::device_slot_card_interface(const machine_config &mconfig, device_t &device) : device_interface(device) diff --git a/src/emu/dislot.h b/src/emu/dislot.h index c947e2d60a4..159fa9ead43 100644 --- a/src/emu/dislot.h +++ b/src/emu/dislot.h @@ -9,68 +9,99 @@ #ifndef __DISLOT_H__ #define __DISLOT_H__ +//************************************************************************** +// LEGACY MACROS +//************************************************************************** + +#define MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_option, _fixed) MCFG_SLOT_OPTION_RESET MCFG_FRAGMENT_ADD(slot_options_##_slot_intf) MCFG_SLOT_DEFAULT_OPTION(_def_option) MCFG_SLOT_FIXED(_fixed) +#define SLOT_INTERFACE_NAME(name) MACHINE_CONFIG_NAME(slot_options_##name) +#define SLOT_INTERFACE_START(name) MACHINE_CONFIG_FRAGMENT(slot_options_##name) +#define SLOT_INTERFACE(name,device) MCFG_SLOT_OPTION_ADD(name, device) +#define SLOT_INTERFACE_INTERNAL(name,device) MCFG_SLOT_OPTION_ADD(name, device) MCFG_SLOT_OPTION_SELECTABLE(name, false) +#define SLOT_INTERFACE_END MACHINE_CONFIG_END +#define SLOT_INTERFACE_EXTERN(name) MACHINE_CONFIG_EXTERN(slot_options_##name) +#define MCFG_DEVICE_CARD_DEFAULT_BIOS(_option, _default_bios) MCFG_SLOT_OPTION_DEFAULT_BIOS(_option, _default_bios) +#define MCFG_DEVICE_CARD_MACHINE_CONFIG(_option, _machine_config_name) MCFG_SLOT_OPTION_MACHINE_CONFIG(_option, _machine_config_name) +#define MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS(_option, _dev_inp_def) MCFG_SLOT_OPTION_DEVICE_INPUT_DEFAULTS(_option, _dev_inp_def) +#define MCFG_DEVICE_CARD_CONFIG(_option, _config) MCFG_SLOT_OPTION_CONFIG(_option, _config) +#define MCFG_DEVICE_CARD_CLOCK(_option, _clock) MCFG_SLOT_OPTION_CLOCK(_option, _clock) + + +//************************************************************************** +// MACROS +//************************************************************************** + +#define MCFG_SLOT_FIXED(_fixed) \ + device_slot_interface::static_set_fixed(*device, _fixed); + +#define MCFG_SLOT_DEFAULT_OPTION(_option) \ + device_slot_interface::static_set_default_option(*device, _option); + +#define MCFG_SLOT_OPTION_RESET \ + device_slot_interface::static_option_reset(*device); + +#define MCFG_SLOT_OPTION_ADD(_option, _devtype) \ + device_slot_interface::static_option_add(*device, _option, _devtype); + +#define MCFG_SLOT_OPTION_SELECTABLE(_option, _selectable) \ + device_slot_interface::static_set_option_selectable(*device, _option, _selectable); + +#define MCFG_SLOT_OPTION_DEFAULT_BIOS(_option, _default_bios) \ + device_slot_interface::static_set_option_default_bios(*device, _option, _default_bios); + +#define MCFG_SLOT_OPTION_MACHINE_CONFIG(_option, _machine_config_name) \ + device_slot_interface::static_set_option_machine_config(*device, _option, MACHINE_CONFIG_NAME(_machine_config_name)); + +#define MCFG_SLOT_OPTION_DEVICE_INPUT_DEFAULTS(_option, _dev_inp_def) \ + device_slot_interface::static_set_option_device_input_defaults(*device, _option, DEVICE_INPUT_DEFAULTS_NAME(_dev_inp_def)); + +#define MCFG_SLOT_OPTION_CONFIG(_option, _config) \ + device_slot_interface::static_set_option_config(*device, _option, _config); + +#define MCFG_SLOT_OPTION_CLOCK(_option, _clock) \ + device_slot_interface::static_set_option_clock(*device, _option, _clock); + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// ======================> device_slot_interface -struct slot_interface -{ - const char * name; - const device_type & devtype; - bool internal; -}; +// ======================> device_slot_option -#define MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_card, _fixed) \ - device_slot_interface::static_set_slot_info(*device, SLOT_INTERFACE_NAME(_slot_intf), _def_card, _fixed); - -#define MCFG_DEVICE_CARD_DEFAULT_BIOS(card, _default_bios) \ - device_slot_interface::static_set_card_default_bios(*device, card, _default_bios); - -#define MCFG_DEVICE_CARD_MACHINE_CONFIG(card, _machine_config_name) \ - device_slot_interface::static_set_card_machine_config(*device, card, MACHINE_CONFIG_NAME(_machine_config_name)); - -#define MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS(card, _dev_inp_def) \ - device_slot_interface::static_set_card_device_input_defaults(*device, card, DEVICE_INPUT_DEFAULTS_NAME(_dev_inp_def)); - -#define MCFG_DEVICE_CARD_CONFIG(card, _config) \ - device_slot_interface::static_set_card_config(*device, card, _config); - -#define MCFG_DEVICE_CARD_CLOCK(card, _clock) \ - device_slot_interface::static_set_card_clock(*device, card, _clock); - -#define SLOT_INTERFACE_NAME(name) slot_interface_##name - -#define SLOT_INTERFACE_START(name) \ - const slot_interface slot_interface_##name[] = \ - { -#define SLOT_INTERFACE(tag,device) \ - { tag, device, false }, -#define SLOT_INTERFACE_INTERNAL(tag,device) \ - { tag, device, true }, -#define SLOT_INTERFACE_END \ - { NULL, NULL, false } \ - }; - -#define SLOT_INTERFACE_EXTERN(name) extern const slot_interface slot_interface_##name[] - -class device_card_options +class device_slot_option { friend class device_slot_interface; - friend class simple_list; + friend class simple_list; + +public: + device_slot_option(const char *name, const device_type &devtype); + + device_slot_option *next() const { return m_next; } + const char *name() const { return m_name; } + const device_type &devtype() const { return m_devtype; } + const bool selectable() const { return m_selectable; } + const char *default_bios() const { return m_default_bios; } + machine_config_constructor machine_config() const { return m_machine_config; } + const input_device_default *input_device_defaults() const { return m_input_device_defaults; } + const void *static_config() const { return m_config; } + UINT32 clock() const { return m_clock; } private: + // internal state + device_slot_option *m_next; + const char *m_name; + const device_type &m_devtype; + bool m_selectable; const char *m_default_bios; machine_config_constructor m_machine_config; const input_device_default *m_input_device_defaults; const void *m_config; UINT32 m_clock; - - // internal state - device_card_options * m_next; // link to the next reference }; + +// ======================> device_slot_interface + class device_slot_interface : public device_interface { public: @@ -78,29 +109,28 @@ public: device_slot_interface(const machine_config &mconfig, device_t &device); virtual ~device_slot_interface(); - static void static_set_slot_info(device_t &device, const slot_interface *slots_info, const char *default_card,bool fixed); - static device_card_options *static_alloc_card_options(device_t &device, const char *card); - static void static_set_card_default_bios(device_t &device, const char *card, const char *default_bios); - static void static_set_card_machine_config(device_t &device, const char *card, const machine_config_constructor machine_config); - static void static_set_card_device_input_defaults(device_t &device, const char *card, const input_device_default *default_input); - static void static_set_card_config(device_t &device, const char *card, const void *config); - static void static_set_card_clock(device_t &device, const char *card, UINT32 default_clock); - const slot_interface* get_slot_interfaces() const { return m_slot_interfaces; }; - const char * get_default_card() const { return m_default_card; }; - virtual const char * get_default_card_software(const machine_config &config, emu_options &options) { return NULL; }; - const char *card_default_bios(const char *card) const; - const machine_config_constructor card_machine_config(const char *card) const; - const input_device_default *card_input_device_defaults(const char *card) const; - const void *card_config(const char *card) const; - const UINT32 card_clock(const char *card) const; + static void static_set_fixed(device_t &device, bool fixed) { dynamic_cast(device).m_fixed = fixed; } + static void static_set_default_option(device_t &device, const char *option) { dynamic_cast(device).m_default_option = option; } + static void static_option_reset(device_t &device); + static void static_option_add(device_t &device, const char *option, const device_type &devtype); + static void static_set_option_selectable(device_t &device, const char *option, bool selectable){ static_option(device, option)->m_selectable = selectable; } + static void static_set_option_default_bios(device_t &device, const char *option, const char *default_bios) { static_option(device, option)->m_default_bios = default_bios; } + static void static_set_option_machine_config(device_t &device, const char *option, const machine_config_constructor machine_config) { static_option(device, option)->m_machine_config = machine_config; } + static void static_set_option_device_input_defaults(device_t &device, const char *option, const input_device_default *default_input) { static_option(device, option)->m_input_device_defaults = default_input; } + static void static_set_option_config(device_t &device, const char *option, const void *config) { static_option(device, option)->m_config = config; } + static void static_set_option_clock(device_t &device, const char *option, UINT32 default_clock) { static_option(device, option)->m_clock = default_clock; } const bool fixed() const { return m_fixed; } - const bool all_internal() const; - bool is_internal_option(const char *option) const; - device_t* get_card_device(); -protected: - const slot_interface *m_slot_interfaces; - const char *m_default_card; - tagged_list m_card_options; + const char *default_option() const { return m_default_option; } + device_slot_option *first_option() const { return m_options.first(); } + device_slot_option *option(const char *name) const { if (name) return m_options.find(name); return NULL; } + virtual const char *get_default_card_software(const machine_config &config, emu_options &options) { return NULL; } + device_t *get_card_device(); + +private: + // internal state + static device_slot_option *static_option(device_t &device, const char *option); + tagged_list m_options; + const char *m_default_option; bool m_fixed; }; diff --git a/src/emu/emu.h b/src/emu/emu.h index 45d8160d4f9..775929b000a 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -49,7 +49,7 @@ // define machine_config_constructor here due to circular dependency // between devices and the machine config class machine_config; -typedef device_t * (*machine_config_constructor)(machine_config &config, device_t *owner); +typedef device_t * (*machine_config_constructor)(machine_config &config, device_t *owner, device_t *device); // I/O #include "input.h" diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c index 78485a40463..6da6d5f7335 100644 --- a/src/emu/emuopts.c +++ b/src/emu/emuopts.c @@ -233,10 +233,11 @@ bool emu_options::add_slot_options(bool isfirst) entry[0].name = slot->device().tag() + 1; entry[0].description = NULL; entry[0].flags = OPTION_STRING | OPTION_FLAG_DEVICE; - entry[0].defvalue = (slot->get_slot_interfaces() != NULL) ? slot->get_default_card() : NULL; + entry[0].defvalue = slot->default_option(); if ( entry[0].defvalue ) { - if ( slot->is_internal_option( entry[0].defvalue ) ) + const device_slot_option *option = slot->option(entry[0].defvalue); + if (option && !option->selectable()) { entry[0].flags |= OPTION_FLAG_INTERNAL; } @@ -269,12 +270,13 @@ void emu_options::update_slot_options() { // retrieve info about the device instance if (exists(slot->device().tag()+1)) { - if (slot->get_slot_interfaces() != NULL) { + if (slot->first_option() != NULL) { const char *def = slot->get_default_card_software(config,*this); if (def) { set_default_value(slot->device().tag()+1,def); - set_flag(slot->device().tag()+1, ~OPTION_FLAG_INTERNAL, slot->is_internal_option(def) ? OPTION_FLAG_INTERNAL : 0 ); + const device_slot_option *option = slot->option( def ); + set_flag(slot->device().tag()+1, ~OPTION_FLAG_INTERNAL, option && !option->selectable() ? OPTION_FLAG_INTERNAL : 0 ); } } } diff --git a/src/emu/info.c b/src/emu/info.c index 73cddd4a41b..d3a9e231168 100644 --- a/src/emu/info.c +++ b/src/emu/info.c @@ -398,12 +398,11 @@ void info_xml_creator::output_devices() slot_interface_iterator iter(m_drivlist.config().root_device()); for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { - const slot_interface* intf = slot->get_slot_interfaces(); - for (int i = 0; intf && intf[i].name != NULL; i++) + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) { astring temptag("_"); - temptag.cat(intf[i].name); - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.cstr(), intf[i].devtype, 0); + temptag.cat(option->name()); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.cstr(), option->devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); @@ -1281,19 +1280,18 @@ void info_xml_creator::output_slots(device_t &device, const char *root_tag) fprintf(m_output, " interface=\"%s\"", xml_normalize_string(slot->slot_interface())); */ - const slot_interface* intf = slot->get_slot_interfaces(); - for (int i = 0; intf && intf[i].name != NULL && !intf[i].internal; i++) + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) { - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", intf[i].devtype, 0); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", option->devtype(), 0); if (!dev->configured()) dev->config_complete(); fprintf(m_output, "\t\t\tname())); fprintf(m_output, " devname=\"%s\"", xml_normalize_string(dev->shortname())); - if (slot->get_default_card()) + if (slot->default_option()) { - if (strcmp(slot->get_default_card(),intf[i].name)==0) + if (strcmp(slot->default_option(),option->name())==0) fprintf(m_output, " default=\"yes\""); } fprintf(m_output, "/>\n"); diff --git a/src/emu/mconfig.c b/src/emu/mconfig.c index 0bbb858ac38..faa17e7f3a3 100644 --- a/src/emu/mconfig.c +++ b/src/emu/mconfig.c @@ -36,62 +36,46 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options) m_root_device(NULL) { // construct the config - (*gamedrv.machine_config)(*this, NULL); + (*gamedrv.machine_config)(*this, NULL, NULL); bool is_selected_driver = mame_stricmp(gamedrv.name,options.system_name())==0; // intialize slot devices - make sure that any required devices have been allocated slot_interface_iterator slotiter(root_device()); for (device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next()) { - const slot_interface *intf = slot->get_slot_interfaces(); - if (intf != NULL) + device_t &owner = slot->device(); + astring temp; + const char *selval = options.main_value(temp, owner.tag()+1); + bool isdefault = (options.priority(owner.tag()+1)==OPTION_PRIORITY_DEFAULT); + if (!is_selected_driver || !options.exists(owner.tag()+1)) + selval = slot->default_option(); + + if (selval != NULL && *selval != 0) { - device_t &owner = slot->device(); - astring temp; - const char *selval = options.main_value(temp, owner.tag()+1); - bool isdefault = (options.priority(owner.tag()+1)==OPTION_PRIORITY_DEFAULT); - if (!is_selected_driver || !options.exists(owner.tag()+1)) - selval = slot->get_default_card(); + const device_slot_option *option = slot->option(selval); - if (selval != NULL && *selval != 0) + if (option && (isdefault || option->selectable())) { - bool found = false; - for (int i = 0; intf[i].name != NULL; i++) - { - if (mame_stricmp(selval, intf[i].name) == 0) - { - if ((!intf[i].internal) || (isdefault && intf[i].internal)) - { - device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, slot->card_clock(selval)); - found = true; + device_t *new_dev = device_add(&owner, option->name(), option->devtype(), option->clock()); - const char *default_bios = slot->card_default_bios(selval); - if (default_bios != NULL) - { - device_t::static_set_default_bios_tag(*new_dev, default_bios); - } + const char *default_bios = option->default_bios(); + if (default_bios != NULL) + device_t::static_set_default_bios_tag(*new_dev, default_bios); - machine_config_constructor additions = slot->card_machine_config(selval); - if (additions != NULL) - (*additions)(const_cast(*this), new_dev); + machine_config_constructor additions = option->machine_config(); + if (additions != NULL) + (*additions)(const_cast(*this), new_dev, NULL); - const input_device_default *input_device_defaults = slot->card_input_device_defaults(selval); - if (input_device_defaults) - { - device_t::static_set_input_default(*new_dev, input_device_defaults); - } + const input_device_default *input_device_defaults = option->input_device_defaults(); + if (input_device_defaults) + device_t::static_set_input_default(*new_dev, input_device_defaults); - const void *config = slot->card_config(selval); - if (config) - { - device_t::static_set_static_config(*new_dev, config); - } - } - } - } - if (!found) - throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1); + const void *config = option->static_config(); + if (config) + device_t::static_set_static_config(*new_dev, config); } + else + throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1); } } @@ -173,7 +157,7 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty // apply any machine configuration owned by the device now machine_config_constructor additions = m_root_device->machine_config_additions(); if (additions != NULL) - (*additions)(*this, m_root_device); + (*additions)(*this, m_root_device, NULL); return m_root_device; } diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 390120d5b6d..ce4e9b4f5ca 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -144,51 +144,43 @@ private: #define MACHINE_CONFIG_NAME(_name) construct_machine_config_##_name #define MACHINE_CONFIG_START(_name, _class) \ -ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner) \ +ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ - device_t *device = NULL; \ - (void)device; \ devcb2_base *devcb = NULL; \ (void)devcb; \ if (owner == NULL) owner = config.device_add(NULL, "root", &driver_device_creator<_class>, 0); #define MACHINE_CONFIG_FRAGMENT(_name) \ -ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner) \ +ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ - device_t *device = NULL; \ - (void)device; \ devcb2_base *devcb = NULL; \ (void)devcb; \ assert(owner != NULL); #define MACHINE_CONFIG_DERIVED(_name, _base) \ -ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner) \ +ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ - device_t *device = NULL; \ - (void)device; \ devcb2_base *devcb = NULL; \ (void)devcb; \ - owner = MACHINE_CONFIG_NAME(_base)(config, owner); \ + owner = MACHINE_CONFIG_NAME(_base)(config, owner, device); \ assert(owner != NULL); #define MACHINE_CONFIG_DERIVED_CLASS(_name, _base, _class) \ -ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner) \ +ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ - device_t *device = NULL; \ - (void)device; \ devcb2_base *devcb = NULL; \ (void)devcb; \ if (owner == NULL) owner = config.device_add(NULL, "root", &driver_device_creator<_class>, 0); \ - owner = MACHINE_CONFIG_NAME(_base)(config, owner); + owner = MACHINE_CONFIG_NAME(_base)(config, owner, device); #define MACHINE_CONFIG_END \ return owner; \ } // use this to declare external references to a machine driver #define MACHINE_CONFIG_EXTERN(_name) \ - extern device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner) + extern device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) // importing data from other machine drivers #define MCFG_FRAGMENT_ADD(_name) \ - MACHINE_CONFIG_NAME(_name)(config, owner); + MACHINE_CONFIG_NAME(_name)(config, owner, device); // scheduling parameters diff --git a/src/emu/uimain.c b/src/emu/uimain.c index ef04c174892..79e078d3cbf 100644 --- a/src/emu/uimain.c +++ b/src/emu/uimain.c @@ -365,19 +365,46 @@ void ui_menu_keyboard_mode::handle() } +/*------------------------------------------------- + ui_slot_get_current_option - returns +-------------------------------------------------*/ +device_slot_option *ui_menu_slot_devices::slot_get_current_option(device_slot_interface *slot) +{ + const char *current; + if (slot->fixed()) + { + current = slot->default_option(); + } + else + { + astring temp; + current = machine().options().main_value(temp,slot->device().tag()+1); + } + + return slot->option(current); +} + /*------------------------------------------------- ui_slot_get_current_index - returns -------------------------------------------------*/ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) { - astring temp; - const char *current = machine().options().main_value(temp,slot->device().tag()+1); - const slot_interface* intf = slot->get_slot_interfaces(); - int val = -1; - for (int i = 0; intf[i].name != NULL; i++) { - if (strcmp(current, intf[i].name) == 0) val = i; + const device_slot_option *current = slot_get_current_option(slot); + + if (current != NULL) + { + int val = 0; + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) + { + if (option == current) + return val; + + if (option->selectable()) + val++; + } } - return val; + + return -1; } /*------------------------------------------------- @@ -385,9 +412,13 @@ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) -------------------------------------------------*/ int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) { - const slot_interface* intf = slot->get_slot_interfaces(); + const device_slot_option *current = slot_get_current_option(slot); + int val = 0; - for (int i = 0; intf[i].name != NULL; i++) val++; + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) + if (option == current || option->selectable()) + val++; + return val; } @@ -396,13 +427,16 @@ int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) -------------------------------------------------*/ const char *ui_menu_slot_devices::slot_get_next(device_slot_interface *slot) { - int idx = slot_get_current_index(slot) + 1; - do { - if (idx==slot_get_length(slot)) return ""; - if (slot->get_slot_interfaces()[idx].internal) idx++; - } while (slot->get_slot_interfaces()[idx].internal); - if (idx==slot_get_length(slot)) return ""; - return slot->get_slot_interfaces()[idx].name; + int idx = slot_get_current_index(slot); + if (idx < 0) + idx = 0; + else + idx++; + + if (idx >= slot_get_length(slot)) + return ""; + + return slot_get_option(slot, idx); } /*------------------------------------------------- @@ -410,26 +444,39 @@ const char *ui_menu_slot_devices::slot_get_next(device_slot_interface *slot) -------------------------------------------------*/ const char *ui_menu_slot_devices::slot_get_prev(device_slot_interface *slot) { - int idx = slot_get_current_index(slot) - 1; - do { - if (idx==-1) return ""; - if (idx==-2) idx = slot_get_length(slot) -1; - if (idx==-1) return ""; - if (slot->get_slot_interfaces()[idx].internal) idx--; - } while (slot->get_slot_interfaces()[idx].internal); - return slot->get_slot_interfaces()[idx].name; + int idx = slot_get_current_index(slot); + if (idx < 0) + idx = slot_get_length(slot) - 1; + else + idx--; + + if (idx < 0) + return ""; + + return slot_get_option(slot, idx); } /*------------------------------------------------- - ui_get_slot_device - returns + ui_slot_get_option - returns -------------------------------------------------*/ -const char *ui_menu_slot_devices::get_slot_device(device_slot_interface *slot) +const char *ui_menu_slot_devices::slot_get_option(device_slot_interface *slot, int index) { - int idx = slot_get_current_index(slot); - if (idx == -1) - return ""; - else - return slot->get_slot_interfaces()[idx].name; + const device_slot_option *current = slot_get_current_option(slot); + + if (index >= 0 ) + { + int val = 0; + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) + { + if (val == index) + return option->name(); + + if (option == current || option->selectable()) + val++; + } + } + + return ""; } @@ -461,11 +508,9 @@ void ui_menu_slot_devices::populate() for (device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { /* record the menu item */ - const char *title = get_slot_device(slot); - // do no display fixed slots - if (slot->fixed()) title = slot->get_default_card(); - if (title==NULL) title = ""; - item_append(slot->device().tag()+1, strcmp(title,"")==0 ? "------" : title, (slot->fixed() || slot->all_internal()) ? 0 : (MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW), (void *)slot); + const device_slot_option *option = slot_get_current_option(slot); + + item_append(slot->device().tag()+1, option == NULL ? "------" : option->name(), (slot->fixed() || slot_get_length(slot) == 0) ? 0 : (MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW), (void *)slot); } item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); item_append("Reset", NULL, 0, NULL); diff --git a/src/emu/uimain.h b/src/emu/uimain.h index b40da22cd08..0e0bd6a5261 100644 --- a/src/emu/uimain.h +++ b/src/emu/uimain.h @@ -67,11 +67,12 @@ public: virtual void handle(); private: + device_slot_option *slot_get_current_option(device_slot_interface *slot); int slot_get_current_index(device_slot_interface *slot); int slot_get_length(device_slot_interface *slot); const char *slot_get_next(device_slot_interface *slot); const char *slot_get_prev(device_slot_interface *slot); - const char *get_slot_device(device_slot_interface *slot); + const char *slot_get_option(device_slot_interface *slot, int index); void set_slot_device(device_slot_interface *slot, const char *val); }; diff --git a/src/emu/validity.c b/src/emu/validity.c index e74f150c472..17f2521d520 100644 --- a/src/emu/validity.c +++ b/src/emu/validity.c @@ -1103,12 +1103,11 @@ void validity_checker::validate_devices() slot_interface_iterator slotiter(m_current_config->root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next()) { - const slot_interface* intf = slot->get_slot_interfaces(); - for (int i = 0; intf && intf[i].name != NULL; i++) + for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) { astring temptag("_"); - temptag.cat(intf[i].name); - device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.cstr(), intf[i].devtype, 0); + temptag.cat(option->name()); + device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.cstr(), option->devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev);