New driver specifiers; changes to -listclones, -listsource; add -listtree

Five new specifiers for driver enumeration and all commands depending thereon:
- @source.cpp matches all drivers in source.cpp
- ^driver matches driver and all its clones
- :drivbios matches drivbios and all drivers having it as their BIOS
- ^ matches all drivers excluding clone sets
- : matches all BIOS roots

Note that these new specifiers are not compatible with other wildcards; they only perform normal case-insensitive matches with driver or source file names.

The -listclones command now lists drivers in a completely different, human-readable format. It performs an extra loop to deduce the parent set name if a clone was specified; this causes, for instance, -listclones pacman and -listclones puckman to produce identical output. It includes descriptions with the clone driver names much like -listfull, and uses the parent set's description as a header for its clones. It also recognizes BIOSes and lists unique matching sets with no clones at the end of the output.

The -listsource command outputs not only the source file of each matching driver, but also its parent set and BIOS root (if any). These are output using the new @sourcefile, ^driver and :bios specifiers.

The new -listtree command is a human-readable analogue to -listsource and an alternative to -listclones. It tabulates drivers by source file in tree format, with the names of clones indented under their parents and drivers indented under their respective BIOS roots.

The -listbrothers command remains functionally unchanged, but should be considered somewhat deprecated in favor of the @sourcefile specifier with other listing commands.

Fix include_all counting error causing assert to fail in find_approximate_matches (nw)

Relax dependencies on drivenum.h in UI headers (nw)
This commit is contained in:
AJR 2016-02-24 18:47:37 -05:00
parent 5a31d8513b
commit 3fc0787fa8
21 changed files with 342 additions and 70 deletions

View File

