mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
ui/utils: Added a source file filter for system selection menu.
* ui/selmenu.cpp: Show system source file in general info. * frontend/infoxml.cpp: Consolidated source file path formatting in one place. * ui/devopt.cpp: Get decimal separator from C++ locale.
This commit is contained in:
parent
f0f9e45d62
commit
456e6948a8
@ -403,25 +403,10 @@ void cli_frontend::listsource(const std::vector<std::string> &args)
|
||||
{
|
||||
auto const list_system_source = [] (device_type type)
|
||||
{
|
||||
std::string_view src(type.source());
|
||||
auto prefix(src.find("src/mame/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\mame\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
{
|
||||
src.remove_prefix(prefix + 9);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto prefix(src.find("src/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
{
|
||||
src.remove_prefix(prefix + 4);
|
||||
}
|
||||
}
|
||||
osd_printf_info("%-16s %s\n", type.shortname(), src);
|
||||
osd_printf_info(
|
||||
"%-16s %s\n",
|
||||
type.shortname(),
|
||||
info_xml_creator::format_sourcefile(type.source()));
|
||||
};
|
||||
apply_action(
|
||||
args,
|
||||
@ -520,13 +505,8 @@ void cli_frontend::listbrothers(const std::vector<std::string> &args)
|
||||
drivlist.reset();
|
||||
while (drivlist.next())
|
||||
{
|
||||
std::string_view src(drivlist.driver().type.source());
|
||||
auto prefix(src.find("src/mame/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\mame\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
src.remove_prefix(prefix + 9);
|
||||
int const clone_of = drivlist.clone();
|
||||
auto const src(info_xml_creator::format_sourcefile(drivlist.driver().type.source()));
|
||||
int const clone_of(drivlist.clone());
|
||||
if (clone_of != -1)
|
||||
osd_printf_info("%-20s %-16s %s\n", src, drivlist.driver().name, (clone_of == -1 ? "" : drivlist.driver(clone_of).name));
|
||||
else
|
||||
|
@ -340,7 +340,7 @@ constexpr std::pair<device_t::feature_type, char const *> f_feature_names[] = {
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_feature_name - get XML name for feature
|
||||
// feature_name - get XML name for feature
|
||||
//-------------------------------------------------
|
||||
|
||||
char const *info_xml_creator::feature_name(device_t::feature_type feature)
|
||||
@ -357,6 +357,33 @@ char const *info_xml_creator::feature_name(device_t::feature_type feature)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// format_sourcefile - sanitise source file path
|
||||
//-------------------------------------------------
|
||||
|
||||
std::string info_xml_creator::format_sourcefile(std::string_view path)
|
||||
{
|
||||
using namespace std::literals;
|
||||
|
||||
if (auto prefix(path.rfind("src/mame/"sv)); std::string_view::npos != prefix)
|
||||
path.remove_prefix(prefix + 9);
|
||||
else if (auto prefix(path.rfind("src\\mame\\"sv)); std::string_view::npos != prefix)
|
||||
path.remove_prefix(prefix + 9);
|
||||
else if (auto prefix(path.rfind("/src/"sv)); std::string_view::npos != prefix)
|
||||
path.remove_prefix(prefix + 5);
|
||||
else if (auto prefix(path.rfind("\\src\\"sv)); std::string_view::npos != prefix)
|
||||
path.remove_prefix(prefix + 5);
|
||||
else if (path.substr(0, 4) == "src/"sv)
|
||||
path.remove_prefix(4);
|
||||
else if (path.substr(0, 4) == "src\\"sv)
|
||||
path.remove_prefix(4);
|
||||
|
||||
std::string result(path);
|
||||
std::replace(result.begin(), result.end(), '\\', '/');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// info_xml_creator - constructor
|
||||
//-------------------------------------------------
|
||||
@ -714,14 +741,8 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
|
||||
// print the header and the machine name
|
||||
util::stream_format(out, "\t<%s name=\"%s\"", XML_TOP, normalize_string(driver.name));
|
||||
|
||||
// strip away any path information from the source_file and output it
|
||||
std::string_view src(driver.type.source());
|
||||
auto prefix(src.find("src/mame/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\mame\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
src.remove_prefix(prefix + 9);
|
||||
util::stream_format(out, " sourcefile=\"%s\"", normalize_string(src));
|
||||
// strip away extra path information from the source file and output it
|
||||
util::stream_format(out, " sourcefile=\"%s\"", normalize_string(info_xml_creator::format_sourcefile(driver.type.source())));
|
||||
|
||||
// append bios and runnable flags
|
||||
if (driver.flags & machine_flags::IS_BIOS_ROOT)
|
||||
@ -815,13 +836,7 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi
|
||||
|
||||
// start to output info
|
||||
util::stream_format(out, "\t<%s name=\"%s\"", XML_TOP, normalize_string(device.shortname()));
|
||||
std::string_view src(device.source());
|
||||
auto prefix(src.find("src/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
src.remove_prefix(prefix + 4);
|
||||
util::stream_format(out, " sourcefile=\"%s\" isdevice=\"yes\" runnable=\"no\"", normalize_string(src));
|
||||
util::stream_format(out, " sourcefile=\"%s\" isdevice=\"yes\" runnable=\"no\"", normalize_string(info_xml_creator::format_sourcefile(device.source())));
|
||||
auto const parent(device.type().parent_rom_device_type());
|
||||
if (parent)
|
||||
util::stream_format(out, " romof=\"%s\"", normalize_string(parent->shortname()));
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "emuopts.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -35,6 +37,7 @@ public:
|
||||
void output(std::ostream &out, const std::function<bool(const char *shortname, bool &done)> &filter = { }, bool include_devices = true);
|
||||
|
||||
static char const *feature_name(device_t::feature_type feature);
|
||||
static std::string format_sourcefile(std::string_view path);
|
||||
|
||||
private:
|
||||
// internal state
|
||||
|
@ -15,7 +15,10 @@
|
||||
#include "romload.h"
|
||||
#include "screen.h"
|
||||
|
||||
#include "utf8.h"
|
||||
#include "util/unicode.h"
|
||||
#include "util/utf8.h"
|
||||
|
||||
#include <locale>
|
||||
|
||||
|
||||
namespace ui {
|
||||
@ -55,6 +58,13 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
|
||||
if (!d.configured())
|
||||
d.config_complete();
|
||||
|
||||
// get decimal separator
|
||||
std::string point;
|
||||
{
|
||||
wchar_t const s(std::use_facet<std::numpunct<wchar_t> >(std::locale()).decimal_point());
|
||||
point = utf8_from_wstring(std::wstring_view(&s, 1));
|
||||
}
|
||||
|
||||
layout->add_text(
|
||||
util::string_format(
|
||||
m_mounted
|
||||
@ -93,7 +103,7 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
|
||||
if (d > 0)
|
||||
{
|
||||
size_t dpos = hz.length() - d;
|
||||
hz.insert(dpos, ".");
|
||||
hz.insert(dpos, point);
|
||||
size_t last = hz.find_last_not_of('0');
|
||||
hz = hz.substr(0, last + (last != dpos ? 1 : 0));
|
||||
}
|
||||
@ -129,7 +139,7 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
|
||||
if (valid)
|
||||
{
|
||||
size_t dpos = hz.length() - 6;
|
||||
hz.insert(dpos, ".");
|
||||
hz.insert(dpos, point);
|
||||
size_t last = hz.find_last_not_of('0');
|
||||
hz = hz.substr(0, last + (last != dpos ? 1 : 0));
|
||||
}
|
||||
@ -175,7 +185,7 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
|
||||
if (d > 0)
|
||||
{
|
||||
size_t dpos = hz.length() - d;
|
||||
hz.insert(dpos, ".");
|
||||
hz.insert(dpos, point);
|
||||
size_t last = hz.find_last_not_of('0');
|
||||
hz = hz.substr(0, last + (last != dpos ? 1 : 0));
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "ui/systemlist.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include "infoxml.h"
|
||||
|
||||
#include "drivenum.h"
|
||||
#include "emuopts.h"
|
||||
#include "romload.h"
|
||||
@ -374,17 +376,11 @@ std::string machine_info::game_info_string() const
|
||||
}
|
||||
|
||||
// print description, manufacturer, and CPU:
|
||||
std::string_view src(m_machine.system().type.source());
|
||||
auto prefix(src.find("src/mame/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\mame\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
src.remove_prefix(prefix + 9);
|
||||
util::stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"),
|
||||
system_list::instance().systems()[driver_list::find(m_machine.system().name)].description,
|
||||
m_machine.system().year,
|
||||
m_machine.system().manufacturer,
|
||||
src);
|
||||
info_xml_creator::format_sourcefile(m_machine.system().type.source()));
|
||||
|
||||
// loop over all CPUs
|
||||
execute_interface_enumerator execiter(m_machine.root_device());
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "audit.h"
|
||||
#include "cheat.h"
|
||||
#include "infoxml.h"
|
||||
#include "mame.h"
|
||||
#include "mameopts.h"
|
||||
|
||||
@ -3124,6 +3125,8 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
|
||||
str << _("Media Audit\tDisabled\nSamples Audit\tDisabled\n");
|
||||
}
|
||||
|
||||
util::stream_format(str, _("Source File\t%1$s\n"), info_xml_creator::format_sourcefile(driver.type.source()));
|
||||
|
||||
buffer = std::move(str).str();
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "ui/ui.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
#include "infoxml.h"
|
||||
|
||||
#include "audit.h"
|
||||
#include "drivenum.h"
|
||||
#include "emuopts.h"
|
||||
@ -352,13 +354,7 @@ void simple_menu_select_game::custom_render(void *selectedref, float top, float
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), driver->year, driver->manufacturer);
|
||||
|
||||
// next line source path
|
||||
std::string_view src(driver->type.source());
|
||||
auto prefix(src.find("src/mame/"));
|
||||
if (std::string_view::npos == prefix)
|
||||
prefix = src.find("src\\mame\\");
|
||||
if (std::string_view::npos != prefix)
|
||||
src.remove_prefix(prefix + 9);
|
||||
tempbuf[2] = string_format(_("Driver: %1$s"), src);
|
||||
tempbuf[2] = string_format(_("Driver: %1$s"), info_xml_creator::format_sourcefile(driver->type.source()));
|
||||
|
||||
// update cached values if selection changed
|
||||
if (driver != m_cached_driver)
|
||||
|
@ -301,6 +301,7 @@ void system_list::populate_list(bool copydesc)
|
||||
|
||||
m_filter_data.add_manufacturer(driver.manufacturer);
|
||||
m_filter_data.add_year(driver.year);
|
||||
m_filter_data.add_source_file(driver.type.source());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "ui/inifile.h"
|
||||
#include "ui/selector.h"
|
||||
|
||||
#include "infoxml.h"
|
||||
#include "language.h"
|
||||
#include "mame.h"
|
||||
|
||||
@ -96,6 +97,7 @@ constexpr char const *MACHINE_FILTER_NAMES[machine_filter::COUNT] = {
|
||||
N_p("machine-filter", "Clones"),
|
||||
N_p("machine-filter", "Manufacturer"),
|
||||
N_p("machine-filter", "Year"),
|
||||
N_p("machine-filter", "Source File"),
|
||||
N_p("machine-filter", "Save Supported"),
|
||||
N_p("machine-filter", "Save Unsupported"),
|
||||
N_p("machine-filter", "CHD Required"),
|
||||
@ -800,6 +802,18 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class source_file_machine_filter : public choice_filter_impl_base<machine_filter, machine_filter::SOURCE_FILE>
|
||||
{
|
||||
public:
|
||||
source_file_machine_filter(machine_filter_data const &data, char const *value, util::core_file *file, unsigned indent)
|
||||
: choice_filter_impl_base<machine_filter, machine_filter::SOURCE_FILE>(data.source_files(), value)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool apply(ui_system_info const &system) const override { return !have_choices() || (selection_valid() && (selection_text() == info_xml_creator::format_sourcefile(system.driver->type.source()))); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// complementary machine filters
|
||||
@ -1227,6 +1241,7 @@ public:
|
||||
case FAVORITE:
|
||||
case MANUFACTURER:
|
||||
case YEAR:
|
||||
case SOURCE_FILE:
|
||||
case CUSTOM:
|
||||
case COUNT:
|
||||
break;
|
||||
@ -1236,7 +1251,17 @@ public:
|
||||
|
||||
static bool is_inclusion(type n)
|
||||
{
|
||||
return (CATEGORY == n) || (MANUFACTURER == n) || (YEAR == n);
|
||||
switch (n)
|
||||
{
|
||||
case CATEGORY:
|
||||
case MANUFACTURER:
|
||||
case YEAR:
|
||||
case SOURCE_FILE:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1602,10 +1627,21 @@ void machine_filter_data::add_year(std::string const &year)
|
||||
m_years.emplace(pos, year);
|
||||
}
|
||||
|
||||
void machine_filter_data::add_source_file(std::string_view path)
|
||||
{
|
||||
std::vector<std::string>::iterator const pos(std::lower_bound(m_source_files.begin(), m_source_files.end(), path));
|
||||
if ((m_source_files.end() == pos) || (*pos != path))
|
||||
m_source_files.emplace(pos, path);
|
||||
}
|
||||
|
||||
void machine_filter_data::finalise()
|
||||
{
|
||||
for (std::string &path : m_source_files)
|
||||
path = info_xml_creator::format_sourcefile(path);
|
||||
|
||||
std::stable_sort(m_manufacturers.begin(), m_manufacturers.end());
|
||||
std::stable_sort(m_years.begin(), m_years.end());
|
||||
std::stable_sort(m_source_files.begin(), m_source_files.end());
|
||||
}
|
||||
|
||||
std::string machine_filter_data::extract_manufacturer(std::string const &manufacturer)
|
||||
@ -1780,6 +1816,8 @@ machine_filter::ptr machine_filter::create(type n, machine_filter_data const &da
|
||||
return std::make_unique<manufacturer_machine_filter>(data, value, file, indent);
|
||||
case YEAR:
|
||||
return std::make_unique<year_machine_filter>(data, value, file, indent);
|
||||
case SOURCE_FILE:
|
||||
return std::make_unique<source_file_machine_filter>(data, value, file, indent);
|
||||
case SAVE:
|
||||
return std::make_unique<save_machine_filter>(data, value, file, indent);
|
||||
case NOSAVE:
|
||||
|
@ -186,6 +186,7 @@ public:
|
||||
CLONES,
|
||||
MANUFACTURER,
|
||||
YEAR,
|
||||
SOURCE_FILE,
|
||||
SAVE,
|
||||
NOSAVE,
|
||||
CHD,
|
||||
@ -276,10 +277,13 @@ class machine_filter_data
|
||||
public:
|
||||
std::vector<std::string> const &manufacturers() const { return m_manufacturers; }
|
||||
std::vector<std::string> const &years() const { return m_years; }
|
||||
std::vector<std::string> const &source_files() const { return m_source_files; }
|
||||
|
||||
// adding entries
|
||||
void add_manufacturer(std::string const &manufacturer);
|
||||
void add_year(std::string const &year);
|
||||
void add_source_file(std::string_view path);
|
||||
|
||||
void finalise();
|
||||
|
||||
// use heuristics to extract meaningful parts from machine metadata
|
||||
@ -306,6 +310,7 @@ private:
|
||||
|
||||
std::vector<std::string> m_manufacturers;
|
||||
std::vector<std::string> m_years;
|
||||
std::vector<std::string> m_source_files;
|
||||
|
||||
machine_filter::type m_current_filter = machine_filter::ALL;
|
||||
filter_map m_filters;
|
||||
|
Loading…
Reference in New Issue
Block a user