summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/clifront.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/clifront.cpp')
-rw-r--r--src/frontend/mame/clifront.cpp451
1 files changed, 221 insertions, 230 deletions
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index f2dbf4e1c55..28249e7bd3e 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -99,11 +99,11 @@ const options_entry cli_option_entries[] =
{ CLICOMMAND_LISTCLONES ";lc", "0", OPTION_COMMAND, "show clones" },
{ CLICOMMAND_LISTBROTHERS ";lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" },
{ CLICOMMAND_LISTCRC, "0", OPTION_COMMAND, "CRC-32s" },
- { CLICOMMAND_LISTROMS ";lr", "0", OPTION_COMMAND, "list required roms for a driver" },
+ { CLICOMMAND_LISTROMS ";lr", "0", OPTION_COMMAND, "list required ROMs for a driver" },
{ CLICOMMAND_LISTSAMPLES, "0", OPTION_COMMAND, "list optional samples for a driver" },
{ CLICOMMAND_VERIFYROMS, "0", OPTION_COMMAND, "report romsets that have problems" },
{ CLICOMMAND_VERIFYSAMPLES, "0", OPTION_COMMAND, "report samplesets that have problems" },
- { CLICOMMAND_ROMIDENT, "0", OPTION_COMMAND, "compare files with known MAME roms" },
+ { CLICOMMAND_ROMIDENT, "0", OPTION_COMMAND, "compare files with known MAME ROMs" },
{ CLICOMMAND_LISTDEVICES ";ld", "0", OPTION_COMMAND, "list available devices" },
{ CLICOMMAND_LISTSLOTS ";lslot", "0", OPTION_COMMAND, "list available slots and slot devices" },
{ CLICOMMAND_LISTMEDIA ";lm", "0", OPTION_COMMAND, "list available media for the system" },
@@ -183,9 +183,9 @@ void print_summary(
//-------------------------------------------------
cli_frontend::cli_frontend(emu_options &options, osd_interface &osd)
- : m_options(options),
- m_osd(osd),
- m_result(EMU_ERR_NONE)
+ : m_options(options)
+ , m_osd(osd)
+ , m_result(EMU_ERR_NONE)
{
m_options.add_entries(cli_option_entries);
}
@@ -211,6 +211,7 @@ void cli_frontend::start_execution(mame_machine_manager *manager, const std::vec
try
{
m_options.parse_command_line(args, OPTION_PRIORITY_CMDLINE);
+ m_osd.set_verbose(m_options.verbose());
}
catch (options_exception &ex)
{
@@ -234,7 +235,10 @@ void cli_frontend::start_execution(mame_machine_manager *manager, const std::vec
// read INI's, if appropriate
if (m_options.read_config())
+ {
mame_options::parse_standard_inis(m_options, option_errors);
+ m_osd.set_verbose(m_options.verbose());
+ }
// otherwise, check for a valid system
load_translation(m_options);
@@ -291,14 +295,25 @@ int cli_frontend::execute(std::vector<std::string> &args)
// get the top 16 approximate matches
driver_enumerator drivlist(m_options);
int matches[16];
- drivlist.find_approximate_matches(m_options.attempted_system_name().c_str(), ARRAY_LENGTH(matches), matches);
+ drivlist.find_approximate_matches(m_options.attempted_system_name(), ARRAY_LENGTH(matches), matches);
+
+ // work out how wide the titles need to be
+ int titlelen(0);
+ for (int match : matches)
+ if (0 <= match)
+ titlelen = (std::max)(titlelen, int(strlen(drivlist.driver(match).type.fullname())));
// print them out
osd_printf_error("\n\"%s\" approximately matches the following\n"
"supported machines (best match first):\n\n", m_options.attempted_system_name().c_str());
- for (auto & matche : matches)
- if (matche != -1)
- osd_printf_error("%-18s%s\n", drivlist.driver(matche).name, drivlist.driver(matche).type.fullname());
+ for (int match : matches)
+ {
+ if (0 <= match)
+ {
+ game_driver const &drv(drivlist.driver(match));
+ osd_printf_error("%s", util::string_format("%-18s%-*s(%s, %s)\n", drv.name, titlelen + 2, drv.type.fullname(), drv.manufacturer, drv.year).c_str());
+ }
+ }
}
}
catch (emu_exception &)
@@ -349,77 +364,20 @@ void cli_frontend::listxml(const std::vector<std::string> &args)
void cli_frontend::listfull(const std::vector<std::string> &args)
{
- bool const iswild((1U != args.size()) || core_iswildstr(args[0].c_str()));
- std::vector<bool> matched(args.size(), false);
- auto const included = [&args, &matched] (char const *name) -> bool
- {
- if (args.empty())
- return true;
-
- bool result = false;
- auto it = matched.begin();
- for (std::string const &pat : args)
- {
- if (!core_strwildcmp(pat.c_str(), name))
- {
- result = true;
- *it = true;
- }
- ++it;
- }
- return result;
- };
-
- bool first = true;
- auto const list_system_name = [&first] (device_type const &type)
+ auto const list_system_name = [] (device_type type, bool first)
{
// print the header
if (first)
osd_printf_info("Name: Description:\n");
- first = false;
osd_printf_info("%-17s \"%s\"\n", type.shortname(), type.fullname());
};
-
- // determine which drivers to output
- driver_enumerator drivlist(m_options);
- while (drivlist.next())
- {
- if (included(drivlist.driver().name))
- {
- list_system_name(drivlist.driver().type);
-
- // if it wasn't a wildcard, there can only be one
- if (!iswild)
- break;
- }
- }
-
- // try devices as well
- if (iswild || first)
- {
- for (device_type type : registered_device_types)
- {
- if (included(type.shortname()))
- {
- list_system_name(type);
-
- // if it wasn't a wildcard, there can only be one
- if (!iswild)
- break;
- }
- }
- }
-
- // return an error if none found
- auto it = matched.begin();
- for (std::string const &pat : args)
- {
- if (!*it)
- throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching systems found for '%s'", pat.c_str());
-
- ++it;
- }
+ apply_action(
+ args,
+ [&list_system_name] (driver_enumerator &drivlist, bool first)
+ { list_system_name(drivlist.driver().type, first); },
+ [&list_system_name] (device_type type, bool first)
+ { list_system_name(type, first); });
}
@@ -430,16 +388,16 @@ void cli_frontend::listfull(const std::vector<std::string> &args)
void cli_frontend::listsource(const std::vector<std::string> &args)
{
- const char *gamename = args.empty() ? nullptr : args[0].c_str();
-
- // determine which drivers to output; return an error if none found
- driver_enumerator drivlist(m_options, gamename);
- if (drivlist.count() == 0)
- throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching systems found for '%s'", gamename);
-
- // iterate through drivers and output the info
- while (drivlist.next())
- osd_printf_info("%-16s %s\n", drivlist.driver().name, core_filename_extract_base(drivlist.driver().type.source()).c_str());
+ auto const list_system_source = [] (device_type type)
+ {
+ osd_printf_info("%-16s %s\n", type.shortname(), core_filename_extract_base(type.source()).c_str());
+ };
+ apply_action(
+ args,
+ [&list_system_source] (driver_enumerator &drivlist, bool first)
+ { list_system_source(drivlist.driver().type); },
+ [&list_system_source] (device_type type, bool first)
+ { list_system_source(type); });
}
@@ -547,164 +505,92 @@ void cli_frontend::listbrothers(const std::vector<std::string> &args)
void cli_frontend::listcrc(const std::vector<std::string> &args)
{
- const char *gamename = args.empty() ? nullptr : args[0].c_str();
-
- // determine which drivers to output; return an error if none found
- driver_enumerator drivlist(m_options, gamename);
- if (drivlist.count() == 0)
- throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching systems found for '%s'", gamename);
-
- // iterate through matches, and then through ROMs
- while (drivlist.next())
- {
- for (device_t const &device : device_iterator(drivlist.config()->root_device()))
- {
- for (tiny_rom_entry const *rom = device.rom_region(); rom && !ROMENTRY_ISEND(rom); ++rom)
+ apply_device_action(
+ args,
+ [] (device_t &root, char const *type, bool first)
{
- if (ROMENTRY_ISFILE(rom))
+ for (device_t const &device : device_iterator(root))
{
- // if we have a CRC, display it
- uint32_t crc;
- if (util::hash_collection(rom->hashdata).crc(crc))
- osd_printf_info("%08x %-32s\t%-16s\t%s\n", crc, rom->name, device.shortname(), device.name());
+ for (tiny_rom_entry const *rom = device.rom_region(); rom && !ROMENTRY_ISEND(rom); ++rom)
+ {
+ if (ROMENTRY_ISFILE(rom))
+ {
+ // if we have a CRC, display it
+ uint32_t crc;
+ if (util::hash_collection(rom->hashdata).crc(crc))
+ osd_printf_info("%08x %-32s\t%-16s\t%s\n", crc, rom->name, device.shortname(), device.name());
+ }
+ }
}
- }
- }
- }
+ });
}
//-------------------------------------------------
// listroms - output the list of ROMs referenced
-// by a given game or set of games
+// by matching systems/devices
//-------------------------------------------------
void cli_frontend::listroms(const std::vector<std::string> &args)
{
- bool const iswild((1U != args.size()) || core_iswildstr(args[0].c_str()));
- std::vector<bool> matched(args.size(), false);
- auto const included = [&args, &matched] (char const *name) -> bool
- {
- if (args.empty())
- return true;
-
- bool result = false;
- auto it = matched.begin();
- for (std::string const &pat : args)
- {
- if (!core_strwildcmp(pat.c_str(), name))
+ apply_device_action(
+ args,
+ [] (device_t &root, char const *type, bool first)
{
- result = true;
- *it = true;
- }
- ++it;
- }
- return result;
- };
-
- bool first = true;
- auto const list_system_roms = [&first] (device_t &root, char const *type)
- {
- // print a header
- if (!first)
- osd_printf_info("\n");
- first = false;
+ // space between items
+ if (!first)
+ osd_printf_info("\n");
- // iterate through roms
- bool hasroms = false;
- for (device_t const &device : device_iterator(root))
- {
- for (const rom_entry *region = rom_first_region(device); region; region = rom_next_region(region))
- {
- for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ // iterate through ROMs
+ bool hasroms = false;
+ for (device_t const &device : device_iterator(root))
{
- // print a header
- if (!hasroms)
- osd_printf_info(
- "ROMs required for %s \"%s\".\n"
- "%-32s %10s %s\n",
- type, root.shortname(), "Name", "Size", "Checksum");
- hasroms = true;
-
- // accumulate the total length of all chunks
- int64_t length = -1;
- if (ROMREGION_ISROMDATA(region))
- length = rom_file_size(rom);
-
- // start with the name
- const char *name = ROM_GETNAME(rom);
- osd_printf_info("%-32s ", name);
-
- // output the length next
- if (length >= 0)
- osd_printf_info("%10u", unsigned(uint64_t(length)));
- else
- osd_printf_info("%10s", "");
-
- // output the hash data
- util::hash_collection hashes(ROM_GETHASHDATA(rom));
- if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
+ for (const rom_entry *region = rom_first_region(device); region; region = rom_next_region(region))
{
- if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP))
- osd_printf_info(" BAD");
- osd_printf_info(" %s", hashes.macro_string().c_str());
- }
- else
- osd_printf_info(" NO GOOD DUMP KNOWN");
+ for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom))
+ {
+ // print a header
+ if (!hasroms)
+ osd_printf_info(
+ "ROMs required for %s \"%s\".\n"
+ "%-32s %10s %s\n",
+ type, root.shortname(), "Name", "Size", "Checksum");
+ hasroms = true;
+
+ // accumulate the total length of all chunks
+ int64_t length = -1;
+ if (ROMREGION_ISROMDATA(region))
+ length = rom_file_size(rom);
+
+ // start with the name
+ const char *name = ROM_GETNAME(rom);
+ osd_printf_info("%-32s ", name);
+
+ // output the length next
+ if (length >= 0)
+ osd_printf_info("%10u", unsigned(uint64_t(length)));
+ else
+ osd_printf_info("%10s", "");
+
+ // output the hash data
+ util::hash_collection hashes(ROM_GETHASHDATA(rom));
+ if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
+ {
+ if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP))
+ osd_printf_info(" BAD");
+ osd_printf_info(" %s", hashes.macro_string().c_str());
+ }
+ else
+ osd_printf_info(" NO GOOD DUMP KNOWN");
- // end with a CR
- osd_printf_info("\n");
+ // end with a CR
+ osd_printf_info("\n");
+ }
+ }
}
- }
- }
- if (!hasroms)
- osd_printf_info("No ROMs required for %s \"%s\".\n", type, root.shortname());
- };
-
- // determine which drivers to output
- driver_enumerator drivlist(m_options);
-
- // iterate through matches
- while (drivlist.next())
- {
- if (included(drivlist.driver().name))
- {
- list_system_roms(drivlist.config()->root_device(), "driver");
-
- // if it wasn't a wildcard, there can only be one
- if (!iswild)
- break;
- }
- }
-
- if (iswild || first)
- {
- machine_config config(GAME_NAME(___empty), m_options);
- machine_config::token const tok(config.begin_configuration(config.root_device()));
- for (device_type type : registered_device_types)
- {
- if (included(type.shortname()))
- {
- device_t *const dev = config.device_add("_tmp", type, 0);
- list_system_roms(*dev, "device");
- config.device_remove("_tmp");
-
- // if it wasn't a wildcard, there can only be one
- if (!iswild)
- break;
- }
- }
- }
-
- // return an error if none found
- auto it = matched.begin();
- for (std::string const &pat : args)
- {
- if (!*it)
- throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching systems found for '%s'", pat.c_str());
-
- ++it;
- }
+ if (!hasroms)
+ osd_printf_info("No ROMs required for %s \"%s\".\n", type, root.shortname());
+ });
}
@@ -1223,7 +1109,7 @@ void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlis
for (const feature_list_item &flist : part.featurelist())
fprintf(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name().c_str(), util::xml::normalize_string(flist.value().c_str()));
- /* TODO: display rom region information */
+ // TODO: display ROM region information
for (const rom_entry *region = part.romdata().data(); region; region = rom_next_region(region))
{
int is_disk = ROMREGION_ISDISKDATA(region);
@@ -1354,7 +1240,7 @@ void cli_frontend::listsoftware(const std::vector<std::string> &args)
/*-------------------------------------------------
- verifysoftware - verify roms from the software
+ verifysoftware - verify ROMs from the software
list of the specified driver(s)
-------------------------------------------------*/
void cli_frontend::verifysoftware(const std::vector<std::string> &args)
@@ -1427,6 +1313,7 @@ void cli_frontend::verifysoftware(const std::vector<std::string> &args)
}
+
/*-------------------------------------------------
getsoftlist - retrieve software list by name
-------------------------------------------------*/
@@ -1561,6 +1448,105 @@ void cli_frontend::romident(const std::vector<std::string> &args)
//-------------------------------------------------
+// apply_action - apply action to matching
+// systems/devices
+//-------------------------------------------------
+
+template <typename T, typename U> void cli_frontend::apply_action(const std::vector<std::string> &args, T &&drvact, U &&devact)
+
+{
+ bool const iswild((1U != args.size()) || core_iswildstr(args[0].c_str()));
+ std::vector<bool> matched(args.size(), false);
+ auto const included = [&args, &matched] (char const *name) -> bool
+ {
+ if (args.empty())
+ return true;
+
+ bool result = false;
+ auto it = matched.begin();
+ for (std::string const &pat : args)
+ {
+ if (!core_strwildcmp(pat.c_str(), name))
+ {
+ result = true;
+ *it = true;
+ }
+ ++it;
+ }
+ return result;
+ };
+
+ // determine which drivers to output
+ driver_enumerator drivlist(m_options);
+
+ // iterate through matches
+ bool first(true);
+ while (drivlist.next())
+ {
+ if (included(drivlist.driver().name))
+ {
+ drvact(drivlist, first);
+ first = false;
+
+ // if it wasn't a wildcard, there can only be one
+ if (!iswild)
+ break;
+ }
+ }
+
+ if (iswild || first)
+ {
+ for (device_type type : registered_device_types)
+ {
+ if (included(type.shortname()))
+ {
+ devact(type, first);
+ first = false;
+
+ // if it wasn't a wildcard, there can only be one
+ if (!iswild)
+ break;
+ }
+ }
+ }
+
+ // return an error if none found
+ auto it = matched.begin();
+ for (std::string const &pat : args)
+ {
+ if (!*it)
+ throw emu_fatalerror(EMU_ERR_NO_SUCH_GAME, "No matching systems found for '%s'", pat.c_str());
+
+ ++it;
+ }
+}
+
+
+//-------------------------------------------------
+// apply_device_action - apply action to matching
+// systems/devices
+//-------------------------------------------------
+
+template <typename T> void cli_frontend::apply_device_action(const std::vector<std::string> &args, T &&action)
+{
+ machine_config config(GAME_NAME(___empty), m_options);
+ machine_config::token const tok(config.begin_configuration(config.root_device()));
+ apply_action(
+ args,
+ [&action] (driver_enumerator &drivlist, bool first)
+ {
+ action(drivlist.config()->root_device(), "driver", first);
+ },
+ [&action, &config] (device_type type, bool first)
+ {
+ device_t *const dev = config.device_add("_tmp", type, 0);
+ action(*dev, "device", first);
+ config.device_remove("_tmp");
+ });
+}
+
+
+//-------------------------------------------------
// find_command
//-------------------------------------------------
@@ -1570,10 +1556,10 @@ const cli_frontend::info_command_struct *cli_frontend::find_command(const std::s
{
{ CLICOMMAND_LISTXML, 0, -1, &cli_frontend::listxml, "[pattern] ..." },
{ CLICOMMAND_LISTFULL, 0, -1, &cli_frontend::listfull, "[pattern] ..." },
- { CLICOMMAND_LISTSOURCE, 0, 1, &cli_frontend::listsource, "[system name]" },
+ { CLICOMMAND_LISTSOURCE, 0, -1, &cli_frontend::listsource, "[system name]" },
{ CLICOMMAND_LISTCLONES, 0, 1, &cli_frontend::listclones, "[system name]" },
{ CLICOMMAND_LISTBROTHERS, 0, 1, &cli_frontend::listbrothers, "[system name]" },
- { CLICOMMAND_LISTCRC, 0, 1, &cli_frontend::listcrc, "[system name]" },
+ { CLICOMMAND_LISTCRC, 0, -1, &cli_frontend::listcrc, "[system name]" },
{ CLICOMMAND_LISTDEVICES, 0, 1, &cli_frontend::listdevices, "[system name]" },
{ CLICOMMAND_LISTSLOTS, 0, 1, &cli_frontend::listslots, "[system name]" },
{ CLICOMMAND_LISTROMS, 0, -1, &cli_frontend::listroms, "[pattern] ..." },
@@ -1622,6 +1608,11 @@ void cli_frontend::execute_commands(const char *exename)
// validate?
if (m_options.command() == CLICOMMAND_VALIDATE)
{
+ if (m_options.command_arguments().size() > 1)
+ {
+ osd_printf_error("Auxiliary verb -validate takes at most 1 argument\n");
+ return;
+ }
validity_checker valid(m_options);
valid.set_validate_all(true);
const char *sysname = m_options.command_arguments().empty() ? nullptr : m_options.command_arguments()[0].c_str();
@@ -1689,9 +1680,9 @@ void cli_frontend::execute_commands(const char *exename)
// validate argument count
const char *error_message = nullptr;
if (m_options.command_arguments().size() < info_command->min_args)
- error_message = "Auxillary verb -%s requires at least %d argument(s)\n";
+ error_message = "Auxiliary verb -%s requires at least %d argument(s)\n";
if ((info_command->max_args >= 0) && (m_options.command_arguments().size() > info_command->max_args))
- error_message = "Auxillary verb -%s takes at most %d argument(s)\n";
+ error_message = "Auxiliary verb -%s takes at most %d argument(s)\n";
if (error_message)
{
osd_printf_info(error_message, info_command->option, info_command->max_args);
@@ -1700,7 +1691,7 @@ void cli_frontend::execute_commands(const char *exename)
return;
}
- // invoke the auxillary command!
+ // invoke the auxiliary command!
(this->*info_command->function)(m_options.command_arguments());
return;
}