@ -229,7 +229,7 @@ int cli_frontend::execute(int argc, char **argv)
// if a game was specified, wasn't a wildcard, and our error indicates this was the
// reason for failure, offer some suggestions
if (m_result == MAMERR_NO_SUCH_GAME && *(m_options.system_name()) != 0 && strchr(m_options.system_name(), '*') == nullptr && m_options.system() == nullptr)
if (m_result == MAMERR_NO_SUCH_GAME && *(m_options.system_name()) != 0 && strchr(m_options.system_name(), '*') == nullptr)
{
// get the top 16 approximate matches
driver_enumerator drivlist(m_options);
@ -326,7 +326,16 @@ void cli_frontend::listsource(const char *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().source_file).c_str());
{
osd_printf_info("%-16s @%s", drivlist.driver().name, core_filename_extract_base(drivlist.driver().source_file).c_str());
int bios = drivlist.bios_root();
if (bios != -1)
osd_printf_info(" :%s", drivlist.driver(bios).name);
int parent = drivlist.non_bios_clone();
if (parent != -1)
osd_printf_info(" ^%s", drivlist.driver(parent).name);
osd_printf_info("\n");
}
}
@ -339,39 +348,123 @@ void cli_frontend::listclones(const char *gamename)
{
// 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 & MACHINE_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
osd_printf_info("Found %d matches for '%s' but none were clones\n", drivlist.count(), gamename);
return;
}
throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename);
// print the header
osd_printf_info("Name: Clone of:\n");
// iterate through drivers and output the info
drivlist.reset();
// find the parent sets and BIOSes of the matching drivers
driver_enumerator parentlist(m_options);
driver_enumerator bioslist(m_options);
parentlist.exclude_all();
bioslist.exclude_all();
while (drivlist.next())
{
int clone_of = drivlist.clone();
if (clone_of != -1 && (drivlist.driver(clone_of).flags & MACHINE_IS_BIOS_ROOT) == 0)
osd_printf_info("%-16s %-8s\n", drivlist.driver().name, drivlist.driver(clone_of).name);
// check if we have a non-bios clone
int clone_of = drivlist.non_bios_clone();
if (clone_of != -1)
{
// add the parent to the list
drivlist.include(clone_of);
parentlist.include(clone_of);
}
// add BIOS roots to a separate list
int bios = drivlist.bios_root();
if (bios != -1)
bioslist.include(bios);
}
// iterate through the remaining ones to see if their parent matches
drivlist.reset();
while (drivlist.next_excluded())
{
// if we have a non-bios clone and it matches, keep it
int clone_of = drivlist.non_bios_clone();
if (clone_of != -1 && drivlist.included(clone_of))
{
drivlist.include();
parentlist.include(clone_of);
}
}
if (parentlist.count() == 0)
osd_printf_info("No clones found for games matching '%s'\n", gamename);
else
{
// iterate through the list of parents
parentlist.reset();
bool first = true;
while (parentlist.next())
{
int bios = parentlist.bios_root();
// print a separate header for each parent
if (!first)
osd_printf_info("\n");
first = false;
if (bios == -1)
osd_printf_info("Clones of \"%s\" (%s):\n", parentlist.driver().description, parentlist.driver().name);
else
{
osd_printf_info("Clones of \"%s\" (%s, %s BIOS):\n", parentlist.driver().description, parentlist.driver().name, parentlist.driver(bios).name);
drivlist.exclude(bios);
}
// prevent further output about parent
drivlist.exclude(parentlist.current());
// iterate through drivers
drivlist.reset();
while (drivlist.next())
{
// keep clones of the same parent together
if (drivlist.is_clone_of(parentlist.current()))
{
// output the info and remove the driver from the list
osd_printf_info("%-18s\"%s\"\n", drivlist.driver().name, drivlist.driver().description);
drivlist.exclude();
}
}
}
}
// sort non-clone sets by BIOS, if any
bioslist.reset();
while (bioslist.next() && drivlist.count() != 0)
{
// iterate over the remaining drivers
bool first = true;
drivlist.reset();
while (drivlist.next())
{
if (drivlist.bios_root() == bioslist.current())
{
// print a header for the BIOS
if (first)
{
osd_printf_info("\nOther sets (%s BIOS):\n", bioslist.driver().name);
drivlist.exclude(bioslist.current());
first = false;
}
// output the info and remove the driver from the list
osd_printf_info("%-18s\"%s\"\n", drivlist.driver().name, drivlist.driver().description);
drivlist.exclude();
}
}
}
// finally list any remaining matching drivers that have no clones
if (drivlist.count() != 0)
{
// print a header
osd_printf_info("\nUnique sets:\n");
// iterate and output the info
drivlist.reset();
while (drivlist.next())
osd_printf_info("%-18s\"%s\"\n", drivlist.driver().name, drivlist.driver().description);
}
}
@ -420,6 +513,125 @@ void cli_frontend::listbrothers(const char *gamename)
}
//-------------------------------------------------
// listtree - output a tree of matching games,
// their parents and BIOS roots, separated by
// source file
//-------------------------------------------------
void cli_frontend::listtree(const char *gamename)
{
// 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);
// scan through the initially-selected drivers
bool first = true;
while (initial_drivlist.next())
{
// get the source file and print the header
if (!first)
osd_printf_info("\n");
first = false;
const char *source = initial_drivlist.driver().source_file;
osd_printf_info("Drivers in source file %s:\n", core_filename_extract_base(source).c_str());
// build a new brother list for each source file
driver_enumerator drivlist(m_options);
driver_enumerator brotherlist(m_options);
driver_enumerator bioslist(m_options);
drivlist.exclude_all();
brotherlist.exclude_all();
bioslist.exclude_all();
// walk the initial driver list and mark those with the same source
initial_drivlist.reset();
while (initial_drivlist.next())
{
if (strcmp(initial_drivlist.driver().source_file, source) == 0)
{
brotherlist.include(initial_drivlist.current());
int parent = initial_drivlist.non_bios_clone();
drivlist.include(parent != -1 ? parent : initial_drivlist.current());
int bios = initial_drivlist.bios_root();
if (bios != -1)
bioslist.include(bios);
initial_drivlist.exclude();
}
}
// output the entries found for each source file (with BIOS root)
bioslist.reset();
while (bioslist.next())
{
if (strcmp(bioslist.driver().source_file, source) != 0)
osd_printf_info("%-16s (BIOS root in %s)\n", bioslist.driver().name, core_filename_extract_base(bioslist.driver().source_file).c_str());
else
{
osd_printf_info("%-16s %s\n", bioslist.driver().name, bioslist.driver().description);
brotherlist.exclude(bioslist.current());
drivlist.exclude(bioslist.current());
}
drivlist.reset();
while (drivlist.next())
{
// drivers with this BIOS
if (drivlist.bios_root() != bioslist.current())
continue;
// print the parent
if (strcmp(drivlist.driver().source_file, source) != 0)
osd_printf_info(" %-16s (parent set in %s)\n", drivlist.driver().name, core_filename_extract_base(drivlist.driver().source_file).c_str());
else
{
osd_printf_info(" %-16s %s\n", drivlist.driver().name, drivlist.driver().description);
brotherlist.exclude(drivlist.current());
}
// print the clones
brotherlist.reset();
while (brotherlist.next())
{
if (!brotherlist.is_clone_of(drivlist.current()))
continue;
osd_printf_info(" %-16s %s\n", brotherlist.driver().name, brotherlist.driver().description);
brotherlist.exclude();
}
drivlist.exclude();
}
}
// output the entries found for each source file (no BIOS root)
drivlist.reset();
while (drivlist.next())
{
// print the parent
if (strcmp(drivlist.driver().source_file, source) != 0)
osd_printf_info("%-16s (parent set in %s)\n", drivlist.driver().name, core_filename_extract_base(drivlist.driver().source_file).c_str());
else
{
osd_printf_info("%-16s %s\n", drivlist.driver().name, drivlist.driver().description);
brotherlist.exclude(drivlist.current());
}
// print the clones
brotherlist.reset();
while (brotherlist.next())
{
if (!brotherlist.is_clone_of(drivlist.current()))
continue;
osd_printf_info(" %-16s %s\n", brotherlist.driver().name, brotherlist.driver().description);
brotherlist.exclude();
}
}
// reset for next source
initial_drivlist.reset();
}
}
//-------------------------------------------------
// listcrc - output the CRC and name of all ROMs
// referenced by the emulator
@ -1654,6 +1866,7 @@ void cli_frontend::execute_commands(const char *exename)
{ CLICOMMAND_LISTSOURCE, &cli_frontend::listsource },
{ CLICOMMAND_LISTCLONES, &cli_frontend::listclones },
{ CLICOMMAND_LISTBROTHERS, &cli_frontend::listbrothers },
{ CLICOMMAND_LISTTREE, &cli_frontend::listtree },
{ CLICOMMAND_LISTCRC, &cli_frontend::listcrc },
{ CLICOMMAND_LISTDEVICES, &cli_frontend::listdevices },
{ CLICOMMAND_LISTSLOTS, &cli_frontend::listslots },

