summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/clifront.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/clifront.c')
-rw-r--r--src/emu/clifront.c1936
1 files changed, 935 insertions, 1001 deletions
diff --git a/src/emu/clifront.c b/src/emu/clifront.c
index 81435650c34..6035aa0e77f 100644
--- a/src/emu/clifront.c
+++ b/src/emu/clifront.c
@@ -56,42 +56,6 @@
#endif
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct romident_status
-{
- int total; /* total files processed */
- int matches; /* number of matches found */
- int nonroms; /* number of non-ROM files found */
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-static void execute_commands(cli_options &options, const char *exename);
-static void display_help(void);
-
-/* informational functions */
-static void info_verifyroms(emu_options &options, const char *gamename);
-static void info_verifysamples(emu_options &options, const char *gamename);
-static void info_romident(emu_options &options, const char *gamename);
-static void info_listmedia(emu_options &options, const char *gamename);
-static void info_listsoftware(emu_options &options, const char *gamename);
-
-/* utilities */
-static void romident(emu_options &options, const char *filename, romident_status *status);
-static void identify_file(emu_options &options, const char *name, romident_status *status);
-static void identify_data(emu_options &options, const char *name, const UINT8 *data, int length, romident_status *status);
-static void match_roms(emu_options &options, const hash_collection &hashes, int length, int *found);
-static void display_suggestions(const char *gamename);
-
-
-
//**************************************************************************
// COMMAND-LINE OPTIONS
//**************************************************************************
@@ -146,45 +110,55 @@ cli_options::cli_options()
-/***************************************************************************
- CORE IMPLEMENTATION
-***************************************************************************/
+//**************************************************************************
+// CLI FRONTEND
+//**************************************************************************
+
+//-------------------------------------------------
+// cli_frontend - constructor
+//-------------------------------------------------
+
+cli_frontend::cli_frontend(cli_options &options, osd_interface &osd)
+ : m_options(options),
+ m_osd(osd),
+ m_result(MAMERR_NONE)
+{
+ // begin tracking memory
+ track_memory(true);
+}
+
+
+//-------------------------------------------------
+// ~cli_frontend - destructor
+//-------------------------------------------------
-static void display_suggestions(const char *gamename)
+cli_frontend::~cli_frontend()
{
- const game_driver *matches[10];
- int drvnum;
-
- /* get the top 10 approximate matches */
- driver_list_get_approx_matches(drivers, gamename, ARRAY_LENGTH(matches), matches);
-
- /* print them out */
- fprintf(stderr, "\n\"%s\" approximately matches the following\n"
- "supported " GAMESNOUN " (best match first):\n\n", gamename);
- for (drvnum = 0; drvnum < ARRAY_LENGTH(matches); drvnum++)
- if (matches[drvnum] != NULL)
- fprintf(stderr, "%-18s%s\n", matches[drvnum]->name, matches[drvnum]->description);
+ // report any unfreed memory on clean exits
+ track_memory(false);
+ if (m_result == MAMERR_NONE)
+ dump_unfreed_mem();
}
//-------------------------------------------------
-// cli_execute - execute a game via the standard
+// execute - execute a game via the standard
// command line interface
//-------------------------------------------------
-int cli_execute(cli_options &options, osd_interface &osd, int argc, char **argv)
+int cli_frontend::execute(int argc, char **argv)
{
// wrap the core execution in a try/catch to field all fatal errors
- int result = MAMERR_NONE;
+ m_result = MAMERR_NONE;
try
{
// parse the command line, adding any system-specific options
astring option_errors;
- if (!options.parse_command_line(argc, argv, option_errors))
+ if (!m_options.parse_command_line(argc, argv, option_errors))
{
// if we failed, check for no command and a system name first; in that case error on the name
- if (strlen(options.command()) == 0 && options.system() == NULL && strlen(options.system_name()) > 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "Unknown system '%s'", options.system_name());
+ if (strlen(m_options.command()) == 0 && m_options.system() == NULL && strlen(m_options.system_name()) > 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "Unknown system '%s'", m_options.system_name());
// otherwise, error on the options
throw emu_fatalerror(MAMERR_INVALID_CONFIG, "%s", option_errors.trimspace().cstr());
@@ -197,19 +171,19 @@ int cli_execute(cli_options &options, osd_interface &osd, int argc, char **argv)
core_filename_extract_base(&exename, argv[0], TRUE);
// if we have a command, execute that
- if (strlen(options.command()) != 0)
- execute_commands(options, exename);
+ if (strlen(m_options.command()) != 0)
+ execute_commands(exename);
// otherwise, check for a valid system
else
{
// if we can't find it, give an appropriate error
- const game_driver *system = options.system();
- if (system == NULL && strlen(options.system_name()) > 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "Unknown system '%s'", options.system_name());
+ const game_driver *system = m_options.system();
+ if (system == NULL && strlen(m_options.system_name()) > 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "Unknown system '%s'", m_options.system_name());
// otherwise just run the game
- result = mame_execute(options, osd);
+ m_result = mame_execute(m_options, m_osd);
}
}
@@ -218,577 +192,605 @@ int cli_execute(cli_options &options, osd_interface &osd, int argc, char **argv)
{
astring string(fatal.string());
fprintf(stderr, "%s\n", string.trimspace().cstr());
- result = (fatal.exitcode() != 0) ? fatal.exitcode() : MAMERR_FATALERROR;
+ m_result = (fatal.exitcode() != 0) ? fatal.exitcode() : MAMERR_FATALERROR;
// if a game was specified, wasn't a wildcard, and our error indicates this was the
// reason for failure, offer some suggestions
- if (result == MAMERR_NO_SUCH_GAME && strlen(options.system_name()) > 0 && strchr(options.system_name(), '*') == NULL && options.system() == NULL)
- display_suggestions(options.system_name());
+ if (m_result == MAMERR_NO_SUCH_GAME && strlen(m_options.system_name()) > 0 && strchr(m_options.system_name(), '*') == NULL && m_options.system() == NULL)
+ {
+ // get the top 10 approximate matches
+ driver_enumerator drivlist(m_options);
+ int matches[10];
+ drivlist.find_approximate_matches(m_options.system_name(), ARRAY_LENGTH(matches), matches);
+
+ // print them out
+ fprintf(stderr, "\n\"%s\" approximately matches the following\n"
+ "supported " GAMESNOUN " (best match first):\n\n", m_options.system_name());
+ for (int matchnum = 0; matchnum < ARRAY_LENGTH(matches); matchnum++)
+ if (matches[matchnum] != -1)
+ fprintf(stderr, "%-18s%s\n", drivlist.driver(matches[matchnum]).name, drivlist.driver(matches[matchnum]).description);
+ }
}
catch (emu_exception &)
{
fprintf(stderr, "Caught unhandled emulator exception\n");
- result = MAMERR_FATALERROR;
+ m_result = MAMERR_FATALERROR;
}
catch (std::bad_alloc &)
{
fprintf(stderr, "Out of memory!\n");
- result = MAMERR_FATALERROR;
+ m_result = MAMERR_FATALERROR;
}
// handle any other exceptions
catch (...)
{
fprintf(stderr, "Caught unhandled exception\n");
- result = MAMERR_FATALERROR;
+ m_result = MAMERR_FATALERROR;
}
- // report any unfreed memory on clean exits
- if (result == MAMERR_NONE)
- dump_unfreed_mem();
- return result;
+ return m_result;
}
//-------------------------------------------------
-// execute_commands - execute various frontend
-// commands
+// listxml - output the XML data for one or more
+// games
//-------------------------------------------------
-static void execute_commands(cli_options &options, const char *exename)
+void cli_frontend::listxml(const char *gamename)
{
- // help?
- if (strcmp(options.command(), CLICOMMAND_HELP) == 0)
- {
- display_help();
- return;
- }
-
- // showusage?
- if (strcmp(options.command(), CLICOMMAND_SHOWUSAGE) == 0)
- {
- astring helpstring;
-#ifndef MESS
- mame_printf_info("Usage: %s [%s] [options]\n\nOptions:\n%s", exename, GAMENOUN, options.output_help(helpstring));
-#else
- mame_printf_info("Usage: %s [%s] [media] [software] [options]\n\nOptions:\n%s", exename, GAMENOUN, options.output_help(helpstring));
-#endif
- return;
- }
-
- // validate?
- if (strcmp(options.command(), CLICOMMAND_VALIDATE) == 0)
- {
- validate_drivers(options);
- return;
- }
-
- // other commands need the INIs parsed
- astring option_errors;
- options.parse_standard_inis(option_errors);
- if (option_errors)
- printf("%s\n", option_errors.cstr());
-
- // createconfig?
- if (strcmp(options.command(), CLICOMMAND_CREATECONFIG) == 0)
- {
- // attempt to open the output file
- emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(CONFIGNAME ".ini") != FILERR_NONE)
- throw emu_fatalerror("Unable to create file " CONFIGNAME ".ini\n");
-
- // generate the updated INI
- astring initext;
- file.puts(options.output_ini(initext));
- return;
- }
-
- // showconfig?
- if (strcmp(options.command(), CLICOMMAND_SHOWCONFIG) == 0)
- {
- // print the INI text
- astring initext;
- printf("%s\n", options.output_ini(initext));
- return;
- }
-
- // all other commands call out to one of these helpers
- static const struct
- {
- const char *option;
- void (*function)(emu_options &options, const char *gamename);
- } info_commands[] =
- {
- { CLICOMMAND_LISTXML, cli_info_listxml },
- { CLICOMMAND_LISTFULL, cli_info_listfull },
- { CLICOMMAND_LISTSOURCE, cli_info_listsource },
- { CLICOMMAND_LISTCLONES, cli_info_listclones },
- { CLICOMMAND_LISTBROTHERS, cli_info_listbrothers },
- { CLICOMMAND_LISTCRC, cli_info_listcrc },
- { CLICOMMAND_LISTDEVICES, cli_info_listdevices },
- { CLICOMMAND_LISTROMS, cli_info_listroms },
- { CLICOMMAND_LISTSAMPLES, cli_info_listsamples },
- { CLICOMMAND_VERIFYROMS, info_verifyroms },
- { CLICOMMAND_VERIFYSAMPLES, info_verifysamples },
- { CLICOMMAND_LISTMEDIA, info_listmedia },
- { CLICOMMAND_LISTSOFTWARE, info_listsoftware },
- { CLICOMMAND_ROMIDENT, info_romident }
- };
-
- // find the command
- for (int cmdindex = 0; cmdindex < ARRAY_LENGTH(info_commands); cmdindex++)
- if (strcmp(options.command(), info_commands[cmdindex].option) == 0)
- {
- // parse any relevant INI files before proceeding
- const char *sysname = options.system_name();
- (*info_commands[cmdindex].function)(options, (sysname[0] == 0) ? "*" : sysname);
- return;
- }
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- // if we get here, we don't know what has been requested
- throw emu_fatalerror(MAMERR_INVALID_CONFIG, "Unknown command '%s' specified", options.command());
+ // create the XML and print it to stdout
+ info_xml_creator creator(drivlist);
+ creator.output(stdout);
}
-/*-------------------------------------------------
- display_help - display help to standard
- output
--------------------------------------------------*/
-
-static void display_help(void)
+//-------------------------------------------------
+// listfull - output the name and description of
+// one or more games
+//-------------------------------------------------
+
+void cli_frontend::listfull(const char *gamename)
{
-#ifndef MESS
- mame_printf_info("M.A.M.E. v%s - Multiple Arcade Machine Emulator\n"
- "Copyright Nicola Salmoria and the MAME Team\n\n", build_version);
- mame_printf_info("%s\n", mame_disclaimer);
- mame_printf_info("Usage: MAME gamename [options]\n\n"
- " MAME -showusage for a brief list of options\n"
- " MAME -showconfig for a list of configuration options\n"
- " MAME -createconfig to create a " CONFIGNAME ".ini\n\n"
- "For usage instructions, please consult the file windows.txt\n");
-#else
- mess_display_help();
-#endif
-}
-
-
-
-/***************************************************************************
- INFORMATIONAL FUNCTIONS
-***************************************************************************/
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
-/*-------------------------------------------------
- cli_info_listxml - output the XML data for one
- or more games
--------------------------------------------------*/
+ // print the header
+ mame_printf_info("Name: Description:\n");
-void cli_info_listxml(emu_options &options, const char *gamename)
-{
- print_mame_xml(stdout, drivers, gamename, options);
+ // iterate through drivers and output the info
+ while (drivlist.next())
+ if ((drivlist.driver().flags & GAME_NO_STANDALONE) == 0)
+ mame_printf_info("%-18s\"%s\"\n", drivlist.driver().name, drivlist.driver().description);
}
-/*-------------------------------------------------
- cli_info_listfull - output the name and
- description of one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// listsource - output the name and source
+// filename of one or more games
+//-------------------------------------------------
-void cli_info_listfull(emu_options &options, const char *gamename)
+void cli_frontend::listsource(const char *gamename)
{
- int count = 0;
-
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if ((drivers[drvindex]->flags & GAME_NO_STANDALONE) == 0 && mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- /* print the header on the first one */
- if (count == 0)
- mame_printf_info("Name: Description:\n");
-
- /* output the remaining information */
- mame_printf_info("%-18s\"%s\"\n", drivers[drvindex]->name, drivers[drvindex]->description);
- count++;
- }
-
- /* return an error if none found */
- if (count == 0)
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+
+ // iterate through drivers and output the info
+ astring filename;
+ while (drivlist.next())
+ mame_printf_info("%-16s %s\n", drivlist.driver().name, core_filename_extract_base(&filename, drivlist.driver().source_file, FALSE)->cstr());
}
-/*-------------------------------------------------
- cli_info_listsource - output the name and source
- filename of one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// listclones - output the name and parent of all
+// clones matching the given pattern
+//-------------------------------------------------
-void cli_info_listsource(emu_options &options, const char *gamename)
+void cli_frontend::listclones(const char *gamename)
{
- int count = 0;
- astring filename;
+ // start with a filtered list of drivers
+ driver_enumerator drivlist(m_options, gamename);
+ int original_count = drivlist.count();
+
+ // iterate through the remaining ones to see if their parent matches
+ while (drivlist.next_excluded())
+ {
+ // if we have a non-bios clone and it matches, keep it
+ int clone_of = drivlist.clone();
+ if (clone_of != -1 && (drivlist.driver(clone_of).flags & GAME_IS_BIOS_ROOT) == 0)
+ if (drivlist.matches(gamename, drivlist.driver(clone_of).name))
+ drivlist.include();
+ }
+
+ // return an error if none found
+ if (drivlist.count() == 0)
+ {
+ // see if we match but just weren't a clone
+ if (original_count == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+ else
+ mame_printf_info("Found %d matches for '%s' but none were clones\n", drivlist.count(), gamename);
+ return;
+ }
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- /* output the remaining information */
- mame_printf_info("%-16s %s\n", drivers[drvindex]->name, core_filename_extract_base(&filename, drivers[drvindex]->source_file, FALSE)->cstr());
- count++;
- }
+ // print the header
+ mame_printf_info("Name: Clone of:\n");
- /* return an error if none found */
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+ // iterate through drivers and output the info
+ drivlist.reset();
+ while (drivlist.next())
+ {
+ int clone_of = drivlist.clone();
+ if (clone_of != -1)
+ mame_printf_info("%-16s %-8s\n", drivlist.driver().name, drivlist.driver(clone_of).name);
+ }
}
-/*-------------------------------------------------
- cli_info_listclones - output the name and source
- filename of one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// listbrothers - for each matching game, output
+// the list of other games that share the same
+// source file
+//-------------------------------------------------
-void cli_info_listclones(emu_options &options, const char *gamename)
+void cli_frontend::listbrothers(const char *gamename)
{
- int count = 0, drvcnt = 0;
-
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- drvcnt++;
-
- if (drvcnt == 0)
+ // start with a filtered list of drivers; return an error if none found
+ driver_enumerator initial_drivlist(m_options, gamename);
+ if (initial_drivlist.count() == 0)
throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- {
- const game_driver *clone_of = driver_get_clone(drivers[drvindex]);
+ // for the final list, start with an empty driver list
+ driver_enumerator drivlist(m_options);
+ drivlist.exclude_all();
- /* if we are a clone, and either our name matches the gamename, or the clone's name matches, display us */
- if (clone_of != NULL && (clone_of->flags & GAME_IS_BIOS_ROOT) == 0)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0 || mame_strwildcmp(gamename, clone_of->name) == 0)
- {
- /* print the header on the first one */
- if (count == 0)
- mame_printf_info("Name: Clone of:\n");
+ // scan through the initially-selected drivers
+ while (initial_drivlist.next())
+ {
+ // if we are already marked in the final list, we don't need to do anything
+ if (drivlist.included(initial_drivlist.current()))
+ continue;
+
+ // otherwise, walk excluded items in the final list and mark any that match
+ drivlist.reset();
+ while (drivlist.next_excluded())
+ if (strcmp(drivlist.driver().source_file, initial_drivlist.driver().source_file) == 0)
+ drivlist.include();
+ }
+
+ // print the header
+ mame_printf_info("Source file: Name: Parent:\n");
- /* output the remaining information */
- mame_printf_info("%-16s %-8s\n", drivers[drvindex]->name, clone_of->name);
- count++;
- }
+ // output the entries found
+ drivlist.reset();
+ astring filename;
+ while (drivlist.next())
+ {
+ int clone_of = drivlist.clone();
+ mame_printf_info("%-16s %-16s %-16s\n", core_filename_extract_base(&filename, drivlist.driver().source_file, FALSE)->cstr(), drivlist.driver().name, (clone_of == -1 ? "" : drivlist.driver(clone_of).name));
}
}
-/*-------------------------------------------------
- cli_info_listbrothers - output the name and
- source filename of one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// listcrc - output the CRC and name of all ROMs
+// referenced by the emulator
+//-------------------------------------------------
-void cli_info_listbrothers(emu_options &options, const char *gamename)
+void cli_frontend::listcrc(const char *gamename)
{
- UINT8 *didit = global_alloc_array_clear(UINT8, driver_list_get_count(drivers));
- int count = 0;
- astring filename;
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (!didit[drvindex] && mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- didit[drvindex] = TRUE;
- if (count > 0)
- mame_printf_info("\n");
- mame_printf_info("%s ... other drivers in %s:\n", drivers[drvindex]->name, core_filename_extract_base(&filename, drivers[drvindex]->source_file, FALSE)->cstr());
-
- /* now iterate again over drivers, finding those with the same source file */
- for (int matchindex = 0; drivers[matchindex]; matchindex++)
- if (matchindex != drvindex && strcmp(drivers[drvindex]->source_file, drivers[matchindex]->source_file) == 0)
+ // iterate through matches, and then through ROMs
+ while (drivlist.next())
+ for (const rom_source *source = rom_first_source(drivlist.config()); source != NULL; source = rom_next_source(*source))
+ for (const rom_entry *region = rom_first_region(*source); region; region = rom_next_region(region))
+ for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
{
- const char *matchstring = (mame_strwildcmp(gamename, drivers[matchindex]->name) == 0) ? "-> " : " ";
- const game_driver *clone_of = driver_get_clone(drivers[matchindex]);
-
- if (clone_of != NULL && (clone_of->flags & GAME_IS_BIOS_ROOT) == 0)
- mame_printf_info("%s%-16s [%s]\n", matchstring, drivers[matchindex]->name, clone_of->name);
- else
- mame_printf_info("%s%s\n", matchstring, drivers[matchindex]->name);
- didit[matchindex] = TRUE;
+ // if we have a CRC, display it
+ UINT32 crc;
+ if (hash_collection(ROM_GETHASHDATA(rom)).crc(crc))
+ mame_printf_info("%08x %-16s %s\n", crc, ROM_GETNAME(rom), drivlist.driver().description);
}
-
- count++;
- }
-
- /* return an error if none found */
- global_free(didit);
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
}
-/*-------------------------------------------------
- cli_info_listcrc - output the CRC and name of
- all ROMs referenced by MAME
--------------------------------------------------*/
+//-------------------------------------------------
+// listroms - output the list of ROMs referenced
+// by a given game or set of games
+//-------------------------------------------------
-void cli_info_listcrc(emu_options &options, const char *gamename)
+void cli_frontend::listroms(const char *gamename)
{
- int count = 0;
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- machine_config config(*drivers[drvindex], options);
- const rom_entry *region, *rom;
- const rom_source *source;
-
- /* iterate over sources, regions, and then ROMs within the region */
- for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source))
- for (region = rom_first_region(*source); region; region = rom_next_region(region))
- for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ // iterate through matches
+ astring tempstr;
+ bool first = true;
+ while (drivlist.next())
+ {
+ // print a header
+ if (!first)
+ mame_printf_info("\n");
+ first = false;
+ mame_printf_info("ROMs required for driver \"%s\".\n"
+ "Name Size Checksum\n", drivlist.driver().name);
+
+ // iterate through roms
+ for (const rom_source *source = rom_first_source(drivlist.config()); source != NULL; source = rom_next_source(*source))
+ for (const rom_entry *region = rom_first_region(*source); region; region = rom_next_region(region))
+ for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ {
+ // accumulate the total length of all chunks
+ int length = -1;
+ if (ROMREGION_ISROMDATA(region))
+ length = rom_file_size(rom);
+
+ // start with the name
+ const char *name = ROM_GETNAME(rom);
+ mame_printf_info("%-20s ", name);
+
+ // output the length next
+ if (length >= 0)
+ mame_printf_info("%7d", length);
+ else
+ mame_printf_info(" ");
+
+ // output the hash data
+ hash_collection hashes(ROM_GETHASHDATA(rom));
+ if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
{
- /* if we have a CRC, display it */
- UINT32 crc;
- if (hash_collection(ROM_GETHASHDATA(rom)).crc(crc))
- mame_printf_info("%08x %-12s %s\n", crc, ROM_GETNAME(rom), drivers[drvindex]->description);
+ if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
+ mame_printf_info(" BAD");
+ mame_printf_info(" %s", hashes.macro_string(tempstr));
}
+ else
+ mame_printf_info(" NO GOOD DUMP KNOWN");
- count++;
- }
-
- /* return an error if none found */
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+ // end with a CR
+ mame_printf_info("\n");
+ }
+ }
}
-/*-------------------------------------------------
- cli_info_listroms - output the list of ROMs
- referenced by a given game or set of games
--------------------------------------------------*/
+//-------------------------------------------------
+// listsamples - output the list of samples
+// referenced by a given game or set of games
+//-------------------------------------------------
-void cli_info_listroms(emu_options &options, const char *gamename)
+void cli_frontend::listsamples(const char *gamename)
{
- int count = 0;
- astring tempstr;
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- machine_config config(*drivers[drvindex], options);
-
- /* print the header */
- if (count > 0)
- mame_printf_info("\n");
- mame_printf_info("This is the list of the ROMs required for driver \"%s\".\n"
- "Name Size Checksum\n", drivers[drvindex]->name);
-
- /* iterate over sources, regions and then ROMs within the region */
- for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source))
- for (const rom_entry *region = rom_first_region(*source); region != NULL; region = rom_next_region(region))
- for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
- {
- /* accumulate the total length of all chunks */
- int length = -1;
- if (ROMREGION_ISROMDATA(region))
- length = rom_file_size(rom);
-
- /* start with the name */
- const char *name = ROM_GETNAME(rom);
- mame_printf_info("%-20s ", name);
-
- /* output the length next */
- if (length >= 0)
- mame_printf_info("%7d", length);
- else
- mame_printf_info(" ");
-
- /* output the hash data */
- hash_collection hashes(ROM_GETHASHDATA(rom));
- if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
- {
- if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
- mame_printf_info(" BAD");
- mame_printf_info(" %s", hashes.macro_string(tempstr));
- }
- else
- mame_printf_info(" NO GOOD DUMP KNOWN");
+ // iterate over drivers, looking for SAMPLES devices
+ bool first = true;
+ while (drivlist.next())
+ {
+ // see if we have samples
+ const device_config *devconfig;
+ for (devconfig = drivlist.config().first_device(); devconfig != NULL; devconfig = devconfig->next())
+ if (devconfig->type() == SAMPLES)
+ break;
+ if (devconfig == NULL)
+ continue;
+
+ // print a header
+ if (!first)
+ mame_printf_info("\n");
+ first = false;
+ mame_printf_info("Samples required for driver \"%s\".\n", drivlist.driver().name);
+
+ // iterate over samples devices
+ for ( ; devconfig != NULL; devconfig = devconfig->next())
+ if (devconfig->type() == SAMPLES)
+ {
+ // if the list is legit, walk it and print the sample info
+ const char *const *samplenames = reinterpret_cast<const samples_interface *>(devconfig->static_config())->samplenames;
+ if (samplenames != NULL)
+ for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++)
+ if (samplenames[sampnum][0] != '*')
+ mame_printf_info("%s\n", samplenames[sampnum]);
+ }
+ }
+}
- /* end with a CR */
- mame_printf_info("\n");
- }
- count++;
- }
+//-------------------------------------------------
+// listdevices - output the list of devices
+// referenced by a given game or set of games
+//-------------------------------------------------
- if (count == 0)
+void cli_frontend::listdevices(const char *gamename)
+{
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+
+ // iterate over drivers, looking for SAMPLES devices
+ bool first = true;
+ while (drivlist.next())
+ {
+ // print a header
+ if (!first)
+ printf("\n");
+ first = false;
+ printf("Driver %s (%s):\n", drivlist.driver().name, drivlist.driver().description);
+
+ // iterate through devices
+ for (const device_config *devconfig = drivlist.config().first_device(); devconfig != NULL; devconfig = devconfig->next())
+ {
+ printf(" %s ('%s')", devconfig->name(), devconfig->tag());
+
+ UINT32 clock = devconfig->clock();
+ if (clock >= 1000000000)
+ printf(" @ %d.%02d GHz\n", clock / 1000000000, (clock / 10000000) % 100);
+ else if (clock >= 1000000)
+ printf(" @ %d.%02d MHz\n", clock / 1000000, (clock / 10000) % 100);
+ else if (clock >= 1000)
+ printf(" @ %d.%02d kHz\n", clock / 1000, (clock / 10) % 100);
+ else if (clock > 0)
+ printf(" @ %d Hz\n", clock);
+ else
+ printf("\n");
+ }
+ }
}
-/*-------------------------------------------------
- cli_info_listsamples - output the list of samples
- referenced by a given game or set of games
--------------------------------------------------*/
+//-------------------------------------------------
+// listmedia - output the list of image devices
+// referenced by a given game or set of games
+//-------------------------------------------------
-void cli_info_listsamples(emu_options &options, const char *gamename)
+void cli_frontend::listmedia(const char *gamename)
{
- int count = 0;
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- machine_config config(*drivers[drvindex], options);
- const device_config_sound_interface *sound = NULL;
+ // print header
+ printf(" SYSTEM MEDIA NAME (brief) IMAGE FILE EXTENSIONS SUPPORTED \n");
+ printf("---------- -------------------- ------------------------------------\n");
- /* find samples interfaces */
- 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;
- int sampnum;
+ // iterate over drivers
+ while (drivlist.next())
+ {
+ // iterate
+ const device_config_image_interface *imagedev = NULL;
+ bool first = true;
+ for (bool gotone = drivlist.config().m_devicelist.first(imagedev); gotone; gotone = imagedev->next(imagedev))
+ {
+ // extract the shortname with parentheses
+ astring paren_shortname;
+ paren_shortname.format("(%s)", imagedev->brief_instance_name());
- /* if the list is legit, walk it and print the sample info */
- if (samplenames != NULL)
- for (sampnum = 0; samplenames[sampnum] != NULL; sampnum++)
- mame_printf_info("%s\n", samplenames[sampnum]);
- }
+ // output the line, up to the list of extensions
+ printf("%-13s%-12s%-8s ", first ? drivlist.driver().name : "", imagedev->instance_name(), paren_shortname.cstr());
- count++;
+ // get the extensions and print them
+ astring extensions(imagedev->file_extensions());
+ for (int start = 0, end = extensions.chr(0, ','); ; start = end + 1, end = extensions.chr(start, ','))
+ {
+ astring curext(extensions, start, (end == -1) ? -1 : end - 1);
+ printf(".%-5s", curext.cstr());
+ if (end == -1)
+ break;
+ }
+
+ // end the line
+ printf("\n");
+ first = false;
}
-
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+
+ // if we didn't get any at all, just print a none line
+ if (first)
+ printf("%-13s(none)\n", drivlist.driver().name);
+ }
}
-/*-------------------------------------------------
- cli_info_listdevices - output the list of
- devices referenced by a given game or set of
- games
--------------------------------------------------*/
+//-------------------------------------------------
+// verifyroms - verify the ROM sets of one or
+// more games
+//-------------------------------------------------
-void cli_info_listdevices(emu_options &options, const char *gamename)
+void cli_frontend::verifyroms(const char *gamename)
{
- int count = 0;
-
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- machine_config config(*drivers[drvindex], options);
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- if (count != 0)
- printf("\n");
- printf("Driver %s (%s):\n", drivers[drvindex]->name, drivers[drvindex]->description);
+ int correct = 0;
+ int incorrect = 0;
+ int notfound = 0;
- /* iterate through devices */
- for (const device_config *devconfig = config.m_devicelist.first(); devconfig != NULL; devconfig = devconfig->next())
+ // iterate over drivers
+ media_auditor auditor(drivlist);
+ while (drivlist.next())
+ {
+ // audit the ROMs in this set
+ media_auditor::summary summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
+
+ // output the summary of the audit
+ astring summary_string;
+ auditor.summarize(&summary_string);
+ mame_printf_info("%s", summary_string.cstr());
+
+ // if not found, count that and leave it at that
+ if (summary == media_auditor::NOTFOUND)
+ notfound++;
+
+ // else display information about what we discovered
+ else
+ {
+ // output the name of the driver and its clone
+ mame_printf_info("romset %s ", drivlist.driver().name);
+ int clone_of = drivlist.clone();
+ if (clone_of != -1)
+ mame_printf_info("[%s] ", drivlist.driver(clone_of).name);
+
+ // switch off of the result
+ switch (summary)
{
- printf(" %s ('%s')", devconfig->name(), devconfig->tag());
-
- UINT32 clock = devconfig->clock();
- if (clock >= 1000000000)
- printf(" @ %d.%02d GHz\n", clock / 1000000000, (clock / 10000000) % 100);
- else if (clock >= 1000000)
- printf(" @ %d.%02d MHz\n", clock / 1000000, (clock / 10000) % 100);
- else if (clock >= 1000)
- printf(" @ %d.%02d kHz\n", clock / 1000, (clock / 10) % 100);
- else if (clock > 0)
- printf(" @ %d Hz\n", clock);
- else
- printf("\n");
+ case media_auditor::INCORRECT:
+ mame_printf_info("is bad\n");
+ incorrect++;
+ break;
+
+ case media_auditor::CORRECT:
+ mame_printf_info("is good\n");
+ correct++;
+ break;
+
+ case media_auditor::BEST_AVAILABLE:
+ mame_printf_info("is best available\n");
+ correct++;
+ break;
+
+ default:
+ break;
}
-
- count++;
}
+ }
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+ // clear out any cached files
+ zip_file_cache_clear();
+
+ // if we didn't get anything at all, display a generic end message
+ if (correct + incorrect == 0)
+ {
+ if (notfound > 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not found!\n", gamename);
+ else
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not supported!\n", gamename);
+ }
+
+ // otherwise, print a summary
+ else
+ {
+ if (incorrect > 0)
+ throw emu_fatalerror(MAMERR_MISSING_FILES, "%d romsets found, %d were OK.\n", correct + incorrect, correct);
+ mame_printf_info("%d romsets found, %d were OK.\n", correct, correct);
+ }
}
-/*-------------------------------------------------
- info_verifyroms - verify the ROM sets of
- one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// info_verifysamples - verify the sample sets of
+// one or more games
+//-------------------------------------------------
-static void info_verifyroms(emu_options &options, const char *gamename)
+void cli_frontend::verifysamples(const char *gamename)
{
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+
int correct = 0;
int incorrect = 0;
int notfound = 0;
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
+ // iterate over drivers
+ media_auditor auditor(drivlist);
+ while (drivlist.next())
+ {
+ // audit the samples in this set
+ media_auditor::summary summary = auditor.audit_samples();
+
+ // output the summary of the audit
+ astring summary_string;
+ auditor.summarize(&summary_string);
+ mame_printf_info("%s", summary_string.cstr());
+
+ // if not found, print a message and set the flag
+ if (summary == media_auditor::NOTFOUND)
{
- audit_record *audit;
- int audit_records;
- int res;
-
- /* audit the ROMs in this set */
- audit_records = audit_images(options, drivers[drvindex], AUDIT_VALIDATE_FAST, &audit);
- res = audit_summary(drivers[drvindex], audit_records, audit, TRUE);
- if (audit_records > 0)
- global_free(audit);
-
- /* if not found, count that and leave it at that */
- if (res == NOTFOUND)
- notfound++;
+ mame_printf_error("sampleset \"%s\" not found!\n", drivlist.driver().name);
+ notfound++;
+ }
- /* else display information about what we discovered */
- else
+ // else display information about what we discovered
+ else
+ {
+ // output the name of the driver and its clone
+ mame_printf_info("sampleset %s ", drivlist.driver().name);
+ int clone_of = drivlist.clone();
+ if (clone_of != -1)
+ mame_printf_info("[%s] ", drivlist.driver(clone_of).name);
+
+ // switch off of the result
+ switch (summary)
{
- const game_driver *clone_of;
-
- /* output the name of the driver and its clone */
- mame_printf_info("romset %s ", drivers[drvindex]->name);
- clone_of = driver_get_clone(drivers[drvindex]);
- if (clone_of != NULL)
- mame_printf_info("[%s] ", clone_of->name);
-
- /* switch off of the result */
- switch (res)
- {
- case INCORRECT:
- mame_printf_info("is bad\n");
- incorrect++;
- break;
-
- case CORRECT:
- mame_printf_info("is good\n");
- correct++;
- break;
-
- case BEST_AVAILABLE:
- mame_printf_info("is best available\n");
- correct++;
- break;
- }
+ case media_auditor::INCORRECT:
+ mame_printf_info("is bad\n");
+ incorrect++;
+ break;
+
+ case media_auditor::CORRECT:
+ mame_printf_info("is good\n");
+ correct++;
+ break;
+
+ case media_auditor::BEST_AVAILABLE:
+ mame_printf_info("is best available\n");
+ correct++;
+ break;
+
+ default:
+ break;
}
}
+ }
- /* clear out any cached files */
+ // clear out any cached files
zip_file_cache_clear();
- /* if we didn't get anything at all, display a generic end message */
+ // if we didn't get anything at all, display a generic end message
if (correct + incorrect == 0)
{
if (notfound > 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not found!\n", gamename);
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "sampleset \"%s\" not found!\n", gamename);
else
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not supported!\n", gamename);
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "sampleset \"%s\" not supported!\n", gamename);
}
- /* otherwise, print a summary */
+ // otherwise, print a summary
else
{
if (incorrect > 0)
- throw emu_fatalerror(MAMERR_MISSING_FILES, "%d romsets found, %d were OK.\n", correct + incorrect, correct);
- mame_printf_info("%d romsets found, %d were OK.\n", correct, correct);
+ throw emu_fatalerror(MAMERR_MISSING_FILES, "%d samplesets found, %d were OK.\n", correct + incorrect, correct);
+ mame_printf_info("%d samplesets found, %d were OK.\n", correct, correct);
}
}
+
+
+#if 0
/*-------------------------------------------------
info_listsoftware - output the list of
software supported by a given game or set of
@@ -798,37 +800,31 @@ static void info_verifyroms(emu_options &options, const char *gamename)
identifying duplicate lists.
-------------------------------------------------*/
-static void info_listsoftware(emu_options &options, const char *gamename)
+static void info_listsoftware(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(*drivers[drvindex], options);
+ // determine which drivers to output; return an error if none found
+ driver_enumerator drivlist(m_options, gamename);
+ if (drivlist.count() == 0)
+ throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- 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();
+ // first determine the maximum number of lists we might encounter
+ int list_count = 0;
+ while (drivlist.next())
+ for (const device_config *dev = 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] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM))
- nr_lists++;
- }
- }
+ for (int listnum = 0; listnum < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; listnum++)
+ if (swlist->list_name[listnum] && *swlist->list_name[listnum] && swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
+ list_count++;
}
- }
- lists = global_alloc_array( char *, nr_lists );
+ // allocate a list
+ astring *lists = global_alloc_array(astring, list_count);
- if (nr_lists)
+ if (list_count)
{
fprintf( out,
"<?xml version=\"1.0\"?>\n"
@@ -902,664 +898,602 @@ static void info_listsoftware(emu_options &options, const char *gamename)
);
}
- for ( int drvindex = 0; drivers[drvindex] != NULL; drvindex++ )
- {
- if ( mame_strwildcmp( gamename, drivers[drvindex]->name ) == 0 )
+ drivlist.reset();
+ list_count = 0;
+ while (drivlist.next())
+ for (const device_config *dev = drivlist.config().m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
{
- /* allocate the machine config */
- machine_config config(*drivers[drvindex], options);
+ software_list_config *swlist = (software_list_config *)downcast<const legacy_device_config_base *>(dev)->inline_config();
- for (const device_config *dev = config.m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext())
+ for (int listnum = 0; listnum < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; listnum++)
{
- 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[listnum] && *swlist->list_name[listnum] && swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
{
- if ( swlist->list_name[i] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM))
+ software_list *list = software_list_open(m_options, swlist->list_name[listnum], FALSE, NULL);
+
+ if ( list )
{
- software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL );
+ /* Verify if we have encountered this list before */
+ bool seen_before = false;
+ for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++)
+ if (lists[seen_index] == swlist->list_name[listnum])
+ seen_before = true;
- if ( list )
+ if (!seen_before)
{
- /* 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;
- }
- }
+ lists[list_count++] = swlist->list_name[i];
+ software_list_parse( list, NULL, NULL );
+
+ fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name[i], xml_normalize_string(software_list_get_description(list)) );
- if ( ! seen_before )
+ for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) )
{
- lists[list_idx] = core_strdup( swlist->list_name[i] );
- list_idx++;
- software_list_parse( list, NULL, NULL );
+ 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_ );
- fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name[i], xml_normalize_string(software_list_get_description(list)) );
+ fprintf( out, ">\n");
- 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 ) )
+ if ( part->featurelist )
{
- fprintf( out, "\t\t\t<part name=\"%s\"", part->name );
- if ( part->interface_ )
- fprintf( out, " interface=\"%s\"", part->interface_ );
+ feature_list *list = part->featurelist;
- fprintf( out, ">\n");
-
- if ( part->featurelist )
+ while( list )
{
- feature_list *list = part->featurelist;
-
- while( list )
- {
- fprintf( out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", list->name, list->value );
- list = list->next;
- }
+ fprintf( out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", list->name, list->value );
+ list = list->next;
}
+ }
- /* TODO: display rom region information */
- for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) )
- {
- int is_disk = ROMREGION_ISDISKDATA(region);
+ /* TODO: display rom region information */
+ for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) )
+ {
+ int is_disk = ROMREGION_ISDISKDATA(region);
- if (!is_disk)
- fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) );
- else
- fprintf( out, "\t\t\t\t<diskarea name=\"%s\">\n", ROMREGION_GETTAG(region) );
+ if (!is_disk)
+ fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) );
+ else
+ fprintf( out, "\t\t\t\t<diskarea name=\"%s\">\n", ROMREGION_GETTAG(region) );
- for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ )
+ for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ )
+ {
+ if ( ROMENTRY_ISFILE(rom) )
{
- if ( ROMENTRY_ISFILE(rom) )
+ if (!is_disk)
+ fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) );
+ else
+ fprintf( out, "\t\t\t\t\t<disk name=\"%s\"", xml_normalize_string(ROM_GETNAME(rom)) );
+
+ /* dump checksum information only if there is a known dump */
+ hash_collection hashes(ROM_GETHASHDATA(rom));
+ if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
{
- if (!is_disk)
- fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) );
- else
- fprintf( out, "\t\t\t\t\t<disk name=\"%s\"", xml_normalize_string(ROM_GETNAME(rom)) );
-
- /* dump checksum information only if there is a known dump */
- hash_collection hashes(ROM_GETHASHDATA(rom));
- if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
- {
- astring tempstr;
- for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
- fprintf(out, " %s=\"%s\"", hash->name(), hash->string(tempstr));
- }
-
- if (!is_disk)
- fprintf( out, " offset=\"0x%x\"", ROM_GETOFFSET(rom) );
-
- if ( hashes.flag(hash_collection::FLAG_BAD_DUMP) )
- fprintf( out, " status=\"baddump\"" );
- if ( hashes.flag(hash_collection::FLAG_NO_DUMP) )
- fprintf( out, " status=\"nodump\"" );
-
- if (is_disk)
- fprintf( out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes");
-
- if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1))
- fprintf( out, " loadflag=\"load16_byte\"" );
-
- if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3))
- fprintf( out, " loadflag=\"load32_byte\"" );
-
- if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(2)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
- {
- if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
- fprintf( out, " loadflag=\"load32_word\"" );
- else
- fprintf( out, " loadflag=\"load32_word_swap\"" );
- }
-
- if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(6)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
- {
- if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
- fprintf( out, " loadflag=\"load64_word\"" );
- else
- fprintf( out, " loadflag=\"load64_word_swap\"" );
- }
-
- if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_NOSKIP) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
- {
- if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
- fprintf( out, " loadflag=\"load32_dword\"" );
- else
- fprintf( out, " loadflag=\"load16_word_swap\"" );
- }
-
- fprintf( out, "/>\n" );
+ astring tempstr;
+ for (hash_base *hash = hashes.first(); hash != NULL; hash = hash->next())
+ fprintf(out, " %s=\"%s\"", hash->name(), hash->string(tempstr));
}
- else if ( ROMENTRY_ISRELOAD(rom) )
+
+ if (!is_disk)
+ fprintf( out, " offset=\"0x%x\"", ROM_GETOFFSET(rom) );
+
+ if ( hashes.flag(hash_collection::FLAG_BAD_DUMP) )
+ fprintf( out, " status=\"baddump\"" );
+ if ( hashes.flag(hash_collection::FLAG_NO_DUMP) )
+ fprintf( out, " status=\"nodump\"" );
+
+ if (is_disk)
+ fprintf( out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes");
+
+ if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1))
+ fprintf( out, " loadflag=\"load16_byte\"" );
+
+ if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3))
+ fprintf( out, " loadflag=\"load32_byte\"" );
+
+ if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(2)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
{
- fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
+ fprintf( out, " loadflag=\"load32_word\"" );
+ else
+ fprintf( out, " loadflag=\"load32_word_swap\"" );
}
- else if ( ROMENTRY_ISCONTINUE(rom) )
+
+ if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(6)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
{
- fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"continue\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
+ fprintf( out, " loadflag=\"load64_word\"" );
+ else
+ fprintf( out, " loadflag=\"load64_word_swap\"" );
}
- else if ( ROMENTRY_ISFILL(rom) )
+
+ if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_NOSKIP) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
{
- fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"fill\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
+ fprintf( out, " loadflag=\"load32_dword\"" );
+ else
+ fprintf( out, " loadflag=\"load16_word_swap\"" );
}
- }
- if (!is_disk)
- fprintf( out, "\t\t\t\t</dataarea>\n" );
- else
- fprintf( out, "\t\t\t\t</diskarea>\n" );
+ fprintf( out, "/>\n" );
+ }
+ else if ( ROMENTRY_ISRELOAD(rom) )
+ {
+ fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ }
+ else if ( ROMENTRY_ISCONTINUE(rom) )
+ {
+ fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"continue\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ }
+ else if ( ROMENTRY_ISFILL(rom) )
+ {
+ fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"fill\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) );
+ }
}
- fprintf( out, "\t\t\t</part>\n" );
+ if (!is_disk)
+ fprintf( out, "\t\t\t\t</dataarea>\n" );
+ else
+ fprintf( out, "\t\t\t\t</diskarea>\n" );
}
- fprintf( out, "\t\t</software>\n" );
+ fprintf( out, "\t\t\t</part>\n" );
}
- fprintf(out, "\t</softwarelist>\n" );
+ fprintf( out, "\t\t</software>\n" );
}
- software_list_close( list );
+ fprintf(out, "\t</softwarelist>\n" );
}
+
+ software_list_close( list );
}
}
}
}
- }
- if (nr_lists)
+ if (list_count > 0)
fprintf( out, "</softwarelists>\n" );
else
fprintf( out, "No software lists found for this system\n" );
global_free( lists );
}
+#endif
-/*-------------------------------------------------
- softlist_match_roms - scan for a matching
- software ROM by hash
--------------------------------------------------*/
-void softlist_match_roms(machine_config &config, const hash_collection &hashes, int length, int *found)
-{
- 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] )
- {
- software_list *list = software_list_open( config.options(), swlist->list_name[i], FALSE, NULL );
-
- for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) )
- {
- for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) )
- {
- for ( const rom_entry *region = part->romdata; region != NULL; region = rom_next_region(region) )
- {
- for ( const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom) )
- {
- hash_collection romhashes(ROM_GETHASHDATA(rom));
- if ( hashes == romhashes )
- {
- bool baddump = romhashes.flag(hash_collection::FLAG_BAD_DUMP);
-
- /* output information about the match */
- if (*found != 0)
- mame_printf_info(" ");
- mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name[i], swinfo->shortname, swinfo->longname);
- (*found)++;
- }
- }
- }
- }
- }
-
- software_list_close( list );
- }
- }
- }
-}
-
-/*-------------------------------------------------
- info_listmedia - output the list of image
- devices referenced by a given game or set of
- games
--------------------------------------------------*/
+//-------------------------------------------------
+// romident - identify ROMs by looking for
+// matches in our internal database
+//-------------------------------------------------
-static void info_listmedia(emu_options &options, const char *gamename)
+void cli_frontend::romident(const char *filename)
{
- int count = 0, devcount;
- const device_config_image_interface *dev = NULL;
- const char *src;
- const char *driver_name;
- const char *name;
- const char *shortname;
- char paren_shortname[16];
+ media_identifier ident(m_options);
- printf(" SYSTEM MEDIA NAME (brief) IMAGE FILE EXTENSIONS SUPPORTED \n");
- printf("---------- -------------------- ------------------------------------\n");
-
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- /* allocate the machine config */
- machine_config config(*drivers[drvindex], options);
+ // identify the file, then output results
+ mame_printf_info("Identifying %s....\n", filename);
+ ident.identify(filename);
+ mame_printf_info("%s\n", ident.result());
- driver_name = drivers[drvindex]->name;
-
- devcount = 0;
-
- for (bool gotone = config.m_devicelist.first(dev); gotone; gotone = dev->next(dev))
- {
- src = downcast<const legacy_image_device_config_base *>(dev)->file_extensions();
- name = downcast<const legacy_image_device_config_base *>(dev)->instance_name();
- shortname = downcast<const legacy_image_device_config_base *>(dev)->brief_instance_name();
-
- sprintf(paren_shortname, "(%s)", shortname);
-
- printf("%-13s%-12s%-8s ", driver_name, name, paren_shortname);
- driver_name = " ";
-
- astring extensions(src);
- char *ext = strtok((char*)extensions.cstr(),",");
- while (ext != NULL)
- {
- printf(".%-5s",ext);
- ext = strtok (NULL, ",");
- devcount++;
- }
- printf("\n");
- }
- if (!devcount)
- printf("%-13s(none)\n",driver_name);
-
- count++;
- }
-
- if (!count)
- printf("There are no Computers or Consoles named %s\n", gamename);
-
- if (count == 0)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
+ // return the appropriate error code
+ if (ident.matches() == ident.total())
+ return;
+ else if (ident.matches() == ident.total() - ident.nonroms())
+ throw emu_fatalerror(MAMERR_IDENT_NONROMS, "");
+ else if (ident.matches() > 0)
+ throw emu_fatalerror(MAMERR_IDENT_PARTIAL, "");
+ else
+ throw emu_fatalerror(MAMERR_IDENT_NONE, "");
}
-/*-------------------------------------------------
- info_verifysamples - verify the sample sets of
- one or more games
--------------------------------------------------*/
+//-------------------------------------------------
+// execute_commands - execute various frontend
+// commands
+//-------------------------------------------------
-static void info_verifysamples(emu_options &options, const char *gamename)
+void cli_frontend::execute_commands(const char *exename)
{
- int correct = 0;
- int incorrect = 0;
- int notfound = FALSE;
+ // help?
+ if (strcmp(m_options.command(), CLICOMMAND_HELP) == 0)
+ {
+ display_help();
+ return;
+ }
- /* now iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
- {
- audit_record *audit;
- int audit_records;
- int res;
-
- /* audit the samples in this set */
- audit_records = audit_samples(options, drivers[drvindex], &audit);
- res = audit_summary(drivers[drvindex], audit_records, audit, TRUE);
- if (audit_records > 0)
- global_free(audit);
- else
- continue;
+ // showusage?
+ if (strcmp(m_options.command(), CLICOMMAND_SHOWUSAGE) == 0)
+ {
+ astring helpstring;
+#ifndef MESS
+ mame_printf_info("Usage: %s [%s] [options]\n\nOptions:\n%s", exename, GAMENOUN, m_options.output_help(helpstring));
+#else
+ mame_printf_info("Usage: %s [%s] [media] [software] [options]\n\nOptions:\n%s", exename, GAMENOUN, m_options.output_help(helpstring));
+#endif
+ return;
+ }
- /* if not found, print a message and set the flag */
- if (res == NOTFOUND)
- {
- mame_printf_error("sampleset \"%s\" not found!\n", drivers[drvindex]->name);
- notfound = TRUE;
- }
+ // validate?
+ if (strcmp(m_options.command(), CLICOMMAND_VALIDATE) == 0)
+ {
+ validate_drivers(m_options);
+ return;
+ }
- /* else display information about what we discovered */
- else
- {
- mame_printf_info("sampleset %s ", drivers[drvindex]->name);
+ // other commands need the INIs parsed
+ astring option_errors;
+ m_options.parse_standard_inis(option_errors);
+ if (option_errors)
+ printf("%s\n", option_errors.cstr());
- /* switch off of the result */
- switch (res)
- {
- case INCORRECT:
- mame_printf_info("is bad\n");
- incorrect++;
- break;
-
- case CORRECT:
- mame_printf_info("is good\n");
- correct++;
- break;
-
- case BEST_AVAILABLE:
- mame_printf_info("is best available\n");
- correct++;
- break;
- }
- }
- }
+ // createconfig?
+ if (strcmp(m_options.command(), CLICOMMAND_CREATECONFIG) == 0)
+ {
+ // attempt to open the output file
+ emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ if (file.open(CONFIGNAME ".ini") != FILERR_NONE)
+ throw emu_fatalerror("Unable to create file " CONFIGNAME ".ini\n");
- /* clear out any cached files */
- zip_file_cache_clear();
+ // generate the updated INI
+ astring initext;
+ file.puts(m_options.output_ini(initext));
+ return;
+ }
- /* if we didn't get anything at all because of an unsupported set, display message */
- if (correct + incorrect == 0)
+ // showconfig?
+ if (strcmp(m_options.command(), CLICOMMAND_SHOWCONFIG) == 0)
{
- if (!notfound)
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
- else
- throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No sample sets found for '%s'", gamename);
+ // print the INI text
+ astring initext;
+ printf("%s\n", m_options.output_ini(initext));
+ return;
}
- /* otherwise, print a summary */
- else
+ // all other commands call out to one of these helpers
+ static const struct
{
- if (incorrect > 0)
- throw emu_fatalerror(MAMERR_MISSING_FILES, "%d sample sets found, %d were OK.\n", correct + incorrect, correct);
- mame_printf_info("%d sample sets found, %d were OK.\n", correct, correct);
- }
+ const char *option;
+ void (cli_frontend::*function)(const char *gamename);
+ } info_commands[] =
+ {
+ { CLICOMMAND_LISTXML, &cli_frontend::listxml },
+ { CLICOMMAND_LISTFULL, &cli_frontend::listfull },
+ { CLICOMMAND_LISTSOURCE, &cli_frontend::listsource },
+ { CLICOMMAND_LISTCLONES, &cli_frontend::listclones },
+ { CLICOMMAND_LISTBROTHERS, &cli_frontend::listbrothers },
+ { CLICOMMAND_LISTCRC, &cli_frontend::listcrc },
+ { CLICOMMAND_LISTDEVICES, &cli_frontend::listdevices },
+ { CLICOMMAND_LISTROMS, &cli_frontend::listroms },
+ { CLICOMMAND_LISTSAMPLES, &cli_frontend::listsamples },
+ { CLICOMMAND_VERIFYROMS, &cli_frontend::verifyroms },
+ { CLICOMMAND_VERIFYSAMPLES, &cli_frontend::verifysamples },
+ { CLICOMMAND_LISTMEDIA, &cli_frontend::listmedia },
+// { CLICOMMAND_LISTSOFTWARE, &cli_frontend::listsoftware },
+ { CLICOMMAND_ROMIDENT, &cli_frontend::romident }
+ };
+
+ // find the command
+ for (int cmdindex = 0; cmdindex < ARRAY_LENGTH(info_commands); cmdindex++)
+ if (strcmp(m_options.command(), info_commands[cmdindex].option) == 0)
+ {
+ // parse any relevant INI files before proceeding
+ const char *sysname = m_options.system_name();
+ (this->*info_commands[cmdindex].function)((sysname[0] == 0) ? "*" : sysname);
+ return;
+ }
+
+ // if we get here, we don't know what has been requested
+ throw emu_fatalerror(MAMERR_INVALID_CONFIG, "Unknown command '%s' specified", m_options.command());
}
-/*-------------------------------------------------
- info_romident - identify ROMs by looking for
- matches in our internal database
--------------------------------------------------*/
+//-------------------------------------------------
+// display_help - display help to standard
+// output
+//-------------------------------------------------
-static void info_romident(emu_options &options, const char *gamename)
+void cli_frontend::display_help()
{
- romident_status status;
+#ifndef MESS
+ mame_printf_info("M.A.M.E. v%s - Multiple Arcade Machine Emulator\n"
+ "Copyright Nicola Salmoria and the MAME Team\n\n", build_version);
+ mame_printf_info("%s\n", mame_disclaimer);
+ mame_printf_info("Usage: MAME gamename [options]\n\n"
+ " MAME -showusage for a brief list of options\n"
+ " MAME -showconfig for a list of configuration options\n"
+ " MAME -createconfig to create a " CONFIGNAME ".ini\n\n"
+ "For usage instructions, please consult the file windows.txt\n");
+#else
+ mess_display_help();
+#endif
+}
- /* do the identification */
- romident(options, gamename, &status);
- /* clear out any cached files */
- zip_file_cache_clear();
+//-------------------------------------------------
+// display_suggestions - display 10 possible
+// matches for a given invalid gamename
+//-------------------------------------------------
- /* return the appropriate error code */
- if (status.matches == status.total)
- return;
- else if (status.matches == status.total - status.nonroms)
- throw emu_fatalerror(MAMERR_IDENT_NONROMS, "");
- else if (status.matches > 0)
- throw emu_fatalerror(MAMERR_IDENT_PARTIAL, "");
- else
- throw emu_fatalerror(MAMERR_IDENT_NONE, "");
+void cli_frontend::display_suggestions(const char *gamename)
+{
}
+//**************************************************************************
+// MEDIA IDENTIFIER
+//**************************************************************************
-/***************************************************************************
- UTILITIES
-***************************************************************************/
-
-/*-------------------------------------------------
- romident - identify files
--------------------------------------------------*/
+//-------------------------------------------------
+// media_identifier - constructor
+//-------------------------------------------------
-static void romident(emu_options &options, const char *filename, romident_status *status)
+media_identifier::media_identifier(cli_options &options)
+ : m_drivlist(options),
+ m_total(0),
+ m_matches(0),
+ m_nonroms(0)
{
- osd_directory *directory;
+}
- /* reset the status */
- memset(status, 0, sizeof(*status));
- /* first try to open as a directory */
- directory = osd_opendir(filename);
+//-------------------------------------------------
+// identify - identify a directory, ZIP file,
+// or raw file
+//-------------------------------------------------
+
+void media_identifier::identify(const char *filename)
+{
+ // first try to open as a directory
+ osd_directory *directory = osd_opendir(filename);
if (directory != NULL)
{
- const osd_directory_entry *entry;
-
- /* iterate over all files in the directory */
- while ((entry = osd_readdir(directory)) != NULL)
+ // iterate over all files in the directory
+ for (const osd_directory_entry *entry = osd_readdir(directory); entry != NULL; entry = osd_readdir(directory))
if (entry->type == ENTTYPE_FILE)
{
astring curfile(filename, PATH_SEPARATOR, entry->name);
- identify_file(options, curfile, status);
+ identify_file(curfile);
}
+
+ // close the directory and be done
osd_closedir(directory);
}
- /* if that failed, and the filename ends with .zip, identify as a ZIP file */
+ // if that failed, and the filename ends with .zip, identify as a ZIP file
else if (core_filename_ends_with(filename, ".zip"))
{
- /* first attempt to examine it as a valid ZIP file */
+ // first attempt to examine it as a valid ZIP file
zip_file *zip = NULL;
zip_error ziperr = zip_file_open(filename, &zip);
if (ziperr == ZIPERR_NONE && zip != NULL)
{
- const zip_file_header *entry;
-
- /* loop over entries in the ZIP, skipping empty files and directories */
- for (entry = zip_file_first_file(zip); entry; entry = zip_file_next_file(zip))
+ // loop over entries in the ZIP, skipping empty files and directories
+ for (const zip_file_header *entry = zip_file_first_file(zip); entry != NULL; entry = zip_file_next_file(zip))
if (entry->uncompressed_length != 0)
{
UINT8 *data = global_alloc_array(UINT8, entry->uncompressed_length);
if (data != NULL)
{
- /* decompress data into RAM and identify it */
+ // decompress data into RAM and identify it
ziperr = zip_file_decompress(zip, data, entry->uncompressed_length);
if (ziperr == ZIPERR_NONE)
- identify_data(options, entry->filename, data, entry->uncompressed_length, status);
+ identify_data(entry->filename, data, entry->uncompressed_length);
global_free(data);
}
}
- /* close up */
+ // close up
zip_file_close(zip);
}
+
+ // clear out any cached files
+ zip_file_cache_clear();
}
- /* otherwise, identify as a raw file */
+ // otherwise, identify as a raw file
else
- identify_file(options, filename, status);
+ identify_file(filename);
}
-/*-------------------------------------------------
- identify_file - identify a file; if it is a
- ZIP file, scan it and identify all enclosed
- files
--------------------------------------------------*/
+//-------------------------------------------------
+// identify_file - identify a file
+//-------------------------------------------------
-static void identify_file(emu_options &options, const char *name, romident_status *status)
+void media_identifier::identify_file(const char *name)
{
- file_error filerr;
- osd_file *file;
- UINT64 length;
-
+ // CHD files need to be parsed and their hashes extracted from the header
if (core_filename_ends_with(name, ".chd"))
{
- chd_file *chd;
- chd_error err;
+ // output the name
astring basename;
- int found = 0;
-
- core_filename_extract_base(&basename, name, FALSE);
- mame_printf_info("%-20s", basename.cstr());
+ m_result.catprintf("%-20s", core_filename_extract_base(&basename, name, FALSE)->cstr());
+ m_total++;
- status->total++;
-
- err = chd_open(name, CHD_OPEN_READ, NULL, &chd);
+ // attempt to open as a CHD; fail if not
+ chd_file *chd;
+ chd_error err = chd_open(name, CHD_OPEN_READ, NULL, &chd);
if (err != CHDERR_NONE)
{
- mame_printf_info("NOT A CHD\n");
- status->nonroms++;
+ m_result.catprintf("NOT A CHD\n");
+ m_nonroms++;
+ return;
}
- else
- {
- chd_header header;
-
- header = *chd_get_header(chd);
- if (header.flags & CHDFLAGS_IS_WRITEABLE)
- {
- mame_printf_info("is a writeable CHD\n");
- }
- else
- {
- static const UINT8 nullhash[20] = { 0 };
- hash_collection hashes;
-
- /* if there's an MD5 or SHA1 hash, add them to the output hash */
- if (memcmp(nullhash, header.md5, sizeof(header.md5)) != 0)
- hashes.add_from_buffer(hash_collection::HASH_MD5, header.md5, sizeof(header.md5));
- if (memcmp(nullhash, header.sha1, sizeof(header.sha1)) != 0)
- hashes.add_from_buffer(hash_collection::HASH_SHA1, header.sha1, sizeof(header.sha1));
- length = header.logicalbytes;
+ // fetch the header and close the file
+ chd_header header = *chd_get_header(chd);
+ chd_close(chd);
- match_roms(options, hashes, length, &found);
-
- if (found == 0)
- {
- mame_printf_info("NO MATCH\n");
- }
-
- /* if we did find it, count it as a match */
- else
- status->matches++;
- }
-
- chd_close(chd);
+ // error on writable CHDs
+ if (header.flags & CHDFLAGS_IS_WRITEABLE)
+ {
+ m_result.catprintf("is a writeable CHD\n");
+ return;
}
+
+ // otherwise, get the hash collection for this CHD
+ static const UINT8 nullhash[20] = { 0 };
+ hash_collection hashes;
+
+ if (memcmp(nullhash, header.md5, sizeof(header.md5)) != 0)
+ hashes.add_from_buffer(hash_collection::HASH_MD5, header.md5, sizeof(header.md5));
+ if (memcmp(nullhash, header.sha1, sizeof(header.sha1)) != 0)
+ hashes.add_from_buffer(hash_collection::HASH_SHA1, header.sha1, sizeof(header.sha1));
+
+ // determine whether this file exists
+ int found = find_by_hash(hashes, header.logicalbytes);
+ if (found == 0)
+ m_result.catprintf("NO MATCH\n");
+ else
+ m_matches++;
}
+
+ // all other files have their hashes computed directly
else
{
- /* open for read and process if it opens and has a valid length */
- filerr = osd_open(name, OPEN_FLAG_READ, &file, &length);
- if (filerr == FILERR_NONE && length > 0 && (UINT32)length == length)
- {
- UINT8 *data = global_alloc_array(UINT8, length);
- if (data != NULL)
- {
- UINT32 bytes;
-
- /* read file data into RAM and identify it */
- filerr = osd_read(file, data, 0, length, &bytes);
- if (filerr == FILERR_NONE)
- identify_data(options, name, data, bytes, status);
- global_free(data);
- }
- osd_close(file);
- }
+ // load the file and process if it opens and has a valid length
+ UINT32 length;
+ void *data;
+ file_error filerr = core_fload(name, &data, &length);
+ if (filerr == FILERR_NONE && length > 0)
+ identify_data(name, reinterpret_cast<UINT8 *>(data), length);
}
}
-/*-------------------------------------------------
- identify_data - identify a buffer full of
- data; if it comes from a .JED file, parse the
- fusemap into raw data first
--------------------------------------------------*/
+//-------------------------------------------------
+// identify_data - identify a buffer full of
+// data; if it comes from a .JED file, parse the
+// fusemap into raw data first
+//-------------------------------------------------
-static void identify_data(emu_options &options, const char *name, const UINT8 *data, int length, romident_status *status)
+void media_identifier::identify_data(const char *name, const UINT8 *data, int length)
{
+ // if this is a '.jed' file, process it into raw bits first
UINT8 *tempjed = NULL;
- astring basename;
- int found = 0;
jed_data jed;
-
- /* if this is a '.jed' file, process it into raw bits first */
if (core_filename_ends_with(name, ".jed") && jed_parse(data, length, &jed) == JEDERR_NONE)
{
- /* now determine the new data length and allocate temporary memory for it */
+ // now determine the new data length and allocate temporary memory for it
length = jedbin_output(&jed, NULL, 0);
tempjed = global_alloc_array(UINT8, length);
- if (tempjed == NULL)
- return;
-
- /* create a binary output of the JED data and use that instead */
jedbin_output(&jed, tempjed, length);
data = tempjed;
}
- /* compute the hash of the data */
+ // compute the hash of the data
hash_collection hashes;
hashes.compute(data, length, hash_collection::HASH_TYPES_CRC_SHA1);
- /* output the name */
- status->total++;
- core_filename_extract_base(&basename, name, FALSE);
- mame_printf_info("%-20s", basename.cstr());
+ // output the name
+ m_total++;
+ astring basename;
+ m_result.catprintf("%-20s", core_filename_extract_base(&basename, name, FALSE)->cstr());
- /* see if we can find a match in the ROMs */
- match_roms(options, hashes, length, &found);
+ // see if we can find a match in the ROMs
+ int found = find_by_hash(hashes, length);
- /* if we didn't find it, try to guess what it might be */
+ // if we didn't find it, try to guess what it might be
if (found == 0)
{
- /* if not a power of 2, assume it is a non-ROM file */
+ // if not a power of 2, assume it is a non-ROM file
if ((length & (length - 1)) != 0)
{
- mame_printf_info("NOT A ROM\n");
- status->nonroms++;
+ m_result.catprintf("NOT A ROM\n");
+ m_nonroms++;
}
- /* otherwise, it's just not a match */
+ // otherwise, it's just not a match
else
- mame_printf_info("NO MATCH\n");
+ m_result.catprintf("NO MATCH\n");
}
- /* if we did find it, count it as a match */
+ // if we did find it, count it as a match
else
- status->matches++;
+ m_matches++;
- /* free any temporary JED data */
+ // free any temporary JED data
global_free(tempjed);
}
-/*-------------------------------------------------
- match_roms - scan for a matching ROM by hash
--------------------------------------------------*/
+//-------------------------------------------------
+// find_by_hash - scan for a file in the list
+// of drivers by hash
+//-------------------------------------------------
-static void match_roms(emu_options &options, const hash_collection &hashes, int length, int *found)
+int media_identifier::find_by_hash(const hash_collection &hashes, int length)
{
- /* iterate over drivers */
- for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++)
- {
- machine_config config(*drivers[drvindex], options);
+ int found = 0;
- /* iterate over sources, regions and files within the region */
- for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source))
- for (const rom_entry *region = rom_first_region(*source); region; region = rom_next_region(region))
- for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ // iterate over drivers
+ m_drivlist.reset();
+ while (m_drivlist.next())
+ {
+ // iterate over sources, regions and files within the region */
+ 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))
+ for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
{
hash_collection romhashes(ROM_GETHASHDATA(rom));
if (!romhashes.flag(hash_collection::FLAG_NO_DUMP) && hashes == romhashes)
{
bool baddump = romhashes.flag(hash_collection::FLAG_BAD_DUMP);
- /* output information about the match */
- if (*found != 0)
+ // output information about the match
+ if (!found)
mame_printf_info(" ");
- mame_printf_info("= %s%-20s %-10s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), drivers[drvindex]->name, drivers[drvindex]->description);
- (*found)++;
+ mame_printf_info("= %s%-20s %-10s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), m_drivlist.driver().name, m_drivlist.driver().description);
+ found++;
}
}
- // also check any softlists
- softlist_match_roms( config, hashes, length, found );
+ // next iterate over softlists
+ 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 listnum = 0; listnum < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; listnum++)
+ if (swlist->list_name[listnum] != NULL)
+ {
+ software_list *list = software_list_open(m_drivlist.options(), swlist->list_name[listnum], FALSE, NULL);
+
+ for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
+ for (software_part *part = software_find_part(swinfo, NULL, NULL); part != NULL; part = software_part_next(part))
+ for (const rom_entry *region = part->romdata; region != NULL; region = rom_next_region(region))
+ for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
+ {
+ hash_collection romhashes(ROM_GETHASHDATA(rom));
+ if (hashes == romhashes)
+ {
+ bool baddump = romhashes.flag(hash_collection::FLAG_BAD_DUMP);
+
+ // output information about the match
+ if (!found)
+ mame_printf_info(" ");
+ mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name[listnum], swinfo->shortname, swinfo->longname);
+ found++;
+ }
+ }
+
+ software_list_close(list);
+ }
+ }
}
+
+ return found;
}