diff options
Diffstat (limited to 'docs/release/src/frontend/mame/info.cpp')
-rw-r--r-- | docs/release/src/frontend/mame/info.cpp | 197 |
1 files changed, 100 insertions, 97 deletions
diff --git a/docs/release/src/frontend/mame/info.cpp b/docs/release/src/frontend/mame/info.cpp index 2576edf878e..fa742dfe2f4 100644 --- a/docs/release/src/frontend/mame/info.cpp +++ b/docs/release/src/frontend/mame/info.cpp @@ -30,6 +30,7 @@ #define XML_ROOT "mame" #define XML_TOP "machine" + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -90,7 +91,7 @@ const char info_xml_creator::s_dtd_string[] = "\t\t<!ELEMENT display EMPTY>\n" "\t\t\t<!ATTLIST display tag CDATA #IMPLIED>\n" "\t\t\t<!ATTLIST display type (raster|vector|lcd|unknown) #REQUIRED>\n" -"\t\t\t<!ATTLIST display rotate (0|90|180|270) #REQUIRED>\n" +"\t\t\t<!ATTLIST display rotate (0|90|180|270) #IMPLIED>\n" "\t\t\t<!ATTLIST display flipx (yes|no) \"no\">\n" "\t\t\t<!ATTLIST display width CDATA #IMPLIED>\n" "\t\t\t<!ATTLIST display height CDATA #IMPLIED>\n" @@ -188,10 +189,11 @@ const char info_xml_creator::s_dtd_string[] = // info_xml_creator - constructor //------------------------------------------------- -info_xml_creator::info_xml_creator(driver_enumerator &drivlist) - : m_output(nullptr), - m_drivlist(drivlist), - m_lookup_options(m_drivlist.options()) +info_xml_creator::info_xml_creator(driver_enumerator &drivlist, bool filter_devices) + : m_output(nullptr) + , m_drivlist(drivlist) + , m_filter_devices(filter_devices) + , m_lookup_options(m_drivlist.options()) { mame_options::remove_device_options(m_lookup_options); } @@ -227,13 +229,15 @@ void info_xml_creator::output(FILE *out, bool nodevices) CONFIG_VERSION ); + std::unique_ptr<device_type_set> devfilter((m_filter_devices && !nodevices) ? new device_type_set : nullptr); + // iterate through the drivers, outputting one at a time while (m_drivlist.next()) - output_one(); + output_one(devfilter.get()); // output devices (both devices with roms and slot devices) if (!nodevices) - output_devices(); + output_devices(devfilter.get()); // close the top level tag fprintf(m_output, "</%s>\n",XML_ROOT); @@ -245,21 +249,27 @@ void info_xml_creator::output(FILE *out, bool nodevices) // for one particular game driver //------------------------------------------------- -void info_xml_creator::output_one() +void info_xml_creator::output_one(device_type_set *devtypes) { // no action if not a game const game_driver &driver = m_drivlist.driver(); if (driver.flags & MACHINE_NO_STANDALONE) return; + std::shared_ptr<machine_config> const config(m_drivlist.config()); + device_iterator iter(config->root_device()); + // allocate input ports - std::shared_ptr<machine_config> config = m_drivlist.config(); ioport_list portlist; std::string errors; - device_iterator iter(config->root_device()); for (device_t &device : iter) + { portlist.append(device, errors); + if (devtypes && device.owner() && device.shortname() && *device.shortname()) + devtypes->insert(&device.type()); + } + // renumber player numbers for controller ports int player_offset = 0; // but treat keyboard count separately from players' number @@ -288,17 +298,16 @@ void info_xml_creator::output_one() if (new_kbd) kbd_offset++; } - // print the header and the game name + // print the header and the machine name fprintf(m_output, "\t<%s",XML_TOP); fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(driver.name)); // strip away any path information from the source_file and output it const char *start = strrchr(driver.source_file, '/'); - if (start == nullptr) + if (!start) start = strrchr(driver.source_file, '\\'); - if (start == nullptr) - start = driver.source_file - 1; - fprintf(m_output, " sourcefile=\"%s\"", util::xml::normalize_string(start + 1)); + start = start ? (start + 1) : driver.source_file; + fprintf(m_output, " sourcefile=\"%s\"", util::xml::normalize_string(start)); // append bios and runnable flags if (driver.flags & MACHINE_IS_BIOS_ROOT) @@ -316,7 +325,7 @@ void info_xml_creator::output_one() fprintf(m_output, " romof=\"%s\"", util::xml::normalize_string(m_drivlist.driver(clone_of).name)); // display sample information and close the game tag - output_sampleof(); + output_sampleof(config->root_device()); fprintf(m_output, ">\n"); // output game description @@ -337,7 +346,7 @@ void info_xml_creator::output_one() output_device_roms(); output_sample(config->root_device()); output_chips(config->root_device(), ""); - output_display(config->root_device(), ""); + output_display(config->root_device(), &m_drivlist.driver().flags, ""); output_sound(config->root_device()); output_input(portlist); output_switches(portlist, "", IPT_DIPSWITCH, "dipswitch", "dipvalue"); @@ -346,7 +355,7 @@ void info_xml_creator::output_one() output_adjusters(portlist); output_driver(); output_images(config->root_device(), ""); - output_slots(config->root_device(), ""); + output_slots(*config, config->root_device(), "", devtypes); output_software_list(); output_ramoptions(); @@ -360,7 +369,7 @@ void info_xml_creator::output_one() // a single device //------------------------------------------------- -void info_xml_creator::output_one_device(device_t &device, const char *devtag) +void info_xml_creator::output_one_device(machine_config &config, device_t &device, const char *devtag) { bool has_speaker = false, has_input = false; // check if the device adds speakers to the system @@ -389,17 +398,17 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag) fprintf(m_output, " sourcefile=\"%s\"", util::xml::normalize_string(src.c_str())); fprintf(m_output, " isdevice=\"yes\""); fprintf(m_output, " runnable=\"no\""); - output_sampleof(); + output_sampleof(device); fprintf(m_output, ">\n"); fprintf(m_output, "\t\t<description>%s</description>\n", util::xml::normalize_string(device.name())); output_rom(device); - samples_device *samples = dynamic_cast<samples_device*>(&device); - if (samples==nullptr) output_sample(device); // ignore samples_device itself + if (device.type().type() != typeid(samples_device)) // ignore samples_device itself + output_sample(device); output_chips(device, devtag); - output_display(device, devtag); + output_display(device, nullptr, devtag); if (has_speaker) output_sound(device); if (has_input) @@ -408,7 +417,7 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag) output_switches(portlist, devtag, IPT_CONFIG, "configuration", "confsetting"); output_adjusters(portlist); output_images(device, devtag); - output_slots(device, devtag); + output_slots(config, device, devtag, nullptr); fprintf(m_output, "\t</%s>\n", XML_TOP); } @@ -425,53 +434,34 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag) // directly to a driver as device or sub-device) //------------------------------------------------- -void info_xml_creator::output_devices() +void info_xml_creator::output_devices(device_type_set const *filter) { - m_drivlist.reset(); - std::unordered_set<std::string> shortnames; - - while (m_drivlist.next()) - { - // first, run through devices with roms which belongs to the default configuration - for (device_t &device : device_iterator(m_drivlist.config()->root_device())) - { - if (device.owner() != nullptr && device.shortname() != nullptr && device.shortname()[0]!='\0') - { - if (shortnames.insert(device.shortname()).second) - output_one_device(device, device.tag()); - } - } + // get config for empty machine + machine_config config(GAME_NAME(___empty), m_lookup_options); - // then, run through slot devices - for (const device_slot_interface &slot : slot_interface_iterator(m_drivlist.config()->root_device())) - { - for (auto &option : slot.option_list()) + auto const action = [this, &config] (device_type type) { - std::string temptag("_"); - temptag.append(option.second->name()); - device_t *dev = m_drivlist.config()->device_add(&m_drivlist.config()->root_device(), temptag.c_str(), option.second->devtype(), 0); + // add it at the root of the machine config + device_t *const dev = config.device_add(&config.root_device(), "_tmp", type, 0); // notify this device and all its subdevices that they are now configured for (device_t &device : device_iterator(*dev)) if (!device.configured()) device.config_complete(); - if (shortnames.insert(dev->shortname()).second) - output_one_device(*dev, temptag.c_str()); + // print details and remove it + output_one_device(config, *dev, dev->tag()); + config.device_remove(&config.root_device(), "_tmp"); + }; - // also, check for subdevices with ROMs (a few devices are missed otherwise, e.g. MPU401) - for (device_t &device : device_iterator(*dev)) - { - if (device.owner() == dev && device.shortname() != nullptr && device.shortname()[0]!='\0') - { - if (shortnames.insert(device.shortname()).second) - output_one_device(device, device.tag()); - } - } - - m_drivlist.config()->device_remove(&m_drivlist.config()->root_device(), temptag.c_str()); - } - } + // run through devices + if (filter) + { + for (std::add_pointer_t<device_type> type : *filter) action(*type); + } + else + { + for (device_type type : registered_device_types) action(type); } } @@ -494,12 +484,12 @@ void info_xml_creator::output_device_roms() // attribute, if appropriate //------------------------------------------------- -void info_xml_creator::output_sampleof() +void info_xml_creator::output_sampleof(device_t &device) { // iterate over sample devices - for (samples_device &device : samples_device_iterator(m_drivlist.config()->root_device())) + for (samples_device &samples : samples_device_iterator(device)) { - samples_iterator sampiter(device); + samples_iterator sampiter(samples); if (sampiter.altbasename() != nullptr) { fprintf(m_output, " sampleof=\"%s\"", util::xml::normalize_string(sampiter.altbasename())); @@ -577,10 +567,9 @@ void info_xml_creator::output_rom(device_t &device) // if we have a valid ROM and we are a clone, see if we can find the parent ROM util::hash_collection hashes(ROM_GETHASHDATA(rom)); - if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP)) + if (dynamic_cast<driver_device *>(&device) &&!hashes.flag(util::hash_collection::FLAG_NO_DUMP)) merge_name = get_merge_name(hashes); - if (&device != &m_drivlist.config()->root_device()) - merge_name = nullptr; + // scan for a BIOS name bios_name[0] = 0; if (!is_disk && is_bios) @@ -721,7 +710,7 @@ void info_xml_creator::output_chips(device_t &device, const char *root_tag) // displays //------------------------------------------------- -void info_xml_creator::output_display(device_t &device, const char *root_tag) +void info_xml_creator::output_display(device_t &device, u32 const *flags, const char *root_tag) { // iterate over screens for (const screen_device &screendev : screen_device_iterator(device)) @@ -743,8 +732,10 @@ void info_xml_creator::output_display(device_t &device, const char *root_tag) } // output the orientation as a string - switch (m_drivlist.driver().flags & ORIENTATION_MASK) + if (flags) { + switch (*flags & ORIENTATION_MASK) + { case ORIENTATION_FLIP_X: fprintf(m_output, " rotate=\"0\" flipx=\"yes\""); break; @@ -769,6 +760,7 @@ void info_xml_creator::output_display(device_t &device, const char *root_tag) default: fprintf(m_output, " rotate=\"0\""); break; + } } // output width and height only for games that are not vector @@ -1405,44 +1397,45 @@ void info_xml_creator::output_driver() /* some minor issues, games marked as status=preliminary */ /* don't work or have major emulation problems. */ - if (m_drivlist.driver().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_MECHANICAL)) + u32 const flags = m_drivlist.driver().flags; + if (flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_MECHANICAL)) fprintf(m_output, " status=\"preliminary\""); - else if (m_drivlist.driver().flags & (MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS)) + else if (flags & (MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS)) fprintf(m_output, " status=\"imperfect\""); else fprintf(m_output, " status=\"good\""); - if (m_drivlist.driver().flags & MACHINE_NOT_WORKING) + if (flags & MACHINE_NOT_WORKING) fprintf(m_output, " emulation=\"preliminary\""); else fprintf(m_output, " emulation=\"good\""); - if (m_drivlist.driver().flags & MACHINE_WRONG_COLORS) + if (flags & MACHINE_WRONG_COLORS) fprintf(m_output, " color=\"preliminary\""); - else if (m_drivlist.driver().flags & MACHINE_IMPERFECT_COLORS) + else if (flags & MACHINE_IMPERFECT_COLORS) fprintf(m_output, " color=\"imperfect\""); else fprintf(m_output, " color=\"good\""); - if (m_drivlist.driver().flags & MACHINE_NO_SOUND) + if (flags & MACHINE_NO_SOUND) fprintf(m_output, " sound=\"preliminary\""); - else if (m_drivlist.driver().flags & MACHINE_IMPERFECT_SOUND) + else if (flags & MACHINE_IMPERFECT_SOUND) fprintf(m_output, " sound=\"imperfect\""); else fprintf(m_output, " sound=\"good\""); - if (m_drivlist.driver().flags & MACHINE_IMPERFECT_GRAPHICS) + if (flags & MACHINE_IMPERFECT_GRAPHICS) fprintf(m_output, " graphic=\"imperfect\""); else fprintf(m_output, " graphic=\"good\""); - if (m_drivlist.driver().flags & MACHINE_NO_COCKTAIL) + if (flags & MACHINE_NO_COCKTAIL) fprintf(m_output, " cocktail=\"preliminary\""); - if (m_drivlist.driver().flags & MACHINE_UNEMULATED_PROTECTION) + if (flags & MACHINE_UNEMULATED_PROTECTION) fprintf(m_output, " protection=\"preliminary\""); - if (m_drivlist.driver().flags & MACHINE_SUPPORTS_SAVE) + if (flags & MACHINE_SUPPORTS_SAVE) fprintf(m_output, " savestate=\"supported\""); else fprintf(m_output, " savestate=\"unsupported\""); @@ -1489,8 +1482,8 @@ void info_xml_creator::output_images(device_t &device, const char *root_tag) if (loadable) { - const char *name = imagedev.instance_name(); - const char *shortname = imagedev.brief_instance_name(); + const char *name = imagedev.instance_name().c_str(); + const char *shortname = imagedev.brief_instance_name().c_str(); fprintf(m_output, "\t\t\t<instance"); fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(name)); @@ -1518,44 +1511,54 @@ void info_xml_creator::output_images(device_t &device, const char *root_tag) // output_images - prints all info about slots //------------------------------------------------- -void info_xml_creator::output_slots(device_t &device, const char *root_tag) +void info_xml_creator::output_slots(machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes) { for (const device_slot_interface &slot : slot_interface_iterator(device)) { - if (slot.fixed()) continue; // or shall we list these as non-configurable? + // shall we list fixed slots as non-configurable? + bool const listed(!slot.fixed() && strcmp(slot.device().tag(), device.tag())); - if (strcmp(slot.device().tag(), device.tag())) + if (devtypes || listed) { std::string newtag(slot.device().tag()), oldtag(":"); newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length()); // print m_output device type - fprintf(m_output, "\t\t<slot name=\"%s\">\n", util::xml::normalize_string(newtag.c_str())); + if (listed) + fprintf(m_output, "\t\t<slot name=\"%s\">\n", util::xml::normalize_string(newtag.c_str())); /* - if (slot.slot_interface()[0]) + if (listed && slot.slot_interface()[0]) fprintf(m_output, " interface=\"%s\"", util::xml::normalize_string(slot.slot_interface())); */ for (auto &option : slot.option_list()) { - if (option.second->selectable()) + if (devtypes || (listed && option.second->selectable())) { - device_t *dev = m_drivlist.config()->device_add(&m_drivlist.config()->root_device(), "dummy", option.second->devtype(), 0); + device_t *const dev = config.device_add(&device, "_dummy", option.second->devtype(), 0); if (!dev->configured()) dev->config_complete(); - fprintf(m_output, "\t\t\t<slotoption"); - fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(option.second->name())); - fprintf(m_output, " devname=\"%s\"", util::xml::normalize_string(dev->shortname())); - if (slot.default_option() != nullptr && strcmp(slot.default_option(), option.second->name())==0) - fprintf(m_output, " default=\"yes\""); - fprintf(m_output, "/>\n"); - m_drivlist.config()->device_remove(&m_drivlist.config()->root_device(), "dummy"); + if (devtypes) + for (device_t &device : device_iterator(*dev)) devtypes->insert(&device.type()); + + if (listed && option.second->selectable()) + { + fprintf(m_output, "\t\t\t<slotoption"); + fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(option.second->name())); + fprintf(m_output, " devname=\"%s\"", util::xml::normalize_string(dev->shortname())); + if (slot.default_option() != nullptr && strcmp(slot.default_option(), option.second->name())==0) + fprintf(m_output, " default=\"yes\""); + fprintf(m_output, "/>\n"); + } + + config.device_remove(&device, "_dummy"); } } - fprintf(m_output, "\t\t</slot>\n"); + if (listed) + fprintf(m_output, "\t\t</slot>\n"); } } } |