View File

@ -41,6 +41,7 @@ public:
void listsource(const char *gamename = "*");
void listclones(const char *gamename = "*");
void listbrothers(const char *gamename = "*");
void listtree(const char *gamename = "*");
void listcrc(const char *gamename = "*");
void listroms(const char *gamename = "*");
void listsamples(const char *gamename = "*");

View File

@ -33,6 +33,7 @@ const options_entry cli_options::s_option_entries[] =
{ CLICOMMAND_LISTSOURCE ";ls", "0", OPTION_COMMAND, "driver sourcefile" },
{ CLICOMMAND_LISTCLONES ";lc", "0", OPTION_COMMAND, "show clones" },
{ CLICOMMAND_LISTBROTHERS ";lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" },
{ CLICOMMAND_LISTTREE ";lt", "0", OPTION_COMMAND, "show drivers in tree format" },
{ CLICOMMAND_LISTCRC, "0", OPTION_COMMAND, "CRC-32s" },
{ CLICOMMAND_LISTROMS ";lr", "0", OPTION_COMMAND, "list required roms for a driver" },
{ CLICOMMAND_LISTSAMPLES, "0", OPTION_COMMAND, "list optional samples for a driver" },

View File

@ -34,6 +34,7 @@
#define CLICOMMAND_LISTSOURCE "listsource"
#define CLICOMMAND_LISTCLONES "listclones"
#define CLICOMMAND_LISTBROTHERS "listbrothers"
#define CLICOMMAND_LISTTREE "listtree"
#define CLICOMMAND_LISTCRC "listcrc"
#define CLICOMMAND_LISTROMS "listroms"
#define CLICOMMAND_LISTSAMPLES "listsamples"

View File

