void info_xml_creator::output_sampleof() { // iterate over sample devices samples_device_iterator iter(m_drivlist.config().root_device()); for (samples_device *device = iter.first(); device != NULL; device = iter.next()) { const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames; if (samplenames != NULL) // iterate over sample names for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) { // 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)); // must stop here, as there can only be one attribute of the same name return; } } }
void info_xml_creator::output(FILE *out) { m_output = out; // output the DTD fprintf(m_output, "<?xml version=\"1.0\"?>\n"); astring dtd(s_dtd_string); dtd.replace(0,"__XML_ROOT__", emulator_info::get_xml_root()); dtd.replace(0,"__XML_TOP__", emulator_info::get_xml_top()); fprintf(m_output, "%s\n\n", dtd.cstr()); // top-level tag fprintf(m_output, "<%s build=\"%s\" debug=\"" #ifdef MAME_DEBUG "yes" #else "no" #endif "\" mameconfig=\"%d\">\n", emulator_info::get_xml_root(), xml_normalize_string(build_version), CONFIG_VERSION ); m_device_used = global_alloc_array_clear(UINT8, m_device_count); // iterate through the drivers, outputting one at a time while (m_drivlist.next()) output_one(); // iterate through the devices, and output their roms output_devices(); global_free(m_device_used); // close the top level tag fprintf(m_output, "</%s>\n",emulator_info::get_xml_root()); }
static void print_game_sample(FILE *out, const game_driver *game, const machine_config *config) { #if (HAS_SAMPLES) const device_config *device; /* iterate over sound chips looking for samples */ for (device = sound_first(config); device != NULL; device = sound_next(device)) if (sound_get_type(device) == SOUND_SAMPLES) { const char *const *samplenames = ((const samples_interface *)device->static_config)->samplenames; if (samplenames != NULL) { 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; /* filter out duplicates */ 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)); } } } #endif }
void info_xml_creator::output_images() { const device_image_interface *dev = NULL; for (bool gotone = m_drivlist.config().devicelist().first(dev); gotone; gotone = dev->next(dev)) { // 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? if (dev->device().tag()) fprintf(m_output, " tag=\"%s\"", xml_normalize_string(dev->device().tag())); // is this device mandatory? if (dev->must_be_loaded()) fprintf(m_output, " mandatory=\"1\""); if (dev->image_interface() && dev->image_interface()[0]) fprintf(m_output, " interface=\"%s\"", xml_normalize_string(dev->image_interface())); // close the XML tag fprintf(m_output, ">\n"); const char *name = dev->instance_name(); const char *shortname = dev->brief_instance_name(); 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(), ","); while (ext != 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(m_output, "\t\t</device>\n"); } }
void print_mame_xml(FILE *out, const game_driver *const games[], const char *gamename) { 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" #ifdef MESS "\t<!ELEMENT " XML_TOP " (description, year?, manufacturer, biosset*, rom*, disk*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, category*, adjuster*, driver?, device*, ramoption*)>\n" #else "\t<!ELEMENT " XML_TOP " (description, year?, manufacturer, biosset*, rom*, disk*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, adjuster*, driver?)>\n" #endif "\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 " 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<!ELEMENT dipvalue EMPTY>\n" "\t\t\t\t<!ATTLIST dipvalue name 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<!ELEMENT confsetting EMPTY>\n" "\t\t\t\t<!ATTLIST confsetting name CDATA #REQUIRED>\n" "\t\t\t\t<!ATTLIST confsetting default (yes|no) \"no\">\n" #ifdef MESS "\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" #endif "\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" #ifdef MESS "\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<!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 ramoption (#PCDATA)>\n" "\t\t\t<!ATTLIST ramoption default CDATA #IMPLIED>\n" #endif "]>\n\n" "<" XML_ROOT " build=\"%s\" debug=\"" #ifdef MAME_DEBUG "yes" #else "no" #endif "\">\n", xml_normalize_string(build_version) ); for (drvnum = 0; games[drvnum] != NULL; drvnum++) if (mame_strwildcmp(gamename, games[drvnum]->name) == 0) print_game_info(out, games[drvnum]); fprintf(out, "</" XML_ROOT ">\n"); }
static void print_game_info(FILE *out, const game_driver *game) { const input_port_config *portconfig; const game_driver *clone_of; machine_config *config; 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 */ config = machine_config_alloc(game->machine_config); #ifdef MESS /* temporary hook until MESS device transition is complete */ mess_devices_setup(NULL, config, game); #endif /* MESS */ portconfig = input_port_config_alloc(game->ipt, NULL, 0); /* print the header and the game name */ fprintf(out, "\t<" XML_TOP); fprintf(out, " name=\"%s\"", xml_normalize_string(game->name) ); /* 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\""); /* 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 */ 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, portconfig); print_game_switches(out, game, portconfig); print_game_configs(out, game, portconfig); #ifdef MESS print_game_categories(out, game, portconfig); #endif /* MESS */ print_game_adjusters(out, game, portconfig); print_game_driver(out, game, config); #ifdef MESS print_game_device(out, game, config); print_game_ramoptions(out, game, config); #endif /* MESS */ /* close the topmost tag */ fprintf(out, "\t</" XML_TOP ">\n"); input_port_config_free(portconfig); machine_config_free(config); }
static void print_game_rom(FILE *out, const game_driver *game, const machine_config *config) { const game_driver *clone_of = driver_get_clone(game); int rom_type; machine_config *pconfig = (clone_of != NULL) ? machine_config_alloc(clone_of->machine_config) : NULL; /* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */ for (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(game, config); source != NULL; source = rom_next_source(game, config, source)) for (region = rom_first_region(game, source); region != NULL; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); const rom_entry *rom; /* 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)) { int is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const rom_entry *parent_rom = NULL; char bios_name[100]; /* 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 (!ROM_NOGOODDUMP(rom) && clone_of != NULL) { const rom_source *psource; const rom_entry *pregion, *prom; /* scan the clone_of ROM for a matching ROM entry */ for (psource = rom_first_source(clone_of, pconfig); psource != NULL; psource = rom_next_source(clone_of, pconfig, psource)) for (pregion = rom_first_region(clone_of, psource); pregion != NULL; pregion = rom_next_region(pregion)) for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0)) { parent_rom = prom; break; } } /* 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--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); break; } } /* opening tag */ if (!is_disk) fprintf(out, "\t\t<rom"); else fprintf(out, "\t\t<disk"); /* add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) fprintf(out, " name=\"%s\"", xml_normalize_string(name)); if (parent_rom != NULL) fprintf(out, " merge=\"%s\"", xml_normalize_string(ROM_GETNAME(parent_rom))); if (bios_name[0] != 0) fprintf(out, " bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) fprintf(out, " size=\"%d\"", rom_file_size(rom)); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { char checksum[HASH_BUF_SIZE]; int hashtype; /* iterate over hash function types and print out their values */ for (hashtype = 0; hashtype < HASH_NUM_FUNCTIONS; hashtype++) if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), 1 << hashtype, checksum)) fprintf(out, " %s=\"%s\"", hash_function_name(1 << hashtype), checksum); } /* append a region name */ fprintf(out, " region=\"%s\"", ROMREGION_GETTAG(region)); /* add nodump/baddump flags */ if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) fprintf(out, " status=\"nodump\""); if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP)) fprintf(out, " status=\"baddump\""); /* for non-disk entries, print offset */ if (!is_disk) fprintf(out, " offset=\"%x\"", offset); /* for disk entries, add the disk index */ else fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); /* add optional flag */ if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom))) fprintf(out, " optional=\"yes\""); fprintf(out, "/>\n"); } } } if (pconfig != NULL) machine_config_free(pconfig); }
static void print_game_input(FILE *out, const game_driver *game, const input_port_config *portlist) { /* fix me -- this needs to be cleaned up to match the core style */ enum {cjoy, cdoublejoy, cAD_stick, cdial, ctrackball, cpaddle, clightgun, cpedal, 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"}; static struct _input_info { const char * type; /* general type of input */ const char * Xway; /* 2, 4, or 8 way */ int analog; 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++) { control[i].type = control_types[i]; control[i].Xway = NULL; control[i].analog = 0; control[i].min = 0; control[i].max = 0; control[i].sensitivity = 0; control[i].keydelta = 0; control[i].reverse = 0; } for (port = portlist; port != NULL; port = port->next) for (field = port->fieldlist; field != NULL; field = field->next) { if (nplayer < field->player+1) nplayer = field->player+1; switch (field->type) { 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: /* 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; } /* 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); } 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"); } } fprintf(out, "\t\t</input>\n"); }
void info_xml_creator::output_input(const ioport_list &portlist) { // enumerated list of control types enum { ANALOG_TYPE_PADDLE, ANALOG_TYPE_PEDAL, ANALOG_TYPE_JOYSTICK, ANALOG_TYPE_POSITIONAL, ANALOG_TYPE_LIGHTGUN, ANALOG_TYPE_DIAL, ANALOG_TYPE_TRACKBALL, ANALOG_TYPE_MOUSE, ANALOG_TYPE_COUNT }; // directions const UINT8 DIR_UP = 0x01; const UINT8 DIR_DOWN = 0x02; const UINT8 DIR_LEFT = 0x04; const UINT8 DIR_RIGHT = 0x08; const UINT8 DIR_4WAY = 0x10; // 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[3] = { 0,0,0 }; bool service = false; bool tilt = false; bool keypad = false; bool keyboard = false; bool mahjong = false; bool hanafuda = false; bool gambling = false; // iterate over the ports for (ioport_port *port = portlist.first(); port != NULL; port = port->next()) for (ioport_field *field = port->first_field(); 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_JOYSTICK_UP: joytype[0] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICK_DOWN: joytype[0] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICK_LEFT: joytype[0] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICK_RIGHT: joytype[0] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKLEFT_UP: joytype[1] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKLEFT_DOWN: joytype[1] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKLEFT_LEFT: joytype[1] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKLEFT_RIGHT: joytype[1] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKRIGHT_UP: joytype[2] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKRIGHT_DOWN: joytype[2] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKRIGHT_LEFT: joytype[2] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; case IPT_JOYSTICKRIGHT_RIGHT: joytype[2] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; // mark as an analog input, and get analog stats after switch case IPT_AD_STICK_X: case IPT_AD_STICK_Y: case IPT_AD_STICK_Z: control_info[analogtype = ANALOG_TYPE_JOYSTICK].type = "stick"; break; case IPT_PADDLE: case IPT_PADDLE_V: control_info[analogtype = ANALOG_TYPE_PADDLE].type = "paddle"; break; case IPT_PEDAL: case IPT_PEDAL2: case IPT_PEDAL3: control_info[analogtype = ANALOG_TYPE_PEDAL].type = "pedal"; break; case IPT_LIGHTGUN_X: case IPT_LIGHTGUN_Y: control_info[analogtype = ANALOG_TYPE_LIGHTGUN].type = "lightgun"; break; case IPT_POSITIONAL: case IPT_POSITIONAL_V: control_info[analogtype = ANALOG_TYPE_POSITIONAL].type = "positional"; break; case IPT_DIAL: case IPT_DIAL_V: control_info[analogtype = ANALOG_TYPE_DIAL].type = "dial"; break; case IPT_TRACKBALL_X: case IPT_TRACKBALL_Y: control_info[analogtype = ANALOG_TYPE_TRACKBALL].type = "trackball"; break; case IPT_MOUSE_X: case IPT_MOUSE_Y: control_info[analogtype = ANALOG_TYPE_MOUSE].type = "mouse"; 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; default: if (field->type() > IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST) mahjong = true; else if (field->type() > IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST) hanafuda = true; else if (field->type() > IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST) gambling = true; break; } // get the analog stats if (analogtype != -1) { if (field->minval() != 0) control_info[analogtype].min = field->minval(); if (field->maxval() != 0) control_info[analogtype].max = field->maxval(); if (field->sensitivity() != 0) control_info[analogtype].sensitivity = field->sensitivity(); if (field->delta() != 0) control_info[analogtype].keydelta = field->delta(); if (field->analog_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[1]==0 && joytype[2]!=0) { joytype[1] = joytype[2]; joytype[2] = 0; } if (joytype[0]==0 && joytype[1]!=0) { joytype[0] = joytype[1]; joytype[1] = 0; } if (joytype[1]==0 && joytype[2]!=0) { joytype[1] = joytype[2]; joytype[2] = 0; } if (joytype[0] != 0) { const char *joys = (joytype[2]!=0) ? "triple" : (joytype[1]!=0) ? "double" : ""; fprintf(m_output, "\t\t\t<control type=\"%sjoy\"", joys); for (int lp=0; lp<3 && joytype[lp]!=0; lp++) { const char *plural = (lp==2) ? "3" : (lp==1) ? "2" : ""; const char *ways; switch (joytype[lp] & (DIR_UP | DIR_DOWN | DIR_LEFT | DIR_RIGHT)) { case DIR_UP | DIR_DOWN | DIR_LEFT | DIR_RIGHT: ways = ((joytype[lp] & DIR_4WAY) != 0) ? "4" : "8"; break; case DIR_LEFT | DIR_RIGHT: ways = "2"; break; case DIR_UP | DIR_DOWN: ways = "vertical2"; break; case DIR_UP: case DIR_DOWN: case DIR_LEFT: case DIR_RIGHT: ways = "1"; break; case DIR_UP | DIR_DOWN | DIR_LEFT: case DIR_UP | DIR_DOWN | DIR_RIGHT: case DIR_UP | DIR_LEFT | DIR_RIGHT: case DIR_DOWN | DIR_LEFT | DIR_RIGHT: ways = ((joytype[lp] & DIR_4WAY) != 0) ? "3 (half4)" : "5 (half8)"; break; default: ways = "strange2"; break; } fprintf(m_output, " ways%s=\"%s\"", plural,ways); } fprintf(m_output, "/>\n"); } // 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"); // misc if (mahjong) fprintf(m_output, "\t\t\t<control type=\"mahjong\"/>\n"); if (hanafuda) fprintf(m_output, "\t\t\t<control type=\"hanafuda\"/>\n"); if (gambling) fprintf(m_output, "\t\t\t<control type=\"gambling\"/>\n"); fprintf(m_output, "\t\t</input>\n"); }
void info_xml_creator::output_display(device_t &device, const char *root_tag) { // iterate over screens screen_device_iterator iter(device); for (const screen_device *screendev = iter.first(); screendev != NULL; screendev = iter.next()) { if (strcmp(screendev->tag(), device.tag())) { astring newtag(screendev->tag()), oldtag(":"); newtag.substr(newtag.find(oldtag.cat(root_tag)) + oldtag.len()); fprintf(m_output, "\t\t<display"); fprintf(m_output, " tag=\"%s\"", xml_normalize_string(newtag)); switch (screendev->screen_type()) { 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 (m_drivlist.driver().flags & ORIENTATION_MASK) { case ORIENTATION_FLIP_X: fprintf(m_output, " rotate=\"0\" flipx=\"yes\""); break; case ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"180\" flipx=\"yes\""); break; case ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"180\""); break; case ORIENTATION_SWAP_XY: fprintf(m_output, " rotate=\"90\" flipx=\"yes\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X: fprintf(m_output, " rotate=\"90\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"270\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"270\" flipx=\"yes\""); break; default: fprintf(m_output, " rotate=\"0\""); break; } // output width and height only for games that are not vector if (screendev->screen_type() != SCREEN_TYPE_VECTOR) { const rectangle &visarea = screendev->visible_area(); fprintf(m_output, " width=\"%d\"", visarea.width()); fprintf(m_output, " height=\"%d\"", visarea.height()); } // output refresh rate fprintf(m_output, " refresh=\"%f\"", ATTOSECONDS_TO_HZ(screendev->refresh_attoseconds())); // output raw video parameters only for games that are not vector // and had raw parameters specified if (screendev->screen_type() != SCREEN_TYPE_VECTOR && !screendev->oldstyle_vblank_supplied()) { int pixclock = screendev->width() * screendev->height() * ATTOSECONDS_TO_HZ(screendev->refresh_attoseconds()); fprintf(m_output, " pixclock=\"%d\"", pixclock); fprintf(m_output, " htotal=\"%d\"", screendev->width()); fprintf(m_output, " hbend=\"%d\"", screendev->visible_area().min_x); fprintf(m_output, " hbstart=\"%d\"", screendev->visible_area().max_x+1); fprintf(m_output, " vtotal=\"%d\"", screendev->height()); fprintf(m_output, " vbend=\"%d\"", screendev->visible_area().min_y); fprintf(m_output, " vbstart=\"%d\"", screendev->visible_area().max_y+1); } fprintf(m_output, " />\n"); } } }
void info_xml_creator::output_rom(device_t &device) { // iterate over 3 different ROM "types": BIOS, ROMs, DISKs for (int rom_type = 0; rom_type < 3; rom_type++) for (const rom_entry *region = rom_first_region(device); region != NULL; region = rom_next_region(region)) { bool is_disk = ROMREGION_ISDISKDATA(region); // disk regions only work for disks if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; // iterate through ROM entries for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(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 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 hash_collection hashes(ROM_GETHASHDATA(rom)); if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) merge_name = get_merge_name(hashes); if (&device != &m_drivlist.config().root_device()) merge_name = NULL; // scan for a BIOS name bios_name[0] = 0; if (!is_disk && is_bios) { // 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)); break; } } astring output; // opening tag if (!is_disk) output.cat("\t\t<rom"); else output.cat("\t\t<disk"); // add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) output.catprintf(" name=\"%s\"", xml_normalize_string(name)); if (merge_name != NULL) output.catprintf(" merge=\"%s\"", xml_normalize_string(merge_name)); if (bios_name[0] != 0) output.catprintf(" bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) output.catprintf(" size=\"%d\"", rom_file_size(rom)); // 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 m_output their values astring tempstr; output.catprintf(" %s", hashes.attribute_string(tempstr)); } else output.cat(" status=\"nodump\""); // append a region name output.catprintf(" region=\"%s\"", ROMREGION_GETTAG(region)); // for non-disk entries, print offset if (!is_disk) output.catprintf(" offset=\"%x\"", offset); // for disk entries, add the disk index else { output.catprintf(" index=\"%x\"", DISK_GETINDEX(rom)); output.catprintf(" writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes"); } // add optional flag if (ROM_ISOPTIONAL(rom)) output.cat(" optional=\"yes\""); output.cat("/>\n"); fprintf(m_output, "%s", output.cstr()); } } }
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; // allocate input ports machine_config &config = m_drivlist.config(); ioport_list portlist; astring errors; device_iterator iter(config.root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) portlist.append(*device, errors); // print the header and the game name fprintf(m_output, "\t<%s",emulator_info::get_xml_top()); fprintf(m_output, " name=\"%s\"", xml_normalize_string(driver.name)); // strip away any path information from the source_file and output it const char *start = strrchr(driver.source_file, '/'); if (start == 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(m_drivlist.config().root_device()); output_device_roms(); output_sample(m_drivlist.config().root_device()); output_chips(m_drivlist.config().root_device(), ""); output_display(m_drivlist.config().root_device(), ""); output_sound(m_drivlist.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_images(m_drivlist.config().root_device(), ""); output_slots(m_drivlist.config().root_device(), ""); output_software_list(); output_ramoptions(); // close the topmost tag fprintf(m_output, "\t</%s>\n",emulator_info::get_xml_top()); }
void info_xml_creator::output_input(const ioport_list &portlist) { // 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 (input_port_config *port = portlist.first(); port != NULL; port = port->next()) for (input_field_config *field = port->fieldlist().first(); 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"); }
static int info_listsoftware(core_options *options, const char *gamename) { FILE *out = stdout; int nr_lists = 0; char ** lists = NULL; int list_idx = 0; /* First determine the maximum number of lists we might encounter */ for ( int drvindex = 0; drivers[drvindex] != NULL; drvindex++ ) { if ( mame_strwildcmp( gamename, drivers[drvindex]->name ) == 0 ) { /* allocate the machine config */ machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); for (const device_config *dev = 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] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)) nr_lists++; } } /* free the machine config */ global_free(config); } } lists = global_alloc_array( char *, nr_lists ); fprintf( out, "<?xml version=\"1.0\"?>\n" "<!DOCTYPE softwarelist [\n" "<!ELEMENT softwarelists (softwarelist*)>\n" "\t<!ELEMENT softwarelist (software+)>\n" "\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" "\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" "\t\t<!ELEMENT software (description, year?, publisher, part*)>\n" "\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" "\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" "\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" "\t\t\t<!ELEMENT description (#PCDATA)>\n" "\t\t\t<!ELEMENT year (#PCDATA)>\n" "\t\t\t<!ELEMENT publisher (#PCDATA)>\n" "\t\t\t<!ELEMENT part (dataarea*)>\n" "\t\t\t\t<!ATTLIST part name CDATA #REQUIRED>\n" "\t\t\t\t<!ATTLIST part interface CDATA #REQUIRED>\n" "\t\t\t\t<!ATTLIST part feature CDATA #IMPLIED>\n" "\t\t\t\t<!ELEMENT dataarea (rom*)>\n" "\t\t\t\t\t<!ATTLIST dataarea name CDATA #REQUIRED>\n" "\t\t\t\t\t<!ATTLIST dataarea size CDATA #REQUIRED>\n" "\t\t\t\t\t<!ATTLIST dataarea databits (8|16|32|64) \"8\">\n" "\t\t\t\t\t<!ATTLIST dataarea endian (big|little) \"little\">\n" "\t\t\t\t\t<!ELEMENT rom EMPTY>\n" "\t\t\t\t\t\t<!ATTLIST rom name CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n" "\t\t\t\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom md5 CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" "\t\t\t\t\t\t<!ATTLIST rom loadflag (load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload) #IMPLIED>\n" "]>\n\n" "<softwarelists>\n" ); for ( int drvindex = 0; drivers[drvindex] != NULL; drvindex++ ) { if ( mame_strwildcmp( gamename, drivers[drvindex]->name ) == 0 ) { /* allocate the machine config */ machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); for (const device_config *dev = 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] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)) { software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); if ( list ) { /* Verify if we have encountered this list before */ bool seen_before = false; for ( int l = 0; l < list_idx && !seen_before; l++ ) { if ( ! strcmp( swlist->list_name[i], lists[l] ) ) { seen_before = true; } } if ( ! seen_before ) { lists[list_idx] = core_strdup( swlist->list_name[i] ); list_idx++; fprintf(out, "\t<softwarelist name=\"%s\">\n", swlist->list_name[i] ); for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { fprintf( out, "\t\t<software name=\"%s\"", swinfo->shortname ); if ( swinfo->parentname != NULL ) fprintf( out, " cloneof=\"%s\"", swinfo->parentname ); if ( swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL ) fprintf( out, " supported=\"partial\"" ); if ( swinfo->supported == SOFTWARE_SUPPORTED_NO ) fprintf( out, " supported=\"no\"" ); fprintf( out, ">\n" ); fprintf( out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo->longname) ); fprintf( out, "\t\t\t<year>%s</year>\n", xml_normalize_string( swinfo->year ) ); fprintf( out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string( swinfo->publisher ) ); for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) { fprintf( out, "\t\t\t<part name=\"%s\"", part->name ); if ( part->interface_ ) fprintf( out, " interface=\"%s\"", part->interface_ ); // if ( part->feature ) // fprintf( out, " features=\"%s\"", part->feature ); fprintf( out, ">\n"); /* TODO: display rom region information */ for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) ) { fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%x\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) ); for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ ) { if ( ROMENTRY_ISFILE(rom) ) { fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) ); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { char checksum[HASH_BUF_SIZE]; int hashtype; /* iterate over hash function types and print out their values */ for (hashtype = 0; hashtype < HASH_NUM_FUNCTIONS; hashtype++) if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), 1 << hashtype, checksum)) fprintf(out, " %s=\"%s\"", hash_function_name(1 << hashtype), checksum); } fprintf( out, " offset=\"%x\"", ROM_GETOFFSET(rom) ); if ( hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP) ) fprintf( out, " status=\"baddump\"" ); if ( hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP) ) fprintf( out, " status=\"nodump\"" ); fprintf( out, "/>\n" ); } else if ( ROMENTRY_ISRELOAD(rom) ) { fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); } } fprintf( out, "\t\t\t\t</dataarea>\n" ); } fprintf( out, "\t\t\t</part>\n" ); } fprintf( out, "\t\t</software>\n" ); } fprintf(out, "\t</softwarelist>\n" ); } software_list_close( list ); } } } } global_free(config); } } fprintf( out, "</softwarelists>\n" ); global_free( lists ); return MAMERR_NONE; }