From 291bfb64328a466adf482e716d69c294e62e1f35 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 19 Dec 2019 20:08:27 +1100 Subject: [PATCH] Make -listsoftware and -getsoflist recognise software lists that come from slot cards. (nw) These verbs are still horribly inefficient and don't preserve all the information from the input software list. This isn't supposed to solve those problems, it just makes the verbs no longer blind to stuff like the Spectrum Miles Gordon floppy list and Spectrum Wafadrive list. --- src/frontend/mame/clifront.cpp | 178 +++++++++++++++++---------------- src/frontend/mame/clifront.h | 2 +- 2 files changed, 91 insertions(+), 89 deletions(-) diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp index 3316240ea9b..e50f8276567 100644 --- a/src/frontend/mame/clifront.cpp +++ b/src/frontend/mame/clifront.cpp @@ -1083,36 +1083,36 @@ const char cli_frontend::s_softlist_xml_dtd[] = "\t\t\t\t\t\t\n" \ "]>\n\n"; -void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlistdev) +void cli_frontend::output_single_softlist(std::ostream &out, software_list_device &swlistdev) { - fprintf(out, "\t\n", swlistdev.list_name().c_str(), util::xml::normalize_string(swlistdev.description().c_str())); + util::stream_format(out, "\t\n", swlistdev.list_name(), util::xml::normalize_string(swlistdev.description().c_str())); for (const software_info &swinfo : swlistdev.get_info()) { - fprintf(out, "\t\t\n" ); - fprintf(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.longname().c_str())); - fprintf(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.year().c_str())); - fprintf(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.publisher().c_str())); + out << " supported=\"no\""; + out << ">\n"; + util::stream_format(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.longname().c_str())); + util::stream_format(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.year().c_str())); + util::stream_format(out, "\t\t\t%s\n", util::xml::normalize_string(swinfo.publisher().c_str())); for (const feature_list_item &flist : swinfo.other_info()) - fprintf( out, "\t\t\t\n", flist.name().c_str(), util::xml::normalize_string( flist.value().c_str()) ); + util::stream_format(out, "\t\t\t\n", flist.name().c_str(), util::xml::normalize_string(flist.value().c_str())); for (const software_part &part : swinfo.parts()) { - fprintf(out, "\t\t\t\n"); + out << ">\n"; for (const feature_list_item &flist : part.featurelist()) - fprintf(out, "\t\t\t\t\n", flist.name().c_str(), util::xml::normalize_string(flist.value().c_str())); + util::stream_format(out, "\t\t\t\t\n", flist.name().c_str(), util::xml::normalize_string(flist.value().c_str())); // TODO: display ROM region information for (const rom_entry *region = part.romdata().data(); region; region = rom_next_region(region)) @@ -1120,84 +1120,86 @@ void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlis int is_disk = ROMREGION_ISDISKDATA(region); if (!is_disk) - fprintf( out, "\t\t\t\t\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) ); + util::stream_format(out, "\t\t\t\t\n", util::xml::normalize_string(ROMREGION_GETTAG(region)), ROMREGION_GETLENGTH(region)); else - fprintf( out, "\t\t\t\t\n", ROMREGION_GETTAG(region) ); + util::stream_format(out, "\t\t\t\t\n", util::xml::normalize_string(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\n" ); + out << "/>\n"; } - else if ( ROMENTRY_ISRELOAD(rom) ) + else if (ROMENTRY_ISRELOAD(rom)) { - fprintf( out, "\t\t\t\t\t\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); + util::stream_format(out, "\t\t\t\t\t\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom)); } - else if ( ROMENTRY_ISFILL(rom) ) + else if (ROMENTRY_ISFILL(rom)) { - fprintf( out, "\t\t\t\t\t\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); + util::stream_format(out, "\t\t\t\t\t\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom)); } } if (!is_disk) - fprintf( out, "\t\t\t\t\n" ); + out << "\t\t\t\t\n"; else - fprintf( out, "\t\t\t\t\n" ); + out << "\t\t\t\t\n"; } - fprintf( out, "\t\t\t\n" ); + out << "\t\t\t\n"; } - fprintf( out, "\t\t\n" ); + out << "\t\t\n"; } - fprintf(out, "\t\n" ); + out << "\t\n"; } + + /*------------------------------------------------- info_listsoftware - output the list of software supported by a given game or set of @@ -1207,38 +1209,35 @@ void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlis void cli_frontend::listsoftware(const std::vector &args) { - const char *gamename = args.empty() ? nullptr : args[0].c_str(); - - FILE *out = stdout; std::unordered_set list_map; - bool isfirst = true; - - // 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_SYSTEM, "No matching systems found for '%s'", gamename); - - while (drivlist.next()) - { - for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config()->root_device())) - if (list_map.insert(swlistdev.list_name()).second) - if (!swlistdev.get_info().empty()) + bool firstlist(true); + apply_device_action( + args, + [this, &list_map, &firstlist] (device_t &root, char const *type, bool first) + { + for (software_list_device &swlistdev : software_list_device_iterator(root)) { - if (isfirst) + if (list_map.insert(swlistdev.list_name()).second) { - if (m_options.bool_value(CLIOPTION_DTD)) - fprintf(out, s_softlist_xml_dtd); - fprintf(out, "\n"); - isfirst = false; + if (!swlistdev.get_info().empty()) + { + if (firstlist) + { + if (m_options.bool_value(CLIOPTION_DTD)) + std::cout << s_softlist_xml_dtd; + std::cout << "\n"; + firstlist = false; + } + output_single_softlist(std::cout, swlistdev); + } } - output_single_softlist(out, swlistdev); } - } + }); - if (!isfirst) - fprintf( out, "\n" ); + if (!firstlist) + std::cout << "\n"; else - fprintf( out, "No software lists found for this system\n" ); + fprintf(stdout, "No software lists found for this system\n"); // TODO: should this go to stderr instead? } @@ -1325,32 +1324,35 @@ void cli_frontend::getsoftlist(const std::vector &args) { const char *gamename = args.empty() ? "*" : args[0].c_str(); - FILE *out = stdout; std::unordered_set list_map; - bool isfirst = true; - - driver_enumerator drivlist(m_options); - while (drivlist.next()) - { - for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config()->root_device())) - if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second) - if (!swlistdev.get_info().empty()) + bool firstlist(true); + apply_device_action( + std::vector(), + [this, gamename, &list_map, &firstlist] (device_t &root, char const *type, bool first) + { + for (software_list_device &swlistdev : software_list_device_iterator(root)) { - if (isfirst) + if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second) { - if (m_options.bool_value(CLIOPTION_DTD)) - fprintf(out, s_softlist_xml_dtd); - fprintf(out, "\n"); - isfirst = false; + if (!swlistdev.get_info().empty()) + { + if (firstlist) + { + if (m_options.bool_value(CLIOPTION_DTD)) + std::cout << s_softlist_xml_dtd; + std::cout << "\n"; + firstlist = false; + } + output_single_softlist(std::cout, swlistdev); + } } - output_single_softlist(out, swlistdev); } - } + }); - if (!isfirst) - fprintf( out, "\n" ); + if (!firstlist) + std::cout << "\n"; else - fprintf( out, "No such software lists found\n" ); + fprintf(stdout, "No such software lists found\n"); // TODO: should this go to stderr instead? } diff --git a/src/frontend/mame/clifront.h b/src/frontend/mame/clifront.h index 84157f2a6d8..8a2ae059b6c 100644 --- a/src/frontend/mame/clifront.h +++ b/src/frontend/mame/clifront.h @@ -72,7 +72,7 @@ private: template void apply_device_action(const std::vector &args, T &&action); void execute_commands(const char *exename); void display_help(const char *exename); - void output_single_softlist(FILE *out, software_list_device &swlist); + void output_single_softlist(std::ostream &out, software_list_device &swlist); void start_execution(mame_machine_manager *manager, const std::vector &args); static const info_command_struct *find_command(const std::string &s);