@ -54,14 +54,42 @@ int driver_list::find(const char *name)
// account wildcards in the wildstring
//-------------------------------------------------
bool driver_list::matches(const char *wildstring, const char *string)
bool driver_list::matches(const char *wildstring, const game_driver &driver)
{
// can only match internal drivers if the wildstring starts with an underscore
if (string[0] == '_' && (wildstring == nullptr || wildstring[0] != '_'))
if (driver.name[0] == '_' && (wildstring == nullptr || wildstring[0] != '_'))
return false;
// null matches any normal driver
if (wildstring == nullptr)
return true;
// special case: match on parent name
if (wildstring[0] == '^')
{
int clone_index = non_bios_clone(driver);
if (clone_index == -1)
return (wildstring[1] == '\0') || (core_stricmp(wildstring+1, driver.name) == 0);
else
return (core_stricmp(wildstring+1, s_drivers_sorted[clone_index]->name) == 0);
}
// special case: match on BIOS name
if (wildstring[0] == ':')
{
int bios_index = bios_root(driver);
if (bios_index == -1)
return (driver.flags & MACHINE_IS_BIOS_ROOT) && ((wildstring[1] == '\0') || (core_stricmp(wildstring+1, driver.name) == 0));
else
return (core_stricmp(wildstring+1, s_drivers_sorted[bios_index]->name) == 0);
}
// special case: match on source filename
if (wildstring[0] == '@')
return (core_stricmp(wildstring+1, core_filename_extract_base(driver.source_file).c_str()) == 0);
// match everything else normally
return (wildstring == nullptr || core_strwildcmp(wildstring, string) == 0);
return (core_strwildcmp(wildstring, driver.name) == 0);
}
@ -215,7 +243,7 @@ int driver_enumerator::filter(const char *filterstring)
// match name against each driver in the list
for (int index = 0; index < s_driver_count; index++)
if (matches(filterstring, s_drivers_sorted[index]->name))
if (matches(filterstring, *s_drivers_sorted[index]))
include(index);
return m_filtered_count;
@ -253,7 +281,7 @@ void driver_enumerator::include_all()
// always exclude the empty driver
int empty = find("___empty");
assert(empty != -1);
m_included[empty] = 0;
exclude(empty);
}
@ -313,9 +341,15 @@ bool driver_enumerator::next_excluded()
void driver_enumerator::find_approximate_matches(const char *string, int count, int *results)
{
#undef rand
// skip leading nonalphanumeric characters
if (string != nullptr)
{
while (string[0] != '\0' && !isalnum(string[0]))
string++;
}
// if no name, pick random entries
if (string == nullptr || string[0] == 0)
if (string == nullptr || string[0] == '\0')
{
// seed the RNG first
srand(osd_ticks());

View File

@ -35,21 +35,23 @@ public:
// any item by index
static const game_driver &driver(int index) { assert(index >= 0 && index < s_driver_count); return *s_drivers_sorted[index]; }
static int clone(int index) { return find(driver(index).parent); }
static int non_bios_clone(int index) { int result = find(driver(index).parent); return (result != -1 && (driver(result).flags & MACHINE_IS_BIOS_ROOT) == 0) ? result : -1; }
static int compatible_with(int index) { return find(driver(index).compatible_with); }
static int clone(int index) { return clone(driver(index)); }
static int non_bios_clone(int index) { return non_bios_clone(driver(index)); }
static int bios_root(int index) { return bios_root(driver(index)); }
static int compatible_with(int index) { return compatible_with(driver(index)); }
// any item by driver
static int clone(const game_driver &driver) { int index = find(driver); assert(index != -1); return clone(index); }
static int non_bios_clone(const game_driver &driver) { int index = find(driver); assert(index != -1); return non_bios_clone(index); }
static int compatible_with(const game_driver &driver) { int index = find(driver); assert(index != -1); return compatible_with(index); }
static int clone(const game_driver &driver) { return find(driver.parent); }
static int non_bios_clone(const game_driver &driver) { int result = find(driver.parent); return (result != -1 && (driver_list::driver(result).flags & MACHINE_IS_BIOS_ROOT) == 0) ? result : -1; }
static int bios_root(const game_driver &driver) { int result = find(driver.parent); return (result == -1) ? -1 : ((driver_list::driver(result).flags & MACHINE_IS_BIOS_ROOT) == 0) ? bios_root(result) : result; }
static int compatible_with(const game_driver &driver) { return find(driver.compatible_with); }
// general helpers
static int find(const char *name);
static int find(const game_driver &driver) { return find(driver.name); }
// static helpers
static bool matches(const char *wildstring, const char *string);
static bool matches(const char *wildstring, const game_driver &driver);
static int penalty_compare(const char *source, const char *target);
protected:
@ -84,9 +86,12 @@ public:
// current item
const game_driver &driver() const { return driver_list::driver(m_current); }
machine_config &config() const { return config(m_current, m_options); }
int clone() { return driver_list::clone(m_current); }
int non_bios_clone() { return driver_list::non_bios_clone(m_current); }
int compatible_with() { return driver_list::compatible_with(m_current); }
int clone() const { return driver_list::clone(m_current); }
int non_bios_clone() const { return driver_list::non_bios_clone(m_current); }
int bios_root() const { return driver_list::bios_root(m_current); }
int compatible_with() const { return driver_list::compatible_with(m_current); }
bool is_clone_of(int index) const { return strcmp(driver_list::driver(index).name, driver_list::driver(m_current).parent) == 0; }
bool is_clone_of(const game_driver &driver) const { return strcmp(driver.name, driver_list::driver(m_current).parent) == 0; }
void include() { include(m_current); }
void exclude() { exclude(m_current); }
@ -100,6 +105,7 @@ public:
using driver_list::driver;
using driver_list::clone;
using driver_list::non_bios_clone;
using driver_list::bios_root;
using driver_list::compatible_with;
// filtering/iterating

View File

@ -9,6 +9,7 @@
***************************************************************************/
#include "emu.h"
#include "drivenum.h"
#include "ui/ui.h"
#include "ui/menu.h"
#include "ui/imgcntrl.h"

View File

@ -13,8 +13,6 @@
#ifndef __UI_IMGCNTRL_H__
#define __UI_IMGCNTRL_H__
#include "drivenum.h"
// ======================> ui_menu_control_device_image
class ui_menu_control_device_image : public ui_menu {

View File

@ -13,8 +13,6 @@
#ifndef __UI_INPUTMAP_H__
#define __UI_INPUTMAP_H__
//#include "drivenum.h"
class ui_menu_input_groups : public ui_menu {
public:
ui_menu_input_groups(running_machine &machine, render_container *container);

View File

@ -13,8 +13,6 @@
#ifndef __UI_MAINMENU_H__
#define __UI_MAINMENU_H__
#include "drivenum.h"
class ui_menu_main : public ui_menu {
public:
ui_menu_main(running_machine &machine, render_container *container);

View File

@ -9,6 +9,7 @@
*********************************************************************/
#include "emu.h"
#include "drivenum.h"
#include "rendutil.h"
#include "cheat.h"
#include "uiinput.h"

View File

@ -13,7 +13,6 @@
#ifndef __UI_MISCMENU_H__
#define __UI_MISCMENU_H__
#include "drivenum.h"
#include "crsshair.h"
class ui_menu_keyboard_mode : public ui_menu {

View File

@ -10,6 +10,7 @@
#include "emu.h"
#include "emuopts.h"
#include "drivenum.h"
#include "ui/ui.h"
#include "ui/menu.h"
#include "uiinput.h"

View File

@ -13,7 +13,6 @@
#ifndef __UI_MAIN_H__
#define __UI_MAIN_H__
#include "drivenum.h"
#include "ui/menu.h"
class ui_menu_select_game : public ui_menu

View File

@ -10,6 +10,7 @@
#include "emu.h"
#include "emuopts.h"
#include "drivenum.h"
#include "ui/ui.h"
#include "ui/menu.h"
#include "uiinput.h"

View File

@ -13,9 +13,10 @@
#ifndef __UI_SIMPLESELGAME_H__
#define __UI_SIMPLESELGAME_H__
#include "drivenum.h"
#include "menu.h"
class driver_enumerator;
class ui_simple_menu_select_game : public ui_menu {
public:
ui_simple_menu_select_game(running_machine &machine, render_container *container, const char *gamename);

View File

@ -13,8 +13,6 @@
#ifndef __UI_SLOTOPT_H__
#define __UI_SLOTOPT_H__
//#include "drivenum.h"
class ui_menu_slot_devices : public ui_menu {
public:
ui_menu_slot_devices(running_machine &machine, render_container *container);

View File

@ -10,6 +10,7 @@
#include "emu.h"
#include "emuopts.h"
#include "drivenum.h"
#include "video/vector.h"
#include "machine/laserdsc.h"
#include "render.h"

View File

@ -211,7 +211,7 @@ bool validity_checker::check_all_matching(const char *string)
// then iterate over all drivers and check them
m_drivlist.reset();
while (m_drivlist.next())
if (m_drivlist.matches(string, m_drivlist.driver().name))
if (m_drivlist.matches(string, m_drivlist.driver()))
validate_one(m_drivlist.driver());
// cleanup

View File

@ -91,22 +91,31 @@ games are listed; however, you can limit this list by specifying a
driver name or wildcard after the \-listfull command.
.TP
.B \-listsource, \-ls \fR[\fIgamename\fR|\fIwildcard\fR]
Displays a list of drivers and the names of the source files their game
drivers live in. Useful for finding which driver a game runs on in
order to fix bugs. By default all games are listed; however, you can
Displays a list of drivers, the names of the source files their game
drivers live in, and their parent sets and BIOS roots, if any. These
are listed in the form of wildcards that will match all drivers with
similar properties. By default all games are listed; however, you can
limit this list by specifying a driver name or wildcard after the
\-listsource command.
.TP
.B \-listclones, \-lc \fR[\fIgamename\fR|\fIwildcard\fR]
Displays a list of clones. By default all clones are listed; however,
you can limit this list by specifying a driver name or wildcard after
the \-listclones command.
Displays a list of clones, sorted under their parent sets. By default
all drivers are listed; however, you can limit this list to clones of
certain drivers by specifying a name or wildcard after the \-listclones
command.
.TP
.B \-listbrothers, \-lb \fR[\fIgamename\fR|\fIwildcard\fR]
Displays a list of "brothers" or other drivers from same sourcefile.
By default all games are listed; however, you can limit this list by
specifying a driver name or wildcard after the \-listbrothers command.
.TP
.B \-listtree, \-lt \fR[\fIgamename\fR|\fIwildcard\fR]
Displays a list of driver names and descriptions in tree format.
Clones are listed under their parent sets, and drivers are grouped
together with their "brothers" from the same sourcefile. By default
all games are listed; however, you can limit this list by specifying a
driver name or wildcard.
.TP
.B \-listcrc
Displays a full list of CRCs of all ROM images referenced by all
drivers within MAME code.

View File

@ -113,20 +113,31 @@ systems are listed; however, you can limit this list by specifying a
driver name or wildcard.
.TP
.B \-listsource, \-ls \fR[\fIsystem\fR|\fIwildcard\fR]
Displays a list of drivers and the names of the source files their system
drivers live in. Useful for finding which driver a system runs on in
order to fix bugs. By default all systems are listed; however, you can
limit this list by specifying a driver name or wildcard.
Displays a list of drivers, the names of the source files their system
drivers live in, and their parent sets and BIOS roots, if any. These
are listed in the form of wildcards that will match all drivers with
similar properties. By default all systems are listed; however, you
can limit this list by specifying a driver name or wildcard after the
\-listsource command.
.TP
.B \-listclones, \-lc \fR[\fIsystem\fR|\fIwildcard\fR]
Displays a list of clones. By default all clones are listed; however,
you can limit this list by specifying a driver name or wildcard.
Displays a list of clones, sorted under their parent sets. By default
all drivers are listed; however, you can limit this list to clones of
certain drivers by specifying a name or wildcard after the \-listclones
command.
.TP
.B \-listbrothers, \-lb \fR[\fIsystem\fR|\fIwildcard\fR]
Displays a list of "brothers" or other drivers from same sourcefile.
By default all systems are listed; however, you can limit this list by
specifying a driver name or wildcard.
.TP
.B \-listtree, \-lt \fR[\fIsystem\fR|\fIwildcard\fR]
Displays a list of driver names and descriptions in tree format.
Clones are listed under their parent sets, and drivers are grouped
together with their "brothers" from the same sourcefile. By default
all systems are listed; however, you can limit this list by specifying
a driver name or wildcard.
.TP
.B \-listcrc
Displays a full list of CRCs of all ROM images referenced by all
drivers within MESS code.
@ -174,7 +185,7 @@ Output the list of available media for the system.
.B \-listsoftware, \-lsoft
Output the list of known software for the system.
.TP
.B \-verifysoftware, \-vsoft \fR[\fIgamename\fR|\fIwildcard\fR]
.B \-verifysoftware, \-vsoft \fR[\fIsystem\fR|\fIwildcard\fR]
Checks for invalid or missing ROM images in your software lists.
By default all drivers that have valid ZIP files or directories
in the rompath are verified; however, you can limit this list by