mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
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.
This commit is contained in:
parent
4ca22933bc
commit
291bfb6432
@ -1083,36 +1083,36 @@ const char cli_frontend::s_softlist_xml_dtd[] =
|
|||||||
"\t\t\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" \
|
"\t\t\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" \
|
||||||
"]>\n\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<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name().c_str(), util::xml::normalize_string(swlistdev.description().c_str()));
|
util::stream_format(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), util::xml::normalize_string(swlistdev.description().c_str()));
|
||||||
for (const software_info &swinfo : swlistdev.get_info())
|
for (const software_info &swinfo : swlistdev.get_info())
|
||||||
{
|
{
|
||||||
fprintf(out, "\t\t<software name=\"%s\"", swinfo.shortname().c_str());
|
util::stream_format(out, "\t\t<software name=\"%s\"", util::xml::normalize_string(swinfo.shortname().c_str()));
|
||||||
if (!swinfo.parentname().empty())
|
if (!swinfo.parentname().empty())
|
||||||
fprintf(out, " cloneof=\"%s\"", swinfo.parentname().c_str());
|
util::stream_format(out, " cloneof=\"%s\"", util::xml::normalize_string(swinfo.parentname().c_str()));
|
||||||
if (swinfo.supported() == SOFTWARE_SUPPORTED_PARTIAL)
|
if (swinfo.supported() == SOFTWARE_SUPPORTED_PARTIAL)
|
||||||
fprintf(out, " supported=\"partial\"");
|
out << " supported=\"partial\"";
|
||||||
if (swinfo.supported() == SOFTWARE_SUPPORTED_NO)
|
if (swinfo.supported() == SOFTWARE_SUPPORTED_NO)
|
||||||
fprintf(out, " supported=\"no\"");
|
out << " supported=\"no\"";
|
||||||
fprintf(out, ">\n" );
|
out << ">\n";
|
||||||
fprintf(out, "\t\t\t<description>%s</description>\n", util::xml::normalize_string(swinfo.longname().c_str()));
|
util::stream_format(out, "\t\t\t<description>%s</description>\n", util::xml::normalize_string(swinfo.longname().c_str()));
|
||||||
fprintf(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str()));
|
util::stream_format(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str()));
|
||||||
fprintf(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str()));
|
util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str()));
|
||||||
|
|
||||||
for (const feature_list_item &flist : swinfo.other_info())
|
for (const feature_list_item &flist : swinfo.other_info())
|
||||||
fprintf( out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name().c_str(), util::xml::normalize_string( flist.value().c_str()) );
|
util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name().c_str(), util::xml::normalize_string(flist.value().c_str()));
|
||||||
|
|
||||||
for (const software_part &part : swinfo.parts())
|
for (const software_part &part : swinfo.parts())
|
||||||
{
|
{
|
||||||
fprintf(out, "\t\t\t<part name=\"%s\"", part.name().c_str());
|
util::stream_format(out, "\t\t\t<part name=\"%s\"", util::xml::normalize_string(part.name().c_str()));
|
||||||
if (!part.interface().empty())
|
if (!part.interface().empty())
|
||||||
fprintf(out, " interface=\"%s\"", part.interface().c_str());
|
util::stream_format(out, " interface=\"%s\"", util::xml::normalize_string(part.interface().c_str()));
|
||||||
|
|
||||||
fprintf(out, ">\n");
|
out << ">\n";
|
||||||
|
|
||||||
for (const feature_list_item &flist : part.featurelist())
|
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()));
|
util::stream_format(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))
|
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);
|
int is_disk = ROMREGION_ISDISKDATA(region);
|
||||||
|
|
||||||
if (!is_disk)
|
if (!is_disk)
|
||||||
fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) );
|
util::stream_format(out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", util::xml::normalize_string(ROMREGION_GETTAG(region)), ROMREGION_GETLENGTH(region));
|
||||||
else
|
else
|
||||||
fprintf( out, "\t\t\t\t<diskarea name=\"%s\">\n", ROMREGION_GETTAG(region) );
|
util::stream_format(out, "\t\t\t\t<diskarea name=\"%s\">\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)
|
if (!is_disk)
|
||||||
fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", util::xml::normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) );
|
util::stream_format(out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", util::xml::normalize_string(ROM_GETNAME(rom)), rom_file_size(rom));
|
||||||
else
|
else
|
||||||
fprintf( out, "\t\t\t\t\t<disk name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(rom)) );
|
util::stream_format(out, "\t\t\t\t\t<disk name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(rom)));
|
||||||
|
|
||||||
/* dump checksum information only if there is a known dump */
|
// dump checksum information only if there is a known dump
|
||||||
util::hash_collection hashes(ROM_GETHASHDATA(rom));
|
util::hash_collection hashes(ROM_GETHASHDATA(rom));
|
||||||
if ( !hashes.flag(util::hash_collection::FLAG_NO_DUMP) )
|
if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
|
||||||
fprintf( out, " %s", hashes.attribute_string().c_str() );
|
util::stream_format(out, " %s", util::xml::normalize_string(hashes.attribute_string().c_str()));
|
||||||
else
|
else
|
||||||
fprintf( out, " status=\"nodump\"" );
|
out << " status=\"nodump\"";
|
||||||
|
|
||||||
if (is_disk)
|
if (is_disk)
|
||||||
fprintf( out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes");
|
util::stream_format(out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes");
|
||||||
|
|
||||||
if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1))
|
if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1))
|
||||||
fprintf( out, " loadflag=\"load16_byte\"" );
|
out << " loadflag=\"load16_byte\"";
|
||||||
|
|
||||||
if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3))
|
if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3))
|
||||||
fprintf( out, " loadflag=\"load32_byte\"" );
|
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_SKIPMASK) == ROM_SKIP(2)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
|
||||||
{
|
{
|
||||||
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
||||||
fprintf( out, " loadflag=\"load32_word\"" );
|
out << " loadflag=\"load32_word\"";
|
||||||
else
|
else
|
||||||
fprintf( out, " loadflag=\"load32_word_swap\"" );
|
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_SKIPMASK) == ROM_SKIP(6)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
|
||||||
{
|
{
|
||||||
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
||||||
fprintf( out, " loadflag=\"load64_word\"" );
|
out << " loadflag=\"load64_word\"";
|
||||||
else
|
else
|
||||||
fprintf( out, " loadflag=\"load64_word_swap\"" );
|
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_SKIPMASK) == ROM_NOSKIP) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD))
|
||||||
{
|
{
|
||||||
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK))
|
||||||
fprintf( out, " loadflag=\"load32_dword\"" );
|
out << " loadflag=\"load32_dword\"";
|
||||||
else
|
else
|
||||||
fprintf( out, " loadflag=\"load16_word_swap\"" );
|
out << " loadflag=\"load16_word_swap\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( out, "/>\n" );
|
out << "/>\n";
|
||||||
}
|
}
|
||||||
else if ( ROMENTRY_ISRELOAD(rom) )
|
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) );
|
util::stream_format(out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom));
|
||||||
}
|
}
|
||||||
else if ( ROMENTRY_ISFILL(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) );
|
util::stream_format(out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"fill\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_disk)
|
if (!is_disk)
|
||||||
fprintf( out, "\t\t\t\t</dataarea>\n" );
|
out << "\t\t\t\t</dataarea>\n";
|
||||||
else
|
else
|
||||||
fprintf( out, "\t\t\t\t</diskarea>\n" );
|
out << "\t\t\t\t</diskarea>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( out, "\t\t\t</part>\n" );
|
out << "\t\t\t</part>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( out, "\t\t</software>\n" );
|
out << "\t\t</software>\n";
|
||||||
}
|
}
|
||||||
fprintf(out, "\t</softwarelist>\n" );
|
out << "\t</softwarelist>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
info_listsoftware - output the list of
|
info_listsoftware - output the list of
|
||||||
software supported by a given game or set 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<std::string> &args)
|
void cli_frontend::listsoftware(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
const char *gamename = args.empty() ? nullptr : args[0].c_str();
|
|
||||||
|
|
||||||
FILE *out = stdout;
|
|
||||||
std::unordered_set<std::string> list_map;
|
std::unordered_set<std::string> list_map;
|
||||||
bool isfirst = true;
|
bool firstlist(true);
|
||||||
|
apply_device_action(
|
||||||
// determine which drivers to output; return an error if none found
|
args,
|
||||||
driver_enumerator drivlist(m_options, gamename);
|
[this, &list_map, &firstlist] (device_t &root, char const *type, bool first)
|
||||||
if (drivlist.count() == 0)
|
{
|
||||||
throw emu_fatalerror(EMU_ERR_NO_SUCH_SYSTEM, "No matching systems found for '%s'", gamename);
|
for (software_list_device &swlistdev : software_list_device_iterator(root))
|
||||||
|
|
||||||
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 (list_map.insert(swlistdev.list_name()).second)
|
||||||
|
{
|
||||||
if (!swlistdev.get_info().empty())
|
if (!swlistdev.get_info().empty())
|
||||||
{
|
{
|
||||||
if (isfirst)
|
if (firstlist)
|
||||||
{
|
{
|
||||||
if (m_options.bool_value(CLIOPTION_DTD))
|
if (m_options.bool_value(CLIOPTION_DTD))
|
||||||
fprintf(out, s_softlist_xml_dtd);
|
std::cout << s_softlist_xml_dtd;
|
||||||
fprintf(out, "<softwarelists>\n");
|
std::cout << "<softwarelists>\n";
|
||||||
isfirst = false;
|
firstlist = false;
|
||||||
}
|
}
|
||||||
output_single_softlist(out, swlistdev);
|
output_single_softlist(std::cout, swlistdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!isfirst)
|
if (!firstlist)
|
||||||
fprintf( out, "</softwarelists>\n" );
|
std::cout << "</softwarelists>\n";
|
||||||
else
|
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<std::string> &args)
|
|||||||
{
|
{
|
||||||
const char *gamename = args.empty() ? "*" : args[0].c_str();
|
const char *gamename = args.empty() ? "*" : args[0].c_str();
|
||||||
|
|
||||||
FILE *out = stdout;
|
|
||||||
std::unordered_set<std::string> list_map;
|
std::unordered_set<std::string> list_map;
|
||||||
bool isfirst = true;
|
bool firstlist(true);
|
||||||
|
apply_device_action(
|
||||||
driver_enumerator drivlist(m_options);
|
std::vector<std::string>(),
|
||||||
while (drivlist.next())
|
[this, gamename, &list_map, &firstlist] (device_t &root, char const *type, bool first)
|
||||||
|
{
|
||||||
|
for (software_list_device &swlistdev : software_list_device_iterator(root))
|
||||||
{
|
{
|
||||||
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 (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second)
|
||||||
|
{
|
||||||
if (!swlistdev.get_info().empty())
|
if (!swlistdev.get_info().empty())
|
||||||
{
|
{
|
||||||
if (isfirst)
|
if (firstlist)
|
||||||
{
|
{
|
||||||
if (m_options.bool_value(CLIOPTION_DTD))
|
if (m_options.bool_value(CLIOPTION_DTD))
|
||||||
fprintf(out, s_softlist_xml_dtd);
|
std::cout << s_softlist_xml_dtd;
|
||||||
fprintf(out, "<softwarelists>\n");
|
std::cout << "<softwarelists>\n";
|
||||||
isfirst = false;
|
firstlist = false;
|
||||||
}
|
}
|
||||||
output_single_softlist(out, swlistdev);
|
output_single_softlist(std::cout, swlistdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!isfirst)
|
if (!firstlist)
|
||||||
fprintf( out, "</softwarelists>\n" );
|
std::cout << "</softwarelists>\n";
|
||||||
else
|
else
|
||||||
fprintf( out, "No such software lists found\n" );
|
fprintf(stdout, "No such software lists found\n"); // TODO: should this go to stderr instead?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ private:
|
|||||||
template <typename T> void apply_device_action(const std::vector<std::string> &args, T &&action);
|
template <typename T> void apply_device_action(const std::vector<std::string> &args, T &&action);
|
||||||
void execute_commands(const char *exename);
|
void execute_commands(const char *exename);
|
||||||
void display_help(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<std::string> &args);
|
void start_execution(mame_machine_manager *manager, const std::vector<std::string> &args);
|
||||||
static const info_command_struct *find_command(const std::string &s);
|
static const info_command_struct *find_command(const std::string &s);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user