summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/ui/selgame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/ui/selgame.cpp')
-rw-r--r--src/frontend/mame/ui/selgame.cpp502
1 files changed, 129 insertions, 373 deletions
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index aa3d1580e6f..1e504bb858f 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -74,49 +74,40 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
if (!load_available_machines())
build_available_list();
- // load custom filter
- load_custom_filters();
-
if (first_start)
{
reselect_last::set_driver(moptions.last_used_machine());
+
std::string tmp(moptions.last_used_filter());
- std::size_t found = tmp.find_first_of(",");
+ std::size_t const found = tmp.find_first_of(",");
+ std::string fake_ini;
if (found == std::string::npos)
- last_filter = tmp;
+ {
+ fake_ini = util::string_format("%s = 1\n", tmp);
+ }
else
{
- last_filter = tmp.substr(0, found);
- sub_filter = tmp.substr(found + 1);
+ std::string const sub_filter(tmp.substr(found + 1));
+ tmp.resize(found);
+ fake_ini = util::string_format("%s = %s\n", tmp, sub_filter);
}
- main_filters::actual = machine_filter::ALL;
- for (machine_filter::type ind = machine_filter::FIRST; ind < machine_filter::COUNT; ++ind)
+ emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
+ if (file.open_ram(fake_ini.c_str(), fake_ini.size()) == osd_file::error::NONE)
{
- if (last_filter == machine_filter::config_name(ind))
+ machine_filter::ptr flt(machine_filter::create(file));
+ if (flt)
{
- main_filters::actual = ind;
- break;
+ main_filters::actual = flt->get_type();
+ main_filters::filters.emplace(main_filters::actual, std::move(flt));
}
+ file.close();
}
-
- if (main_filters::actual == machine_filter::CATEGORY)
- main_filters::actual = machine_filter::ALL;
- else if (main_filters::actual == machine_filter::MANUFACTURER)
- {
- for (size_t id = 0; id < c_mnfct::ui.size(); ++id)
- if (sub_filter == c_mnfct::ui[id])
- c_mnfct::actual = id;
- }
- else if (main_filters::actual == machine_filter::YEAR)
- {
- for (size_t id = 0; id < c_year::ui.size(); ++id)
- if (sub_filter == c_year::ui[id])
- c_year::actual = id;
- }
- first_start = false;
}
+ // do this after processing the last used filter setting so it overwrites the placeholder
+ load_custom_filters();
+
if (!moptions.remember_last())
reselect_last::reset();
@@ -151,11 +142,17 @@ menu_select_game::~menu_select_game()
else if (swinfo && m_prev_selected)
last_driver = reinterpret_cast<ui_software_info *>(m_prev_selected)->shortname;
- std::string filter(machine_filter::config_name(main_filters::actual));
- if (main_filters::actual == machine_filter::MANUFACTURER)
- filter.append(",").append(c_mnfct::ui[c_mnfct::actual]);
- else if (main_filters::actual == machine_filter::YEAR)
- filter.append(",").append(c_year::ui[c_year::actual]);
+ std::string filter;
+ auto const active_filter(main_filters::filters.find(main_filters::actual));
+ if (main_filters::filters.end() != active_filter)
+ {
+ char const *val(active_filter->second->filter_text());
+ filter = val ? util::string_format("%s,%s", active_filter->second->config_name(), val) : active_filter->second->config_name();
+ }
+ else
+ {
+ filter = machine_filter::config_name(main_filters::actual);
+ }
ui_options &mopt = ui().options();
mopt.set_value(OPTION_LAST_USED_FILTER, filter.c_str(), OPTION_PRIORITY_CMDLINE);
@@ -423,43 +420,38 @@ void menu_select_game::handle()
if (check_filter)
{
m_search.clear();
- if (l_hover == machine_filter::CATEGORY)
+ switch (l_hover)
{
+ 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());
- }
- else if (l_hover == machine_filter::CUSTOM)
- {
- main_filters::actual = machine_filter::type(l_hover);
- menu::stack_push<menu_custom_filter>(ui(), container(), true);
- }
- else if (l_hover == machine_filter::MANUFACTURER)
- {
- menu::stack_push<menu_selector>(
- ui(), container(), std::vector<std::string>(c_mnfct::ui), c_mnfct::actual,
- [this] (int selection)
- {
- c_mnfct::actual = selection;
- main_filters::actual = machine_filter::type(l_hover);
- reset(reset_options::SELECT_FIRST);
- });
- }
- else if (l_hover == machine_filter::YEAR)
- {
- menu::stack_push<menu_selector>(
- ui(), container(), std::vector<std::string>(c_year::ui), c_year::actual,
- [this] (int selection)
- {
- c_year::actual = selection;
- main_filters::actual = machine_filter::type(l_hover);
- reset(reset_options::SELECT_FIRST);
- });
- }
- else
- {
+ break;
+ default:
if (l_hover >= machine_filter::ALL)
- main_filters::actual = machine_filter::type(l_hover);
- reset(reset_options::SELECT_FIRST);
+ {
+ 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)
+ {
+ 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)
+ {
+ filter.save_ini(file, 0);
+ file.close();
+ }
+ }
+ main_filters::actual = new_type;
+ reset(reset_options::SELECT_FIRST);
+ });
+ }
}
}
}
@@ -479,7 +471,9 @@ void menu_select_game::populate(float &customtop, float &custombottom)
{
// if search is not empty, find approximate matches
if (!m_search.empty())
+ {
populate_search();
+ }
else
{
// reset search string
@@ -489,21 +483,27 @@ void menu_select_game::populate(float &customtop, float &custombottom)
// if filter is set on category, build category list
switch (main_filters::actual)
{
- case machine_filter::CATEGORY:
- build_category();
+ case machine_filter::ALL:
+ m_displaylist = m_sortedlist;
break;
- case machine_filter::MANUFACTURER:
- build_list(c_mnfct::ui[c_mnfct::actual].c_str());
+ case machine_filter::AVAILABLE:
+ m_displaylist = m_availsortedlist;
break;
- case machine_filter::YEAR:
- build_list(c_year::ui[c_year::actual].c_str());
+ case machine_filter::UNAVAILABLE:
+ m_displaylist = m_unavailsortedlist;
break;
- case machine_filter::CUSTOM:
- build_custom();
+ case machine_filter::CATEGORY:
+ build_category();
break;
default:
- build_list();
- break;
+ {
+ auto const it(main_filters::filters.find(main_filters::actual));
+ std::copy_if(
+ m_sortedlist.begin(),
+ m_sortedlist.end(),
+ std::back_inserter(m_displaylist),
+ [&flt = *it->second] (game_driver const *drv) { return flt.apply(*drv); });
+ }
}
// iterate over entries
@@ -907,139 +907,6 @@ void menu_select_game::inkey_special(const event *menu_event)
//-------------------------------------------------
-// build list
-//-------------------------------------------------
-
-void menu_select_game::build_list(const char *filter_text, int filter, bool bioscheck, std::vector<const game_driver *> s_drivers)
-{
- if (s_drivers.empty())
- {
- filter = main_filters::actual;
- if (filter == machine_filter::AVAILABLE)
- s_drivers = m_availsortedlist;
- else if (filter == machine_filter::UNAVAILABLE)
- s_drivers = m_unavailsortedlist;
- else
- s_drivers = m_sortedlist;
- }
-
- for (auto & s_driver : s_drivers)
- {
- if (!bioscheck && filter != machine_filter::BIOS && (s_driver->flags & machine_flags::IS_BIOS_ROOT) != 0)
- continue;
-
- switch (filter)
- {
- case machine_filter::ALL:
- case machine_filter::AVAILABLE:
- case machine_filter::UNAVAILABLE:
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::WORKING:
- if (!(s_driver->flags & machine_flags::NOT_WORKING))
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::NOT_MECHANICAL:
- if (!(s_driver->flags & machine_flags::MECHANICAL))
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::BIOS:
- if (s_driver->flags & machine_flags::IS_BIOS_ROOT)
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::PARENT:
- case machine_filter::CLONES:
- {
- bool cloneof = strcmp(s_driver->parent, "0");
- if (cloneof)
- {
- auto cx = driver_list::find(s_driver->parent);
- if (cx != -1 && ((driver_list::driver(cx).flags & machine_flags::IS_BIOS_ROOT) != 0))
- cloneof = false;
- }
-
- if (filter == machine_filter::CLONES && cloneof)
- m_displaylist.push_back(s_driver);
- else if (filter == machine_filter::PARENT && !cloneof)
- m_displaylist.push_back(s_driver);
- }
- break;
- case machine_filter::NOT_WORKING:
- if (s_driver->flags & machine_flags::NOT_WORKING)
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::MECHANICAL:
- if (s_driver->flags & machine_flags::MECHANICAL)
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::SAVE:
- if (s_driver->flags & machine_flags::SUPPORTS_SAVE)
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::NOSAVE:
- if (!(s_driver->flags & machine_flags::SUPPORTS_SAVE))
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::YEAR:
- if (!core_stricmp(filter_text, s_driver->year))
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::VERTICAL:
- if (s_driver->flags & ORIENTATION_SWAP_XY)
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::HORIZONTAL:
- if (!(s_driver->flags & ORIENTATION_SWAP_XY))
- m_displaylist.push_back(s_driver);
- break;
-
- case machine_filter::MANUFACTURER:
- {
- std::string name = c_mnfct::getname(s_driver->manufacturer);
- if (!core_stricmp(filter_text, name.c_str()))
- m_displaylist.push_back(s_driver);
- }
- break;
- case machine_filter::CHD:
- {
- auto entries = rom_build_entries(s_driver->rom);
- for (const rom_entry &rom : entries)
- if (ROMENTRY_ISREGION(&rom) && ROMREGION_ISDISKDATA(&rom))
- {
- m_displaylist.push_back(s_driver);
- break;
- }
- }
- break;
- case machine_filter::NOCHD:
- {
- auto entries = rom_build_entries(s_driver->rom);
- bool found = false;
- for (const rom_entry &rom : entries)
- if (ROMENTRY_ISREGION(&rom) && ROMREGION_ISDISKDATA(&rom))
- {
- found = true;
- break;
- }
- if (!found)
- m_displaylist.push_back(s_driver);
- }
- break;
- }
- }
-}
-
-//-------------------------------------------------
// change what's displayed in the info box
//-------------------------------------------------
@@ -1075,55 +942,6 @@ void menu_select_game::change_info_pane(int delta)
}
//-------------------------------------------------
-// build custom display list
-//-------------------------------------------------
-
-void menu_select_game::build_custom()
-{
- std::vector<const game_driver *> s_drivers;
- bool bioscheck = false;
-
- if (custfltr::main == machine_filter::AVAILABLE)
- s_drivers = m_availsortedlist;
- else if (custfltr::main == machine_filter::UNAVAILABLE)
- s_drivers = m_unavailsortedlist;
- else
- s_drivers = m_sortedlist;
-
- for (auto & elem : s_drivers)
- {
- m_displaylist.push_back(elem);
- }
-
- for (int count = 1; count <= custfltr::numother; ++count)
- {
- int filter = custfltr::other[count];
- if (filter == machine_filter::BIOS)
- bioscheck = true;
- }
-
- for (int count = 1; count <= custfltr::numother; ++count)
- {
- int filter = custfltr::other[count];
- s_drivers = m_displaylist;
- m_displaylist.clear();
-
- switch (filter)
- {
- case machine_filter::YEAR:
- build_list(c_year::ui[custfltr::year[count]].c_str(), filter, bioscheck, s_drivers);
- break;
- case machine_filter::MANUFACTURER:
- build_list(c_mnfct::ui[custfltr::mnfct[count]].c_str(), filter, bioscheck, s_drivers);
- break;
- default:
- build_list(nullptr, filter, bioscheck, s_drivers);
- break;
- }
- }
-}
-
-//-------------------------------------------------
// build category list
//-------------------------------------------------
@@ -1378,24 +1196,27 @@ void menu_select_game::init_sorted_list()
return;
// generate full list
+ std::unordered_set<std::string> manufacturers, years;
for (int x = 0; x < driver_list::total(); ++x)
{
- const game_driver *driver = &driver_list::driver(x);
- if (driver == &GAME_NAME(___empty))
- continue;
- if (driver->flags & machine_flags::IS_BIOS_ROOT)
- m_isabios++;
-
- m_sortedlist.push_back(driver);
- c_mnfct::set(driver->manufacturer);
- c_year::set(driver->year);
- }
+ game_driver const &driver(driver_list::driver(x));
+ if (&driver != &GAME_NAME(___empty))
+ {
+ if (driver.flags & machine_flags::IS_BIOS_ROOT)
+ m_isabios++;
- for (auto & e : c_mnfct::uimap)
- c_mnfct::ui.emplace_back(e.first);
+ m_sortedlist.push_back(&driver);
+ manufacturers.emplace(c_mnfct::getname(driver.manufacturer));
+ years.emplace(driver.year);
+ }
+ }
// sort manufacturers - years and driver
- std::stable_sort(c_mnfct::ui.begin(), c_mnfct::ui.end());
+ for (auto it = manufacturers.begin(); manufacturers.end() != it; it = manufacturers.erase(it))
+ c_mnfct::ui.emplace_back(*it);
+ std::sort(c_mnfct::ui.begin(), c_mnfct::ui.end(), [] (std::string const &x, std::string const &y) { return 0 > core_stricmp(x.c_str(), y.c_str()); });
+ for (auto it = years.begin(); years.end() != it; it = years.erase(it))
+ c_year::ui.emplace_back(*it);
std::stable_sort(c_year::ui.begin(), c_year::ui.end());
std::stable_sort(m_sortedlist.begin(), m_sortedlist.end(), sorted_game_list);
}
@@ -1457,60 +1278,12 @@ bool menu_select_game::load_available_machines()
void menu_select_game::load_custom_filters()
{
- // attempt to open the output file
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
- char buffer[MAX_CHAR_INFO];
-
- // get number of filters
- file.gets(buffer, MAX_CHAR_INFO);
- char *pb = strchr(buffer, '=');
- custfltr::numother = atoi(++pb) - 1;
-
- // get main filter
- file.gets(buffer, MAX_CHAR_INFO);
- pb = strchr(buffer, '=') + 2;
-
- for (machine_filter::type y = machine_filter::FIRST; y < machine_filter::COUNT; ++y)
- {
- char const *const name(machine_filter::config_name(y));
- if (!strncmp(pb, name, strlen(name)))
- {
- custfltr::main = y;
- break;
- }
- }
-
- for (int x = 1; x <= custfltr::numother; ++x)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *cb = strchr(buffer, '=') + 2;
- for (machine_filter::type y = machine_filter::FIRST; y < machine_filter::COUNT; ++y)
- {
- char const *const name(machine_filter::config_name(y));
- if (!strncmp(cb, name, strlen(name)))
- {
- custfltr::other[x] = y;
- if (y == machine_filter::MANUFACTURER)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *ab = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < c_mnfct::ui.size(); ++z)
- if (!strncmp(ab, c_mnfct::ui[z].c_str(), c_mnfct::ui[z].length()))
- custfltr::mnfct[x] = z;
- }
- else if (y == machine_filter::YEAR)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *db = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < c_year::ui.size(); ++z)
- if (!strncmp(db, c_year::ui[z].c_str(), c_year::ui[z].length()))
- custfltr::year[x] = z;
- }
- }
- }
- }
+ machine_filter::ptr flt(machine_filter::create(file));
+ if (flt)
+ main_filters::filters[flt->get_type()] = std::move(flt); // not emplace/insert - could replace bogus filter from ui.ini line
file.close();
}
@@ -1527,13 +1300,13 @@ float menu_select_game::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)
{
+ 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 afilter = main_filters::actual;
int phover = HOVER_FILTER_FIRST;
float sc = y2 - y1 - (2.0f * UI_BOX_TB_BORDER);
@@ -1544,7 +1317,9 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
line_height_max = line_height * text_size;
}
- float text_sign = ui().get_string_width("_# ", 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;
@@ -1569,7 +1344,21 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
for (machine_filter::type filter = machine_filter::FIRST; filter < machine_filter::COUNT; ++filter)
{
- std::string str(machine_filter::display_name(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;
@@ -1589,35 +1378,7 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
}
- float x1t = x1 + text_sign;
- if (afilter == machine_filter::CUSTOM)
- {
- if (filter == custfltr::main)
- {
- str = std::string("@custom1 ") + str;
- x1t -= text_sign;
- }
- else
- {
- for (int count = 1; count <= custfltr::numother; ++count)
- {
- int cfilter = custfltr::other[count];
- if (cfilter == filter)
- {
- str = string_format("@custom%d %s", count + 1, str);
- x1t -= text_sign;
- break;
- }
- }
- }
- convert_command_glyph(str);
- }
- else if (filter == main_filters::actual)
- {
- str = std::string("_> ") + str;
- x1t -= text_sign;
- convert_command_glyph(str);
- }
+ 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);
@@ -1705,33 +1466,28 @@ void menu_select_game::make_topbox_text(std::string &line0, std::string &line1,
(driver_list::total() - 1),
m_isabios);
- std::string filtered;
- if (main_filters::actual == machine_filter::CATEGORY && inifile.total() > 0)
+ if (isfavorite())
{
- filtered = string_format(_("%1$s (%2$s - %3$s) - "),
- machine_filter::display_name(main_filters::actual),
- inifile.get_file(),
- inifile.get_category());
+ line1.clear();
}
- else if (main_filters::actual == machine_filter::MANUFACTURER)
+ if (main_filters::actual == machine_filter::CATEGORY && inifile.total() > 0)
{
- filtered = string_format(_("%1$s (%2$s) - "),
+ line1 = string_format(_("%1$s (%2$s - %3$s) - Search: %4$s_"),
machine_filter::display_name(main_filters::actual),
- c_mnfct::ui[c_mnfct::actual]);
+ inifile.get_file(),
+ inifile.get_category(),
+ m_search);
}
- else if (main_filters::actual == machine_filter::YEAR)
+ else
{
- filtered = string_format(_("%1$s (%2$s) - "),
- machine_filter::display_name(main_filters::actual),
- c_year::ui[c_year::actual]);
+ auto const it(main_filters::filters.find(main_filters::actual));
+ char const *const filter((main_filters::filters.end() != it) ? it->second->filter_text() : nullptr);
+ if (filter)
+ line1 = string_format(_("%1$s: %2$s - Search: %3$s_"), it->second->display_name(), filter, m_search);
+ else
+ line1 = string_format(_("Search: %1$s_"), m_search);
}
- // display the current typeahead
- if (isfavorite())
- line1.clear();
- else
- line1 = string_format(_("%1$s Search: %2$s_"), filtered, m_search);
-
line2.clear();
}