diff options
Diffstat (limited to 'src/frontend/mame/clifront.cpp')
-rw-r--r-- | src/frontend/mame/clifront.cpp | 451 |
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; } |