summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame')
-rw-r--r--src/frontend/mame/ui/custmenu.cpp6
-rw-r--r--src/frontend/mame/ui/custmenu.h4
-rw-r--r--src/frontend/mame/ui/dirmenu.cpp2
-rw-r--r--src/frontend/mame/ui/inifile.cpp156
-rw-r--r--src/frontend/mame/ui/inifile.h54
-rw-r--r--src/frontend/mame/ui/moptions.cpp2
-rw-r--r--src/frontend/mame/ui/moptions.h4
-rw-r--r--src/frontend/mame/ui/optsmenu.cpp101
-rw-r--r--src/frontend/mame/ui/optsmenu.h2
-rw-r--r--src/frontend/mame/ui/selgame.cpp223
-rw-r--r--src/frontend/mame/ui/selgame.h1
-rw-r--r--src/frontend/mame/ui/selmenu.cpp163
-rw-r--r--src/frontend/mame/ui/selmenu.h9
-rw-r--r--src/frontend/mame/ui/selsoft.cpp141
-rw-r--r--src/frontend/mame/ui/utils.cpp425
-rw-r--r--src/frontend/mame/ui/utils.h6
16 files changed, 674 insertions, 625 deletions
diff --git a/src/frontend/mame/ui/custmenu.cpp b/src/frontend/mame/ui/custmenu.cpp
index ea5562a0d9e..6f604ece04a 100644
--- a/src/frontend/mame/ui/custmenu.cpp
+++ b/src/frontend/mame/ui/custmenu.cpp
@@ -45,7 +45,7 @@ constexpr char const *region_lists[] = {
// set software regions
//-------------------------------------------------
-void c_sw_region::set(std::string &str)
+void c_sw_region::set(std::string const &str)
{
std::string name(getname(str));
std::vector<std::string>::iterator const pos(std::lower_bound(ui.begin(), ui.end(), name));
@@ -97,11 +97,11 @@ void c_sw_year::set(std::string &str)
// set software publishers
//-------------------------------------------------
-void c_sw_publisher::set(std::string &str)
+void c_sw_publisher::set(std::string const &str)
{
std::string name(getname(str));
std::vector<std::string>::iterator const pos(std::lower_bound(ui.begin(), ui.end(), name));
- if ((ui.end() == pos) || (*pos != str))
+ if ((ui.end() == pos) || (*pos != name))
ui.emplace(pos, std::move(name));
}
diff --git a/src/frontend/mame/ui/custmenu.h b/src/frontend/mame/ui/custmenu.h
index 09911a50787..dc3c7535b2e 100644
--- a/src/frontend/mame/ui/custmenu.h
+++ b/src/frontend/mame/ui/custmenu.h
@@ -21,7 +21,7 @@ namespace ui {
struct c_sw_region
{
std::vector<std::string> ui;
- void set(std::string &str);
+ void set(std::string const &str);
std::string getname(std::string const &str) const;
};
@@ -29,7 +29,7 @@ struct c_sw_region
struct c_sw_publisher
{
std::vector<std::string> ui;
- void set(std::string &str);
+ void set(std::string const &str);
std::string getname(std::string const &str) const;
};
diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp
index c3c5d85f8d1..f3939089f25 100644
--- a/src/frontend/mame/ui/dirmenu.cpp
+++ b/src/frontend/mame/ui/dirmenu.cpp
@@ -39,7 +39,7 @@ static const folders_entry s_folders[] =
{ __("Samples"), OPTION_SAMPLEPATH, ADDING },
{ __("DATs"), OPTION_HISTORY_PATH, ADDING },
{ __("INIs"), OPTION_INIPATH, ADDING },
- { __("Extra INIs"), OPTION_EXTRAINI_PATH, CHANGE },
+ { __("Category INIs"), OPTION_CATEGORYINI_PATH, CHANGE },
{ __("Icons"), OPTION_ICONS_PATH, ADDING },
{ __("Cheats"), OPTION_CHEATPATH, ADDING },
{ __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY, ADDING },
diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp
index d9673f13a67..852884fea6a 100644
--- a/src/frontend/mame/ui/inifile.cpp
+++ b/src/frontend/mame/ui/inifile.cpp
@@ -9,134 +9,100 @@
***************************************************************************/
#include "emu.h"
-#include "ui/moptions.h"
#include "ui/inifile.h"
-#include "softlist_dev.h"
+
+#include "ui/moptions.h"
+
#include "drivenum.h"
+#include "softlist_dev.h"
-//-------------------------------------------------
-// GLOBAL VARIABLES
-//-------------------------------------------------
-uint16_t inifile_manager::c_cat = 0;
-uint16_t inifile_manager::c_file = 0;
//-------------------------------------------------
// ctor
//-------------------------------------------------
inifile_manager::inifile_manager(running_machine &machine, ui_options &moptions)
- : m_machine(machine)
- , m_options(moptions)
+ : m_options(moptions)
+ , m_ini_index()
{
- ini_index.clear();
- directory_scan();
+ // scan directories and create index
+ file_enumerator path(m_options.categoryini_path());
+ for (osd::directory::entry const *dir = path.next(); dir; dir = path.next())
+ {
+ std::string name(dir->name);
+ if (core_filename_ends_with(name, ".ini"))
+ {
+ emu_file file(m_options.categoryini_path(), OPEN_FLAG_READ);
+ if (file.open(name) == osd_file::error::NONE)
+ {
+ init_category(std::move(name), file);
+ file.close();
+ }
+ }
+ }
+ std::stable_sort(m_ini_index.begin(), m_ini_index.end(), [] (auto const &x, auto const &y) { return 0 > core_stricmp(x.first.c_str(), y.first.c_str()); });
}
//-------------------------------------------------
-// scan directories and create index
+// load and indexing ini files
//-------------------------------------------------
-void inifile_manager::directory_scan()
+void inifile_manager::load_ini_category(size_t file, size_t category, std::unordered_set<game_driver const *> &result) const
{
- file_enumerator path(m_options.extraini_path());
- const osd::directory::entry *dir;
+ std::string const &filename(m_ini_index[file].first);
+ emu_file fp(m_options.categoryini_path(), OPEN_FLAG_READ);
+ if (fp.open(filename) != osd_file::error::NONE)
+ {
+ osd_printf_error("Failed to open category file %s for reading\n", filename.c_str());
+ return;
+ }
- while ((dir = path.next()) != nullptr)
- if (core_filename_ends_with(dir->name, ".ini") && parseopen(dir->name))
- {
- init_category(std::string(dir->name));
- parseclose();
- }
+ int64_t const offset(m_ini_index[file].second[category].second);
+ if (fp.seek(offset, SEEK_SET) || (fp.tell() != offset))
+ {
+ fp.close();
+ osd_printf_error("Failed to seek to category offset in file %s\n", filename.c_str());
+ return;
+ }
- // sort
- std::stable_sort(ini_index.begin(), ini_index.end());
+ char rbuf[MAX_CHAR_INFO];
+ while (fp.gets(rbuf, MAX_CHAR_INFO) && rbuf[0] && ('[' != rbuf[0]))
+ {
+ auto const tail(std::find_if(std::begin(rbuf), std::prev(std::end(rbuf)), [] (char ch) { return !ch || ('\r' == ch) || ('\n' == ch); }));
+ *tail = '\0';
+ int const dfind(driver_list::find(rbuf));
+ if (0 <= dfind)
+ result.emplace(&driver_list::driver(dfind));
+ }
+
+ fp.close();
}
//-------------------------------------------------
// initialize category
//-------------------------------------------------
-void inifile_manager::init_category(std::string filename)
+void inifile_manager::init_category(std::string &&filename, emu_file &file)
{
categoryindex index;
char rbuf[MAX_CHAR_INFO];
- std::string readbuf;
- while (fgets(rbuf, MAX_CHAR_INFO, fp) != nullptr)
- if (rbuf[0] == '[')
- {
- readbuf = rbuf;
- auto name = readbuf.substr(1, readbuf.find("]") - 1);
- if (name == "FOLDER_SETTINGS") continue;
- index.emplace_back(name, ftell(fp));
- }
-
- // sort
- std::stable_sort(index.begin(), index.end());
-
- if (!index.empty())
- ini_index.emplace_back(strmakelower(filename), index);
-}
-
-//-------------------------------------------------
-// load and indexing ini files
-//-------------------------------------------------
-
-void inifile_manager::load_ini_category(std::vector<int> &temp_filter)
-{
- if (ini_index.empty())
- return;
-
- auto search_clones = false;
- std::string filename(ini_index[c_file].first);
- auto offset = ini_index[c_file].second[c_cat].second;
-
- if (filename == "category.ini" || filename == "alltime.ini")
- search_clones = true;
-
- if (parseopen(filename.c_str()))
+ std::string name;
+ while (file.gets(rbuf, ARRAY_LENGTH(rbuf)))
{
- fseek(fp, offset, SEEK_SET);
- char rbuf[MAX_CHAR_INFO];
- std::string readbuf;
- while (fgets(rbuf, MAX_CHAR_INFO, fp) != nullptr)
+ if ('[' == rbuf[0])
{
- readbuf = chartrimcarriage(rbuf);
-
- if (readbuf.empty() || readbuf[0] == '[')
- break;
-
- auto dfind = driver_list::find(readbuf.c_str());
- if (dfind != -1)
- {
- temp_filter.push_back(dfind);
- if (search_clones && driver_list::non_bios_clone(dfind) == -1)
- for (int x = 0; x < driver_list::total(); x++)
- if (readbuf == driver_list::driver(x).parent && readbuf != driver_list::driver(x).name)
- temp_filter.push_back(x);
- }
+ auto const head(std::next(std::begin(rbuf)));
+ auto const tail(std::find_if(head, std::end(rbuf), [] (char ch) { return !ch || (']' == ch); }));
+ name.assign(head, tail);
+ if ("FOLDER_SETTINGS" != name)
+ index.emplace_back(std::move(name), file.tell());
}
- parseclose();
}
+ std::stable_sort(index.begin(), index.end(), [] (auto const &x, auto const &y) { return 0 > core_stricmp(x.first.c_str(), y.first.c_str()); });
+ if (!index.empty())
+ m_ini_index.emplace_back(std::move(filename), std::move(index));
}
-//---------------------------------------------------------
-// parseopen - Open up file for reading
-//---------------------------------------------------------
-
-bool inifile_manager::parseopen(const char *filename)
-{
- emu_file file(m_options.extraini_path(), OPEN_FLAG_READ);
- if (file.open(filename) != osd_file::error::NONE)
- return false;
-
- m_fullpath = file.fullpath();
- file.close();
- fp = fopen(m_fullpath.c_str(), "r");
-
- fgetc(fp);
- fseek(fp, 0, SEEK_SET);
- return true;
-}
/**************************************************************************
FAVORITE MANAGER
diff --git a/src/frontend/mame/ui/inifile.h b/src/frontend/mame/ui/inifile.h
index 88466a5c977..49344fd01eb 100644
--- a/src/frontend/mame/ui/inifile.h
+++ b/src/frontend/mame/ui/inifile.h
@@ -13,7 +13,10 @@
#pragma once
-#include "../frontend/mame/ui/utils.h"
+#include "ui/utils.h"
+
+#include <unordered_set>
+
//-------------------------------------------------
// INIFILE MANAGER
@@ -27,50 +30,25 @@ public:
// construction/destruction
inifile_manager(running_machine &machine, ui_options &moptions);
+ // load systems from category
+ void load_ini_category(size_t file, size_t category, std::unordered_set<game_driver const *> &result) const;
+
// getters
- running_machine &machine() const { return m_machine; }
- std::string get_file() { return ini_index[c_file].first; }
- std::string get_file(int file) { return ini_index[file].first; }
- std::string get_category(int cat) { return ini_index[c_file].second[cat].first; }
- std::string get_category() { return ini_index[c_file].second[c_cat].first; }
- size_t total() { return ini_index.size(); }
- size_t cat_total() { return ini_index[c_file].second.size(); }
- uint16_t &cur_file() { return c_file; }
- uint16_t &cur_cat() { return c_cat; }
-
- // load games from category
- void load_ini_category(std::vector<int> &temp_filter);
-
- // setters
- void move_file(int d) { c_file += d; c_cat = 0; }
- void move_cat(int d) { c_cat += d; }
- void set_cat(uint16_t i) { c_cat = i; }
- void set_file(uint16_t i) { c_file = i; }
+ size_t get_file_count() const { return m_ini_index.size(); }
+ std::string const &get_file_name(size_t file) const { return m_ini_index[file].first; }
+ size_t get_category_count(size_t file) const { return m_ini_index[file].second.size(); }
+ std::string const &get_category_name(size_t file, size_t category) const { return m_ini_index[file].second[category].first; }
private:
-
// ini file structure
- using categoryindex = std::vector<std::pair<std::string, long>>;
-
- // files indices
- static uint16_t c_file, c_cat;
- std::vector<std::pair<std::string, categoryindex>> ini_index;
+ using categoryindex = std::vector<std::pair<std::string, int64_t>>;
- // init category index
- void init_category(std::string filename);
-
- // init file index
- void directory_scan();
-
- // file open/close/seek
- bool parseopen(const char *filename);
- void parseclose() { if (fp != nullptr) fclose(fp); }
+ void init_category(std::string &&filename, emu_file &file);
// internal state
- running_machine &m_machine; // reference to our machine
- ui_options &m_options;
- std::string m_fullpath;
- FILE *fp = nullptr;
+ ui_options &m_options;
+ std::vector<std::pair<std::string, categoryindex> > m_ini_index;
+
};
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/moptions.cpp b/src/frontend/mame/ui/moptions.cpp
index a59090a8f57..a030fa219ef 100644
--- a/src/frontend/mame/ui/moptions.cpp
+++ b/src/frontend/mame/ui/moptions.cpp
@@ -22,7 +22,7 @@ const options_entry ui_options::s_option_entries[] =
// search path options
{ nullptr, nullptr, OPTION_HEADER, "UI SEARCH PATH OPTIONS" },
{ OPTION_HISTORY_PATH, "history;dats;.", OPTION_STRING, "path to history files" },
- { OPTION_EXTRAINI_PATH, "folders", OPTION_STRING, "path to extra ini files" },
+ { OPTION_CATEGORYINI_PATH, "folders", OPTION_STRING, "path to catagory ini files" },
{ OPTION_CABINETS_PATH, "cabinets;cabdevs", OPTION_STRING, "path to cabinets / devices image" },
{ OPTION_CPANELS_PATH, "cpanel", OPTION_STRING, "path to control panel image" },
{ OPTION_PCBS_PATH, "pcb", OPTION_STRING, "path to pcbs image" },
diff --git a/src/frontend/mame/ui/moptions.h b/src/frontend/mame/ui/moptions.h
index 71f42211755..9b750583307 100644
--- a/src/frontend/mame/ui/moptions.h
+++ b/src/frontend/mame/ui/moptions.h
@@ -17,7 +17,7 @@
// core directory options
#define OPTION_HISTORY_PATH "historypath"
-#define OPTION_EXTRAINI_PATH "extrainipath"
+#define OPTION_CATEGORYINI_PATH "categorypath"
#define OPTION_CABINETS_PATH "cabinets_directory"
#define OPTION_CPANELS_PATH "cpanels_directory"
#define OPTION_PCBS_PATH "pcbs_directory"
@@ -80,7 +80,7 @@ public:
// Search path options
const char *history_path() const { return value(OPTION_HISTORY_PATH); }
- const char *extraini_path() const { return value(OPTION_EXTRAINI_PATH); }
+ const char *categoryini_path() const { return value(OPTION_CATEGORYINI_PATH); }
const char *cabinets_directory() const { return value(OPTION_CABINETS_PATH); }
const char *cpanels_directory() const { return value(OPTION_CPANELS_PATH); }
const char *pcbs_directory() const { return value(OPTION_PCBS_PATH); }
diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp
index 901671081fc..fd29c3329bc 100644
--- a/src/frontend/mame/ui/optsmenu.cpp
+++ b/src/frontend/mame/ui/optsmenu.cpp
@@ -13,11 +13,9 @@
#include "ui/ui.h"
#include "ui/submenu.h"
-#include "ui/inifile.h"
#include "ui/selector.h"
#include "ui/custui.h"
#include "ui/sndmenu.h"
-#include "ui/custmenu.h"
#include "ui/inputmap.h"
#include "ui/dirmenu.h"
@@ -25,6 +23,7 @@
#include "mameopts.h"
#include "rendfont.h"
+
namespace ui {
//-------------------------------------------------
@@ -92,65 +91,6 @@ void menu_game_options::handle()
});
}
break;
- case FILE_CATEGORY_FILTER:
- if (menu_event->iptkey == IPT_UI_LEFT)
- {
- mame_machine_manager::instance()->inifile().move_file(-1);
- changed = true;
- }
- else if (menu_event->iptkey == IPT_UI_RIGHT)
- {
- mame_machine_manager::instance()->inifile().move_file(1);
- changed = true;
- }
- else if (menu_event->iptkey == IPT_UI_SELECT)
- {
- inifile_manager &ifile = mame_machine_manager::instance()->inifile();
- int total = ifile.total();
- std::vector<std::string> s_sel(total);
- mame_machine_manager::instance()->inifile().set_cat(0);
- for (size_t index = 0; index < total; ++index)
- s_sel[index] = ifile.get_file(index);
-
- menu::stack_push<menu_selector>(
- ui(), container(), std::move(s_sel), ifile.cur_file(),
- [this] (int selection)
- {
- mame_machine_manager::instance()->inifile().set_file(selection);
- mame_machine_manager::instance()->inifile().set_cat(0);
- reset(reset_options::REMEMBER_REF);
- });
- }
- break;
- case CATEGORY_FILTER:
- if (menu_event->iptkey == IPT_UI_LEFT)
- {
- mame_machine_manager::instance()->inifile().move_cat(-1);
- changed = true;
- }
- else if (menu_event->iptkey == IPT_UI_RIGHT)
- {
- mame_machine_manager::instance()->inifile().move_cat(1);
- changed = true;
- }
- else if (menu_event->iptkey == IPT_UI_SELECT)
- {
- inifile_manager &ifile = mame_machine_manager::instance()->inifile();
- int total = ifile.cat_total();
- std::vector<std::string> s_sel(total);
- for (int index = 0; index < total; ++index)
- s_sel[index] = ifile.get_category(index);
-
- menu::stack_push<menu_selector>(
- ui(), container(), std::move(s_sel), ifile.cur_cat(),
- [this] (int selection)
- {
- mame_machine_manager::instance()->inifile().cur_cat() = selection;
- mame_machine_manager::instance()->inifile().set_cat(selection);
- reset(reset_options::REMEMBER_REF);
- });
- }
- break;
case FILTER_ADJUST:
if (menu_event->iptkey == IPT_UI_LEFT)
{
@@ -247,38 +187,17 @@ void menu_game_options::populate(float &customtop, float &custombottom)
// add filter item
uint32_t arrow_flags = get_arrow_flags<uint16_t>(machine_filter::FIRST, machine_filter::LAST, m_main);
- if (machine_filter::CATEGORY == m_main)
- {
- item_append(_("Filter"), machine_filter::display_name(m_main), arrow_flags, (void *)(uintptr_t)FILTER_MENU);
- if (mame_machine_manager::instance()->inifile().total() > 0)
- {
- inifile_manager &inif = mame_machine_manager::instance()->inifile();
-
- arrow_flags = get_arrow_flags(uint16_t(0), uint16_t(inif.total() - 1), inif.cur_file());
- fbuff = _(" ^!File");
- convert_command_glyph(fbuff);
- item_append(fbuff, inif.get_file(), arrow_flags, (void *)(uintptr_t)FILE_CATEGORY_FILTER);
+ auto active_filter(main_filters::filters.find(m_main));
+ if (main_filters::filters.end() == active_filter)
+ active_filter = main_filters::filters.emplace(m_main, machine_filter::create(m_main)).first;
+ item_append(_("Filter"), active_filter->second->display_name(), arrow_flags, (void *)(uintptr_t)FILTER_MENU);
- arrow_flags = get_arrow_flags(uint16_t(0), uint16_t(inif.cat_total() - 1), inif.cur_cat());
- fbuff = _(" ^!Category");
- convert_command_glyph(fbuff);
- item_append(fbuff, inif.get_category(), arrow_flags, (void *)(uintptr_t)CATEGORY_FILTER);
- }
- }
- else
+ // add subitem if the filter wants it
+ if (active_filter->second->wants_adjuster())
{
- auto active_filter(main_filters::filters.find(m_main));
- if (main_filters::filters.end() == active_filter)
- active_filter = main_filters::filters.emplace(m_main, machine_filter::create(m_main)).first;
- item_append(_("Filter"), active_filter->second->display_name(), arrow_flags, (void *)(uintptr_t)FILTER_MENU);
-
- // add subitem if the filter wants it
- if (active_filter->second->wants_adjuster())
- {
- std::string name("^!");
- convert_command_glyph(name);
- item_append(name, active_filter->second->adjust_text(), active_filter->second->arrow_flags(), (void *)(FILTER_ADJUST));
- }
+ std::string name("^!");
+ convert_command_glyph(name);
+ item_append(name, active_filter->second->adjust_text(), active_filter->second->arrow_flags(), (void *)(FILTER_ADJUST));
}
item_append(menu_item_type::SEPARATOR);
diff --git a/src/frontend/mame/ui/optsmenu.h b/src/frontend/mame/ui/optsmenu.h
index 2ef9d2969c8..e9650e3a95b 100644
--- a/src/frontend/mame/ui/optsmenu.h
+++ b/src/frontend/mame/ui/optsmenu.h
@@ -30,9 +30,7 @@ private:
enum
{
FILTER_MENU = 1,
- FILE_CATEGORY_FILTER,
FILTER_ADJUST,
- CATEGORY_FILTER,
CONF_DIR,
DISPLAY_MENU,
CUSTOM_MENU,
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index cb66194acb5..e2e1ee0bfb4 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -27,7 +27,6 @@
#include "drivenum.h"
#include "emuopts.h"
#include "mame.h"
-#include "rendfont.h"
#include "rendutil.h"
#include "softlist_dev.h"
#include "uiinput.h"
@@ -170,8 +169,6 @@ void menu_select_game::handle()
if (!m_prev_selected)
m_prev_selected = item[0].ref;
- bool check_filter = false;
-
// if I have to load datfile, perform a hard reset
if (ui_globals::reset)
{
@@ -195,6 +192,7 @@ void menu_select_game::handle()
machine().ui_input().pressed(IPT_UI_PAUSE);
// process the menu
+ bool check_filter(false);
const event *menu_event = process(PROCESS_LR_REPEAT);
if (menu_event)
{
@@ -228,7 +226,8 @@ void menu_select_game::handle()
// this is generated when something in the left box is clicked
m_prev_selected = nullptr;
check_filter = true;
- highlight = l_hover;
+ highlight = hover - HOVER_FILTER_FIRST;
+ assert((machine_filter::FIRST <= highlight) && (machine_filter::LAST >= highlight));
break;
case IPT_UI_CONFIGURE:
@@ -250,7 +249,6 @@ void menu_select_game::handle()
}
else if (get_focus() == focused_menu::LEFT)
{
- l_hover = highlight;
check_filter = true;
m_prev_selected = nullptr;
}
@@ -377,38 +375,29 @@ void menu_select_game::handle()
if (check_filter)
{
m_search.clear();
- switch (l_hover)
+ if ((machine_filter::FIRST <= highlight) && (machine_filter::LAST >= highlight))
{
- case machine_filter::CATEGORY:
- // FIXME: this should be unified with the other filters
- main_filters::actual = machine_filter::type(l_hover);
- menu::stack_push<menu_game_options>(ui(), container());
- break;
- default:
- if (l_hover >= machine_filter::ALL)
- {
- auto it(main_filters::filters.find(machine_filter::type(l_hover)));
- if (main_filters::filters.end() == it)
- it = main_filters::filters.emplace(machine_filter::type(l_hover), machine_filter::create(machine_filter::type(l_hover))).first;
- it->second->show_ui(
- ui(),
- container(),
- [this] (machine_filter &filter)
+ auto it(main_filters::filters.find(machine_filter::type(highlight)));
+ if (main_filters::filters.end() == it)
+ it = main_filters::filters.emplace(machine_filter::type(highlight), machine_filter::create(machine_filter::type(highlight))).first;
+ it->second->show_ui(
+ ui(),
+ container(),
+ [this] (machine_filter &filter)
+ {
+ machine_filter::type const new_type(filter.get_type());
+ if (machine_filter::CUSTOM == new_type)
{
- machine_filter::type const new_type(filter.get_type());
- if (machine_filter::CUSTOM == new_type)
+ emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
- emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
- {
- filter.save_ini(file, 0);
- file.close();
- }
+ filter.save_ini(file, 0);
+ file.close();
}
- main_filters::actual = new_type;
- reset(reset_options::SELECT_FIRST);
- });
- }
+ }
+ main_filters::actual = new_type;
+ reset(reset_options::SELECT_FIRST);
+ });
}
}
}
@@ -449,9 +438,6 @@ void menu_select_game::populate(float &customtop, float &custombottom)
case machine_filter::UNAVAILABLE:
m_displaylist = m_unavailsortedlist;
break;
- case machine_filter::CATEGORY:
- build_category();
- break;
default:
{
auto const it(main_filters::filters.find(main_filters::actual));
@@ -886,22 +872,6 @@ void menu_select_game::change_info_pane(int delta)
}
//-------------------------------------------------
-// build category list
-//-------------------------------------------------
-
-void menu_select_game::build_category()
-{
- m_displaylist.clear();
- std::vector<int> temp_filter;
- mame_machine_manager::instance()->inifile().load_ini_category(temp_filter);
-
- for (auto actual : temp_filter)
- m_displaylist.push_back(&driver_list::driver(actual));
-
- std::stable_sort(m_displaylist.begin(), m_displaylist.end(), sorted_game_list);
-}
-
-//-------------------------------------------------
// populate search list
//-------------------------------------------------
@@ -1240,147 +1210,10 @@ void menu_select_game::load_custom_filters()
float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
{
- float line_height = ui().get_line_height();
-
- if (ui_globals::panels_status == SHOW_PANELS || ui_globals::panels_status == HIDE_RIGHT_PANEL)
- {
- auto const active_filter(main_filters::filters.find(main_filters::actual));
- float origy1 = y1;
- float origy2 = y2;
- float text_size = ui().options().infos_size();
- float line_height_max = line_height * text_size;
- float left_width = 0.0f;
- int line_count = machine_filter::COUNT;
- int phover = HOVER_FILTER_FIRST;
- float sc = y2 - y1 - (2.0f * UI_BOX_TB_BORDER);
-
- if ((line_count * line_height_max) > sc)
- {
- float lm = sc / (line_count);
- text_size = lm / line_height;
- line_height_max = line_height * text_size;
- }
-
- std::string tmp("_# ");
- convert_command_glyph(tmp);
- float text_sign = ui().get_string_width(tmp.c_str(), text_size);
- for (machine_filter::type x = machine_filter::FIRST; x < machine_filter::COUNT; ++x)
- {
- float total_width;
-
- // compute width of left hand side
- total_width = ui().get_string_width(machine_filter::display_name(x), text_size);
- total_width += text_sign;
-
- // track the maximum
- if (total_width > left_width)
- left_width = total_width;
- }
-
- x2 = x1 + left_width + 2.0f * UI_BOX_LR_BORDER;
- ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- // take off the borders
- x1 += UI_BOX_LR_BORDER;
- x2 -= UI_BOX_LR_BORDER;
- y1 += UI_BOX_TB_BORDER;
- y2 -= UI_BOX_TB_BORDER;
-
- for (machine_filter::type filter = machine_filter::FIRST; filter < machine_filter::COUNT; ++filter)
- {
- std::string str;
- if (main_filters::filters.end() != active_filter)
- {
- str = active_filter->second->adorned_display_name(filter);
- }
- else
- {
- if (main_filters::actual == filter)
- {
- str = std::string("_> ") + str;
- convert_command_glyph(str);
- }
- str.append(machine_filter::display_name(filter));
- }
-
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- if (mouse_in_rect(x1, y1, x2, y1 + line_height_max))
- {
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = phover + filter;
- menu::highlight(x1, y1, x2, y1 + line_height_max, bgcolor);
- }
-
- if (highlight == filter && get_focus() == focused_menu::LEFT)
- {
- fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
- bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
- ui().draw_textured_box(container(), x1, y1, x2, y1 + line_height_max, bgcolor, rgb_t(255, 43, 43, 43),
- hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
- }
-
- float const x1t = x1 + ((str == machine_filter::display_name(filter)) ? text_sign : 0.0f);
-
- ui().draw_text_full(container(), str.c_str(), x1t, y1, x2 - x1, ui::text_layout::LEFT, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
- y1 += line_height_max;
- }
-
- x1 = x2 + UI_BOX_LR_BORDER;
- x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
- y1 = origy1;
- y2 = origy2;
- float space = x2 - x1;
- float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_in_rect(x1, y1, x2, y2))
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
- return x2 + UI_BOX_LR_BORDER;
- }
- else
- {
- float space = x2 - x1;
- float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_in_rect(x1, y1, x2, y2))
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
- return x2 + UI_BOX_LR_BORDER;
- }
+ return menu_select_launch::draw_left_panel<machine_filter>(main_filters::actual, main_filters::filters, highlight, x1, y1, x2, y2);
}
-
//-------------------------------------------------
// get selected software and/or driver
//-------------------------------------------------
@@ -1401,8 +1234,6 @@ void menu_select_game::get_selection(ui_software_info const *&software, game_dri
void menu_select_game::make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const
{
- inifile_manager &inifile = mame_machine_manager::instance()->inifile();
-
line0 = string_format(_("%1$s %2$s ( %3$d / %4$d machines (%5$d BIOS) )"),
emulator_info::get_appname(),
bare_build_version,
@@ -1414,14 +1245,6 @@ void menu_select_game::make_topbox_text(std::string &line0, std::string &line1,
{
line1.clear();
}
- else if (main_filters::actual == machine_filter::CATEGORY && inifile.total() > 0)
- {
- line1 = string_format(_("%1$s (%2$s - %3$s) - Search: %4$s_"),
- machine_filter::display_name(main_filters::actual),
- inifile.get_file(),
- inifile.get_category(),
- m_search);
- }
else
{
auto const it(main_filters::filters.find(main_filters::actual));
diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h
index 0a2b49e08bd..7cccab7a2fb 100644
--- a/src/frontend/mame/ui/selgame.h
+++ b/src/frontend/mame/ui/selgame.h
@@ -66,7 +66,6 @@ private:
// internal methods
void change_info_pane(int delta);
- void build_category();
void build_available_list();
bool isfavorite() const;
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index 7ae24e1cdae..9a41f285a57 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -26,6 +26,7 @@
#include "drivenum.h"
#include "emuopts.h"
+#include "rendfont.h"
#include "rendutil.h"
#include "softlist.h"
#include "softlist_dev.h"
@@ -133,9 +134,11 @@ char const *const menu_select_launch::s_info_titles[] = {
__("Sysinfo") };
-// instantiate possible variants of select_bios so derived classes don't get link errors
+// instantiate possible variants of these so derived classes don't get link errors
template bool menu_select_launch::select_bios(game_driver const &, bool);
template bool menu_select_launch::select_bios(ui_software_info const &, bool);
+template float menu_select_launch::draw_left_panel<machine_filter>(machine_filter::type current, std::map<machine_filter::type, machine_filter::ptr> const &filters, int focus, float x1, float y1, float x2, float y2);
+template float menu_select_launch::draw_left_panel<software_filter>(software_filter::type current, std::map<software_filter::type, software_filter::ptr> const &filters, int focus, float x1, float y1, float x2, float y2);
menu_select_launch::system_flags::system_flags(machine_static_info const &info)
@@ -813,6 +816,127 @@ bool menu_select_launch::draw_error_text()
}
+template <typename Filter>
+float menu_select_launch::draw_left_panel(
+ typename Filter::type current,
+ std::map<typename Filter::type, typename Filter::ptr> const &filters,
+ int focus,
+ float x1, float y1, float x2, float y2)
+{
+ if ((ui_globals::panels_status != SHOW_PANELS) && (ui_globals::panels_status != HIDE_RIGHT_PANEL))
+ return draw_collapsed_left_panel(x1, y1, x2, y2);
+
+ // calculate line height
+ float const line_height(ui().get_line_height());
+ float const text_size(ui().options().infos_size());
+ float const sc(y2 - y1 - (2.0f * UI_BOX_TB_BORDER));
+ float line_height_max(line_height * text_size);
+ if ((Filter::COUNT * line_height_max) > sc)
+ {
+ float const lm(sc / Filter::COUNT);
+ line_height_max = line_height * (lm / line_height);
+ }
+
+ // calculate horizontal offset for unadorned names
+ std::string tmp("_# ");
+ convert_command_glyph(tmp);
+ float const text_sign = ui().get_string_width(tmp.c_str(), text_size);
+
+ // get the maximum width of a filter name
+ float left_width(0.0f);
+ for (typename Filter::type x = Filter::FIRST; Filter::COUNT > x; ++x)
+ left_width = std::max(ui().get_string_width(Filter::display_name(x), text_size) + text_sign, left_width);
+
+ // outline the box and inset by the border width
+ float const origy1(y1);
+ float const origy2(y2);
+ x2 = x1 + left_width + 2.0f * UI_BOX_LR_BORDER;
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
+ x1 += UI_BOX_LR_BORDER;
+ x2 -= UI_BOX_LR_BORDER;
+ y1 += UI_BOX_TB_BORDER;
+ y2 -= UI_BOX_TB_BORDER;
+
+ // now draw the rows
+ auto const active_filter(filters.find(current));
+ for (typename Filter::type filter = Filter::FIRST; Filter::COUNT > filter; ++filter)
+ {
+ std::string str;
+ if (filters.end() != active_filter)
+ {
+ str = active_filter->second->adorned_display_name(filter);
+ }
+ else
+ {
+ if (current == filter)
+ {
+ str = std::string("_> ");
+ convert_command_glyph(str);
+ }
+ str.append(Filter::display_name(filter));
+ }
+
+ // handle mouse hover in passing
+ rgb_t bgcolor = UI_TEXT_BG_COLOR;
+ rgb_t fgcolor = UI_TEXT_COLOR;
+ if (mouse_in_rect(x1, y1, x2, y1 + line_height_max))
+ {
+ bgcolor = UI_MOUSEOVER_BG_COLOR;
+ fgcolor = UI_MOUSEOVER_COLOR;
+ hover = HOVER_FILTER_FIRST + filter;
+ highlight(x1, y1, x2, y1 + line_height_max, bgcolor);
+ }
+
+ // draw primary highlight if keyboard focus is here
+ if ((focus == filter) && (get_focus() == focused_menu::LEFT))
+ {
+ fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
+ bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
+ ui().draw_textured_box(
+ container(),
+ x1, y1, x2, y1 + line_height_max,
+ bgcolor, rgb_t(255, 43, 43, 43),
+ hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
+ }
+
+ // finally draw the text itself and move to the next line
+ float const x1t = x1 + ((str == Filter::display_name(filter)) ? text_sign : 0.0f);
+ ui().draw_text_full(
+ container(), str.c_str(),
+ x1t, y1, x2 - x1,
+ ui::text_layout::LEFT, ui::text_layout::NEVER,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor,
+ nullptr, nullptr, text_size);
+ y1 += line_height_max;
+ }
+
+ x1 = x2 + UI_BOX_LR_BORDER;
+ x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
+ y1 = origy1;
+ y2 = origy2;
+ float const space = x2 - x1;
+ float const lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
+
+ // set left-right arrows dimension
+ float const ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
+ float const ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
+ float const ar_x1 = ar_x0 + lr_arrow_width;
+ float const ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
+
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xef, 0x12, 0x47, 0x7b));
+
+ rgb_t fgcolor = UI_TEXT_COLOR;
+ if (mouse_in_rect(x1, y1, x2, y2))
+ {
+ fgcolor = UI_MOUSEOVER_COLOR;
+ hover = HOVER_LPANEL_ARROW;
+ }
+
+ draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
+ return x2 + UI_BOX_LR_BORDER;
+}
+
+
template <typename T> bool menu_select_launch::select_bios(T const &driver, bool inlist)
{
s_bios biosname;
@@ -1416,15 +1540,8 @@ void menu_select_launch::handle_events(uint32_t flags, event &ev)
ui_globals::rpanel = (HOVER_RP_FIRST - hover) * (-1);
stop = true;
}
- else if (hover >= HOVER_SW_FILTER_FIRST && hover <= HOVER_SW_FILTER_LAST)
- {
- l_sw_hover = (HOVER_SW_FILTER_FIRST - hover) * (-1);
- ev.iptkey = IPT_OTHER;
- stop = true;
- }
else if (hover >= HOVER_FILTER_FIRST && hover <= HOVER_FILTER_LAST)
{
- l_hover = (HOVER_FILTER_FIRST - hover) * (-1);
ev.iptkey = IPT_OTHER;
stop = true;
}
@@ -2283,6 +2400,36 @@ void menu_select_launch::exit(running_machine &machine)
//-------------------------------------------------
+// draw collapsed left panel
+//-------------------------------------------------
+
+float menu_select_launch::draw_collapsed_left_panel(float x1, float y1, float x2, float y2)
+{
+ float const space = x2 - x1;
+ float const lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
+
+ // set left-right arrows dimension
+ float const ar_x0 = 0.5f * (x2 + x1) - (0.5f * lr_arrow_width);
+ float const ar_y0 = 0.5f * (y2 + y1) + (0.1f * space);
+ float const ar_x1 = ar_x0 + lr_arrow_width;
+ float const ar_y1 = 0.5f * (y2 + y1) + (0.9f * space);
+
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xef, 0x12, 0x47, 0x7b)); // FIXME: magic numbers in colour?
+
+ rgb_t fgcolor = UI_TEXT_COLOR;
+ if (mouse_in_rect(x1, y1, x2, y2))
+ {
+ fgcolor = UI_MOUSEOVER_COLOR;
+ hover = HOVER_LPANEL_ARROW;
+ }
+
+ draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
+
+ return x2 + UI_BOX_LR_BORDER;
+}
+
+
+//-------------------------------------------------
// draw infos
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/selmenu.h b/src/frontend/mame/ui/selmenu.h
index 8b8d0157448..5bad2445b97 100644
--- a/src/frontend/mame/ui/selmenu.h
+++ b/src/frontend/mame/ui/selmenu.h
@@ -114,10 +114,16 @@ protected:
bool draw_error_text();
+ template <typename Filter>
+ float draw_left_panel(
+ typename Filter::type current,
+ std::map<typename Filter::type, typename Filter::ptr> const &filters,
+ int focus,
+ float x1, float y1, float x2, float y2);
+
template <typename T> bool select_bios(T const &driver, bool inlist);
bool select_part(software_info const &info, ui_software_info const &ui_info);
- int l_hover, l_sw_hover;
int visible_items;
void *m_prev_selected;
int m_total_lines;
@@ -188,6 +194,7 @@ private:
// draw left panel
virtual float draw_left_panel(float x1, float y1, float x2, float y2) = 0;
+ float draw_collapsed_left_panel(float x1, float y1, float x2, float y2);
// draw infos
void infos_render(float x1, float y1, float x2, float y2);
diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp
index e64a6136cf7..ec8262c4a93 100644
--- a/src/frontend/mame/ui/selsoft.cpp
+++ b/src/frontend/mame/ui/selsoft.cpp
@@ -20,7 +20,6 @@
#include "drivenum.h"
#include "emuopts.h"
#include "mame.h"
-#include "rendfont.h"
#include "rendutil.h"
#include "softlist_dev.h"
#include "uiinput.h"
@@ -119,12 +118,11 @@ void menu_select_software::handle()
if (m_prev_selected == nullptr)
m_prev_selected = item[0].ref;
- bool check_filter = false;
-
// ignore pause keys by swallowing them before we process the menu
machine().ui_input().pressed(IPT_UI_PAUSE);
// process the menu
+ bool check_filter(false);
const event *menu_event = process(PROCESS_LR_REPEAT);
if (menu_event)
{
@@ -137,7 +135,6 @@ void menu_select_software::handle()
case IPT_UI_SELECT:
if (get_focus() == focused_menu::LEFT)
{
- l_sw_hover = highlight;
check_filter = true;
m_prev_selected = nullptr;
}
@@ -201,8 +198,9 @@ void menu_select_software::handle()
case IPT_OTHER:
// this is generated when something in the left box is clicked
- highlight = l_sw_hover;
check_filter = true;
+ highlight = hover - HOVER_FILTER_FIRST;
+ assert((software_filter::FIRST <= highlight) && (software_filter::LAST >= highlight));
m_prev_selected = nullptr;
break;
@@ -256,9 +254,9 @@ void menu_select_software::handle()
{
m_search.clear();
- filter_map::const_iterator it(m_filters.find(software_filter::type(l_sw_hover)));
+ filter_map::const_iterator it(m_filters.find(software_filter::type(highlight)));
if (m_filters.end() == it)
- it = m_filters.emplace(software_filter::type(l_sw_hover), software_filter::create(software_filter::type(l_sw_hover), m_filter_data)).first;
+ it = m_filters.emplace(software_filter::type(highlight), software_filter::create(software_filter::type(highlight), m_filter_data)).first;
it->second->show_ui(
ui(),
container(),
@@ -585,135 +583,10 @@ void menu_select_software::find_matches(const char *str, int count)
float menu_select_software::draw_left_panel(float x1, float y1, float x2, float y2)
{
- if (ui_globals::panels_status == SHOW_PANELS || ui_globals::panels_status == HIDE_RIGHT_PANEL)
- {
- filter_map::const_iterator active_filter(m_filters.find(m_filter_type));
- if (m_filters.end() == active_filter)
- active_filter = m_filters.emplace(m_filter_type, software_filter::create(m_filter_type, m_filter_data)).first;
- float origy1 = y1;
- float origy2 = y2;
- float text_size = 0.75f;
- float l_height = ui().get_line_height();
- float line_height = l_height * text_size;
- float left_width = 0.0f;
- int line_count = software_filter::COUNT;
- int phover = HOVER_SW_FILTER_FIRST;
- float sc = y2 - y1 - (2.0f * UI_BOX_TB_BORDER);
-
- if ((line_count * line_height) > sc)
- {
- float lm = sc / (line_count);
- text_size = lm / l_height;
- line_height = l_height * text_size;
- }
-
- std::string tmp("_# ");
- convert_command_glyph(tmp);
- float text_sign = ui().get_string_width(tmp.c_str(), text_size);
- for (software_filter::type x = software_filter::FIRST; x < software_filter::COUNT; ++x)
- {
- float total_width;
-
- // compute width of left hand side
- total_width = ui().get_string_width(software_filter::display_name(x), text_size);
- total_width += text_sign;
-
- // track the maximum
- if (total_width > left_width)
- left_width = total_width;
- }
-
- x2 = x1 + left_width + 2.0f * UI_BOX_LR_BORDER;
- ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- // take off the borders
- x1 += UI_BOX_LR_BORDER;
- x2 -= UI_BOX_LR_BORDER;
- y1 += UI_BOX_TB_BORDER;
- y2 -= UI_BOX_TB_BORDER;
-
- for (software_filter::type filter = software_filter::FIRST; filter < software_filter::COUNT; ++filter)
- {
- std::string const str(active_filter->second->adorned_display_name(filter));
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- if (mouse_in_rect(x1, y1, x2, y1 + line_height))
- {
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = phover + filter;
- }
-
- if (highlight == filter && get_focus() == focused_menu::LEFT)
- {
- fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
- bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
- }
-
- if (bgcolor != UI_TEXT_BG_COLOR)
- {
- ui().draw_textured_box(container(), x1, y1, x2, y1 + line_height, bgcolor, rgb_t(255, 43, 43, 43),
- hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
- }
-
- float const x1t = x1 + ((str == software_filter::display_name(filter)) ? text_sign : 0.0f);
-
- ui().draw_text_full(container(), str.c_str(), x1t, y1, x2 - x1, ui::text_layout::LEFT, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
- y1 += line_height;
- }
-
- x1 = x2 + UI_BOX_LR_BORDER;
- x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
- y1 = origy1;
- y2 = origy2;
- float space = x2 - x1;
- float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_in_rect(x1, y1, x2, y2))
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
- return x2 + UI_BOX_LR_BORDER;
- }
- else
- {
- float space = x2 - x1;
- float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_in_rect(x1, y1, x2, y2))
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
- return x2 + UI_BOX_LR_BORDER;
- }
+ return menu_select_launch::draw_left_panel<software_filter>(m_filter_type, m_filters, highlight, x1, y1, x2, y2);
}
+
//-------------------------------------------------
// get selected software and/or driver
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp
index df60068d949..5bd6c6cfe1f 100644
--- a/src/frontend/mame/ui/utils.cpp
+++ b/src/frontend/mame/ui/utils.cpp
@@ -12,16 +12,21 @@
#include "ui/utils.h"
#include "ui/custmenu.h" // FIXME: get s_filter out of here
+#include "ui/inifile.h"
#include "ui/selector.h"
#include "language.h"
+#include "mame.h"
#include "drivenum.h"
#include "rendfont.h"
#include "softlist.h"
+#include <bitset>
#include <cstdlib>
+#include <cstring>
#include <iterator>
+#include <unordered_set>
namespace ui {
@@ -180,9 +185,9 @@ public:
}
protected:
- choice_filter_impl_base(std::vector<std::string> const &choices, char const *value) :
- m_choices(choices),
- m_selection(0U)
+ choice_filter_impl_base(std::vector<std::string> const &choices, char const *value)
+ : m_choices(choices)
+ , m_selection(0U)
{
if (value)
{
@@ -211,6 +216,8 @@ template <class Impl, class Base, typename Base::type Type>
class composite_filter_impl_base : public simple_filter_impl_base<Base, Type>
{
public:
+ virtual void show_ui(mame_ui_manager &mui, render_container &container, std::function<void (Base &)> &&handler) override;
+
virtual bool wants_adjuster() const override { return true; }
virtual char const *adjust_text() const override { return _("<set up filters>"); }
@@ -255,14 +262,15 @@ public:
break;
typename Base::type const t(flt->get_type());
- bool const r(flt->apply(info));
if (Impl::is_inclusion(t))
{
- inclusions.set(t);
- if (r)
- included.set(t);
+ if (!included.test(t))
+ {
+ inclusions.set(t);
+ included.set(t, flt->apply(info));
+ }
}
- else if (!r)
+ else if (!flt->apply(info))
{
return false;
}
@@ -270,8 +278,6 @@ public:
return inclusions == included;
}
- virtual void show_ui(mame_ui_manager &mui, render_container &container, std::function<void (Base &)> &&handler) override;
-
protected:
composite_filter_impl_base() { }
@@ -308,11 +314,11 @@ private:
mame_ui_manager &mui,
render_container &container,
Impl &parent,
- std::function<void (Base &filter)> &&handler) :
- menu(mui, container),
- m_parent(parent),
- m_handler(std::move(handler)),
- m_added(false)
+ std::function<void (Base &filter)> &&handler)
+ : menu(mui, container)
+ , m_parent(parent)
+ , m_handler(std::move(handler))
+ , m_added(false)
{
}
@@ -472,7 +478,7 @@ void composite_filter_impl_base<Impl, Base, Type>::menu_configure::populate(floa
unsigned i = 0;
for (i = 0; (MAX > i) && m_parent.m_filters[i]; ++i)
{
- item_append(util::string_format("Filter %u", i + 1), m_parent.m_filters[i]->display_name(), get_arrow_flags(i), (void *)(FILTER_FIRST + i));
+ item_append(util::string_format(_("Filter %1$u"), i + 1), m_parent.m_filters[i]->display_name(), get_arrow_flags(i), (void *)(FILTER_FIRST + i));
if (m_added)
selected = item.size() - 2;
if (m_parent.m_filters[i]->wants_adjuster())
@@ -700,8 +706,8 @@ public:
class manufacturer_machine_filter : public choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER>
{
public:
- manufacturer_machine_filter(char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER>(c_mnfct::ui, value)
+ manufacturer_machine_filter(char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER>(c_mnfct::ui, value)
{
}
@@ -721,8 +727,8 @@ public:
class year_machine_filter : public choice_filter_impl_base<machine_filter, machine_filter::YEAR>
{
public:
- year_machine_filter(char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<machine_filter, machine_filter::YEAR>(c_year::ui, value)
+ year_machine_filter(char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<machine_filter, machine_filter::YEAR>(c_year::ui, value)
{
}
@@ -781,14 +787,347 @@ using favorite_machine_filter = inclusive_machine_filter_impl<machine_filt
//-------------------------------------------------
+// category machine filter
+//-------------------------------------------------
+
+class category_machine_filter : public simple_filter_impl_base<machine_filter, machine_filter::CATEGORY>
+{
+public:
+ category_machine_filter(char const *value, emu_file *file, unsigned indent)
+ : m_ini(0)
+ , m_group(0)
+ , m_include_clones(false)
+ , m_adjust_text()
+ , m_cache()
+ , m_cache_valid(false)
+ {
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ if (value)
+ {
+ char const *const split(std::strchr(value, '/'));
+ std::string ini;
+ if (split)
+ ini.assign(value, split);
+ else
+ ini.assign(value);
+
+ for (unsigned i = 0; mgr.get_file_count() > i; ++i)
+ {
+ if (mgr.get_file_name(i) == ini)
+ {
+ m_ini = i;
+ if (split)
+ {
+ std::string const group(split + 1);
+ for (unsigned j = 0; mgr.get_category_count(i) > j; ++j)
+ {
+ if (mgr.get_category_name(i, j) == group)
+ {
+ m_group = j;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (mgr.get_file_count() > m_ini)
+ m_include_clones = include_clones_default(mgr.get_file_name(m_ini));
+
+ set_adjust_text();
+ }
+
+ virtual char const *filter_text() const override
+ {
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ return ((mgr.get_file_count() > m_ini) && (mgr.get_category_count(m_ini) > m_group)) ? m_adjust_text.c_str() : nullptr;
+ }
+
+ virtual void show_ui(mame_ui_manager &mui, render_container &container, std::function<void (machine_filter &)> &&handler) override;
+
+ virtual bool wants_adjuster() const override { return mame_machine_manager::instance()->inifile().get_file_count(); }
+ virtual char const *adjust_text() const override { return m_adjust_text.c_str(); }
+
+ virtual void save_ini(emu_file &file, unsigned indent) const override
+ {
+ char const *const text(filter_text());
+ file.puts(util::string_format("%2$*1$s%3$s = %4$s\n", 2 * indent, "", this->config_name(), text ? text : "").c_str());
+ }
+
+ virtual bool apply(game_driver const &drv) const override
+ {
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ if (!mgr.get_file_count())
+ return true;
+ else if ((mgr.get_file_count() <= m_ini) || (mgr.get_category_count(m_ini) <= m_group))
+ return false;
+
+ if (!m_cache_valid)
+ mame_machine_manager::instance()->inifile().load_ini_category(m_ini, m_group, m_cache);
+ m_cache_valid = true;
+
+ if (m_cache.end() != m_cache.find(&drv))
+ return true;
+
+ if (m_include_clones)
+ {
+ int const found(driver_list::find(drv.parent));
+ return m_cache.end() != m_cache.find(&driver_list::driver(found));
+ }
+
+ return false;
+ }
+
+private:
+ class menu_configure : public menu
+ {
+ public:
+ menu_configure(
+ mame_ui_manager &mui,
+ render_container &container,
+ category_machine_filter &parent,
+ std::function<void (machine_filter &filter)> &&handler)
+ : menu(mui, container)
+ , m_parent(parent)
+ , m_handler(std::move(handler))
+ , m_state(std::make_unique<std::pair<unsigned, bool> []>(mame_machine_manager::instance()->inifile().get_file_count()))
+ , m_ini(parent.m_ini)
+ {
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ for (size_t i = 0; mgr.get_file_count() > i; ++i)
+ {
+ m_state[i].first = (m_ini == i) ? m_parent.m_group : 0U;
+ m_state[i].second = (m_ini == i) ? m_parent.m_include_clones : include_clones_default(mgr.get_file_name(i));
+ }
+ }
+
+ virtual ~menu_configure() override
+ {
+ bool const valid(mame_machine_manager::instance()->inifile().get_file_count() > m_ini);
+ unsigned const group(valid ? m_state[m_ini].first : 0);
+ if ((m_ini != m_parent.m_ini) || (group != m_parent.m_group))
+ {
+ m_parent.m_cache.clear();
+ m_parent.m_cache_valid = false;
+ }
+ m_parent.m_ini = m_ini;
+ m_parent.m_group = group;
+ m_parent.m_include_clones = valid ? m_state[m_ini].second : false;
+ m_parent.set_adjust_text();
+ m_handler(m_parent);
+ }
+
+ protected:
+ virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override
+ {
+ char const *const text[] = { _("Select category:") };
+ draw_text_box(
+ std::begin(text), std::end(text),
+ x, x2, y - top, y - UI_BOX_TB_BORDER,
+ ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ UI_TEXT_COLOR, UI_GREEN_COLOR, 1.0f);
+ }
+
+ private:
+ enum : uintptr_t
+ {
+ INI_FILE = 1,
+ SYSTEM_GROUP,
+ INCLUDE_CLONES
+ };
+
+ virtual void populate(float &customtop, float &custombottom) override;
+ virtual void handle() override;
+
+ category_machine_filter &m_parent;
+ std::function<void (machine_filter &)> m_handler;
+ std::unique_ptr<std::pair<unsigned, bool> []> const m_state;
+ unsigned m_ini;
+ };
+
+ void set_adjust_text()
+ {
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ unsigned const filecnt(mgr.get_file_count());
+ if (!filecnt)
+ {
+ m_adjust_text = _("[no category INI files]");
+ }
+ else
+ {
+ m_ini = std::min(m_ini, filecnt - 1);
+ unsigned const groupcnt(mgr.get_category_count(m_ini));
+ if (!groupcnt)
+ {
+ m_adjust_text = _("[no groups in INI file]");
+ }
+ else
+ {
+ m_group = std::min(m_group, groupcnt - 1);
+ m_adjust_text = util::string_format("%s/%s", mgr.get_file_name(m_ini), mgr.get_category_name(m_ini, m_group));
+ }
+ }
+ }
+
+ static bool include_clones_default(std::string const &name)
+ {
+ return !core_stricmp(name.c_str(), "category.ini") || !core_stricmp(name.c_str(), "alltime.ini");
+ }
+
+ unsigned m_ini, m_group;
+ bool m_include_clones;
+ std::string m_adjust_text;
+ mutable std::unordered_set<game_driver const *> m_cache;
+ mutable bool m_cache_valid;
+};
+
+void category_machine_filter::show_ui(mame_ui_manager &mui, render_container &container, std::function<void (machine_filter &)> &&handler)
+{
+ menu::stack_push<menu_configure>(mui, container, *this, std::move(handler));
+}
+
+
+void category_machine_filter::menu_configure::populate(float &customtop, float &custombottom)
+{
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ unsigned const filecnt(mgr.get_file_count());
+ if (!filecnt)
+ {
+ item_append(_("No category INI files found"), "", FLAG_DISABLE, nullptr);
+ }
+ else
+ {
+ m_ini = std::min(m_ini, filecnt - 1);
+ item_append(_("File"), mgr.get_file_name(m_ini), get_arrow_flags(0U, filecnt - 1, m_ini), reinterpret_cast<void *>(INI_FILE));
+ unsigned const groupcnt(mgr.get_category_count(m_ini));
+ if (!groupcnt)
+ {
+ item_append(_("No groups found in category file"), "", FLAG_DISABLE, nullptr);
+ }
+ else
+ {
+ m_state[m_ini].first = std::min(m_state[m_ini].first, groupcnt - 1);
+ item_append(_("Group"), mgr.get_category_name(m_ini, m_state[m_ini].first), get_arrow_flags(0U, groupcnt - 1, m_state[m_ini].first), reinterpret_cast<void *>(SYSTEM_GROUP));
+ item_append(_("Include clones"), m_state[m_ini].second ? _("Yes") : _("No"), m_state[m_ini].second ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, reinterpret_cast<void *>(INCLUDE_CLONES));
+ }
+ }
+ item_append(menu_item_type::SEPARATOR);
+ customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
+}
+
+void category_machine_filter::menu_configure::handle()
+{
+ const event *menu_event = process(PROCESS_LR_REPEAT);
+ if (menu_event && menu_event->itemref)
+ {
+ bool changed(false);
+ uintptr_t const ref(reinterpret_cast<uintptr_t>(menu_event->itemref));
+ inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
+ switch (menu_event->iptkey)
+ {
+ case IPT_UI_LEFT:
+ if ((INI_FILE == ref) && m_ini)
+ {
+ --m_ini;
+ changed = true;
+ }
+ else if ((SYSTEM_GROUP == ref) && m_state[m_ini].first)
+ {
+ --m_state[m_ini].first;
+ changed = true;
+ }
+ else if ((INCLUDE_CLONES == ref) && m_state[m_ini].second)
+ {
+ m_state[m_ini].second = false;
+ changed = true;
+ }
+ break;
+ case IPT_UI_RIGHT:
+ if ((INI_FILE == ref) && (mgr.get_file_count() > (m_ini + 1)))
+ {
+ ++m_ini;
+ changed = true;
+ }
+ else if ((SYSTEM_GROUP == ref) && (mgr.get_category_count(m_ini) > (m_state[m_ini].first + 1)))
+ {
+ ++m_state[m_ini].first;
+ changed = true;
+ }
+ else if ((INCLUDE_CLONES == ref) && !m_state[m_ini].second)
+ {
+ m_state[m_ini].second = true;
+ changed = true;
+ }
+ break;
+
+ case IPT_UI_SELECT:
+ if (INI_FILE == ref)
+ {
+ std::vector<std::string> choices;
+ choices.reserve(mgr.get_file_count());
+ for (size_t i = 0; mgr.get_file_count() > i; ++i)
+ choices.emplace_back(mgr.get_file_name(i));
+ menu::stack_push<menu_selector>(
+ ui(),
+ container(),
+ std::move(choices),
+ m_ini,
+ [this] (int selection)
+ {
+ if (selection != m_ini)
+ {
+ m_ini = selection;
+ reset(reset_options::REMEMBER_REF);
+ }
+ });
+ }
+ else if (SYSTEM_GROUP == ref)
+ {
+ std::vector<std::string> choices;
+ choices.reserve(mgr.get_category_count(m_ini));
+ for (size_t i = 0; mgr.get_category_count(m_ini) > i; ++i)
+ choices.emplace_back(mgr.get_category_name(m_ini, i));
+ menu::stack_push<menu_selector>(
+ ui(),
+ container(),
+ std::move(choices),
+ m_state[m_ini].first,
+ [this] (int selection)
+ {
+ if (selection != m_state[m_ini].first)
+ {
+ m_state[m_ini].first = selection;
+ reset(reset_options::REMEMBER_REF);
+ }
+ });
+ }
+ else if (INCLUDE_CLONES == ref)
+ {
+ m_state[m_ini].second = !m_state[m_ini].second;
+ reset(reset_options::REMEMBER_REF);
+ }
+ break;
+ }
+
+ // rebuild if anything changed
+ if (changed)
+ reset(reset_options::REMEMBER_REF);
+ }
+}
+
+
+
+//-------------------------------------------------
// composite machine filter
//-------------------------------------------------
class custom_machine_filter : public composite_filter_impl_base<custom_machine_filter, machine_filter, machine_filter::CUSTOM>
{
public:
- custom_machine_filter(char const *value, emu_file *file, unsigned indent) :
- composite_filter_impl_base<custom_machine_filter, machine_filter, machine_filter::CUSTOM>()
+ custom_machine_filter(char const *value, emu_file *file, unsigned indent)
+ : composite_filter_impl_base<custom_machine_filter, machine_filter, machine_filter::CUSTOM>()
{
populate(value, file, indent);
}
@@ -798,7 +1137,7 @@ public:
static bool type_allowed(unsigned pos, type n)
{
- return (FIRST <= n) && (LAST >= n) && (ALL != n) && (AVAILABLE != n) && (UNAVAILABLE != n) && (CATEGORY != n) && (FAVORITE != n) && (CUSTOM != n);
+ return (FIRST <= n) && (LAST >= n) && (ALL != n) && (AVAILABLE != n) && (UNAVAILABLE != n) && (FAVORITE != n) && (CUSTOM != n);
}
static bool types_contradictory(type n, type m)
@@ -835,7 +1174,7 @@ public:
static bool is_inclusion(type n)
{
- return (MANUFACTURER == n) || (YEAR == n);
+ return (CATEGORY == n) || (MANUFACTURER == n) || (YEAR == n);
}
};
@@ -893,8 +1232,8 @@ public:
class years_software_filter : public choice_filter_impl_base<software_filter, software_filter::YEAR>
{
public:
- years_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<software_filter, software_filter::YEAR>(data.year.ui, value)
+ years_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<software_filter, software_filter::YEAR>(data.year.ui, value)
{
}
@@ -905,9 +1244,9 @@ public:
class publishers_software_filter : public choice_filter_impl_base<software_filter, software_filter::PUBLISHERS>
{
public:
- publishers_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<software_filter, software_filter::PUBLISHERS>(data.publisher.ui, value),
- m_publishers(data.publisher)
+ publishers_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<software_filter, software_filter::PUBLISHERS>(data.publisher.ui, value)
+ , m_publishers(data.publisher)
{
}
@@ -958,9 +1297,9 @@ public:
class region_software_filter : public choice_filter_impl_base<software_filter, software_filter::REGION>
{
public:
- region_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<software_filter, software_filter::REGION>(data.region.ui, value),
- m_regions(data.region)
+ region_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<software_filter, software_filter::REGION>(data.region.ui, value)
+ , m_regions(data.region)
{
}
@@ -983,8 +1322,8 @@ private:
class device_type_software_filter : public choice_filter_impl_base<software_filter, software_filter::DEVICE_TYPE>
{
public:
- device_type_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<software_filter, software_filter::DEVICE_TYPE>(data.type.ui, value)
+ device_type_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<software_filter, software_filter::DEVICE_TYPE>(data.type.ui, value)
{
}
@@ -995,8 +1334,8 @@ public:
class list_software_filter : public choice_filter_impl_base<software_filter, software_filter::LIST>
{
public:
- list_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- choice_filter_impl_base<software_filter, software_filter::LIST>(data.swlist.name, value)
+ list_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : choice_filter_impl_base<software_filter, software_filter::LIST>(data.swlist.name, value)
{
}
@@ -1012,9 +1351,9 @@ public:
class custom_software_filter : public composite_filter_impl_base<custom_software_filter, software_filter, software_filter::CUSTOM>
{
public:
- custom_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent) :
- composite_filter_impl_base<custom_software_filter, software_filter, software_filter::CUSTOM>(),
- m_data(data)
+ custom_software_filter(s_filter const &data, char const *value, emu_file *file, unsigned indent)
+ : composite_filter_impl_base<custom_software_filter, software_filter, software_filter::CUSTOM>()
+ , m_data(data)
{
populate(value, file, indent);
}
@@ -1089,7 +1428,7 @@ machine_filter::ptr machine_filter::create(type n, char const *value, emu_file *
case NOT_MECHANICAL:
return std::make_unique<not_mechanical_machine_filter>(value, file, indent);
case CATEGORY:
- break;
+ return std::make_unique<category_machine_filter>(value, file, indent);
case FAVORITE:
return std::make_unique<favorite_machine_filter>(value, file, indent);
case BIOS:
@@ -1125,7 +1464,8 @@ machine_filter::ptr machine_filter::create(type n, char const *value, emu_file *
machine_filter::ptr machine_filter::create(emu_file &file, unsigned indent)
{
char buffer[MAX_CHAR_INFO];
- file.gets(buffer, ARRAY_LENGTH(buffer));
+ if (!file.gets(buffer, ARRAY_LENGTH(buffer)))
+ return nullptr;
// split it into a key/value or bail
std::string key(buffer);
@@ -1230,7 +1570,8 @@ software_filter::ptr software_filter::create(type n, s_filter const &data, char
software_filter::ptr software_filter::create(emu_file &file, s_filter const &data, unsigned indent)
{
char buffer[MAX_CHAR_INFO];
- file.gets(buffer, ARRAY_LENGTH(buffer));
+ if (!file.gets(buffer, ARRAY_LENGTH(buffer)))
+ return nullptr;
// split it into a key/value or bail
std::string key(buffer);
diff --git a/src/frontend/mame/ui/utils.h b/src/frontend/mame/ui/utils.h
index 67685bcfdba..7018007eaee 100644
--- a/src/frontend/mame/ui/utils.h
+++ b/src/frontend/mame/ui/utils.h
@@ -272,11 +272,9 @@ enum
HOVER_RPANEL_ARROW,
HOVER_LPANEL_ARROW,
HOVER_FILTER_FIRST,
- HOVER_FILTER_LAST = (HOVER_FILTER_FIRST) + ui::machine_filter::COUNT,
- HOVER_SW_FILTER_FIRST,
- HOVER_SW_FILTER_LAST = (HOVER_SW_FILTER_FIRST) + ui::software_filter::COUNT,
+ HOVER_FILTER_LAST = HOVER_FILTER_FIRST + std::max<unsigned>(ui::machine_filter::COUNT, ui::software_filter::COUNT),
HOVER_RP_FIRST,
- HOVER_RP_LAST = (HOVER_RP_FIRST) + 1 + RP_LAST,
+ HOVER_RP_LAST = HOVER_RP_FIRST + 1 + RP_LAST,
HOVER_INFO_TEXT
};