summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/info.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/info.cpp')
-rw-r--r--src/frontend/mame/info.cpp227
1 files changed, 161 insertions, 66 deletions
diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp
index ea9b39bc731..ae1323786e9 100644
--- a/src/frontend/mame/info.cpp
+++ b/src/frontend/mame/info.cpp
@@ -189,11 +189,9 @@ const char info_xml_creator::s_dtd_string[] =
// info_xml_creator - constructor
//-------------------------------------------------
-info_xml_creator::info_xml_creator(driver_enumerator &drivlist, bool filter_devices)
+info_xml_creator::info_xml_creator(emu_options const &options)
: m_output(nullptr)
- , m_drivlist(drivlist)
- , m_filter_devices(filter_devices)
- , m_lookup_options(m_drivlist.options())
+ , m_lookup_options(options)
{
mame_options::remove_device_options(m_lookup_options);
}
@@ -204,10 +202,108 @@ info_xml_creator::info_xml_creator(driver_enumerator &drivlist, bool filter_devi
// for all known games
//-------------------------------------------------
-void info_xml_creator::output(FILE *out, bool nodevices)
+void info_xml_creator::output(FILE *out, std::vector<std::string> const &patterns)
{
m_output = out;
+ std::unique_ptr<device_type_set> devfilter(patterns.empty() ? nullptr : new device_type_set);
+
+ // track which patterns match machines
+ driver_enumerator drivlist(m_lookup_options);
+ std::vector<bool> matched(patterns.size(), false);
+ auto const included = [&patterns, &drivlist, &matched] () -> bool
+ {
+ if (patterns.empty())
+ return true;
+
+ char const *const name = drivlist.driver().name;
+ bool result = false;
+ auto it = matched.begin();
+ for (std::string const &pat : patterns)
+ {
+ if (!core_strwildcmp(pat.c_str(), name))
+ {
+ result = true;
+ *it = true;
+ }
+ ++it;
+ }
+ return result;
+ };
+
+ // iterate through the drivers, outputting one at a time
+ bool first = true;
+ while (drivlist.next())
+ {
+ if (included())
+ {
+ if (first)
+ {
+ output_header();
+ first = false;
+ }
+ output_one(drivlist, devfilter.get());
+ }
+ }
+
+ // output devices (both devices with roms and slot devices)
+ if (!devfilter || !devfilter->empty())
+ {
+ if (first)
+ {
+ output_header();
+ first = false;
+ }
+ output_devices(devfilter.get());
+ }
+
+ if (!first)
+ output_footer();
+
+ // throw an error if there were unmatched patterns
+ auto it = matched.begin();
+ for (std::string const &pat : patterns)
+ {
+ if (!*it)
+ throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching machines found for '%s'", pat.c_str());
+
+ ++it;
+ }
+}
+
+
+//-------------------------------------------------
+// output_mame_xml - print the XML information
+// for a subset of games
+//-------------------------------------------------
+
+void info_xml_creator::output(FILE *out, driver_enumerator &drivlist, bool nodevices)
+{
+ m_output = out;
+
+ device_type_set devfilter;
+
+ output_header();
+
+ // iterate through the drivers, outputting one at a time
+ while (drivlist.next())
+ output_one(drivlist, &devfilter);
+
+ // output devices (both devices with roms and slot devices)
+ if (!nodevices)
+ output_devices(&devfilter);
+
+ output_footer();
+}
+
+
+//-------------------------------------------------
+// output_header - print the XML DTD and open
+// the root element
+//-------------------------------------------------
+
+void info_xml_creator::output_header()
+{
// output the DTD
fprintf(m_output, "<?xml version=\"1.0\"?>\n");
std::string dtd(s_dtd_string);
@@ -228,19 +324,17 @@ void info_xml_creator::output(FILE *out, bool nodevices)
util::xml::normalize_string(emulator_info::get_build_version()),
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(devfilter.get());
-
- // output devices (both devices with roms and slot devices)
- if (!nodevices)
- output_devices(devfilter.get());
+//-------------------------------------------------
+// output_header - close the root element
+//-------------------------------------------------
+void info_xml_creator::output_footer()
+{
// close the top level tag
- fprintf(m_output, "</%s>\n",XML_ROOT);
+ fprintf(m_output, "</%s>\n", XML_ROOT);
}
@@ -249,14 +343,14 @@ void info_xml_creator::output(FILE *out, bool nodevices)
// for one particular game driver
//-------------------------------------------------
-void info_xml_creator::output_one(device_type_set *devtypes)
+void info_xml_creator::output_one(driver_enumerator &drivlist, device_type_set *devtypes)
{
// no action if not a game
- const game_driver &driver = m_drivlist.driver();
+ const game_driver &driver = drivlist.driver();
if (driver.flags & MACHINE_NO_STANDALONE)
return;
- std::shared_ptr<machine_config> const config(m_drivlist.config());
+ std::shared_ptr<machine_config> const config(drivlist.config());
device_iterator iter(config->root_device());
// allocate input ports
@@ -318,11 +412,11 @@ void info_xml_creator::output_one(device_type_set *devtypes)
fprintf(m_output, " ismechanical=\"yes\"");
// display clone information
- int clone_of = m_drivlist.find(driver.parent);
- if (clone_of != -1 && !(m_drivlist.driver(clone_of).flags & MACHINE_IS_BIOS_ROOT))
- fprintf(m_output, " cloneof=\"%s\"", util::xml::normalize_string(m_drivlist.driver(clone_of).name));
+ int clone_of = drivlist.find(driver.parent);
+ if (clone_of != -1 && !(drivlist.driver(clone_of).flags & MACHINE_IS_BIOS_ROOT))
+ fprintf(m_output, " cloneof=\"%s\"", util::xml::normalize_string(drivlist.driver(clone_of).name));
if (clone_of != -1)
- fprintf(m_output, " romof=\"%s\"", util::xml::normalize_string(m_drivlist.driver(clone_of).name));
+ fprintf(m_output, " romof=\"%s\"", util::xml::normalize_string(drivlist.driver(clone_of).name));
// display sample information and close the game tag
output_sampleof(config->root_device());
@@ -341,23 +435,23 @@ void info_xml_creator::output_one(device_type_set *devtypes)
fprintf(m_output, "\t\t<manufacturer>%s</manufacturer>\n", util::xml::normalize_string(driver.manufacturer));
// now print various additional information
- output_bios();
- output_rom(config->root_device());
- output_device_roms();
+ output_bios(driver);
+ output_rom(&drivlist, config->root_device());
+ output_device_roms(config->root_device());
output_sample(config->root_device());
output_chips(config->root_device(), "");
- output_display(config->root_device(), &m_drivlist.driver().flags, "");
+ output_display(config->root_device(), &drivlist.driver().flags, "");
output_sound(config->root_device());
output_input(portlist);
output_switches(portlist, "", IPT_DIPSWITCH, "dipswitch", "dipvalue");
output_switches(portlist, "", IPT_CONFIG, "configuration", "confsetting");
output_ports(portlist);
output_adjusters(portlist);
- output_driver();
+ output_driver(driver);
output_images(config->root_device(), "");
output_slots(*config, config->root_device(), "", devtypes);
- output_software_list();
- output_ramoptions();
+ output_software_list(config->root_device());
+ output_ramoptions(config->root_device());
// close the topmost tag
fprintf(m_output, "\t</%s>\n",XML_TOP);
@@ -402,7 +496,7 @@ void info_xml_creator::output_one_device(machine_config &config, device_t &devic
fprintf(m_output, ">\n");
fprintf(m_output, "\t\t<description>%s</description>\n", util::xml::normalize_string(device.name()));
- output_rom(device);
+ output_rom(nullptr, device);
if (device.type().type() != typeid(samples_device)) // ignore samples_device itself
output_sample(device);
@@ -471,10 +565,10 @@ void info_xml_creator::output_devices(device_type_set const *filter)
// included in a device set, print a reference
//-------------------------------------------------
-void info_xml_creator::output_device_roms()
+void info_xml_creator::output_device_roms(device_t &root)
{
- for (device_t &device : device_iterator(m_drivlist.config()->root_device()))
- if (device.owner() != nullptr && device.shortname() != nullptr && device.shortname()[0] != '\0')
+ for (device_t &device : device_iterator(root))
+ if (device.owner())
fprintf(m_output, "\t\t<device_ref name=\"%s\"/>\n", util::xml::normalize_string(device.shortname()));
}
@@ -506,32 +600,32 @@ void info_xml_creator::output_sampleof(device_t &device)
// game
//-------------------------------------------------
-void info_xml_creator::output_bios()
+void info_xml_creator::output_bios(game_driver const &driver)
{
// skip if no ROMs
- if (m_drivlist.driver().rom == nullptr)
- return;
-
- auto rom_entries = rom_build_entries(m_drivlist.driver().rom);
+ if (driver.rom)
+ {
+ auto rom_entries = rom_build_entries(driver.rom);
- // first determine the default BIOS name
- std::string defaultname;
- for (const rom_entry &rom : rom_entries)
- if (ROMENTRY_ISDEFAULT_BIOS(&rom))
- defaultname = ROM_GETNAME(&rom);
+ // first determine the default BIOS name
+ std::string defaultname;
+ for (const rom_entry &rom : rom_entries)
+ if (ROMENTRY_ISDEFAULT_BIOS(&rom))
+ defaultname = ROM_GETNAME(&rom);
- // iterate over ROM entries and look for BIOSes
- for (const rom_entry &rom : rom_entries)
- if (ROMENTRY_ISSYSTEM_BIOS(&rom))
- {
- // output extracted name and descriptions
- fprintf(m_output, "\t\t<biosset");
- fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(&rom)));
- fprintf(m_output, " description=\"%s\"", util::xml::normalize_string(ROM_GETHASHDATA(&rom)));
- if (defaultname == ROM_GETNAME(&rom))
- fprintf(m_output, " default=\"yes\"");
- fprintf(m_output, "/>\n");
- }
+ // iterate over ROM entries and look for BIOSes
+ for (const rom_entry &rom : rom_entries)
+ if (ROMENTRY_ISSYSTEM_BIOS(&rom))
+ {
+ // output extracted name and descriptions
+ fprintf(m_output, "\t\t<biosset");
+ fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(&rom)));
+ fprintf(m_output, " description=\"%s\"", util::xml::normalize_string(ROM_GETHASHDATA(&rom)));
+ if (defaultname == ROM_GETNAME(&rom))
+ fprintf(m_output, " default=\"yes\"");
+ fprintf(m_output, "/>\n");
+ }
+ }
}
@@ -540,9 +634,10 @@ void info_xml_creator::output_bios()
// the XML output
//-------------------------------------------------
-void info_xml_creator::output_rom(device_t &device)
+void info_xml_creator::output_rom(driver_enumerator *drivlist, device_t &device)
{
// iterate over 3 different ROM "types": BIOS, ROMs, DISKs
+ bool const do_merge_name = drivlist && dynamic_cast<driver_device *>(&device);
for (int rom_type = 0; rom_type < 3; rom_type++)
for (const rom_entry *region = rom_first_region(device); region != nullptr; region = rom_next_region(region))
{
@@ -567,8 +662,8 @@ 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 (dynamic_cast<driver_device *>(&device) &&!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
- merge_name = get_merge_name(hashes);
+ if (do_merge_name && !hashes.flag(util::hash_collection::FLAG_NO_DUMP))
+ merge_name = get_merge_name(*drivlist, hashes);
// scan for a BIOS name
bios_name[0] = 0;
@@ -1385,7 +1480,7 @@ void info_xml_creator::output_adjusters(const ioport_list &portlist)
// output_driver - print driver status
//-------------------------------------------------
-void info_xml_creator::output_driver()
+void info_xml_creator::output_driver(game_driver const &driver)
{
fprintf(m_output, "\t\t<driver");
@@ -1397,7 +1492,7 @@ void info_xml_creator::output_driver()
/* some minor issues, games marked as status=preliminary */
/* don't work or have major emulation problems. */
- u32 const flags = m_drivlist.driver().flags;
+ u32 const flags = 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 (flags & (MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS))
@@ -1569,9 +1664,9 @@ void info_xml_creator::output_slots(machine_config &config, device_t &device, co
// for all known software lists for this system
//-------------------------------------------------
-void info_xml_creator::output_software_list()
+void info_xml_creator::output_software_list(device_t &root)
{
- for (const software_list_device &swlist : software_list_device_iterator(m_drivlist.config()->root_device()))
+ for (const software_list_device &swlist : software_list_device_iterator(root))
{
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");
@@ -1588,9 +1683,9 @@ void info_xml_creator::output_software_list()
// options for this system
//-------------------------------------------------
-void info_xml_creator::output_ramoptions()
+void info_xml_creator::output_ramoptions(device_t &root)
{
- for (const ram_device &ram : ram_device_iterator(m_drivlist.config()->root_device()))
+ for (const ram_device &ram : ram_device_iterator(root))
{
fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram.default_size());
@@ -1615,14 +1710,14 @@ void info_xml_creator::output_ramoptions()
// parent set
//-------------------------------------------------
-const char *info_xml_creator::get_merge_name(const util::hash_collection &romhashes)
+const char *info_xml_creator::get_merge_name(driver_enumerator &drivlist, util::hash_collection const &romhashes)
{
// walk the parent chain
const char *merge_name = nullptr;
- for (int clone_of = m_drivlist.find(m_drivlist.driver().parent); clone_of != -1; clone_of = m_drivlist.find(m_drivlist.driver(clone_of).parent))
+ for (int clone_of = drivlist.find(drivlist.driver().parent); clone_of != -1; clone_of = drivlist.find(drivlist.driver(clone_of).parent))
{
// look in the parent's ROMs
- device_t *device = &m_drivlist.config(clone_of, m_lookup_options)->root_device();
+ device_t *device = &drivlist.config(clone_of, m_lookup_options)->root_device();
for (const rom_entry *pregion = rom_first_region(*device); pregion != nullptr; pregion = rom_next_region(pregion))
for (const rom_entry *prom = rom_first_file(pregion); prom != nullptr; prom = rom_next_file(prom))
{