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]

This commit is contained in:
smf- 2013-12-16 19:31:52 +00:00
parent 496c6d6722
commit cc9b510f9c
12 changed files with 277 additions and 299 deletions

View File

@ -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<machine_config &>(config).device_add(&config.root_device(), temptag.cstr(), intf[i].devtype, 0);
temptag.cat(option->name());
device_t *dev = const_cast<machine_config &>(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);

View File

@ -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<machine_config &>(mconfig()), device);
(*additions)(const_cast<machine_config &>(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<machine_config &>(mconfig()), device);
(*additions)(const_cast<machine_config &>(mconfig()), device, NULL);
return device;
}

View File

@ -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_slot_interface &>(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);
intf.m_options.reset();
}
return options;
void device_slot_interface::static_option_add(device_t &device, const char *name, const device_type &devtype)
{
device_slot_interface &intf = dynamic_cast<device_slot_interface &>(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_default_bios(device_t &device, const char *card, const char *default_bios)
device_slot_option *device_slot_interface::static_option(device_t &device, const char *name)
{
static_alloc_card_options(device, card)->m_default_bios = default_bios;
}
device_slot_interface &intf = dynamic_cast<device_slot_interface &>(device);
device_slot_option *option = intf.option(name);
void device_slot_interface::static_set_card_machine_config(device_t &device, const char *card, const machine_config_constructor machine_config)
{
static_alloc_card_options(device, card)->m_machine_config = machine_config;
}
if (option == NULL)
throw emu_fatalerror("slot '%s' has no option '%s\n", device.tag(), 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;
}
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)

View File

@ -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<device_card_options>;
friend class simple_list<device_slot_option>;
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_slot_interface &>(device).m_fixed = fixed; }
static void static_set_default_option(device_t &device, const char *option) { dynamic_cast<device_slot_interface &>(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;
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();
protected:
const slot_interface *m_slot_interfaces;
const char *m_default_card;
tagged_list<device_card_options> m_card_options;
private:
// internal state
static device_slot_option *static_option(device_t &device, const char *option);
tagged_list<device_slot_option> m_options;
const char *m_default_option;
bool m_fixed;
};

View File

@ -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"

View File

@ -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 );
}
}
}

View File

@ -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<machine_config &>(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<machine_config &>(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<machine_config &>(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", intf[i].devtype, 0);
device_t *dev = const_cast<machine_config &>(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\t<slotoption");
fprintf(m_output, " name=\"%s\"", xml_normalize_string(intf[i].name));
fprintf(m_output, " name=\"%s\"", xml_normalize_string(option->name()));
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");

View File

@ -36,64 +36,48 @@ 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->get_default_card();
selval = slot->default_option();
if (selval != NULL && *selval != 0)
{
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;
const device_slot_option *option = slot->option(selval);
const char *default_bios = slot->card_default_bios(selval);
if (option && (isdefault || option->selectable()))
{
device_t *new_dev = device_add(&owner, option->name(), option->devtype(), option->clock());
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);
machine_config_constructor additions = option->machine_config();
if (additions != NULL)
(*additions)(const_cast<machine_config &>(*this), new_dev);
(*additions)(const_cast<machine_config &>(*this), new_dev, NULL);
const input_device_default *input_device_defaults = slot->card_input_device_defaults(selval);
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);
const void *config = option->static_config();
if (config)
{
device_t::static_set_static_config(*new_dev, config);
}
}
}
}
if (!found)
else
throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1);
}
}
}
// when finished, set the game driver
driver_device::static_set_game(*m_root_device, gamedrv);
@ -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;
}

View File

@ -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

View File

@ -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 -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)
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 "";
else
return slot->get_slot_interfaces()[idx].name;
}
@ -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);

View File

@ -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);
};

View File

@ -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<machine_config &>(*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<machine_config &>(*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);