diff options
Diffstat (limited to 'src/emu/info.c')
-rw-r--r-- | src/emu/info.c | 1862 |
1 files changed, 875 insertions, 987 deletions
diff --git a/src/emu/info.c b/src/emu/info.c index d0e39604249..7ee5c261500 100644 --- a/src/emu/info.c +++ b/src/emu/info.c @@ -4,8 +4,36 @@ Dumps the MAME internal data as an XML file. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -19,7 +47,8 @@ #include <ctype.h> -/* MESS/MAME configuration */ + +// MAME vs MESS configuration #ifdef MESS #define XML_ROOT "mess" #define XML_TOP "machine" @@ -30,522 +59,375 @@ -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -class parent_info +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// DTD string describing the data +const char info_xml_creator::s_dtd_string[] = +"<!DOCTYPE " XML_ROOT " [\n" +"<!ELEMENT " XML_ROOT " (" XML_TOP "+)>\n" +"\t<!ATTLIST " XML_ROOT " build CDATA #IMPLIED>\n" +"\t<!ATTLIST " XML_ROOT " debug (yes|no) \"no\">\n" +"\t<!ATTLIST " XML_ROOT " mameconfig CDATA #REQUIRED>\n" +"\t<!ELEMENT " XML_TOP " (description, year?, manufacturer, biosset*, rom*, disk*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, category*, adjuster*, driver?, device*, softwarelist*, ramoption*)>\n" +"\t\t<!ATTLIST " XML_TOP " name CDATA #REQUIRED>\n" +"\t\t<!ATTLIST " XML_TOP " sourcefile CDATA #IMPLIED>\n" +"\t\t<!ATTLIST " XML_TOP " isbios (yes|no) \"no\">\n" +"\t\t<!ATTLIST " XML_TOP " ismechanical (yes|no) \"no\">\n" +"\t\t<!ATTLIST " XML_TOP " runnable (yes|no) \"yes\">\n" +"\t\t<!ATTLIST " XML_TOP " cloneof CDATA #IMPLIED>\n" +"\t\t<!ATTLIST " XML_TOP " romof CDATA #IMPLIED>\n" +"\t\t<!ATTLIST " XML_TOP " sampleof CDATA #IMPLIED>\n" +"\t\t<!ELEMENT description (#PCDATA)>\n" +"\t\t<!ELEMENT year (#PCDATA)>\n" +"\t\t<!ELEMENT manufacturer (#PCDATA)>\n" +"\t\t<!ELEMENT biosset EMPTY>\n" +"\t\t\t<!ATTLIST biosset name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST biosset description CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST biosset default (yes|no) \"no\">\n" +"\t\t<!ELEMENT rom EMPTY>\n" +"\t\t\t<!ATTLIST rom name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST rom bios CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom md5 CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom merge CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom region CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" +"\t\t\t<!ATTLIST rom optional (yes|no) \"no\">\n" +"\t\t<!ELEMENT disk EMPTY>\n" +"\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST disk md5 CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST disk merge CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST disk region CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST disk index CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n" +"\t\t\t<!ATTLIST disk optional (yes|no) \"no\">\n" +"\t\t<!ELEMENT sample EMPTY>\n" +"\t\t\t<!ATTLIST sample name CDATA #REQUIRED>\n" +"\t\t<!ELEMENT chip EMPTY>\n" +"\t\t\t<!ATTLIST chip name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST chip tag CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST chip type (cpu|audio) #REQUIRED>\n" +"\t\t\t<!ATTLIST chip clock CDATA #IMPLIED>\n" +"\t\t<!ELEMENT display EMPTY>\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 flipx (yes|no) \"no\">\n" +"\t\t\t<!ATTLIST display width CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display height CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display refresh CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST display pixclock CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display htotal CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display hbend CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display hbstart CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display vtotal CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display vbend CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST display vbstart CDATA #IMPLIED>\n" +"\t\t<!ELEMENT sound EMPTY>\n" +"\t\t\t<!ATTLIST sound channels CDATA #REQUIRED>\n" +"\t\t<!ELEMENT input (control*)>\n" +"\t\t\t<!ATTLIST input service (yes|no) \"no\">\n" +"\t\t\t<!ATTLIST input tilt (yes|no) \"no\">\n" +"\t\t\t<!ATTLIST input players CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST input buttons CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST input coins CDATA #IMPLIED>\n" +"\t\t\t<!ELEMENT control EMPTY>\n" +"\t\t\t\t<!ATTLIST control type CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST control minimum CDATA #IMPLIED>\n" +"\t\t\t\t<!ATTLIST control maximum CDATA #IMPLIED>\n" +"\t\t\t\t<!ATTLIST control sensitivity CDATA #IMPLIED>\n" +"\t\t\t\t<!ATTLIST control keydelta CDATA #IMPLIED>\n" +"\t\t\t\t<!ATTLIST control reverse (yes|no) \"no\">\n" +"\t\t<!ELEMENT dipswitch (dipvalue*)>\n" +"\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n" +"\t\t\t<!ELEMENT dipvalue EMPTY>\n" +"\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" +"\t\t<!ELEMENT configuration (confsetting*)>\n" +"\t\t\t<!ATTLIST configuration name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST configuration tag CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST configuration mask CDATA #REQUIRED>\n" +"\t\t\t<!ELEMENT confsetting EMPTY>\n" +"\t\t\t\t<!ATTLIST confsetting name CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST confsetting value CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST confsetting default (yes|no) \"no\">\n" +"\t\t<!ELEMENT category (item*)>\n" +"\t\t\t<!ATTLIST category name CDATA #REQUIRED>\n" +"\t\t\t<!ELEMENT item EMPTY>\n" +"\t\t\t\t<!ATTLIST item name CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST item default (yes|no) \"no\">\n" +"\t\t<!ELEMENT adjuster EMPTY>\n" +"\t\t\t<!ATTLIST adjuster name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST adjuster default CDATA #REQUIRED>\n" +"\t\t<!ELEMENT driver EMPTY>\n" +"\t\t\t<!ATTLIST driver status (good|imperfect|preliminary) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver emulation (good|imperfect|preliminary) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver color (good|imperfect|preliminary) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver sound (good|imperfect|preliminary) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver graphic (good|imperfect|preliminary) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver cocktail (good|imperfect|preliminary) #IMPLIED>\n" +"\t\t\t<!ATTLIST driver protection (good|imperfect|preliminary) #IMPLIED>\n" +"\t\t\t<!ATTLIST driver savestate (supported|unsupported) #REQUIRED>\n" +"\t\t\t<!ATTLIST driver palettesize CDATA #REQUIRED>\n" +"\t\t<!ELEMENT device (instance*, extension*)>\n" +"\t\t\t<!ATTLIST device type CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST device tag CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST device mandatory CDATA #IMPLIED>\n" +"\t\t\t<!ATTLIST device interface CDATA #IMPLIED>\n" +"\t\t\t<!ELEMENT instance EMPTY>\n" +"\t\t\t\t<!ATTLIST instance name CDATA #REQUIRED>\n" +"\t\t\t\t<!ATTLIST instance briefname CDATA #REQUIRED>\n" +"\t\t\t<!ELEMENT extension EMPTY>\n" +"\t\t\t\t<!ATTLIST extension name CDATA #REQUIRED>\n" +"\t\t<!ELEMENT softwarelist EMPTY>\n" +"\t\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" +"\t\t\t<!ATTLIST softwarelist status (original|compatible) #REQUIRED>\n" +"\t\t<!ELEMENT ramoption (#PCDATA)>\n" +"\t\t\t<!ATTLIST ramoption default CDATA #IMPLIED>\n" +"]>"; + + + +//************************************************************************** +// INFO XML CREATOR +//************************************************************************** + +//------------------------------------------------- +// info_xml_creator - constructor +//------------------------------------------------- + +info_xml_creator::info_xml_creator(driver_enumerator &drivlist) + : m_output(NULL), + m_drivlist(drivlist) { -public: - const game_driver *drv; - machine_config mconfig; - - parent_info(const game_driver *drv, emu_options &options) : mconfig(*drv, options) - { - this->drv = drv; - } -}; - +} -/*************************************************************************** - CORE IMPLEMENTATION -***************************************************************************/ - -/*------------------------------------------------- - print_game_switches - print the DIP switch - settings for a game --------------------------------------------------*/ +//------------------------------------------------- +// output_mame_xml - print the XML information +// for all known games +//------------------------------------------------- -static void print_game_switches(FILE *out, const game_driver *game, const ioport_list &portlist) +void info_xml_creator::output(FILE *out) { - const input_port_config *port; - const input_field_config *field; - - /* iterate looking for DIP switches */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist; field != NULL; field = field->next) - if (field->type == IPT_DIPSWITCH) - { - const input_setting_config *setting; - - /* output the switch name information */ - fprintf(out, "\t\t<dipswitch name=\"%s\"", xml_normalize_string(input_field_name(field))); - fprintf(out, " tag=\"%s\"", xml_normalize_string(field->port->tag)); - fprintf(out, " mask=\"%u\"", field->mask); - fprintf(out, ">\n"); + m_output = out; + + // output the DTD + fprintf(m_output, "<?xml version=\"1.0\"?>\n"); + fprintf(m_output, "%s\n\n", s_dtd_string); + + // top-level tag + fprintf(m_output, "<" XML_ROOT " build=\"%s\" debug=\"" +#ifdef MAME_DEBUG + "yes" +#else + "no" +#endif + "\" mameconfig=\"%d\">\n", + xml_normalize_string(build_version), + CONFIG_VERSION + ); - /* loop over settings */ - for (setting = field->settinglist; setting != NULL; setting = setting->next) - { - fprintf(out, "\t\t\t<dipvalue name=\"%s\"", xml_normalize_string(setting->name)); - fprintf(out, " value=\"%u\"", setting->value); - if (setting->value == field->defvalue) - fprintf(out, " default=\"yes\""); - fprintf(out, "/>\n"); - } + // iterate through the drivers, outputting one at a time + while (m_drivlist.next()) + output_one(); - /* terminate the switch entry */ - fprintf(out, "\t\t</dipswitch>\n"); - } + // close the top level tag + fprintf(m_output, "</" XML_ROOT ">\n"); } -/*------------------------------------------------- - print_game_configs - print the Configuration - settings for a game --------------------------------------------------*/ -static void print_game_configs(FILE *out, const game_driver *game, const ioport_list &portlist) -{ - const input_port_config *port; - const input_field_config *field; +//------------------------------------------------- +// output_one - print the XML information +// for one particular game driver +//------------------------------------------------- - /* iterate looking for configurations */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist; field != NULL; field = field->next) - if (field->type == IPT_CONFIG) - { - const input_setting_config *setting; +void info_xml_creator::output_one() +{ + // no action if not a game + const game_driver &driver = m_drivlist.driver(); + if (driver.flags & GAME_NO_STANDALONE) + return; - /* output the configuration name information */ - fprintf(out, "\t\t<configuration name=\"%s\"", xml_normalize_string(input_field_name(field))); - fprintf(out, " tag=\"%s\"", xml_normalize_string(field->port->tag)); - fprintf(out, " mask=\"%u\"", field->mask); - fprintf(out, ">\n"); + // allocate input ports + machine_config &config = m_drivlist.config(); + ioport_list portlist; + input_port_list_init(portlist, driver.ipt, NULL, 0, FALSE, NULL); + for (device_config *cfg = config.m_devicelist.first(); cfg != NULL; cfg = cfg->next()) + if (cfg->input_ports() != NULL) + input_port_list_init(portlist, cfg->input_ports(), NULL, 0, FALSE, cfg); - /* loop over settings */ - for (setting = field->settinglist; setting != NULL; setting = setting->next) - { - fprintf(out, "\t\t\t<confsetting name=\"%s\"", xml_normalize_string(setting->name)); - fprintf(out, " value=\"%u\"", setting->value); - if (setting->value == field->defvalue) - fprintf(out, " default=\"yes\""); - fprintf(out, "/>\n"); - } + // print the header and the game name + fprintf(m_output, "\t<" XML_TOP); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(driver.name)); - /* terminate the configuration entry */ - fprintf(out, "\t\t</configuration>\n"); - } + // strip away any path information from the source_file and output it + const char *start = strrchr(driver.source_file, '/'); + if (start == NULL) + start = strrchr(driver.source_file, '\\'); + if (start == NULL) + start = driver.source_file - 1; + fprintf(m_output, " sourcefile=\"%s\"", xml_normalize_string(start + 1)); + + // append bios and runnable flags + if (driver.flags & GAME_IS_BIOS_ROOT) + fprintf(m_output, " isbios=\"yes\""); + if (driver.flags & GAME_NO_STANDALONE) + fprintf(m_output, " runnable=\"no\""); + if (driver.flags & GAME_MECHANICAL) + 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 & GAME_IS_BIOS_ROOT)) + fprintf(m_output, " cloneof=\"%s\"", xml_normalize_string(m_drivlist.driver(clone_of).name)); + if (clone_of != -1) + fprintf(m_output, " romof=\"%s\"", xml_normalize_string(m_drivlist.driver(clone_of).name)); + + // display sample information and close the game tag + output_sampleof(); + fprintf(m_output, ">\n"); + + // output game description + if (driver.description != NULL) + fprintf(m_output, "\t\t<description>%s</description>\n", xml_normalize_string(driver.description)); + + // print the year only if is a number or another allowed character (? or +) + if (driver.year != NULL && strspn(driver.year, "0123456789?+") == strlen(driver.year)) + fprintf(m_output, "\t\t<year>%s</year>\n", xml_normalize_string(driver.year)); + + // print the manufacturer information + if (driver.manufacturer != NULL) + fprintf(m_output, "\t\t<manufacturer>%s</manufacturer>\n", xml_normalize_string(driver.manufacturer)); + + // now print various additional information + output_bios(); + output_rom(); + output_sample(); + output_chips(); + output_display(); + output_sound(); + output_input(portlist); + output_switches(portlist, IPT_DIPSWITCH, "dipswitch", "dipvalue"); + output_switches(portlist, IPT_CONFIG, "configuration", "confsetting"); + output_categories(portlist); + output_adjusters(portlist); + output_driver(); + output_images(); + output_software_list(); + output_ramoptions(); + + // close the topmost tag + fprintf(m_output, "\t</" XML_TOP ">\n"); } -/*------------------------------------------------- - print_game_adjusters - print the Analog - Adjusters for a game --------------------------------------------------*/ - -static void print_game_adjusters(FILE *out, const game_driver *game, const ioport_list &portlist) -{ - const input_port_config *port; - const input_field_config *field; - /* iterate looking for Adjusters */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist; field != NULL; field = field->next) - if (field->type == IPT_ADJUSTER) - { - /* output the adjuster information */ - fprintf(out, "\t\t<adjuster name=\"%s\" default=\"%d\"/>\n", xml_normalize_string(input_field_name(field)), field->defvalue); - } -} +//------------------------------------------------ +// output_sampleof - print the 'sampleof' +// attribute, if appropriate +//------------------------------------------------- -/*------------------------------------------------- - print_game_input - print a summary of a game's - input --------------------------------------------------*/ - -static void print_game_input(FILE *out, const game_driver *game, const ioport_list &portlist) +void info_xml_creator::output_sampleof() { - /* fix me -- this needs to be cleaned up to match the core style */ - -enum {cjoy, cdoublejoy, cAD_stick, cdial, ctrackball, cpaddle, clightgun, cpedal, ckeypad, ckeyboard, ENDCONTROLTYPES}; - int nplayer = 0; - int nbutton = 0; - int ncoin = 0; - //int controlsyes = 0; - int analogcontrol = 0; - int i; - const char* service = 0; - const char* tilt = 0; - const char* const control_types[] = {"joy", "doublejoy", "stick", "dial", "trackball", "paddle", "lightgun", "pedal", "keypad", "keyboard"}; - static struct _input_info - { - const char * type; /* general type of input */ - const char * Xway; /* 2, 4, or 8 way */ - int analog; - int keyb; - int min; /* analog minimum value */ - int max; /* analog maximum value */ - int sensitivity; /* default analog sensitivity */ - int keydelta; /* default analog keydelta */ - int reverse; /* default analog reverse setting */ - } control[ENDCONTROLTYPES]; - const input_port_config *port; - const input_field_config *field; - - for (i = 0; i < ENDCONTROLTYPES; i++) + // iterate over sample devices + for (const device_config *devconfig = m_drivlist.config().m_devicelist.first(SAMPLES); devconfig != NULL; devconfig = devconfig->typenext()) { - control[i].type = control_types[i]; - control[i].Xway = NULL; - control[i].analog = 0; - control[i].keyb = 0; - control[i].min = 0; - control[i].max = 0; - control[i].sensitivity = 0; - control[i].keydelta = 0; - control[i].reverse = 0; - } - - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist; field != NULL; field = field->next) - { + const char *const *samplenames = ((const samples_interface *)devconfig->static_config())->samplenames; + if (samplenames != NULL) - if (nplayer < field->player + 1) - nplayer = field->player + 1; - - switch (field->type) + // iterate over sample names + for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) { - case IPT_JOYSTICK_LEFT: - case IPT_JOYSTICK_RIGHT: - - /* if control not defined, start it off as horizontal 2-way */ - if (control[cjoy].Xway == NULL) - control[cjoy].Xway = "joy2way"; - else if (strcmp(control[cjoy].Xway,"joy2way") == 0) - ; - /* if already defined as vertical, make it 4 or 8 way */ - else if (strcmp(control[cjoy].Xway,"vjoy2way") == 0) - { - if (field->way == 4) - control[cjoy].Xway = "joy4way"; - else - control[cjoy].Xway = "joy8way"; - } - //controlsyes = 1; - break; - - case IPT_JOYSTICK_UP: - case IPT_JOYSTICK_DOWN: + // only output sampleof if different from the game name + const char *cursampname = samplenames[sampnum]; + if (cursampname[0] == '*' && strcmp(cursampname + 1, m_drivlist.driver().name) != 0) + fprintf(m_output, " sampleof=\"%s\"", xml_normalize_string(cursampname + 1)); - /* if control not defined, start it off as vertical 2-way */ - if (control[cjoy].Xway == NULL) - control[cjoy].Xway = "vjoy2way"; - else if (strcmp(control[cjoy].Xway,"vjoy2way") == 0) - ; - /* if already defined as horiz, make it 4 or 8way */ - else if (strcmp(control[cjoy].Xway,"joy2way") == 0) - { - if (field->way == 4) - control[cjoy].Xway = "joy4way"; - else - control[cjoy].Xway = "joy8way"; - } - //controlsyes = 1; - break; - - case IPT_JOYSTICKRIGHT_UP: - case IPT_JOYSTICKRIGHT_DOWN: - case IPT_JOYSTICKLEFT_UP: - case IPT_JOYSTICKLEFT_DOWN: - - /* if control not defined, start it off as vertical 2way */ - if (control[cdoublejoy].Xway == NULL) - control[cdoublejoy].Xway = "vdoublejoy2way"; - else if (strcmp(control[cdoublejoy].Xway,"vdoublejoy2way") == 0) - ; - /* if already defined as horiz, make it 4 or 8 way */ - else if (strcmp(control[cdoublejoy].Xway,"doublejoy2way") == 0) - { - if (field->way == 4) - control[cdoublejoy].Xway = "doublejoy4way"; - else - control[cdoublejoy].Xway = "doublejoy8way"; - } - //controlsyes = 1; - break; - - case IPT_JOYSTICKRIGHT_LEFT: - case IPT_JOYSTICKRIGHT_RIGHT: - case IPT_JOYSTICKLEFT_LEFT: - case IPT_JOYSTICKLEFT_RIGHT: - - /* if control not defined, start it off as horiz 2-way */ - if (control[cdoublejoy].Xway == NULL) - control[cdoublejoy].Xway = "doublejoy2way"; - else if (strcmp(control[cdoublejoy].Xway,"doublejoy2way") == 0) - ; - /* if already defined as vertical, make it 4 or 8 way */ - else if (strcmp(control[cdoublejoy].Xway,"vdoublejoy2way") == 0) - { - if (field->way == 4) - control[cdoublejoy].Xway = "doublejoy4way"; - else - control[cdoublejoy].Xway = "doublejoy8way"; - } - //controlsyes = 1; - break; - - /* mark as an analog input, and get analog stats after switch */ - case IPT_PADDLE: - analogcontrol = cpaddle; - break; - case IPT_DIAL: - analogcontrol = cdial; - break; - case IPT_TRACKBALL_X: - case IPT_TRACKBALL_Y: - analogcontrol = ctrackball; - break; - case IPT_AD_STICK_X: - case IPT_AD_STICK_Y: - analogcontrol = cAD_stick; - break; - case IPT_LIGHTGUN_X: - case IPT_LIGHTGUN_Y: - analogcontrol = clightgun; - break; - case IPT_PEDAL: - case IPT_PEDAL2: - case IPT_PEDAL3: - analogcontrol = cpedal; - break; - - case IPT_BUTTON1: - case IPT_BUTTON2: - case IPT_BUTTON3: - case IPT_BUTTON4: - case IPT_BUTTON5: - case IPT_BUTTON6: - case IPT_BUTTON7: - case IPT_BUTTON8: - case IPT_BUTTON9: - case IPT_BUTTON10: - case IPT_BUTTON11: - case IPT_BUTTON12: - case IPT_BUTTON13: - case IPT_BUTTON14: - case IPT_BUTTON15: - case IPT_BUTTON16: - nbutton = MAX(nbutton, field->type - IPT_BUTTON1 + 1); - break; - - case IPT_COIN1: - case IPT_COIN2: - case IPT_COIN3: - case IPT_COIN4: - case IPT_COIN5: - case IPT_COIN6: - case IPT_COIN7: - case IPT_COIN8: - ncoin = MAX(ncoin, field->type - IPT_COIN1 + 1); - - case IPT_SERVICE : - service = "yes"; - break; - - case IPT_TILT : - tilt = "yes"; - break; - - case IPT_KEYPAD: - control[ckeypad].keyb = 1; - break; - - case IPT_KEYBOARD: - control[ckeyboard].keyb = 1; - break; - } - - /* get the analog stats */ - if (analogcontrol) - { - //controlsyes = 1; - control[analogcontrol].analog = 1; - - if (field->min) - control[analogcontrol].min = field->min; - if (field->max) - control[analogcontrol].max = field->max; - if (field->sensitivity) - control[analogcontrol].sensitivity = field->sensitivity; - if (field->delta) - control[analogcontrol].keydelta = field->delta; - if (field->flags & ANALOG_FLAG_REVERSE) - control[analogcontrol].reverse = 1; - - analogcontrol = 0; - } - } - - fprintf(out, "\t\t<input"); - fprintf(out, " players=\"%d\"", nplayer); - if (nbutton != 0) - fprintf(out, " buttons=\"%d\"", nbutton); - if (ncoin != 0) - fprintf(out, " coins=\"%d\"", ncoin); - if (service != NULL) - fprintf(out, " service=\"%s\"", xml_normalize_string(service)); - if (tilt != NULL) - fprintf(out, " tilt=\"%s\"", xml_normalize_string(tilt)); - fprintf(out, ">\n"); - - for (i = 0; i < ENDCONTROLTYPES; i++) - { - if (control[i].Xway != NULL) - fprintf(out, "\t\t\t<control type=\"%s\"/>\n", xml_normalize_string(control[i].Xway)); - if (control[i].analog) - { - fprintf(out, "\t\t\t<control type=\"%s\"", xml_normalize_string(control_types[i])); - if (control[i].min || control[i].max) - { - fprintf(out, " minimum=\"%d\"", control[i].min); - fprintf(out, " maximum=\"%d\"", control[i].max); + // must stop here, as there can only be one attribute of the same name + return; } - if (control[i].sensitivity) - fprintf(out, " sensitivity=\"%d\"", control[i].sensitivity); - if (control[i].keydelta) - fprintf(out, " keydelta=\"%d\"", control[i].keydelta); - if (control[i].reverse) - fprintf(out, " reverse=\"yes\""); - - fprintf(out, "/>\n"); - } - if (control[i].keyb) - { - fprintf(out, "\t\t\t<control type=\"%s\"/>\n", xml_normalize_string(control_types[i])); - } } - fprintf(out, "\t\t</input>\n"); } -/*------------------------------------------------- - print_game_bios - print the BIOS set for a - game --------------------------------------------------*/ +//------------------------------------------------- +// output_bios - print the BIOS set for a +// game +//------------------------------------------------- -static void print_game_bios(FILE *out, const game_driver *game) +void info_xml_creator::output_bios() { - const rom_entry *rom; - - /* skip if no ROMs */ - if (game->rom == NULL) + // skip if no ROMs + if (m_drivlist.driver().rom == NULL) return; - /* iterate over ROM entries and look for BIOSes */ - for (rom = game->rom; !ROMENTRY_ISEND(rom); rom++) + // iterate over ROM entries and look for BIOSes + for (const rom_entry *rom = m_drivlist.driver().rom; !ROMENTRY_ISEND(rom); rom++) if (ROMENTRY_ISSYSTEM_BIOS(rom)) { - const char *name = ROM_GETNAME(rom); - const char *description = ROM_GETHASHDATA(rom); - - /* output extracted name and descriptions */ - fprintf(out, "\t\t<biosset"); - fprintf(out, " name=\"%s\"", xml_normalize_string(name)); - fprintf(out, " description=\"%s\"", xml_normalize_string(description)); + // output extracted name and descriptions + fprintf(m_output, "\t\t<biosset"); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(ROM_GETNAME(rom))); + fprintf(m_output, " description=\"%s\"", xml_normalize_string(ROM_GETHASHDATA(rom))); if (ROM_GETBIOSFLAGS(rom) == 1) - fprintf(out, " default=\"yes\""); - fprintf(out, "/>\n"); + fprintf(m_output, " default=\"yes\""); + fprintf(m_output, "/>\n"); } } -/*------------------------------------------------- - get_merge_name - get the rom name from a - parent set --------------------------------------------------*/ - -static const char *get_merge_name(const hash_collection &romhashes, int parents, const parent_info **pinfoarray) -{ - int parent; - const char *merge_name = NULL; - - for (parent = 0; parent < parents; ++parent) - { - const machine_config *pconfig = &pinfoarray[parent]->mconfig; - const rom_source *psource; - const rom_entry *pregion, *prom; - - /* scan the clone_of ROM for a matching ROM entry */ - for (psource = rom_first_source(*pconfig); psource != NULL; psource = rom_next_source(*psource)) - for (pregion = rom_first_region(*psource); pregion != NULL; pregion = rom_next_region(pregion)) - for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom)) - { - hash_collection phashes(ROM_GETHASHDATA(prom)); - if (!phashes.flag(hash_collection::FLAG_NO_DUMP) && romhashes == phashes) - { - merge_name = ROM_GETNAME(prom); - break; - } - } - } - - return merge_name; -} +//------------------------------------------------- +// output_rom - print the roms section of +// the XML output +//------------------------------------------------- - -/*------------------------------------------------- - print_game_rom - print the roms section of - the XML output --------------------------------------------------*/ - -static void print_game_rom(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_rom() { - const game_driver *clone_of = driver_get_clone(game); - int rom_type; - int parents = 0; - const parent_info *pinfoarray[4]; - - for (; clone_of != NULL; clone_of = driver_get_clone(clone_of)) - { - assert_always(parents < ARRAY_LENGTH(pinfoarray), "too many parents"); - pinfoarray[parents++] = global_alloc(parent_info(clone_of, config.options())); - } - - /* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */ - for (rom_type = 0; rom_type < 3; rom_type++) + // iterate over 3 different ROM "types": BIOS, ROMs, DISKs + for (int rom_type = 0; rom_type < 3; rom_type++) { - const rom_source *source; - const rom_entry *region; - - /* iterate over ROM sources: first the game, then any devices */ - for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) - for (region = rom_first_region(*source); region != NULL; region = rom_next_region(region)) + // iterate over ROM sources: first the game, then any devices + for (const rom_source *source = rom_first_source(m_drivlist.config()); source != NULL; source = rom_next_source(*source)) + for (const rom_entry *region = rom_first_region(*source); region != NULL; region = rom_next_region(region)) { - int is_disk = ROMREGION_ISDISKDATA(region); - const rom_entry *rom; + bool is_disk = ROMREGION_ISDISKDATA(region); - /* disk regions only work for disks */ + // disk regions only work for disks if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; - /* iterate through ROM entries */ - for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) + // iterate through ROM entries + for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { - int is_bios = ROM_GETBIOSFLAGS(rom); + bool is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const char *merge_name = NULL; char bios_name[100]; - /* BIOS ROMs only apply to bioses */ + // BIOS ROMs only apply to bioses if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0)) continue; - /* if we have a valid ROM and we are a clone, see if we can find the parent ROM */ + // if we have a valid ROM and we are a clone, see if we can find the parent ROM hash_collection hashes(ROM_GETHASHDATA(rom)); - if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && parents > 0) - { - merge_name = get_merge_name(hashes, parents, pinfoarray); - } + if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) + merge_name = get_merge_name(hashes); - /* scan for a BIOS name */ + // scan for a BIOS name bios_name[0] = 0; if (!is_disk && is_bios) { - const rom_entry *brom; - - /* scan backwards through the ROM entries */ - for (brom = rom - 1; brom != game->rom; brom--) + // scan backwards through the ROM entries + for (const rom_entry *brom = rom - 1; brom != m_drivlist.driver().rom; brom--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); @@ -553,281 +435,521 @@ static void print_game_rom(FILE *out, const game_driver *game, const machine_con } } - /* opening tag */ + // opening tag if (!is_disk) - fprintf(out, "\t\t<rom"); + fprintf(m_output, "\t\t<rom"); else - fprintf(out, "\t\t<disk"); + fprintf(m_output, "\t\t<disk"); - /* add name, merge, bios, and size tags */ + // add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) - fprintf(out, " name=\"%s\"", xml_normalize_string(name)); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(name)); if (merge_name != NULL) - fprintf(out, " merge=\"%s\"", xml_normalize_string(merge_name)); + fprintf(m_output, " merge=\"%s\"", xml_normalize_string(merge_name)); if (bios_name[0] != 0) - fprintf(out, " bios=\"%s\"", xml_normalize_string(bios_name)); + fprintf(m_output, " bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) - fprintf(out, " size=\"%d\"", rom_file_size(rom)); + fprintf(m_output, " size=\"%d\"", rom_file_size(rom)); - /* dump checksum information only if there is a known dump */ + // dump checksum information only if there is a known dump if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) { - /* iterate over hash function types and print out their values */ + // iterate over hash function types and print m_output their values astring tempstr; for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next()) - fprintf(out, " %s=\"%s\"", hash->name(), hash->string(tempstr)); + fprintf(m_output, " %s=\"%s\"", hash->name(), hash->string(tempstr)); } - /* append a region name */ - fprintf(out, " region=\"%s\"", ROMREGION_GETTAG(region)); + // append a region name + fprintf(m_output, " region=\"%s\"", ROMREGION_GETTAG(region)); - /* add nodump/baddump flags */ + // add nodump/baddump flags if (hashes.flag(hash_collection::FLAG_NO_DUMP)) - fprintf(out, " status=\"nodump\""); + fprintf(m_output, " status=\"nodump\""); if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) - fprintf(out, " status=\"baddump\""); + fprintf(m_output, " status=\"baddump\""); - /* for non-disk entries, print offset */ + // for non-disk entries, print offset if (!is_disk) - fprintf(out, " offset=\"%x\"", offset); - /* for disk entries, add the disk index */ + fprintf(m_output, " offset=\"%x\"", offset); + + // for disk entries, add the disk index else - fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); + fprintf(m_output, " index=\"%x\"", DISK_GETINDEX(rom)); - /* add optional flag */ + // add optional flag if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom))) - fprintf(out, " optional=\"yes\""); + fprintf(m_output, " optional=\"yes\""); - fprintf(out, "/>\n"); + fprintf(m_output, "/>\n"); } } } - - for (; parents > 0; parents--) - global_free(pinfoarray[parents - 1]); -} - - -/*------------------------------------------------- - print_game_sampleof - print the 'sampleof' - attribute, if appropriate --------------------------------------------------*/ - -static void print_game_sampleof(FILE *out, const game_driver *game, const machine_config &config) -{ - const device_config_sound_interface *sound = NULL; - - for (bool gotone = config.m_devicelist.first(sound); gotone; gotone = sound->next(sound)) - if (sound->devconfig().type() == SAMPLES) - { - const char *const *samplenames = ((const samples_interface *)sound->devconfig().static_config())->samplenames; - if (samplenames != NULL) - { - int sampnum; - - /* iterate over sample names */ - for (sampnum = 0; samplenames[sampnum] != NULL; sampnum++) - { - const char *cursampname = samplenames[sampnum]; - - /* only output sampleof if different from the game name */ - if (cursampname[0] == '*' && strcmp(cursampname + 1, game->name) != 0) - fprintf(out, " sampleof=\"%s\"", xml_normalize_string(cursampname + 1)); - - /* must stop here, as there can only be one attribute of the same name */ - return; - } - } - } } -/*------------------------------------------------- - print_game_sample - print a list of all - samples referenced by a game_driver --------------------------------------------------*/ +//------------------------------------------------- +// output_sample - print a list of all +// samples referenced by a game_driver +//------------------------------------------------- -static void print_game_sample(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_sample() { - const device_config_sound_interface *sound = NULL; + // iterate over sample devices + for (const device_config *devconfig = m_drivlist.config().m_devicelist.first(SAMPLES); devconfig != NULL; devconfig = devconfig->typenext()) + { + const char *const *samplenames = ((const samples_interface *)devconfig->static_config())->samplenames; + if (samplenames != NULL) - /* iterate over sound chips looking for samples */ - for (bool gotone = config.m_devicelist.first(sound); gotone; gotone = sound->next(sound)) - if (sound->devconfig().type() == SAMPLES) - { - const char *const *samplenames = ((const samples_interface *)sound->devconfig().static_config())->samplenames; - if (samplenames != NULL) + // iterate over sample names + for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) { - int sampnum; - - /* iterate over sample names */ - for (sampnum = 0; samplenames[sampnum] != NULL; sampnum++) - { - const char *cursampname = samplenames[sampnum]; - int dupnum; - - /* ignore the special '*' samplename */ - if (sampnum == 0 && cursampname[0] == '*') - continue; + // ignore the special '*' samplename + const char *cursampname = samplenames[sampnum]; + if (sampnum == 0 && cursampname[0] == '*') + continue; - /* filter out duplicates */ - for (dupnum = 0; dupnum < sampnum; dupnum++) - if (strcmp(samplenames[dupnum], cursampname) == 0) - break; - if (dupnum < sampnum) - continue; + // filter m_output duplicates + int dupnum; + for (dupnum = 0; dupnum < sampnum; dupnum++) + if (strcmp(samplenames[dupnum], cursampname) == 0) + break; + if (dupnum < sampnum) + continue; - /* output the sample name */ - fprintf(out, "\t\t<sample name=\"%s\"/>\n", xml_normalize_string(cursampname)); - } + // output the sample name + fprintf(m_output, "\t\t<sample name=\"%s\"/>\n", xml_normalize_string(cursampname)); } - } + } } /*------------------------------------------------- - print_game_chips - print a list of CPU and + output_chips - print a list of CPU and sound chips used by a game -------------------------------------------------*/ -static void print_game_chips(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_chips() { - /* iterate over CPUs */ + // iterate over executable devices const device_config_execute_interface *exec = NULL; - for (bool gotone = config.m_devicelist.first(exec); gotone; gotone = exec->next(exec)) + for (bool gotone = m_drivlist.config().m_devicelist.first(exec); gotone; gotone = exec->next(exec)) { - fprintf(out, "\t\t<chip"); - fprintf(out, " type=\"cpu\""); - fprintf(out, " tag=\"%s\"", xml_normalize_string(exec->devconfig().tag())); - fprintf(out, " name=\"%s\"", xml_normalize_string(exec->devconfig().name())); - fprintf(out, " clock=\"%d\"", exec->devconfig().clock()); - fprintf(out, "/>\n"); + fprintf(m_output, "\t\t<chip"); + fprintf(m_output, " type=\"cpu\""); + fprintf(m_output, " tag=\"%s\"", xml_normalize_string(exec->devconfig().tag())); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(exec->devconfig().name())); + fprintf(m_output, " clock=\"%d\"", exec->devconfig().clock()); + fprintf(m_output, "/>\n"); } - /* iterate over sound chips */ + // iterate over sound devices const device_config_sound_interface *sound = NULL; - for (bool gotone = config.m_devicelist.first(sound); gotone; gotone = sound->next(sound)) + for (bool gotone = m_drivlist.config().m_devicelist.first(sound); gotone; gotone = sound->next(sound)) { - fprintf(out, "\t\t<chip"); - fprintf(out, " type=\"audio\""); - fprintf(out, " tag=\"%s\"", xml_normalize_string(sound->devconfig().tag())); - fprintf(out, " name=\"%s\"", xml_normalize_string(sound->devconfig().name())); + fprintf(m_output, "\t\t<chip"); + fprintf(m_output, " type=\"audio\""); + fprintf(m_output, " tag=\"%s\"", xml_normalize_string(sound->devconfig().tag())); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(sound->devconfig().name())); if (sound->devconfig().clock() != 0) - fprintf(out, " clock=\"%d\"", sound->devconfig().clock()); - fprintf(out, "/>\n"); + fprintf(m_output, " clock=\"%d\"", sound->devconfig().clock()); + fprintf(m_output, "/>\n"); } } -/*------------------------------------------------- - print_game_display - print a list of all the - displays --------------------------------------------------*/ +//------------------------------------------------- +// output_display - print a list of all the +// displays +//------------------------------------------------- -static void print_game_display(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_display() { - const screen_device_config *devconfig; - - /* iterate over screens */ - for (devconfig = config.first_screen(); devconfig != NULL; devconfig = devconfig->next_screen()) + // iterate over screens + for (const screen_device_config *devconfig = m_drivlist.config().first_screen(); devconfig != NULL; devconfig = devconfig->next_screen()) { - fprintf(out, "\t\t<display"); + fprintf(m_output, "\t\t<display"); switch (devconfig->screen_type()) { - case SCREEN_TYPE_RASTER: fprintf(out, " type=\"raster\""); break; - case SCREEN_TYPE_VECTOR: fprintf(out, " type=\"vector\""); break; - case SCREEN_TYPE_LCD: fprintf(out, " type=\"lcd\""); break; - default: fprintf(out, " type=\"unknown\""); break; + case SCREEN_TYPE_RASTER: fprintf(m_output, " type=\"raster\""); break; + case SCREEN_TYPE_VECTOR: fprintf(m_output, " type=\"vector\""); break; + case SCREEN_TYPE_LCD: fprintf(m_output, " type=\"lcd\""); break; + default: fprintf(m_output, " type=\"unknown\""); break; } - /* output the orientation as a string */ - switch (game->flags & ORIENTATION_MASK) + // output the orientation as a string + switch (m_drivlist.driver().flags & ORIENTATION_MASK) { case ORIENTATION_FLIP_X: - fprintf(out, " rotate=\"0\" flipx=\"yes\""); + fprintf(m_output, " rotate=\"0\" flipx=\"yes\""); break; case ORIENTATION_FLIP_Y: - fprintf(out, " rotate=\"180\" flipx=\"yes\""); + fprintf(m_output, " rotate=\"180\" flipx=\"yes\""); break; case ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: - fprintf(out, " rotate=\"180\""); + fprintf(m_output, " rotate=\"180\""); break; case ORIENTATION_SWAP_XY: - fprintf(out, " rotate=\"90\" flipx=\"yes\""); + fprintf(m_output, " rotate=\"90\" flipx=\"yes\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X: - fprintf(out, " rotate=\"90\""); + fprintf(m_output, " rotate=\"90\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_Y: - fprintf(out, " rotate=\"270\""); + fprintf(m_output, " rotate=\"270\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: - fprintf(out, " rotate=\"270\" flipx=\"yes\""); + fprintf(m_output, " rotate=\"270\" flipx=\"yes\""); break; default: - fprintf(out, " rotate=\"0\""); + fprintf(m_output, " rotate=\"0\""); break; } - /* output width and height only for games that are not vector */ + // output width and height only for games that are not vector if (devconfig->screen_type() != SCREEN_TYPE_VECTOR) { const rectangle &visarea = devconfig->visible_area(); - int dx = visarea.max_x - visarea.min_x + 1; - int dy = visarea.max_y - visarea.min_y + 1; - - fprintf(out, " width=\"%d\"", dx); - fprintf(out, " height=\"%d\"", dy); + fprintf(m_output, " width=\"%d\"", visarea.max_x - visarea.min_x + 1); + fprintf(m_output, " height=\"%d\"", visarea.max_y - visarea.min_y + 1); } - /* output refresh rate */ - fprintf(out, " refresh=\"%f\"", ATTOSECONDS_TO_HZ(devconfig->refresh())); + // output refresh rate + fprintf(m_output, " refresh=\"%f\"", ATTOSECONDS_TO_HZ(devconfig->refresh())); - /* output raw video parameters only for games that are not vector */ - /* and had raw parameters specified */ + // output raw video parameters only for games that are not vector + // and had raw parameters specified if (devconfig->screen_type() != SCREEN_TYPE_VECTOR && !devconfig->oldstyle_vblank_supplied()) { int pixclock = devconfig->width() * devconfig->height() * ATTOSECONDS_TO_HZ(devconfig->refresh()); - fprintf(out, " pixclock=\"%d\"", pixclock); - fprintf(out, " htotal=\"%d\"", devconfig->width()); - fprintf(out, " hbend=\"%d\"", devconfig->visible_area().min_x); - fprintf(out, " hbstart=\"%d\"", devconfig->visible_area().max_x+1); - fprintf(out, " vtotal=\"%d\"", devconfig->height()); - fprintf(out, " vbend=\"%d\"", devconfig->visible_area().min_y); - fprintf(out, " vbstart=\"%d\"", devconfig->visible_area().max_y+1); + fprintf(m_output, " pixclock=\"%d\"", pixclock); + fprintf(m_output, " htotal=\"%d\"", devconfig->width()); + fprintf(m_output, " hbend=\"%d\"", devconfig->visible_area().min_x); + fprintf(m_output, " hbstart=\"%d\"", devconfig->visible_area().max_x+1); + fprintf(m_output, " vtotal=\"%d\"", devconfig->height()); + fprintf(m_output, " vbend=\"%d\"", devconfig->visible_area().min_y); + fprintf(m_output, " vbstart=\"%d\"", devconfig->visible_area().max_y+1); } - fprintf(out, " />\n"); + fprintf(m_output, " />\n"); } } -/*------------------------------------------------- - print_game_sound - print a list of all the - displays --------------------------------------------------*/ +//------------------------------------------------- +// output_sound - print a list of all the +// displays +//------------------------------------------------ -static void print_game_sound(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_sound() { - int speakers = config.m_devicelist.count(SPEAKER); + int speakers = m_drivlist.config().m_devicelist.count(SPEAKER); - /* if we have no sound, zero out the speaker count */ + // if we have no sound, zero m_output the speaker count const device_config_sound_interface *sound = NULL; - if (!config.m_devicelist.first(sound)) + if (!m_drivlist.config().m_devicelist.first(sound)) speakers = 0; - fprintf(out, "\t\t<sound channels=\"%d\"/>\n", speakers); + fprintf(m_output, "\t\t<sound channels=\"%d\"/>\n", speakers); } -/*------------------------------------------------- - print_game_driver - print driver status --------------------------------------------------*/ +//------------------------------------------------- +// output_input - print a summary of a game's +// input +//------------------------------------------------- -static void print_game_driver(FILE *out, const game_driver *game, const machine_config &config) +void info_xml_creator::output_input(const ioport_list &portlist) { - fprintf(out, "\t\t<driver"); + // enumerated list of control types + enum + { + ANALOG_TYPE_JOYSTICK, + ANALOG_TYPE_DIAL, + ANALOG_TYPE_TRACKBALL, + ANALOG_TYPE_PADDLE, + ANALOG_TYPE_LIGHTGUN, + ANALOG_TYPE_PEDAL, + ANALOG_TYPE_COUNT + }; + + // directions + const UINT8 DIR_LEFTRIGHT = 0x01; + const UINT8 DIR_UPDOWN = 0x02; + const UINT8 DIR_4WAY = 0x04; + const UINT8 DIR_DUAL = 0x08; + + // initialize the list of control types + struct + { + const char * type; /* general type of input */ + bool analog; + bool keyb; + INT32 min; /* analog minimum value */ + INT32 max; /* analog maximum value */ + INT32 sensitivity; /* default analog sensitivity */ + INT32 keydelta; /* default analog keydelta */ + bool reverse; /* default analog reverse setting */ + } control_info[ANALOG_TYPE_COUNT]; + + memset(&control_info, 0, sizeof(control_info)); + + // tracking info as we iterate + int nplayer = 0; + int nbutton = 0; + int ncoin = 0; + UINT8 joytype = 0; + bool service = false; + bool tilt = false; + bool keypad = false; + bool keyboard = false; + + // iterate over the ports + for (const input_port_config *port = portlist.first(); port != NULL; port = port->next()) + for (const input_field_config *field = port->fieldlist; field != NULL; field = field->next) + { + int analogtype = -1; + + // track the highest player number + if (nplayer < field->player + 1) + nplayer = field->player + 1; + + // switch off of the type + switch (field->type) + { + // map which joystick directions are present + case IPT_JOYSTICKRIGHT_LEFT: + case IPT_JOYSTICKRIGHT_RIGHT: + case IPT_JOYSTICKLEFT_LEFT: + case IPT_JOYSTICKLEFT_RIGHT: + joytype |= DIR_DUAL; + // fall through... + + case IPT_JOYSTICK_LEFT: + case IPT_JOYSTICK_RIGHT: + joytype |= DIR_LEFTRIGHT | ((field->way == 4) ? DIR_4WAY : 0); + break; + + case IPT_JOYSTICKRIGHT_UP: + case IPT_JOYSTICKRIGHT_DOWN: + case IPT_JOYSTICKLEFT_UP: + case IPT_JOYSTICKLEFT_DOWN: + joytype |= DIR_DUAL; + // fall through... + + case IPT_JOYSTICK_UP: + case IPT_JOYSTICK_DOWN: + joytype |= DIR_UPDOWN | ((field->way == 4) ? DIR_4WAY : 0); + break; + + // mark as an analog input, and get analog stats after switch + case IPT_PADDLE: + control_info[analogtype = ANALOG_TYPE_PADDLE].type = "paddle"; + break; + + case IPT_DIAL: + control_info[analogtype = ANALOG_TYPE_DIAL].type = "dial"; + analogtype = ANALOG_TYPE_DIAL; + break; + + case IPT_TRACKBALL_X: + case IPT_TRACKBALL_Y: + control_info[analogtype = ANALOG_TYPE_TRACKBALL].type = "trackball"; + analogtype = ANALOG_TYPE_TRACKBALL; + break; + + case IPT_AD_STICK_X: + case IPT_AD_STICK_Y: + control_info[analogtype = ANALOG_TYPE_JOYSTICK].type = "stick"; + break; + + case IPT_LIGHTGUN_X: + case IPT_LIGHTGUN_Y: + control_info[analogtype = ANALOG_TYPE_LIGHTGUN].type = "lightgun"; + break; + + case IPT_PEDAL: + case IPT_PEDAL2: + case IPT_PEDAL3: + control_info[analogtype = ANALOG_TYPE_PEDAL].type = "pedal"; + break; + + // track maximum button index + case IPT_BUTTON1: + case IPT_BUTTON2: + case IPT_BUTTON3: + case IPT_BUTTON4: + case IPT_BUTTON5: + case IPT_BUTTON6: + case IPT_BUTTON7: + case IPT_BUTTON8: + case IPT_BUTTON9: + case IPT_BUTTON10: + case IPT_BUTTON11: + case IPT_BUTTON12: + case IPT_BUTTON13: + case IPT_BUTTON14: + case IPT_BUTTON15: + case IPT_BUTTON16: + nbutton = MAX(nbutton, field->type - IPT_BUTTON1 + 1); + break; + + // track maximum coin index + case IPT_COIN1: + case IPT_COIN2: + case IPT_COIN3: + case IPT_COIN4: + case IPT_COIN5: + case IPT_COIN6: + case IPT_COIN7: + case IPT_COIN8: + ncoin = MAX(ncoin, field->type - IPT_COIN1 + 1); + break; + + // track presence of these guys + case IPT_KEYPAD: + keypad = true; + break; + + case IPT_KEYBOARD: + keyboard = true; + break; + + // additional types + case IPT_SERVICE: + service = true; + break; + + case IPT_TILT: + tilt = true; + break; + } + + // get the analog stats + if (analogtype != -1) + { + if (field->min != 0) + control_info[analogtype].min = field->min; + if (field->max != 0) + control_info[analogtype].max = field->max; + if (field->sensitivity != 0) + control_info[analogtype].sensitivity = field->sensitivity; + if (field->delta != 0) + control_info[analogtype].keydelta = field->delta; + if ((field->flags & ANALOG_FLAG_REVERSE) != 0) + control_info[analogtype].reverse = true; + } + } + + // output the basic info + fprintf(m_output, "\t\t<input"); + fprintf(m_output, " players=\"%d\"", nplayer); + if (nbutton != 0) + fprintf(m_output, " buttons=\"%d\"", nbutton); + if (ncoin != 0) + fprintf(m_output, " coins=\"%d\"", ncoin); + if (service) + fprintf(m_output, " service=\"yes\""); + if (tilt) + fprintf(m_output, " tilt=\"yes\""); + fprintf(m_output, ">\n"); + + // output the joystick types + if (joytype != 0) + { + const char *vertical = ((joytype & DIR_LEFTRIGHT) == 0) ? "v" : ""; + const char *doubletype = ((joytype & DIR_DUAL) != 0) ? "doublejoy" : "joy"; + const char *way = ((joytype & DIR_LEFTRIGHT) == 0 || (joytype & DIR_UPDOWN) == 0) ? "2way" : ((joytype & DIR_4WAY) != 0) ? "4way" : "8way"; + fprintf(m_output, "\t\t\t<control type=\"%s%s%s\"/>\n", vertical, doubletype, way); + } + + // output analog types + for (int type = 0; type < ANALOG_TYPE_COUNT; type++) + if (control_info[type].type != NULL) + { + fprintf(m_output, "\t\t\t<control type=\"%s\"", xml_normalize_string(control_info[type].type)); + if (control_info[type].min != 0 || control_info[type].max != 0) + { + fprintf(m_output, " minimum=\"%d\"", control_info[type].min); + fprintf(m_output, " maximum=\"%d\"", control_info[type].max); + } + if (control_info[type].sensitivity != 0) + fprintf(m_output, " sensitivity=\"%d\"", control_info[type].sensitivity); + if (control_info[type].keydelta != 0) + fprintf(m_output, " keydelta=\"%d\"", control_info[type].keydelta); + if (control_info[type].reverse) + fprintf(m_output, " reverse=\"yes\""); + + fprintf(m_output, "/>\n"); + } + + // output keypad and keyboard + if (keypad) + fprintf(m_output, "\t\t\t<control type=\"keypad\"/>\n"); + if (keyboard) + fprintf(m_output, "\t\t\t<control type=\"keyboard\"/>\n"); + + fprintf(m_output, "\t\t</input>\n"); +} + + +//------------------------------------------------- +// output_switches - print the configurations or +// DIP switch settings +//------------------------------------------------- + +void info_xml_creator::output_switches(const ioport_list &portlist, int type, const char *outertag, const char *innertag) +{ + // iterate looking for DIP switches + for (const input_port_config *port = portlist.first(); port != NULL; port = port->next()) + for (const input_field_config *field = port->fieldlist; field != NULL; field = field->next) + if (field->type == type) + { + // output the switch name information + fprintf(m_output, "\t\t<%s name=\"%s\"", outertag, xml_normalize_string(input_field_name(field))); + fprintf(m_output, " tag=\"%s\"", xml_normalize_string(field->port->tag)); + fprintf(m_output, " mask=\"%u\"", field->mask); + fprintf(m_output, ">\n"); + + // loop over settings + for (const input_setting_config *setting = field->settinglist; setting != NULL; setting = setting->next) + { + fprintf(m_output, "\t\t\t<%s name=\"%s\"", innertag, xml_normalize_string(setting->name)); + fprintf(m_output, " value=\"%u\"", setting->value); + if (setting->value == field->defvalue) + fprintf(m_output, " default=\"yes\""); + fprintf(m_output, "/>\n"); + } + + // terminate the switch entry + fprintf(m_output, "\t\t</%s>\n", outertag); + } +} + + +//------------------------------------------------- +// output_adjusters - print the Analog +// Adjusters for a game +//------------------------------------------------- + +void info_xml_creator::output_adjusters(const ioport_list &portlist) +{ + // iterate looking for Adjusters + for (const input_port_config *port = portlist.first(); port != NULL; port = port->next()) + for (const input_field_config *field = port->fieldlist; field != NULL; field = field->next) + if (field->type == IPT_ADJUSTER) + fprintf(m_output, "\t\t<adjuster name=\"%s\" default=\"%d\"/>\n", xml_normalize_string(input_field_name(field)), field->defvalue); +} + + +//------------------------------------------------- +// output_driver - print driver status +//------------------------------------------------- + +void info_xml_creator::output_driver() +{ + fprintf(m_output, "\t\t<driver"); /* The status entry is an hint for frontend authors */ /* to select working and not working games without */ @@ -837,444 +959,210 @@ static void print_game_driver(FILE *out, const game_driver *game, const machine_ /* some minor issues, games marked as status=preliminary */ /* don't work or have major emulation problems. */ - if (game->flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_NO_SOUND | GAME_WRONG_COLORS)) - fprintf(out, " status=\"preliminary\""); - else if (game->flags & (GAME_IMPERFECT_COLORS | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS)) - fprintf(out, " status=\"imperfect\""); + if (m_drivlist.driver().flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_NO_SOUND | GAME_WRONG_COLORS)) + fprintf(m_output, " status=\"preliminary\""); + else if (m_drivlist.driver().flags & (GAME_IMPERFECT_COLORS | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS)) + fprintf(m_output, " status=\"imperfect\""); else - fprintf(out, " status=\"good\""); + fprintf(m_output, " status=\"good\""); - if (game->flags & GAME_NOT_WORKING) - fprintf(out, " emulation=\"preliminary\""); + if (m_drivlist.driver().flags & GAME_NOT_WORKING) + fprintf(m_output, " emulation=\"preliminary\""); else - fprintf(out, " emulation=\"good\""); + fprintf(m_output, " emulation=\"good\""); - if (game->flags & GAME_WRONG_COLORS) - fprintf(out, " color=\"preliminary\""); - else if (game->flags & GAME_IMPERFECT_COLORS) - fprintf(out, " color=\"imperfect\""); + if (m_drivlist.driver().flags & GAME_WRONG_COLORS) + fprintf(m_output, " color=\"preliminary\""); + else if (m_drivlist.driver().flags & GAME_IMPERFECT_COLORS) + fprintf(m_output, " color=\"imperfect\""); else - fprintf(out, " color=\"good\""); + fprintf(m_output, " color=\"good\""); - if (game->flags & GAME_NO_SOUND) - fprintf(out, " sound=\"preliminary\""); - else if (game->flags & GAME_IMPERFECT_SOUND) - fprintf(out, " sound=\"imperfect\""); + if (m_drivlist.driver().flags & GAME_NO_SOUND) + fprintf(m_output, " sound=\"preliminary\""); + else if (m_drivlist.driver().flags & GAME_IMPERFECT_SOUND) + fprintf(m_output, " sound=\"imperfect\""); else - fprintf(out, " sound=\"good\""); + fprintf(m_output, " sound=\"good\""); - if (game->flags & GAME_IMPERFECT_GRAPHICS) - fprintf(out, " graphic=\"imperfect\""); + if (m_drivlist.driver().flags & GAME_IMPERFECT_GRAPHICS) + fprintf(m_output, " graphic=\"imperfect\""); else - fprintf(out, " graphic=\"good\""); + fprintf(m_output, " graphic=\"good\""); - if (game->flags & GAME_NO_COCKTAIL) - fprintf(out, " cocktail=\"preliminary\""); + if (m_drivlist.driver().flags & GAME_NO_COCKTAIL) + fprintf(m_output, " cocktail=\"preliminary\""); - if (game->flags & GAME_UNEMULATED_PROTECTION) - fprintf(out, " protection=\"preliminary\""); + if (m_drivlist.driver().flags & GAME_UNEMULATED_PROTECTION) + fprintf(m_output, " protection=\"preliminary\""); - if (game->flags & GAME_SUPPORTS_SAVE) - fprintf(out, " savestate=\"supported\""); + if (m_drivlist.driver().flags & GAME_SUPPORTS_SAVE) + fprintf(m_output, " savestate=\"supported\""); else - fprintf(out, " savestate=\"unsupported\""); + fprintf(m_output, " savestate=\"unsupported\""); - fprintf(out, " palettesize=\"%d\"", config.m_total_colors); + fprintf(m_output, " palettesize=\"%d\"", m_drivlist.config().m_total_colors); - fprintf(out, "/>\n"); + fprintf(m_output, "/>\n"); } -/*------------------------------------------------- - print_game_categories - print the Categories - settings for a system --------------------------------------------------*/ -static void print_game_categories(FILE *out, const game_driver *game, const ioport_list &portlist) -{ - const input_port_config *port; - const input_field_config *field; +//------------------------------------------------- +// output_categories - print the Categories +// settings for a system +//------------------------------------------------- - /* iterate looking for Categories */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist; field != NULL; field = field->next) +void info_xml_creator::output_categories(const ioport_list &portlist) +{ + // iterate looking for Categories + for (const input_port_config *port = portlist.first(); port != NULL; port = port->next()) + for (const input_field_config *field = port->fieldlist; field != NULL; field = field->next) if (field->type == IPT_CATEGORY) { - const input_setting_config *setting; - - /* output the category name information */ - fprintf(out, "\t\t<category name=\"%s\">\n", xml_normalize_string(input_field_name(field))); + // output the category name information + fprintf(m_output, "\t\t<category name=\"%s\">\n", xml_normalize_string(input_field_name(field))); - /* loop over item settings */ - for (setting = field->settinglist; setting != NULL; setting = setting->next) + // loop over item settings + for (const input_setting_config *setting = field->settinglist; setting != NULL; setting = setting->next) { - fprintf(out, "\t\t\t<item name=\"%s\"", xml_normalize_string(setting->name)); + fprintf(m_output, "\t\t\t<item name=\"%s\"", xml_normalize_string(setting->name)); if (setting->value == field->defvalue) - fprintf(out, " default=\"yes\""); - fprintf(out, "/>\n"); + fprintf(m_output, " default=\"yes\""); + fprintf(m_output, "/>\n"); } - /* terminate the category entry */ - fprintf(out, "\t\t</category>\n"); + // terminate the category entry + fprintf(m_output, "\t\t</category>\n"); } } -/*------------------------------------------------- - print_game_images - prints out all info on - image devices --------------------------------------------------*/ -static void print_game_images(FILE *out, const game_driver *game, const machine_config &config) +//------------------------------------------------- +// output_images - prints m_output all info on +// image devices +//------------------------------------------------- + +void info_xml_creator::output_images() { const device_config_image_interface *dev = NULL; - const char *name; - const char *shortname; - - for (bool gotone = config.m_devicelist.first(dev); gotone; gotone = dev->next(dev)) + for (bool gotone = m_drivlist.config().m_devicelist.first(dev); gotone; gotone = dev->next(dev)) { - /* print out device type */ - fprintf(out, "\t\t<device type=\"%s\"", xml_normalize_string(dev->image_type_name())); + // print m_output device type + fprintf(m_output, "\t\t<device type=\"%s\"", xml_normalize_string(dev->image_type_name())); - /* does this device have a tag? */ + // does this device have a tag? if (dev->devconfig().tag()) - fprintf(out, " tag=\"%s\"", xml_normalize_string(dev->devconfig().tag())); + fprintf(m_output, " tag=\"%s\"", xml_normalize_string(dev->devconfig().tag())); - /* is this device mandatory? */ + // is this device mandatory? if (dev->must_be_loaded()) - fprintf(out, " mandatory=\"1\""); + fprintf(m_output, " mandatory=\"1\""); - if (dev->image_interface()[0] ) - fprintf(out, " interface=\"%s\"", xml_normalize_string(dev->image_interface())); + if (dev->image_interface()[0]) + fprintf(m_output, " interface=\"%s\"", xml_normalize_string(dev->image_interface())); - /* close the XML tag */ - fprintf(out, ">\n"); + // close the XML tag + fprintf(m_output, ">\n"); - name = dev->instance_name(); - shortname = dev->brief_instance_name(); + const char *name = dev->instance_name(); + const char *shortname = dev->brief_instance_name(); - fprintf(out, "\t\t\t<instance"); - fprintf(out, " name=\"%s\"", xml_normalize_string(name)); - fprintf(out, " briefname=\"%s\"", xml_normalize_string(shortname)); - fprintf(out, "/>\n"); + fprintf(m_output, "\t\t\t<instance"); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(name)); + fprintf(m_output, " briefname=\"%s\"", xml_normalize_string(shortname)); + fprintf(m_output, "/>\n"); astring extensions(dev->file_extensions()); - char *ext = strtok((char*)extensions.cstr(),","); + char *ext = strtok((char *)extensions.cstr(), ","); while (ext != NULL) { - fprintf(out, "\t\t\t<extension"); - fprintf(out, " name=\"%s\"", xml_normalize_string(ext)); - fprintf(out, "/>\n"); - ext = strtok (NULL, ","); + fprintf(m_output, "\t\t\t<extension"); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(ext)); + fprintf(m_output, "/>\n"); + ext = strtok(NULL, ","); } - fprintf(out, "\t\t</device>\n"); + fprintf(m_output, "\t\t</device>\n"); } } -/*------------------------------------------------- - print_game_software_list - print the information - for all known software lists for this system --------------------------------------------------*/ -static void print_game_software_list(FILE *out, const game_driver *game, const machine_config &config) +//------------------------------------------------- +// output_software_list - print the information +// for all known software lists for this system +//------------------------------------------------- + +void info_xml_creator::output_software_list() { - for (const device_config *dev = config.m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + for (const device_config *dev = m_drivlist.config().m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { software_list_config *swlist = (software_list_config *)downcast<const legacy_device_config_base *>(dev)->inline_config(); - for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ ) - { - if ( swlist->list_name[i] ) + for (int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++) + if (swlist->list_name[i]) { - fprintf(out, "\t\t<softwarelist name=\"%s\" ", swlist->list_name[i] ); - fprintf(out, "status=\"%s\" />\n", (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible" ); + fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist->list_name[i]); + fprintf(m_output, "status=\"%s\" />\n", (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible"); } - } } } -/* device iteration helpers */ -#define ram_first(config) (config).m_devicelist.first(RAM) -#define ram_next(previous) ((previous)->typenext()) -/*------------------------------------------------- - print_game_ramoptions - prints out all RAM - options for this system --------------------------------------------------*/ -static void print_game_ramoptions(FILE *out, const game_driver *game, const machine_config &config) -{ - const device_config *device; - for (device = ram_first(config); device != NULL; device = ram_next(device)) +//------------------------------------------------- +// output_ramoptions - prints m_output all RAM +// options for this system +//------------------------------------------------- + +void info_xml_creator::output_ramoptions() +{ + for (const device_config *device = m_drivlist.config().m_devicelist.first(RAM); device != NULL; device = device->typenext()) { ram_config *ram = (ram_config *)downcast<const legacy_device_config_base *>(device)->inline_config(); - fprintf(out, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram_parse_string(ram->default_size)); + fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram_parse_string(ram->default_size)); + if (ram->extra_options != NULL) { - int j; - int size = strlen(ram->extra_options); - char * const s = mame_strdup(ram->extra_options); - char * const e = s + size; - char *p = s; - for (j=0;j<size;j++) { - if (p[j]==',') p[j]=0; - } - /* try to parse each option */ - while(p <= e) + astring options(ram->extra_options); + for (int start, end = options.chr(0, ','); ; start = end + 1, end = options.chr(start, ',')) { - fprintf(out, "\t\t<ramoption>%u</ramoption>\n", ram_parse_string(p)); - p += strlen(p); - if (p == e) + astring option; + option.cpysubstr(options, start, (end == -1) ? -1 : end - start); + fprintf(m_output, "\t\t<ramoption>%u</ramoption>\n", ram_parse_string(option)); + if (end == -1) break; - p += 1; } - - osd_free(s); } } } -/*------------------------------------------------- - print_game_info - print the XML information - for one particular game driver --------------------------------------------------*/ - -static void print_game_info(FILE *out, const game_driver *game, emu_options &options) -{ - const game_driver *clone_of; - machine_config config(*game, options); - ioport_list portlist; - const char *start; - - /* no action if not a game */ - if (game->flags & GAME_NO_STANDALONE) - return; - /* start tracking resources and allocate the machine and input configs */ - input_port_list_init(portlist, game->ipt, NULL, 0, FALSE, NULL); - for (device_config *cfg = config.m_devicelist.first(); cfg != NULL; cfg = cfg->next()) - { - if (cfg->input_ports() != NULL) - input_port_list_init(portlist, cfg->input_ports(), NULL, 0, FALSE, cfg); - } - - /* print the header and the game name */ - fprintf(out, "\t<" XML_TOP); - fprintf(out, " name=\"%s\"", xml_normalize_string(game->name) ); +//------------------------------------------------- +// get_merge_name - get the rom name from a +// parent set +//------------------------------------------------- - /* strip away any path information from the source_file and output it */ - start = strrchr(game->source_file, '/'); - if (start == NULL) - start = strrchr(game->source_file, '\\'); - if (start == NULL) - start = game->source_file - 1; - fprintf(out, " sourcefile=\"%s\"", xml_normalize_string(start + 1)); - - /* append bios and runnable flags */ - if (game->flags & GAME_IS_BIOS_ROOT) - fprintf(out, " isbios=\"yes\""); - if (game->flags & GAME_NO_STANDALONE) - fprintf(out, " runnable=\"no\""); - if (game->flags & GAME_MECHANICAL) - fprintf(out, " ismechanical=\"yes\""); - - /* display clone information */ - clone_of = driver_get_clone(game); - if (clone_of != NULL && !(clone_of->flags & GAME_IS_BIOS_ROOT)) - fprintf(out, " cloneof=\"%s\"", xml_normalize_string(clone_of->name)); - if (clone_of != NULL) - fprintf(out, " romof=\"%s\"", xml_normalize_string(clone_of->name)); - - /* display sample information and close the game tag */ - print_game_sampleof(out, game, config); - fprintf(out, ">\n"); - - /* output game description */ - if (game->description != NULL) - fprintf(out, "\t\t<description>%s</description>\n", xml_normalize_string(game->description)); - - /* print the year only if is a number or another allowed character (? or +) */ - if (game->year != NULL && strspn(game->year, "0123456789?+") == strlen(game->year)) - fprintf(out, "\t\t<year>%s</year>\n", xml_normalize_string(game->year)); - - /* print the manufacturer information */ - if (game->manufacturer != NULL) - fprintf(out, "\t\t<manufacturer>%s</manufacturer>\n", xml_normalize_string(game->manufacturer)); - - /* now print various additional information */ - print_game_bios(out, game); - print_game_rom(out, game, config); - print_game_sample(out, game, config); - print_game_chips(out, game, config); - print_game_display(out, game, config); - print_game_sound(out, game, config); - print_game_input(out, game, portlist); - print_game_switches(out, game, portlist); - print_game_configs(out, game, portlist); - print_game_categories(out, game, portlist); - print_game_adjusters(out, game, portlist); - print_game_driver(out, game, config); - print_game_images( out, game, config ); - print_game_software_list( out, game, config ); - print_game_ramoptions( out, game, config ); - /* close the topmost tag */ - fprintf(out, "\t</" XML_TOP ">\n"); -} - - -/*------------------------------------------------- - print_mame_xml - print the XML information - for all known games --------------------------------------------------*/ - -void print_mame_xml(FILE *out, const game_driver *const games[], const char *gamename, emu_options &options) +const char *info_xml_creator::get_merge_name(const hash_collection &romhashes) { - int drvnum; - - fprintf(out, - "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE " XML_ROOT " [\n" - "<!ELEMENT " XML_ROOT " (" XML_TOP "+)>\n" - "\t<!ATTLIST " XML_ROOT " build CDATA #IMPLIED>\n" - "\t<!ATTLIST " XML_ROOT " debug (yes|no) \"no\">\n" - "\t<!ATTLIST " XML_ROOT " mameconfig CDATA #REQUIRED>\n" - "\t<!ELEMENT " XML_TOP " (description, year?, manufacturer, biosset*, rom*, disk*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, category*, adjuster*, driver?, device*, softwarelist*, ramoption*)>\n" - "\t\t<!ATTLIST " XML_TOP " name CDATA #REQUIRED>\n" - "\t\t<!ATTLIST " XML_TOP " sourcefile CDATA #IMPLIED>\n" - "\t\t<!ATTLIST " XML_TOP " isbios (yes|no) \"no\">\n" - "\t\t<!ATTLIST " XML_TOP " ismechanical (yes|no) \"no\">\n" - "\t\t<!ATTLIST " XML_TOP " runnable (yes|no) \"yes\">\n" - "\t\t<!ATTLIST " XML_TOP " cloneof CDATA #IMPLIED>\n" - "\t\t<!ATTLIST " XML_TOP " romof CDATA #IMPLIED>\n" - "\t\t<!ATTLIST " XML_TOP " sampleof CDATA #IMPLIED>\n" - "\t\t<!ELEMENT description (#PCDATA)>\n" - "\t\t<!ELEMENT year (#PCDATA)>\n" - "\t\t<!ELEMENT manufacturer (#PCDATA)>\n" - "\t\t<!ELEMENT biosset EMPTY>\n" - "\t\t\t<!ATTLIST biosset name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST biosset description CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST biosset default (yes|no) \"no\">\n" - "\t\t<!ELEMENT rom EMPTY>\n" - "\t\t\t<!ATTLIST rom name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST rom bios CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom md5 CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom merge CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom region CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" - "\t\t\t<!ATTLIST rom optional (yes|no) \"no\">\n" - "\t\t<!ELEMENT disk EMPTY>\n" - "\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST disk md5 CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST disk merge CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST disk region CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST disk index CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n" - "\t\t\t<!ATTLIST disk optional (yes|no) \"no\">\n" - "\t\t<!ELEMENT sample EMPTY>\n" - "\t\t\t<!ATTLIST sample name CDATA #REQUIRED>\n" - "\t\t<!ELEMENT chip EMPTY>\n" - "\t\t\t<!ATTLIST chip name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST chip tag CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST chip type (cpu|audio) #REQUIRED>\n" - "\t\t\t<!ATTLIST chip clock CDATA #IMPLIED>\n" - "\t\t<!ELEMENT display EMPTY>\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 flipx (yes|no) \"no\">\n" - "\t\t\t<!ATTLIST display width CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display height CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display refresh CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST display pixclock CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display htotal CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display hbend CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display hbstart CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display vtotal CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display vbend CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST display vbstart CDATA #IMPLIED>\n" - "\t\t<!ELEMENT sound EMPTY>\n" - "\t\t\t<!ATTLIST sound channels CDATA #REQUIRED>\n" - "\t\t<!ELEMENT input (control*)>\n" - "\t\t\t<!ATTLIST input service (yes|no) \"no\">\n" - "\t\t\t<!ATTLIST input tilt (yes|no) \"no\">\n" - "\t\t\t<!ATTLIST input players CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST input buttons CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST input coins CDATA #IMPLIED>\n" - "\t\t\t<!ELEMENT control EMPTY>\n" - "\t\t\t\t<!ATTLIST control type CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST control minimum CDATA #IMPLIED>\n" - "\t\t\t\t<!ATTLIST control maximum CDATA #IMPLIED>\n" - "\t\t\t\t<!ATTLIST control sensitivity CDATA #IMPLIED>\n" - "\t\t\t\t<!ATTLIST control keydelta CDATA #IMPLIED>\n" - "\t\t\t\t<!ATTLIST control reverse (yes|no) \"no\">\n" - "\t\t<!ELEMENT dipswitch (dipvalue*)>\n" - "\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n" - "\t\t\t<!ELEMENT dipvalue EMPTY>\n" - "\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" - "\t\t<!ELEMENT configuration (confsetting*)>\n" - "\t\t\t<!ATTLIST configuration name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST configuration tag CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST configuration mask CDATA #REQUIRED>\n" - "\t\t\t<!ELEMENT confsetting EMPTY>\n" - "\t\t\t\t<!ATTLIST confsetting name CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST confsetting value CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST confsetting default (yes|no) \"no\">\n" - "\t\t<!ELEMENT category (item*)>\n" - "\t\t\t<!ATTLIST category name CDATA #REQUIRED>\n" - "\t\t\t<!ELEMENT item EMPTY>\n" - "\t\t\t\t<!ATTLIST item name CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST item default (yes|no) \"no\">\n" - "\t\t<!ELEMENT adjuster EMPTY>\n" - "\t\t\t<!ATTLIST adjuster name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST adjuster default CDATA #REQUIRED>\n" - "\t\t<!ELEMENT driver EMPTY>\n" - "\t\t\t<!ATTLIST driver status (good|imperfect|preliminary) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver emulation (good|imperfect|preliminary) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver color (good|imperfect|preliminary) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver sound (good|imperfect|preliminary) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver graphic (good|imperfect|preliminary) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver cocktail (good|imperfect|preliminary) #IMPLIED>\n" - "\t\t\t<!ATTLIST driver protection (good|imperfect|preliminary) #IMPLIED>\n" - "\t\t\t<!ATTLIST driver savestate (supported|unsupported) #REQUIRED>\n" - "\t\t\t<!ATTLIST driver palettesize CDATA #REQUIRED>\n" - "\t\t<!ELEMENT device (instance*, extension*)>\n" - "\t\t\t<!ATTLIST device type CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST device tag CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST device mandatory CDATA #IMPLIED>\n" - "\t\t\t<!ATTLIST device interface CDATA #IMPLIED>\n" - "\t\t\t<!ELEMENT instance EMPTY>\n" - "\t\t\t\t<!ATTLIST instance name CDATA #REQUIRED>\n" - "\t\t\t\t<!ATTLIST instance briefname CDATA #REQUIRED>\n" - "\t\t\t<!ELEMENT extension EMPTY>\n" - "\t\t\t\t<!ATTLIST extension name CDATA #REQUIRED>\n" - "\t\t<!ELEMENT softwarelist EMPTY>\n" - "\t\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" - "\t\t\t<!ATTLIST softwarelist status (original|compatible) #REQUIRED>\n" - "\t\t<!ELEMENT ramoption (#PCDATA)>\n" - "\t\t\t<!ATTLIST ramoption default CDATA #IMPLIED>\n" - "]>\n\n" - "<" XML_ROOT " build=\"%s\" debug=\"" -#ifdef MAME_DEBUG - "yes" -#else - "no" -#endif - "\" mameconfig=\"%d\">\n", - xml_normalize_string(build_version), - CONFIG_VERSION - ); - - for (drvnum = 0; games[drvnum] != NULL; drvnum++) - if (mame_strwildcmp(gamename, games[drvnum]->name) == 0) - print_game_info(out, games[drvnum], options); + const char *merge_name = NULL; + + // walk the parent chain + 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)) + + // look in the parent's ROMs + for (const rom_source *psource = rom_first_source(m_drivlist.config(clone_of)); psource != NULL; psource = rom_next_source(*psource)) + for (const rom_entry *pregion = rom_first_region(*psource); pregion != NULL; pregion = rom_next_region(pregion)) + for (const rom_entry *prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom)) + { + hash_collection phashes(ROM_GETHASHDATA(prom)); + if (!phashes.flag(hash_collection::FLAG_NO_DUMP) && romhashes == phashes) + { + // stop when we find a match + merge_name = ROM_GETNAME(prom); + break; + } + } - fprintf(out, "</" XML_ROOT ">\n"); + return merge_name; } |