mirror of
https://github.com/holub/mame
synced 2025-05-30 17:41:47 +03:00
Polymorphic machine/software list filters:
* Localisable filter names * Uniform interface for most filters without far less special-casing * Stacking year/manufacturer/etc. does OR rather than useless AND * Prevent stacking contradictory filters (e.g. parents and clones) * Fix alignment of filter list * Removed most of the lambdas added the other day * There's no longer an implicit "not BIOS" filter * Can't add (un)available to custom machine filter (will address)
This commit is contained in:
parent
ba14f72569
commit
651d8ee692
@ -11,571 +11,108 @@
|
||||
#include "emu.h"
|
||||
#include "ui/custmenu.h"
|
||||
|
||||
#include "ui/ui.h"
|
||||
#include "ui/selector.h"
|
||||
#include "ui/inifile.h"
|
||||
|
||||
#include "rendfont.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace ui {
|
||||
|
||||
/**************************************************
|
||||
MENU CUSTOM FILTER
|
||||
**************************************************/
|
||||
namespace {
|
||||
|
||||
constexpr char const *region_lists[] = {
|
||||
"arab", "arg", "asia", "aus", "aut",
|
||||
"bel", "blr", "bra",
|
||||
"can", "chi", "chn", "cze",
|
||||
"den",
|
||||
"ecu", "esp", "euro",
|
||||
"fin", "fra",
|
||||
"gbr", "ger", "gre",
|
||||
"hkg", "hun",
|
||||
"irl", "isr", "isv", "ita",
|
||||
"jpn",
|
||||
"kaz", "kor",
|
||||
"lat", "lux",
|
||||
"mex",
|
||||
"ned", "nld", "nor", "nzl",
|
||||
"pol",
|
||||
"rus",
|
||||
"slo", "spa", "sui", "swe",
|
||||
"tha", "tpe", "tw",
|
||||
"uk", "ukr", "usa" };
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
//-------------------------------------------------
|
||||
// ctor / dtor
|
||||
// set software regions
|
||||
//-------------------------------------------------
|
||||
menu_custom_filter::menu_custom_filter(mame_ui_manager &mui, render_container &container, bool _single_menu)
|
||||
: menu(mui, container)
|
||||
, m_single_menu(_single_menu)
|
||||
, m_added(false)
|
||||
|
||||
void c_sw_region::set(std::string &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))
|
||||
ui.emplace(pos, std::move(name));
|
||||
}
|
||||
|
||||
menu_custom_filter::~menu_custom_filter()
|
||||
std::string c_sw_region::getname(std::string const &str) const
|
||||
{
|
||||
if (m_single_menu)
|
||||
reset_topmost(reset_options::SELECT_FIRST);
|
||||
save_custom_filters();
|
||||
}
|
||||
std::string fullname(str);
|
||||
strmakelower(fullname);
|
||||
size_t found = fullname.find("(");
|
||||
|
||||
//-------------------------------------------------
|
||||
// handle
|
||||
//-------------------------------------------------
|
||||
void menu_custom_filter::handle()
|
||||
{
|
||||
bool changed = false;
|
||||
m_added = false;
|
||||
|
||||
// process the menu
|
||||
const event *menu_event = process(PROCESS_LR_REPEAT);
|
||||
if (menu_event != nullptr && menu_event->itemref != nullptr)
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
switch ((uintptr_t)menu_event->itemref)
|
||||
{
|
||||
case MAIN_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? custfltr::main++ : custfltr::main--;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
size_t ends = fullname.find_first_not_of("abcdefghijklmnopqrstuvwxyz", found + 1);
|
||||
std::string temp(fullname.substr(found + 1, ends - found - 1));
|
||||
|
||||
case ADD_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
custfltr::numother++;
|
||||
custfltr::other[custfltr::numother] = machine_filter::UNAVAILABLE;
|
||||
++custfltr::other[custfltr::numother];
|
||||
m_added = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOVE_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
custfltr::other[custfltr::numother] = machine_filter::UNAVAILABLE;
|
||||
++custfltr::other[custfltr::numother];
|
||||
custfltr::numother--;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((uintptr_t)menu_event->itemref >= OTHER_FILTER && (uintptr_t)menu_event->itemref < OTHER_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - OTHER_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && custfltr::other[pos] > machine_filter::UNAVAILABLE + 1)
|
||||
{
|
||||
custfltr::other[pos]--;
|
||||
for ( ; custfltr::other[pos] > machine_filter::UNAVAILABLE && (custfltr::other[pos] == machine_filter::CATEGORY
|
||||
|| custfltr::other[pos] == machine_filter::FAVORITE); custfltr::other[pos]--) { };
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && custfltr::other[pos] < machine_filter::LAST - 1)
|
||||
{
|
||||
custfltr::other[pos]++;
|
||||
for ( ; custfltr::other[pos] < machine_filter::LAST && (custfltr::other[pos] == machine_filter::CATEGORY
|
||||
|| custfltr::other[pos] == machine_filter::FAVORITE); custfltr::other[pos]++) { };
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
std::vector<machine_filter::type> types;
|
||||
std::vector<std::string> names;
|
||||
types.reserve(machine_filter::COUNT);
|
||||
names.reserve(machine_filter::COUNT);
|
||||
int sel(-1);
|
||||
for (machine_filter::type index = machine_filter::FIRST; index < machine_filter::COUNT; ++index)
|
||||
{
|
||||
if ((index > machine_filter::UNAVAILABLE) && (index != machine_filter::CATEGORY) && (index != machine_filter::FAVORITE) && (index != machine_filter::CUSTOM))
|
||||
{
|
||||
if (custfltr::other[pos] == index)
|
||||
sel = types.size();
|
||||
types.emplace_back(index);
|
||||
names.emplace_back(machine_filter::display_name(index));
|
||||
}
|
||||
}
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::move(names), sel, [this, pos, t = std::move(types)] (int selection) { custfltr::other[pos] = t[selection]; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= YEAR_FILTER && (uintptr_t)menu_event->itemref < YEAR_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - YEAR_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && custfltr::year[pos] > 0)
|
||||
{
|
||||
custfltr::year[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && custfltr::year[pos] < c_year::ui.size() - 1)
|
||||
{
|
||||
custfltr::year[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(c_year::ui), custfltr::year[pos], [this, pos] (int selection) { custfltr::year[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= MNFCT_FILTER && (uintptr_t)menu_event->itemref < MNFCT_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - MNFCT_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && custfltr::mnfct[pos] > 0)
|
||||
{
|
||||
custfltr::mnfct[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && custfltr::mnfct[pos] < c_mnfct::ui.size() - 1)
|
||||
{
|
||||
custfltr::mnfct[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(c_mnfct::ui), custfltr::mnfct[pos], [this, pos] (int selection) { custfltr::mnfct[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
for (auto & elem : region_lists)
|
||||
if (temp == elem)
|
||||
return (str.substr(found + 1, ends - found - 1));
|
||||
}
|
||||
|
||||
if (changed)
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
else if (m_added)
|
||||
reset(reset_options::SELECT_FIRST);
|
||||
return std::string("<none>");
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// populate
|
||||
// set software device type
|
||||
//-------------------------------------------------
|
||||
void menu_custom_filter::populate(float &customtop, float &custombottom)
|
||||
|
||||
void c_sw_type::set(std::string &str)
|
||||
{
|
||||
// add main filter
|
||||
uint32_t arrow_flags = get_arrow_flags<uint16_t>(machine_filter::ALL, machine_filter::UNAVAILABLE, custfltr::main);
|
||||
item_append(_("Main filter"), machine_filter::display_name(custfltr::main), arrow_flags, (void *)(uintptr_t)MAIN_FILTER);
|
||||
|
||||
// add other filters
|
||||
for (int x = 1; x <= custfltr::numother; x++)
|
||||
{
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
||||
// add filter items
|
||||
arrow_flags = get_arrow_flags<uint16_t>(machine_filter::UNAVAILABLE + 1, machine_filter::LAST - 1, custfltr::other[x]);
|
||||
item_append(_("Other filter"), machine_filter::display_name(custfltr::other[x]), arrow_flags, (void *)(uintptr_t)(OTHER_FILTER + x));
|
||||
|
||||
if (m_added)
|
||||
selected = item.size() - 2;
|
||||
|
||||
// add manufacturer subitem
|
||||
if (custfltr::other[x] == machine_filter::MANUFACTURER && c_mnfct::ui.size() > 0)
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, c_mnfct::ui.size() - 1, custfltr::mnfct[x]);
|
||||
std::string fbuff(_("^!Manufacturer"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, c_mnfct::ui[custfltr::mnfct[x]], arrow_flags, (void *)(uintptr_t)(MNFCT_FILTER + x));
|
||||
}
|
||||
|
||||
// add year subitem
|
||||
else if (custfltr::other[x] == machine_filter::YEAR && c_year::ui.size() > 0)
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, c_year::ui.size() - 1, custfltr::year[x]);
|
||||
std::string fbuff(_("^!Year"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, c_year::ui[custfltr::year[x]], arrow_flags, (void *)(uintptr_t)(YEAR_FILTER + x));
|
||||
}
|
||||
}
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
||||
if (custfltr::numother > 0)
|
||||
item_append(_("Remove last filter"), "", 0, (void *)(uintptr_t)REMOVE_FILTER);
|
||||
|
||||
if (custfltr::numother < MAX_CUST_FILTER - 2)
|
||||
item_append(_("Add filter"), "", 0, (void *)(uintptr_t)ADD_FILTER);
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
|
||||
std::vector<std::string>::iterator const pos(std::lower_bound(ui.begin(), ui.end(), str));
|
||||
if ((ui.end() == pos) || (*pos != str))
|
||||
ui.emplace(pos, str);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
// set software years
|
||||
//-------------------------------------------------
|
||||
void menu_custom_filter::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
|
||||
|
||||
void c_sw_year::set(std::string &str)
|
||||
{
|
||||
char const *const text[] = { _("Select custom filters:") };
|
||||
draw_text_box(
|
||||
std::begin(text), std::end(text),
|
||||
origx1, origx2, origy1 - top, origy1 - UI_BOX_TB_BORDER,
|
||||
ui::text_layout::CENTER, ui::text_layout::NEVER, false,
|
||||
UI_TEXT_COLOR, UI_GREEN_COLOR, 1.0f);
|
||||
std::vector<std::string>::iterator const pos(std::lower_bound(ui.begin(), ui.end(), str));
|
||||
if ((ui.end() == pos) || (*pos != str))
|
||||
ui.emplace(pos, str);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// save custom filters info to file
|
||||
// set software publishers
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_custom_filter::save_custom_filters()
|
||||
void c_sw_publisher::set(std::string &str)
|
||||
{
|
||||
// attempt to open the output file
|
||||
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)
|
||||
{
|
||||
// generate custom filters info
|
||||
std::ostringstream cinfo;
|
||||
util::stream_format(cinfo, "Total filters = %d\n", (custfltr::numother + 1));
|
||||
util::stream_format(cinfo, "Main filter = %s\n", machine_filter::config_name(custfltr::main));
|
||||
|
||||
for (int x = 1; x <= custfltr::numother; x++)
|
||||
{
|
||||
util::stream_format(cinfo, "Other filter = %s\n", machine_filter::config_name(custfltr::other[x]));
|
||||
if (custfltr::other[x] == machine_filter::MANUFACTURER)
|
||||
util::stream_format(cinfo, " Manufacturer filter = %s\n", c_mnfct::ui[custfltr::mnfct[x]]);
|
||||
else if (custfltr::other[x] == machine_filter::YEAR)
|
||||
util::stream_format(cinfo, " Year filter = %s\n", c_year::ui[custfltr::year[x]]);
|
||||
}
|
||||
file.puts(cinfo.str().c_str());
|
||||
file.close();
|
||||
}
|
||||
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))
|
||||
ui.emplace(pos, std::move(name));
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
MENU CUSTOM SOFTWARE FILTER
|
||||
**************************************************/
|
||||
//-------------------------------------------------
|
||||
// ctor / dtor
|
||||
//-------------------------------------------------
|
||||
menu_swcustom_filter::menu_swcustom_filter(mame_ui_manager &mui, render_container &container, const game_driver *_driver, s_filter &_filter)
|
||||
: menu(mui, container)
|
||||
, m_added(false)
|
||||
, m_filter(_filter)
|
||||
, m_driver(_driver)
|
||||
std::string c_sw_publisher::getname(std::string const &str) const
|
||||
{
|
||||
}
|
||||
size_t found = str.find("(");
|
||||
|
||||
menu_swcustom_filter::~menu_swcustom_filter()
|
||||
{
|
||||
reset_topmost(reset_options::SELECT_FIRST);
|
||||
save_sw_custom_filters();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// handle
|
||||
//-------------------------------------------------
|
||||
void menu_swcustom_filter::handle()
|
||||
{
|
||||
bool changed = false;
|
||||
m_added = false;
|
||||
|
||||
// process the menu
|
||||
const event *menu_event = process(PROCESS_LR_REPEAT);
|
||||
if (menu_event != nullptr && menu_event->itemref != nullptr)
|
||||
{
|
||||
switch ((uintptr_t)menu_event->itemref)
|
||||
{
|
||||
case MAIN_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? sw_custfltr::main++ : sw_custfltr::main--;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADD_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
sw_custfltr::numother++;
|
||||
sw_custfltr::other[sw_custfltr::numother] = software_filter::UNAVAILABLE;
|
||||
++sw_custfltr::other[sw_custfltr::numother];
|
||||
m_added = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOVE_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
sw_custfltr::other[sw_custfltr::numother] = software_filter::UNAVAILABLE;
|
||||
++sw_custfltr::other[sw_custfltr::numother];
|
||||
sw_custfltr::numother--;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((uintptr_t)menu_event->itemref >= OTHER_FILTER && (uintptr_t)menu_event->itemref < OTHER_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - OTHER_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::other[pos] > software_filter::UNAVAILABLE + 1)
|
||||
{
|
||||
sw_custfltr::other[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::other[pos] < software_filter::LAST - 1)
|
||||
{
|
||||
sw_custfltr::other[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
std::vector<software_filter::type> types;
|
||||
std::vector<std::string> names;
|
||||
types.reserve(software_filter::COUNT);
|
||||
names.reserve(software_filter::COUNT);
|
||||
uint16_t sel(0);
|
||||
for (software_filter::type index = software_filter::FIRST; index < software_filter::COUNT; ++index)
|
||||
{
|
||||
if ((index >= software_filter::UNAVAILABLE) && (index != software_filter::CUSTOM))
|
||||
{
|
||||
if (sw_custfltr::other[pos] == index)
|
||||
sel = types.size();
|
||||
types.emplace_back(index);
|
||||
names.emplace_back(software_filter::display_name(index));
|
||||
}
|
||||
}
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::move(names), sel, [this, pos, t = std::move(types)] (int selection) { sw_custfltr::other[pos] = t[selection]; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= YEAR_FILTER && (uintptr_t)menu_event->itemref < YEAR_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - YEAR_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::year[pos] > 0)
|
||||
{
|
||||
sw_custfltr::year[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::year[pos] < m_filter.year.ui.size() - 1)
|
||||
{
|
||||
sw_custfltr::year[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.year.ui), sw_custfltr::year[pos], [this, pos] (int selection) { sw_custfltr::year[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= TYPE_FILTER && (uintptr_t)menu_event->itemref < TYPE_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - TYPE_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::type[pos] > 0)
|
||||
{
|
||||
sw_custfltr::type[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::type[pos] < m_filter.type.ui.size() - 1)
|
||||
{
|
||||
sw_custfltr::type[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.type.ui), sw_custfltr::type[pos], [this, pos] (int selection) { sw_custfltr::type[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= MNFCT_FILTER && (uintptr_t)menu_event->itemref < MNFCT_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - MNFCT_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::mnfct[pos] > 0)
|
||||
{
|
||||
sw_custfltr::mnfct[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::mnfct[pos] < m_filter.publisher.ui.size() - 1)
|
||||
{
|
||||
sw_custfltr::mnfct[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.publisher.ui), sw_custfltr::mnfct[pos], [this, pos] (int selection) { sw_custfltr::mnfct[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= REGION_FILTER && (uintptr_t)menu_event->itemref < REGION_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - REGION_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::region[pos] > 0)
|
||||
{
|
||||
sw_custfltr::region[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::region[pos] < m_filter.region.ui.size() - 1)
|
||||
{
|
||||
sw_custfltr::region[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.region.ui), sw_custfltr::region[pos], [this, pos] (int selection) { sw_custfltr::region[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
else if ((uintptr_t)menu_event->itemref >= LIST_FILTER && (uintptr_t)menu_event->itemref < LIST_FILTER + MAX_CUST_FILTER)
|
||||
{
|
||||
int pos = (int)((uintptr_t)menu_event->itemref - LIST_FILTER);
|
||||
if (menu_event->iptkey == IPT_UI_LEFT && sw_custfltr::list[pos] > 0)
|
||||
{
|
||||
sw_custfltr::list[pos]--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT && sw_custfltr::list[pos] < m_filter.swlist.name.size() - 1)
|
||||
{
|
||||
sw_custfltr::list[pos]++;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.swlist.description), sw_custfltr::list[pos], [this, pos] (int selection) { sw_custfltr::list[pos] = selection; reset(reset_options::REMEMBER_REF); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
else if (m_added)
|
||||
reset(reset_options::SELECT_FIRST);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// populate
|
||||
//-------------------------------------------------
|
||||
void menu_swcustom_filter::populate(float &customtop, float &custombottom)
|
||||
{
|
||||
// add main filter
|
||||
uint32_t arrow_flags = get_arrow_flags<uint16_t>(software_filter::ALL, software_filter::UNAVAILABLE, sw_custfltr::main);
|
||||
item_append(_("Main filter"), software_filter::display_name(sw_custfltr::main), arrow_flags, (void *)(uintptr_t)MAIN_FILTER);
|
||||
|
||||
// add other filters
|
||||
for (int x = 1; x <= sw_custfltr::numother; x++)
|
||||
{
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
||||
// add filter items
|
||||
arrow_flags = get_arrow_flags<uint16_t>(software_filter::UNAVAILABLE + 1, software_filter::LAST - 1, sw_custfltr::other[x]);
|
||||
item_append(_("Other filter"), software_filter::display_name(sw_custfltr::other[x]), arrow_flags, (void *)(uintptr_t)(OTHER_FILTER + x));
|
||||
|
||||
if (m_added)
|
||||
selected = item.size() - 2;
|
||||
|
||||
// add publisher subitem
|
||||
if (sw_custfltr::other[x] == software_filter::PUBLISHERS && m_filter.publisher.ui.size())
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, m_filter.publisher.ui.size() - 1, sw_custfltr::mnfct[x]);
|
||||
std::string fbuff(_("^!Publisher"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, m_filter.publisher.ui[sw_custfltr::mnfct[x]], arrow_flags, (void *)(uintptr_t)(MNFCT_FILTER + x));
|
||||
}
|
||||
|
||||
// add year subitem
|
||||
else if (sw_custfltr::other[x] == software_filter::YEARS && m_filter.year.ui.size())
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, m_filter.year.ui.size() - 1, sw_custfltr::year[x]);
|
||||
std::string fbuff(_("^!Year"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, m_filter.year.ui[sw_custfltr::year[x]], arrow_flags, (void *)(uintptr_t)(YEAR_FILTER + x));
|
||||
}
|
||||
|
||||
// add year subitem
|
||||
else if (sw_custfltr::other[x] == software_filter::LIST && m_filter.swlist.name.size())
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, m_filter.swlist.name.size() - 1, sw_custfltr::list[x]);
|
||||
std::string fbuff(_("^!Software List"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, m_filter.swlist.description[sw_custfltr::list[x]], arrow_flags, (void *)(uintptr_t)(LIST_FILTER + x));
|
||||
}
|
||||
|
||||
// add device type subitem
|
||||
else if (sw_custfltr::other[x] == software_filter::DEVICE_TYPE && m_filter.type.ui.size())
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, m_filter.type.ui.size() - 1, sw_custfltr::type[x]);
|
||||
std::string fbuff(_("^!Device type"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, m_filter.type.ui[sw_custfltr::type[x]], arrow_flags, (void *)(uintptr_t)(TYPE_FILTER + x));
|
||||
}
|
||||
|
||||
// add region subitem
|
||||
else if (sw_custfltr::other[x] == software_filter::REGION && m_filter.region.ui.size())
|
||||
{
|
||||
arrow_flags = get_arrow_flags<uint16_t>(0, m_filter.region.ui.size() - 1, sw_custfltr::region[x]);
|
||||
std::string fbuff(_("^!Region"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, m_filter.region.ui[sw_custfltr::region[x]], arrow_flags, (void *)(uintptr_t)(REGION_FILTER + x));
|
||||
}
|
||||
}
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
||||
if (sw_custfltr::numother > 0)
|
||||
item_append(_("Remove last filter"), "", 0, (void *)(uintptr_t)REMOVE_FILTER);
|
||||
|
||||
if (sw_custfltr::numother < MAX_CUST_FILTER - 2)
|
||||
item_append(_("Add filter"), "", 0, (void *)(uintptr_t)ADD_FILTER);
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
||||
customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
void menu_swcustom_filter::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
|
||||
{
|
||||
char const *const text[] = { _("Select custom filters:") };
|
||||
draw_text_box(
|
||||
std::begin(text), std::end(text),
|
||||
origx1, origx2, origy1 - top, origy1 - UI_BOX_TB_BORDER,
|
||||
ui::text_layout::CENTER, ui::text_layout::NEVER, false,
|
||||
UI_TEXT_COLOR, UI_GREEN_COLOR, 1.0f);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// save custom filters info to file
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_swcustom_filter::save_sw_custom_filters()
|
||||
{
|
||||
// attempt to open the output file
|
||||
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
|
||||
if (file.open("custom_", m_driver->name, "_filter.ini") == osd_file::error::NONE)
|
||||
{
|
||||
// generate custom filters info
|
||||
std::ostringstream cinfo;
|
||||
util::stream_format(cinfo, "Total filters = %d\n", (sw_custfltr::numother + 1));
|
||||
util::stream_format(cinfo, "Main filter = %s\n", software_filter::config_name(sw_custfltr::main));
|
||||
|
||||
for (int x = 1; x <= sw_custfltr::numother; x++)
|
||||
{
|
||||
util::stream_format(cinfo, "Other filter = %s\n", software_filter::config_name(sw_custfltr::other[x]));
|
||||
if (sw_custfltr::other[x] == software_filter::PUBLISHERS)
|
||||
util::stream_format(cinfo, " Manufacturer filter = %s\n", m_filter.publisher.ui[sw_custfltr::mnfct[x]]);
|
||||
else if (sw_custfltr::other[x] == software_filter::LIST)
|
||||
util::stream_format(cinfo, " Software List filter = %s\n", m_filter.swlist.name[sw_custfltr::list[x]]);
|
||||
else if (sw_custfltr::other[x] == software_filter::YEARS)
|
||||
util::stream_format(cinfo, " Year filter = %s\n", m_filter.year.ui[sw_custfltr::year[x]]);
|
||||
else if (sw_custfltr::other[x] == software_filter::DEVICE_TYPE)
|
||||
util::stream_format(cinfo, " Type filter = %s\n", m_filter.type.ui[sw_custfltr::type[x]]);
|
||||
else if (sw_custfltr::other[x] == software_filter::REGION)
|
||||
util::stream_format(cinfo, " Region filter = %s\n", m_filter.region.ui[sw_custfltr::region[x]]);
|
||||
}
|
||||
file.puts(cinfo.str().c_str());
|
||||
file.close();
|
||||
}
|
||||
if (found != std::string::npos)
|
||||
return (str.substr(0, found - 1));
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -14,33 +14,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/menu.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Software region
|
||||
struct c_sw_region
|
||||
{
|
||||
std::vector<std::string> ui;
|
||||
uint16_t actual;
|
||||
void set(std::string &str);
|
||||
std::string getname(std::string &str);
|
||||
std::string getname(std::string const &str) const;
|
||||
};
|
||||
|
||||
// Software publishers
|
||||
struct c_sw_publisher
|
||||
{
|
||||
std::vector<std::string> ui;
|
||||
uint16_t actual;
|
||||
void set(std::string &str);
|
||||
std::string getname(std::string &str);
|
||||
std::string getname(std::string const &str) const;
|
||||
};
|
||||
|
||||
// Software device type
|
||||
struct c_sw_type
|
||||
{
|
||||
std::vector<std::string> ui;
|
||||
uint16_t actual;
|
||||
void set(std::string &str);
|
||||
};
|
||||
|
||||
@ -49,14 +45,12 @@ struct c_sw_list
|
||||
{
|
||||
std::vector<std::string> name;
|
||||
std::vector<std::string> description;
|
||||
uint16_t actual;
|
||||
};
|
||||
|
||||
// Software years
|
||||
struct c_sw_year
|
||||
{
|
||||
std::vector<std::string> ui;
|
||||
uint16_t actual;
|
||||
void set(std::string &str);
|
||||
};
|
||||
|
||||
@ -69,73 +63,6 @@ struct s_filter
|
||||
c_sw_list swlist;
|
||||
};
|
||||
|
||||
//-------------------------------------------------
|
||||
// custom software filter menu class
|
||||
//-------------------------------------------------
|
||||
class menu_swcustom_filter : public menu
|
||||
{
|
||||
public:
|
||||
menu_swcustom_filter(mame_ui_manager &mui, render_container &container, const game_driver *_driver, s_filter &_filter);
|
||||
virtual ~menu_swcustom_filter() override;
|
||||
|
||||
protected:
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MAIN_FILTER = 1,
|
||||
ADD_FILTER,
|
||||
REMOVE_FILTER,
|
||||
MNFCT_FILTER,
|
||||
YEAR_FILTER = MNFCT_FILTER + MAX_CUST_FILTER + 1,
|
||||
REGION_FILTER = YEAR_FILTER + MAX_CUST_FILTER + 1,
|
||||
TYPE_FILTER = REGION_FILTER + MAX_CUST_FILTER + 1,
|
||||
LIST_FILTER = TYPE_FILTER + MAX_CUST_FILTER + 1,
|
||||
OTHER_FILTER = LIST_FILTER + MAX_CUST_FILTER + 1
|
||||
};
|
||||
|
||||
virtual void populate(float &customtop, float &custombottom) override;
|
||||
virtual void handle() override;
|
||||
|
||||
void save_sw_custom_filters();
|
||||
|
||||
bool m_added;
|
||||
s_filter &m_filter;
|
||||
const game_driver *m_driver;
|
||||
};
|
||||
|
||||
//-------------------------------------------------
|
||||
// custom filter menu class
|
||||
//-------------------------------------------------
|
||||
class menu_custom_filter : public menu
|
||||
{
|
||||
public:
|
||||
menu_custom_filter(mame_ui_manager &mui, render_container &container, bool _single_menu = false);
|
||||
virtual ~menu_custom_filter() override;
|
||||
|
||||
protected:
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MAIN_FILTER = 1,
|
||||
ADD_FILTER,
|
||||
REMOVE_FILTER,
|
||||
MNFCT_FILTER,
|
||||
YEAR_FILTER = MNFCT_FILTER + MAX_CUST_FILTER + 1,
|
||||
SCREEN_FILTER = YEAR_FILTER + MAX_CUST_FILTER + 1,
|
||||
OTHER_FILTER = SCREEN_FILTER + MAX_CUST_FILTER + 1
|
||||
};
|
||||
virtual void populate(float &customtop, float &custombottom) override;
|
||||
virtual void handle() override;
|
||||
|
||||
void save_custom_filters();
|
||||
|
||||
bool m_single_menu, m_added;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif /* MAME_FRONTEND_UI_CUSTMENU_H */
|
||||
|
@ -42,7 +42,7 @@ menu_game_options::menu_game_options(mame_ui_manager &mui, render_container &con
|
||||
|
||||
menu_game_options::~menu_game_options()
|
||||
{
|
||||
main_filters::actual = machine_filter::type(m_main);
|
||||
main_filters::actual = m_main;
|
||||
reset_topmost(reset_options::SELECT_FIRST);
|
||||
ui().save_ui_options();
|
||||
ui_globals::switch_image = true;
|
||||
@ -71,180 +71,163 @@ void menu_game_options::handle()
|
||||
if (menu_event != nullptr && menu_event->itemref != nullptr)
|
||||
switch ((uintptr_t)menu_event->itemref)
|
||||
{
|
||||
case FILTER_MENU:
|
||||
case FILTER_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? ++m_main : --m_main;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
std::vector<std::string> s_sel(machine_filter::COUNT);
|
||||
for (unsigned index = 0; index < s_sel.size(); ++index)
|
||||
s_sel[index] = machine_filter::display_name(machine_filter::type(index));
|
||||
|
||||
menu::stack_push<menu_selector>(
|
||||
ui(), container(), std::move(s_sel), m_main,
|
||||
[this] (int selection)
|
||||
{
|
||||
m_main = selection;
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
});
|
||||
}
|
||||
break;
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? ++m_main : --m_main;
|
||||
changed = true;
|
||||
}
|
||||
case FILE_CATEGORY_FILTER:
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
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);
|
||||
std::vector<std::string> s_sel(machine_filter::COUNT);
|
||||
for (unsigned index = 0; index < s_sel.size(); ++index)
|
||||
s_sel[index] = machine_filter::display_name(machine_filter::type(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;
|
||||
menu::stack_push<menu_selector>(
|
||||
ui(), container(), std::move(s_sel), m_main,
|
||||
[this] (int selection)
|
||||
{
|
||||
m_main = machine_filter::type(selection);
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
});
|
||||
}
|
||||
case CATEGORY_FILTER:
|
||||
break;
|
||||
case FILE_CATEGORY_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT)
|
||||
{
|
||||
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;
|
||||
mame_machine_manager::instance()->inifile().move_file(-1);
|
||||
changed = true;
|
||||
}
|
||||
case MANUFACT_CAT_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? c_mnfct::actual++ : c_mnfct::actual--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(
|
||||
ui(), container(), std::vector<std::string>(c_mnfct::ui), c_mnfct::actual,
|
||||
[this] (int selection)
|
||||
{
|
||||
c_mnfct::actual = selection;
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
});
|
||||
}
|
||||
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);
|
||||
|
||||
break;
|
||||
case YEAR_CAT_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
(menu_event->iptkey == IPT_UI_RIGHT) ? c_year::actual++ : c_year::actual--;
|
||||
changed = true;
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_selector>(
|
||||
ui(), container(), std::vector<std::string>(c_year::ui), c_year::actual,
|
||||
[this] (int selection)
|
||||
{
|
||||
c_year::actual = selection;
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
});
|
||||
}
|
||||
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);
|
||||
|
||||
break;
|
||||
case CONF_DIR:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_directory>(ui(), container());
|
||||
break;
|
||||
case MISC_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::misc_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case SOUND_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_sound_options>(ui(), container());
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case DISPLAY_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::video_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case CUSTOM_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_custom_ui>(ui(), container());
|
||||
break;
|
||||
case CONTROLLER_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::control_options);
|
||||
break;
|
||||
case CGI_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_input_groups>(ui(), container());
|
||||
break;
|
||||
case CUSTOM_FILTER:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_custom_filter>(ui(), container());
|
||||
break;
|
||||
case ADVANCED_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::advanced_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case SAVE_CONFIG:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
ui().save_main_option();
|
||||
break;
|
||||
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)
|
||||
{
|
||||
changed = main_filters::filters.find(m_main)->second->adjust_left();
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
changed = main_filters::filters.find(m_main)->second->adjust_right();
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
main_filters::filters.find(m_main)->second->show_ui(
|
||||
ui(),
|
||||
container(),
|
||||
[this] (machine_filter &filter)
|
||||
{
|
||||
if (machine_filter::CUSTOM == filter.get_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();
|
||||
}
|
||||
}
|
||||
reset_options::REMEMBER_REF;
|
||||
});
|
||||
}
|
||||
break;
|
||||
case CONF_DIR:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_directory>(ui(), container());
|
||||
break;
|
||||
case MISC_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::misc_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case SOUND_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<menu_sound_options>(ui(), container());
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case DISPLAY_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::video_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case CUSTOM_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_custom_ui>(ui(), container());
|
||||
break;
|
||||
case CONTROLLER_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::control_options);
|
||||
break;
|
||||
case CGI_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
menu::stack_push<menu_input_groups>(ui(), container());
|
||||
break;
|
||||
case ADVANCED_MENU:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
menu::stack_push<submenu>(ui(), container(), submenu::advanced_options);
|
||||
ui_globals::reset = true;
|
||||
}
|
||||
break;
|
||||
case SAVE_CONFIG:
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
ui().save_main_option();
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
@ -264,45 +247,38 @@ 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);
|
||||
item_append(_("Filter"), machine_filter::display_name(machine_filter::type(m_main)), arrow_flags, (void *)(uintptr_t)FILTER_MENU);
|
||||
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();
|
||||
|
||||
// add category subitem
|
||||
if (m_main == machine_filter::CATEGORY && 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);
|
||||
|
||||
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);
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
// add manufacturer subitem
|
||||
else if (m_main == machine_filter::MANUFACTURER && c_mnfct::ui.size() > 0)
|
||||
{
|
||||
arrow_flags = get_arrow_flags(uint16_t(0), uint16_t(c_mnfct::ui.size() - 1), c_mnfct::actual);
|
||||
fbuff = _("^!Manufacturer");
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, c_mnfct::ui[c_mnfct::actual], arrow_flags, (void *)(uintptr_t)MANUFACT_CAT_FILTER);
|
||||
}
|
||||
// add year subitem
|
||||
else if (m_main == machine_filter::YEAR && c_year::ui.size() > 0)
|
||||
{
|
||||
arrow_flags = get_arrow_flags(uint16_t(0), uint16_t(c_year::ui.size() - 1), c_year::actual);
|
||||
fbuff.assign(_("^!Year"));
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, c_year::ui[c_year::actual], arrow_flags, (void *)(uintptr_t)YEAR_CAT_FILTER);
|
||||
}
|
||||
// add custom subitem
|
||||
else if (m_main == machine_filter::CUSTOM)
|
||||
{
|
||||
fbuff = _("^!Setup custom filter");
|
||||
convert_command_glyph(fbuff);
|
||||
item_append(fbuff, "", 0, (void *)(uintptr_t)CUSTOM_FILTER);
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
|
@ -7,13 +7,14 @@
|
||||
UI main options menu manager.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MAME_FRONTEND_UI_OPTSMENU_H
|
||||
#define MAME_FRONTEND_UI_OPTSMENU_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/menu.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
|
||||
namespace ui {
|
||||
class menu_game_options : public menu
|
||||
@ -30,8 +31,7 @@ private:
|
||||
{
|
||||
FILTER_MENU = 1,
|
||||
FILE_CATEGORY_FILTER,
|
||||
MANUFACT_CAT_FILTER,
|
||||
YEAR_CAT_FILTER,
|
||||
FILTER_ADJUST,
|
||||
CATEGORY_FILTER,
|
||||
CONF_DIR,
|
||||
DISPLAY_MENU,
|
||||
@ -42,14 +42,13 @@ private:
|
||||
ADVANCED_MENU,
|
||||
SAVE_OPTIONS,
|
||||
CGI_MENU,
|
||||
CUSTOM_FILTER,
|
||||
SAVE_CONFIG
|
||||
};
|
||||
|
||||
virtual void populate(float &customtop, float &custombottom) override;
|
||||
virtual void handle() override;
|
||||
|
||||
uint16_t m_main;
|
||||
machine_filter::type m_main;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
@ -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::ALL:
|
||||
m_displaylist = m_sortedlist;
|
||||
break;
|
||||
case machine_filter::AVAILABLE:
|
||||
m_displaylist = m_availsortedlist;
|
||||
break;
|
||||
case machine_filter::UNAVAILABLE:
|
||||
m_displaylist = m_unavailsortedlist;
|
||||
break;
|
||||
case machine_filter::CATEGORY:
|
||||
build_category();
|
||||
break;
|
||||
case machine_filter::MANUFACTURER:
|
||||
build_list(c_mnfct::ui[c_mnfct::actual].c_str());
|
||||
break;
|
||||
case machine_filter::YEAR:
|
||||
build_list(c_year::ui[c_year::actual].c_str());
|
||||
break;
|
||||
case machine_filter::CUSTOM:
|
||||
build_custom();
|
||||
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
|
||||
@ -906,139 +906,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
|
||||
//-------------------------------------------------
|
||||
@ -1074,55 +941,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++;
|
||||
game_driver const &driver(driver_list::driver(x));
|
||||
if (&driver != &GAME_NAME(___empty))
|
||||
{
|
||||
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);
|
||||
m_sortedlist.push_back(&driver);
|
||||
manufacturers.emplace(c_mnfct::getname(driver.manufacturer));
|
||||
years.emplace(driver.year);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & e : c_mnfct::uimap)
|
||||
c_mnfct::ui.emplace_back(e.first);
|
||||
|
||||
// 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,32 +1466,27 @@ void menu_select_game::make_topbox_text(std::string &line0, std::string &line1,
|
||||
(driver_list::total() - 1),
|
||||
m_isabios);
|
||||
|
||||
std::string filtered;
|
||||
if (isfavorite())
|
||||
{
|
||||
line1.clear();
|
||||
}
|
||||
if (main_filters::actual == machine_filter::CATEGORY && inifile.total() > 0)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s - %3$s) - "),
|
||||
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());
|
||||
inifile.get_category(),
|
||||
m_search);
|
||||
}
|
||||
else if (main_filters::actual == machine_filter::MANUFACTURER)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
machine_filter::display_name(main_filters::actual),
|
||||
c_mnfct::ui[c_mnfct::actual]);
|
||||
}
|
||||
else if (main_filters::actual == machine_filter::YEAR)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
machine_filter::display_name(main_filters::actual),
|
||||
c_year::ui[c_year::actual]);
|
||||
}
|
||||
|
||||
// display the current typeahead
|
||||
if (isfavorite())
|
||||
line1.clear();
|
||||
else
|
||||
line1 = string_format(_("%1$s Search: %2$s_"), filtered, m_search);
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
line2.clear();
|
||||
}
|
||||
|
@ -69,10 +69,8 @@ private:
|
||||
// internal methods
|
||||
void change_info_pane(int delta);
|
||||
|
||||
void build_custom();
|
||||
void build_category();
|
||||
void build_available_list();
|
||||
void build_list(const char *filter_text = nullptr, int filter = 0, bool bioscheck = false, std::vector<const game_driver *> vec = {});
|
||||
|
||||
bool isfavorite() const;
|
||||
void populate_search();
|
||||
|
@ -29,11 +29,6 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
static const char *region_lists[] = { "arab", "arg", "asia", "aus", "aut", "bel", "blr", "bra", "can", "chi", "chn", "cze", "den",
|
||||
"ecu", "esp", "euro", "fin", "fra", "gbr", "ger", "gre", "hkg", "hun", "irl", "isr",
|
||||
"isv", "ita", "jpn", "kaz", "kor", "lat", "lux", "mex", "ned", "nld", "nor", "nzl",
|
||||
"pol", "rus", "slo", "spa", "sui", "swe", "tha", "tpe", "tw", "uk", "ukr", "usa" };
|
||||
|
||||
//-------------------------------------------------
|
||||
// compares two items in the software list and
|
||||
// sort them by parent-clone
|
||||
@ -269,41 +264,28 @@ void menu_select_software::handle()
|
||||
if (check_filter)
|
||||
{
|
||||
m_search.clear();
|
||||
auto handler =
|
||||
[this] (uint16_t &actual, int selection)
|
||||
{
|
||||
actual = selection;
|
||||
m_filter_type = software_filter::type(l_sw_hover);
|
||||
reset(reset_options::SELECT_FIRST);
|
||||
};
|
||||
|
||||
using std::placeholders::_1;
|
||||
switch (l_sw_hover)
|
||||
{
|
||||
case software_filter::REGION:
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.region.ui), m_filter.region.actual, std::bind(handler, std::ref(m_filter.region.actual), _1));
|
||||
break;
|
||||
case software_filter::YEARS:
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.year.ui), m_filter.year.actual, std::bind(handler, std::ref(m_filter.year.actual), _1));
|
||||
break;
|
||||
case software_filter::LIST:
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.swlist.description), m_filter.swlist.actual, std::bind(handler, std::ref(m_filter.swlist.actual), _1));
|
||||
break;
|
||||
case software_filter::DEVICE_TYPE:
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.type.ui), m_filter.type.actual, std::bind(handler, std::ref(m_filter.type.actual), _1));
|
||||
break;
|
||||
case software_filter::PUBLISHERS:
|
||||
menu::stack_push<menu_selector>(ui(), container(), std::vector<std::string>(m_filter.publisher.ui), m_filter.publisher.actual, std::bind(handler, std::ref(m_filter.publisher.actual), _1));
|
||||
break;
|
||||
case software_filter::CUSTOM:
|
||||
m_filter_type = software_filter::type(l_sw_hover);
|
||||
menu::stack_push<menu_swcustom_filter>(ui(), container(), m_driver, m_filter);
|
||||
break;
|
||||
default:
|
||||
m_filter_type = software_filter::type(l_sw_hover);
|
||||
reset(reset_options::SELECT_FIRST);
|
||||
break;
|
||||
}
|
||||
filter_map::const_iterator it(m_filters.find(software_filter::type(l_sw_hover)));
|
||||
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->second->show_ui(
|
||||
ui(),
|
||||
container(),
|
||||
[this, driver = m_driver] (software_filter &filter)
|
||||
{
|
||||
software_filter::type const new_type(filter.get_type());
|
||||
if (software_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_", driver->name, "_filter.ini") == osd_file::error::NONE)
|
||||
{
|
||||
filter.save_ini(file, 0);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
m_filter_type = new_type;
|
||||
reset(reset_options::SELECT_FIRST);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,36 +317,11 @@ void menu_select_software::populate(float &customtop, float &custombottom)
|
||||
m_displaylist.clear();
|
||||
m_tmp.clear();
|
||||
|
||||
switch (m_filter_type)
|
||||
{
|
||||
case software_filter::PUBLISHERS:
|
||||
build_list(m_tmp, m_filter.publisher.ui[m_filter.publisher.actual].c_str());
|
||||
break;
|
||||
|
||||
case software_filter::LIST:
|
||||
build_list(m_tmp, m_filter.swlist.name[m_filter.swlist.actual].c_str());
|
||||
break;
|
||||
|
||||
case software_filter::YEARS:
|
||||
build_list(m_tmp, m_filter.year.ui[m_filter.year.actual].c_str());
|
||||
break;
|
||||
|
||||
case software_filter::DEVICE_TYPE:
|
||||
build_list(m_tmp, m_filter.type.ui[m_filter.type.actual].c_str());
|
||||
break;
|
||||
|
||||
case software_filter::REGION:
|
||||
build_list(m_tmp, m_filter.region.ui[m_filter.region.actual].c_str());
|
||||
break;
|
||||
|
||||
case software_filter::CUSTOM:
|
||||
build_custom();
|
||||
break;
|
||||
|
||||
default:
|
||||
build_list(m_tmp);
|
||||
break;
|
||||
}
|
||||
filter_map::const_iterator const it(m_filters.find(m_filter_type));
|
||||
if (m_filters.end() == it)
|
||||
m_displaylist = m_sortedlist;
|
||||
else
|
||||
it->second->apply(std::begin(m_sortedlist), std::end(m_sortedlist), std::back_inserter(m_displaylist));
|
||||
|
||||
// iterate over entries
|
||||
for (size_t curitem = 0; curitem < m_displaylist.size(); ++curitem)
|
||||
@ -419,8 +376,8 @@ void menu_select_software::build_software_list()
|
||||
// iterate thru all software lists
|
||||
for (software_list_device &swlist : software_list_device_iterator(config.root_device()))
|
||||
{
|
||||
m_filter.swlist.name.push_back(swlist.list_name());
|
||||
m_filter.swlist.description.push_back(swlist.description());
|
||||
m_filter_data.swlist.name.push_back(swlist.list_name());
|
||||
m_filter_data.swlist.description.push_back(swlist.description());
|
||||
for (const software_info &swinfo : swlist.get_info())
|
||||
{
|
||||
const software_part &part = swinfo.parts().front();
|
||||
@ -443,10 +400,10 @@ void menu_select_software::build_software_list()
|
||||
|
||||
ui_software_info tmpmatches(swinfo, part, *m_driver, swlist.list_name(), instance_name, type_name);
|
||||
|
||||
m_filter.region.set(tmpmatches.longname);
|
||||
m_filter.publisher.set(tmpmatches.publisher);
|
||||
m_filter.year.set(tmpmatches.year);
|
||||
m_filter.type.set(tmpmatches.devicetype);
|
||||
m_filter_data.region.set(tmpmatches.longname);
|
||||
m_filter_data.publisher.set(tmpmatches.publisher);
|
||||
m_filter_data.year.set(tmpmatches.year);
|
||||
m_filter_data.type.set(tmpmatches.devicetype);
|
||||
m_swinfo.emplace_back(std::move(tmpmatches));
|
||||
}
|
||||
}
|
||||
@ -482,7 +439,7 @@ void menu_select_software::build_software_list()
|
||||
|
||||
std::string searchstr, curpath;
|
||||
const osd::directory::entry *dir;
|
||||
for (auto & elem : m_filter.swlist.name)
|
||||
for (auto & elem : m_filter_data.swlist.name)
|
||||
{
|
||||
path_iterator path(machine().options().media_path());
|
||||
while (path.next(curpath))
|
||||
@ -514,10 +471,10 @@ void menu_select_software::build_software_list()
|
||||
|
||||
// sort array
|
||||
std::stable_sort(m_swinfo.begin() + 1, m_swinfo.end(), compare_software);
|
||||
std::stable_sort(m_filter.region.ui.begin(), m_filter.region.ui.end());
|
||||
std::stable_sort(m_filter.year.ui.begin(), m_filter.year.ui.end());
|
||||
std::stable_sort(m_filter.type.ui.begin(), m_filter.type.ui.end());
|
||||
std::stable_sort(m_filter.publisher.ui.begin(), m_filter.publisher.ui.end());
|
||||
std::stable_sort(m_filter_data.region.ui.begin(), m_filter_data.region.ui.end());
|
||||
std::stable_sort(m_filter_data.year.ui.begin(), m_filter_data.year.ui.end());
|
||||
std::stable_sort(m_filter_data.type.ui.begin(), m_filter_data.type.ui.end());
|
||||
std::stable_sort(m_filter_data.publisher.ui.begin(), m_filter_data.publisher.ui.end());
|
||||
|
||||
for (size_t x = 1; x < m_swinfo.size(); ++x)
|
||||
m_sortedlist.push_back(&m_swinfo[x]);
|
||||
@ -596,253 +553,13 @@ void menu_select_software::load_sw_custom_filters()
|
||||
emu_file file(ui().options().ui_path(), OPEN_FLAG_READ);
|
||||
if (file.open("custom_", m_driver->name, "_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, '=');
|
||||
sw_custfltr::numother = atoi(++pb) - 1;
|
||||
|
||||
// get main filter
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
pb = strchr(buffer, '=') + 2;
|
||||
|
||||
for (software_filter::type y = software_filter::FIRST; y < software_filter::COUNT; ++y)
|
||||
{
|
||||
char const *const name(software_filter::config_name(y));
|
||||
if (!strncmp(pb, name, strlen(name)))
|
||||
{
|
||||
sw_custfltr::main = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 1; x <= sw_custfltr::numother; ++x)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *cb = strchr(buffer, '=') + 2;
|
||||
for (software_filter::type y = software_filter::FIRST; y < software_filter::COUNT; ++y)
|
||||
{
|
||||
char const *const name(software_filter::config_name(y));
|
||||
if (!strncmp(cb, name, strlen(name)))
|
||||
{
|
||||
sw_custfltr::other[x] = y;
|
||||
if (y == software_filter::PUBLISHERS)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *ab = strchr(buffer, '=') + 2;
|
||||
for (size_t z = 0; z < m_filter.publisher.ui.size(); ++z)
|
||||
if (!strncmp(ab, m_filter.publisher.ui[z].c_str(), m_filter.publisher.ui[z].length()))
|
||||
sw_custfltr::mnfct[x] = z;
|
||||
}
|
||||
else if (y == software_filter::YEARS)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *db = strchr(buffer, '=') + 2;
|
||||
for (size_t z = 0; z < m_filter.year.ui.size(); ++z)
|
||||
if (!strncmp(db, m_filter.year.ui[z].c_str(), m_filter.year.ui[z].length()))
|
||||
sw_custfltr::year[x] = z;
|
||||
}
|
||||
else if (y == software_filter::LIST)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *gb = strchr(buffer, '=') + 2;
|
||||
for (size_t z = 0; z < m_filter.swlist.name.size(); ++z)
|
||||
if (!strncmp(gb, m_filter.swlist.name[z].c_str(), m_filter.swlist.name[z].length()))
|
||||
sw_custfltr::list[x] = z;
|
||||
}
|
||||
else if (y == software_filter::DEVICE_TYPE)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *fb = strchr(buffer, '=') + 2;
|
||||
for (size_t z = 0; z < m_filter.type.ui.size(); ++z)
|
||||
if (!strncmp(fb, m_filter.type.ui[z].c_str(), m_filter.type.ui[z].length()))
|
||||
sw_custfltr::type[x] = z;
|
||||
}
|
||||
else if (y == software_filter::REGION)
|
||||
{
|
||||
file.gets(buffer, MAX_CHAR_INFO);
|
||||
char *eb = strchr(buffer, '=') + 2;
|
||||
for (size_t z = 0; z < m_filter.region.ui.size(); ++z)
|
||||
if (!strncmp(eb, m_filter.region.ui[z].c_str(), m_filter.region.ui[z].length()))
|
||||
sw_custfltr::region[x] = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
software_filter::ptr flt(software_filter::create(file, m_filter_data));
|
||||
if (flt)
|
||||
m_filters.emplace(flt->get_type(), std::move(flt));
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set software regions
|
||||
//-------------------------------------------------
|
||||
|
||||
void c_sw_region::set(std::string &str)
|
||||
{
|
||||
std::string name = getname(str);
|
||||
if (std::find(ui.begin(), ui.end(), name) != ui.end())
|
||||
return;
|
||||
|
||||
ui.push_back(name);
|
||||
}
|
||||
|
||||
std::string c_sw_region::getname(std::string &str)
|
||||
{
|
||||
std::string fullname(str);
|
||||
strmakelower(fullname);
|
||||
size_t found = fullname.find("(");
|
||||
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
size_t ends = fullname.find_first_not_of("abcdefghijklmnopqrstuvwxyz", found + 1);
|
||||
std::string temp(fullname.substr(found + 1, ends - found - 1));
|
||||
|
||||
for (auto & elem : region_lists)
|
||||
if (temp == elem)
|
||||
return (str.substr(found + 1, ends - found - 1));
|
||||
}
|
||||
return std::string("<none>");
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set software device type
|
||||
//-------------------------------------------------
|
||||
|
||||
void c_sw_type::set(std::string &str)
|
||||
{
|
||||
if (std::find(ui.begin(), ui.end(), str) != ui.end())
|
||||
return;
|
||||
|
||||
ui.push_back(str);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set software years
|
||||
//-------------------------------------------------
|
||||
|
||||
void c_sw_year::set(std::string &str)
|
||||
{
|
||||
if (std::find(ui.begin(), ui.end(), str) != ui.end())
|
||||
return;
|
||||
|
||||
ui.push_back(str);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set software publishers
|
||||
//-------------------------------------------------
|
||||
|
||||
void c_sw_publisher::set(std::string &str)
|
||||
{
|
||||
std::string name = getname(str);
|
||||
if (std::find(ui.begin(), ui.end(), name) != ui.end())
|
||||
return;
|
||||
|
||||
ui.push_back(name);
|
||||
}
|
||||
|
||||
std::string c_sw_publisher::getname(std::string &str)
|
||||
{
|
||||
size_t found = str.find("(");
|
||||
|
||||
if (found != std::string::npos)
|
||||
return (str.substr(0, found - 1));
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// build display list
|
||||
//-------------------------------------------------
|
||||
void menu_select_software::build_list(std::vector<ui_software_info *> &s_drivers, const char *filter_text, int filter)
|
||||
{
|
||||
if (s_drivers.empty() && filter == -1)
|
||||
{
|
||||
filter = m_filter_type;
|
||||
s_drivers = m_sortedlist;
|
||||
}
|
||||
|
||||
// iterate over entries
|
||||
for (auto & s_driver : s_drivers)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case software_filter::PARENTS:
|
||||
if (s_driver->parentname.empty())
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::CLONES:
|
||||
if (!s_driver->parentname.empty())
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::AVAILABLE:
|
||||
if (s_driver->available)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::UNAVAILABLE:
|
||||
if (!s_driver->available)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::SUPPORTED:
|
||||
if (s_driver->supported == SOFTWARE_SUPPORTED_YES)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::PARTIAL_SUPPORTED:
|
||||
if (s_driver->supported == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::UNSUPPORTED:
|
||||
if (s_driver->supported == SOFTWARE_SUPPORTED_NO)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::REGION:
|
||||
{
|
||||
std::string name = m_filter.region.getname(s_driver->longname);
|
||||
|
||||
if(!name.empty() && name == filter_text)
|
||||
m_displaylist.push_back(s_driver);
|
||||
}
|
||||
break;
|
||||
|
||||
case software_filter::PUBLISHERS:
|
||||
{
|
||||
std::string name = m_filter.publisher.getname(s_driver->publisher);
|
||||
|
||||
if(!name.empty() && name == filter_text)
|
||||
m_displaylist.push_back(s_driver);
|
||||
}
|
||||
break;
|
||||
|
||||
case software_filter::YEARS:
|
||||
if(s_driver->year == filter_text)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::LIST:
|
||||
if(s_driver->listname == filter_text)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
case software_filter::DEVICE_TYPE:
|
||||
if(s_driver->devicetype == filter_text)
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_displaylist.push_back(s_driver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// find approximate matches
|
||||
//-------------------------------------------------
|
||||
@ -881,46 +598,6 @@ void menu_select_software::find_matches(const char *str, int count)
|
||||
(index < count) ? m_searchlist[index] = nullptr : m_searchlist[count] = nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// build custom display list
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_select_software::build_custom()
|
||||
{
|
||||
std::vector<ui_software_info *> s_drivers;
|
||||
|
||||
build_list(m_sortedlist, nullptr, sw_custfltr::main);
|
||||
|
||||
for (int count = 1; count <= sw_custfltr::numother; ++count)
|
||||
{
|
||||
software_filter::type filter = sw_custfltr::other[count];
|
||||
s_drivers = m_displaylist;
|
||||
m_displaylist.clear();
|
||||
|
||||
switch (filter)
|
||||
{
|
||||
case software_filter::YEARS:
|
||||
build_list(s_drivers, m_filter.year.ui[sw_custfltr::year[count]].c_str(), filter);
|
||||
break;
|
||||
case software_filter::LIST:
|
||||
build_list(s_drivers, m_filter.swlist.name[sw_custfltr::list[count]].c_str(), filter);
|
||||
break;
|
||||
case software_filter::DEVICE_TYPE:
|
||||
build_list(s_drivers, m_filter.type.ui[sw_custfltr::type[count]].c_str(), filter);
|
||||
break;
|
||||
case software_filter::PUBLISHERS:
|
||||
build_list(s_drivers, m_filter.publisher.ui[sw_custfltr::mnfct[count]].c_str(), filter);
|
||||
break;
|
||||
case software_filter::REGION:
|
||||
build_list(s_drivers, m_filter.region.ui[sw_custfltr::region[count]].c_str(), filter);
|
||||
break;
|
||||
default:
|
||||
build_list(s_drivers, nullptr, filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// draw left box
|
||||
//-------------------------------------------------
|
||||
@ -929,6 +606,9 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
|
||||
{
|
||||
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;
|
||||
@ -946,7 +626,9 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
|
||||
line_height = l_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 (software_filter::type x = software_filter::FIRST; x < software_filter::COUNT; ++x)
|
||||
{
|
||||
float total_width;
|
||||
@ -971,7 +653,7 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
|
||||
|
||||
for (software_filter::type filter = software_filter::FIRST; filter < software_filter::COUNT; ++filter)
|
||||
{
|
||||
std::string str(software_filter::display_name(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;
|
||||
|
||||
@ -994,35 +676,7 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
|
||||
hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
|
||||
}
|
||||
|
||||
float x1t = x1 + text_sign;
|
||||
if (m_filter_type == software_filter::CUSTOM)
|
||||
{
|
||||
if (filter == sw_custfltr::main)
|
||||
{
|
||||
str = std::string("@custom1 ") + str;
|
||||
x1t -= text_sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int count = 1; count <= sw_custfltr::numother; ++count)
|
||||
{
|
||||
int cfilter = sw_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 == m_filter_type)
|
||||
{
|
||||
str = std::string("_> ") + str;
|
||||
x1t -= text_sign;
|
||||
convert_command_glyph(str);
|
||||
}
|
||||
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);
|
||||
@ -1097,19 +751,12 @@ void menu_select_software::make_topbox_text(std::string &line0, std::string &lin
|
||||
line0 = string_format(_("%1$s %2$s ( %3$d / %4$d software packages )"), emulator_info::get_appname(), bare_build_version, vis_item, m_swinfo.size() - 1);
|
||||
line1 = string_format(_("Driver: \"%1$s\" software list "), m_driver->type.fullname());
|
||||
|
||||
std::string filtered;
|
||||
if (m_filter_type == software_filter::REGION && m_filter.region.ui.size())
|
||||
filtered = string_format(_("Region: %1$s -"), m_filter.region.ui[m_filter.region.actual]);
|
||||
else if (m_filter_type == software_filter::PUBLISHERS)
|
||||
filtered = string_format(_("Publisher: %1$s -"), m_filter.publisher.ui[m_filter.publisher.actual]);
|
||||
else if (m_filter_type == software_filter::YEARS)
|
||||
filtered = string_format(_("Year: %1$s -"), m_filter.year.ui[m_filter.year.actual]);
|
||||
else if (m_filter_type == software_filter::LIST)
|
||||
filtered = string_format(_("Software List: %1$s -"), m_filter.swlist.description[m_filter.swlist.actual]);
|
||||
else if (m_filter_type == software_filter::DEVICE_TYPE)
|
||||
filtered = string_format(_("Device type: %1$s -"), m_filter.type.ui[m_filter.type.actual]);
|
||||
|
||||
line2 = string_format(_("%s Search: %s_"), filtered, m_search);
|
||||
filter_map::const_iterator const it(m_filters.find(m_filter_type));
|
||||
char const *const filter((m_filters.end() != it) ? it->second->filter_text() : nullptr);
|
||||
if (filter)
|
||||
line2 = string_format(_("%1$s: %2$s - Search: %3$s_"), it->second->display_name(), filter, m_search);
|
||||
else
|
||||
line2 = string_format(_("Search: %1$s_"), m_search);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "ui/custmenu.h"
|
||||
#include "ui/selmenu.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -30,10 +32,13 @@ protected:
|
||||
private:
|
||||
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
|
||||
|
||||
typedef std::map<software_filter::type, software_filter::ptr> filter_map;
|
||||
|
||||
std::string m_search;
|
||||
const game_driver *m_driver;
|
||||
bool m_has_empty_start;
|
||||
s_filter m_filter;
|
||||
s_filter m_filter_data;
|
||||
filter_map m_filters;
|
||||
software_filter::type m_filter_type;
|
||||
int highlight;
|
||||
|
||||
@ -56,8 +61,6 @@ private:
|
||||
std::vector<ui_software_info> m_swinfo;
|
||||
|
||||
void build_software_list();
|
||||
void build_list(std::vector<ui_software_info *> &vec, const char *filter_text = nullptr, int filter = -1);
|
||||
void build_custom();
|
||||
void find_matches(const char *str, int count);
|
||||
void load_sw_custom_filters();
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Maurizio Petrarota
|
||||
// copyright-holders:Maurizio Petrarota, Vas Crabb
|
||||
/***************************************************************************
|
||||
|
||||
ui/utils.h
|
||||
@ -14,10 +14,111 @@
|
||||
|
||||
#include "unicode.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class mame_ui_manager;
|
||||
class render_container;
|
||||
|
||||
|
||||
// TODO: namespace this thing
|
||||
struct ui_software_info
|
||||
{
|
||||
ui_software_info() { }
|
||||
|
||||
// info for software list item
|
||||
ui_software_info(
|
||||
software_info const &info,
|
||||
software_part const &p,
|
||||
game_driver const &d,
|
||||
std::string const &li,
|
||||
std::string const &is,
|
||||
std::string const &de);
|
||||
|
||||
// info for starting empty
|
||||
ui_software_info(game_driver const &d);
|
||||
|
||||
// copyable/movable
|
||||
ui_software_info(ui_software_info const &) = default;
|
||||
ui_software_info(ui_software_info &&) = default;
|
||||
ui_software_info &operator=(ui_software_info const &) = default;
|
||||
ui_software_info &operator=(ui_software_info &&) = default;
|
||||
|
||||
bool operator==(ui_software_info const &r)
|
||||
{
|
||||
return shortname == r.shortname && longname == r.longname && parentname == r.parentname
|
||||
&& year == r.year && publisher == r.publisher && supported == r.supported
|
||||
&& part == r.part && driver == r.driver && listname == r.listname
|
||||
&& interface == r.interface && instance == r.instance && startempty == r.startempty
|
||||
&& parentlongname == r.parentlongname && usage == r.usage && devicetype == r.devicetype;
|
||||
}
|
||||
|
||||
std::string shortname;
|
||||
std::string longname;
|
||||
std::string parentname;
|
||||
std::string year;
|
||||
std::string publisher;
|
||||
uint8_t supported = 0;
|
||||
std::string part;
|
||||
const game_driver *driver = nullptr;
|
||||
std::string listname;
|
||||
std::string interface;
|
||||
std::string instance;
|
||||
uint8_t startempty = 0;
|
||||
std::string parentlongname;
|
||||
std::string usage;
|
||||
std::string devicetype;
|
||||
bool available = false;
|
||||
};
|
||||
|
||||
|
||||
namespace ui {
|
||||
|
||||
class machine_filter
|
||||
struct s_filter; // FIXME: this is declared in custmenu.h, it shouldn't be
|
||||
|
||||
template <class Impl, typename Entry>
|
||||
class filter_base
|
||||
{
|
||||
public:
|
||||
typedef std::unique_ptr<Impl> ptr;
|
||||
|
||||
virtual ~filter_base() { }
|
||||
|
||||
virtual char const *config_name() const = 0;
|
||||
virtual char const *display_name() const = 0;
|
||||
virtual char const *filter_text() const = 0;
|
||||
|
||||
virtual bool apply(Entry const &info) const = 0;
|
||||
|
||||
virtual void show_ui(mame_ui_manager &mui, render_container &container, std::function<void (Impl &)> &&handler) = 0;
|
||||
|
||||
virtual bool wants_adjuster() const = 0;
|
||||
virtual char const *adjust_text() const = 0;
|
||||
virtual uint32_t arrow_flags() const = 0;
|
||||
virtual bool adjust_left() = 0;
|
||||
virtual bool adjust_right() = 0;
|
||||
|
||||
virtual void save_ini(emu_file &file, unsigned indent) const = 0;
|
||||
|
||||
template <typename InputIt, class OutputIt>
|
||||
void apply(InputIt first, InputIt last, OutputIt dest) const
|
||||
{
|
||||
std::copy_if(first, last, dest, [this] (Entry const *info) { return apply(*info); });
|
||||
}
|
||||
|
||||
protected:
|
||||
using entry_type = Entry;
|
||||
|
||||
filter_base() { }
|
||||
};
|
||||
|
||||
|
||||
class machine_filter : public filter_base<machine_filter, game_driver>
|
||||
{
|
||||
public:
|
||||
enum type : uint16_t
|
||||
@ -32,7 +133,7 @@ public:
|
||||
CATEGORY,
|
||||
FAVORITE,
|
||||
BIOS,
|
||||
PARENT,
|
||||
PARENTS,
|
||||
CLONES,
|
||||
MANUFACTURER,
|
||||
YEAR,
|
||||
@ -49,14 +150,28 @@ public:
|
||||
LAST = COUNT - 1
|
||||
};
|
||||
|
||||
virtual type get_type() const = 0;
|
||||
virtual std::string adorned_display_name(type n) const = 0;
|
||||
|
||||
static ptr create(type n) { return create(n, nullptr, nullptr, 0); }
|
||||
static ptr create(emu_file &file) { return create(file, 0); }
|
||||
static char const *config_name(type n);
|
||||
static char const *display_name(type n);
|
||||
|
||||
using filter_base<machine_filter, game_driver>::config_name;
|
||||
using filter_base<machine_filter, game_driver>::display_name;
|
||||
|
||||
protected:
|
||||
machine_filter();
|
||||
|
||||
static ptr create(type n, char const *value, emu_file *file, unsigned indent);
|
||||
static ptr create(emu_file &file, unsigned indent);
|
||||
};
|
||||
|
||||
DECLARE_ENUM_INCDEC_OPERATORS(machine_filter::type)
|
||||
|
||||
|
||||
class software_filter
|
||||
class software_filter : public filter_base<software_filter, ui_software_info>
|
||||
{
|
||||
public:
|
||||
enum type : uint16_t
|
||||
@ -66,7 +181,7 @@ public:
|
||||
UNAVAILABLE,
|
||||
PARENTS,
|
||||
CLONES,
|
||||
YEARS,
|
||||
YEAR,
|
||||
PUBLISHERS,
|
||||
SUPPORTED,
|
||||
PARTIAL_SUPPORTED,
|
||||
@ -81,8 +196,22 @@ public:
|
||||
LAST = COUNT - 1
|
||||
};
|
||||
|
||||
virtual type get_type() const = 0;
|
||||
virtual std::string adorned_display_name(type n) const = 0;
|
||||
|
||||
static ptr create(type n, s_filter const &data) { return create(n, data, nullptr, nullptr, 0); }
|
||||
static ptr create(emu_file &file, s_filter const &data) { return create(file, data, 0); }
|
||||
static char const *config_name(type n);
|
||||
static char const *display_name(type n);
|
||||
|
||||
using filter_base<software_filter, ui_software_info>::config_name;
|
||||
using filter_base<software_filter, ui_software_info>::display_name;
|
||||
|
||||
protected:
|
||||
software_filter();
|
||||
|
||||
static ptr create(type n, s_filter const &data, char const *value, emu_file *file, unsigned indent);
|
||||
static ptr create(emu_file &file, s_filter const &data, unsigned indent);
|
||||
};
|
||||
|
||||
DECLARE_ENUM_INCDEC_OPERATORS(software_filter::type)
|
||||
@ -151,73 +280,7 @@ enum
|
||||
HOVER_RP_LAST = (HOVER_RP_FIRST) + 1 + RP_LAST
|
||||
};
|
||||
|
||||
// GLOBAL STRUCTURES
|
||||
struct ui_software_info
|
||||
{
|
||||
ui_software_info() { }
|
||||
|
||||
// info for software list item
|
||||
ui_software_info(
|
||||
software_info const &info,
|
||||
software_part const &p,
|
||||
game_driver const &d,
|
||||
std::string const &li,
|
||||
std::string const &is,
|
||||
std::string const &de);
|
||||
|
||||
// info for starting empty
|
||||
ui_software_info(game_driver const &d);
|
||||
|
||||
// copyable/movable
|
||||
ui_software_info(ui_software_info const &) = default;
|
||||
ui_software_info(ui_software_info &&) = default;
|
||||
ui_software_info &operator=(ui_software_info const &) = default;
|
||||
ui_software_info &operator=(ui_software_info &&) = default;
|
||||
|
||||
bool operator==(ui_software_info const &r)
|
||||
{
|
||||
return shortname == r.shortname && longname == r.longname && parentname == r.parentname
|
||||
&& year == r.year && publisher == r.publisher && supported == r.supported
|
||||
&& part == r.part && driver == r.driver && listname == r.listname
|
||||
&& interface == r.interface && instance == r.instance && startempty == r.startempty
|
||||
&& parentlongname == r.parentlongname && usage == r.usage && devicetype == r.devicetype;
|
||||
}
|
||||
|
||||
std::string shortname;
|
||||
std::string longname;
|
||||
std::string parentname;
|
||||
std::string year;
|
||||
std::string publisher;
|
||||
uint8_t supported = 0;
|
||||
std::string part;
|
||||
const game_driver *driver = nullptr;
|
||||
std::string listname;
|
||||
std::string interface;
|
||||
std::string instance;
|
||||
uint8_t startempty = 0;
|
||||
std::string parentlongname;
|
||||
std::string usage;
|
||||
std::string devicetype;
|
||||
bool available = false;
|
||||
};
|
||||
|
||||
// Manufacturers
|
||||
struct c_mnfct
|
||||
{
|
||||
static void set(const char *str);
|
||||
static std::string getname(const char *str);
|
||||
static std::vector<std::string> ui;
|
||||
static std::unordered_map<std::string, int> uimap;
|
||||
static uint16_t actual;
|
||||
};
|
||||
|
||||
// Years
|
||||
struct c_year
|
||||
{
|
||||
static void set(const char *str);
|
||||
static std::vector<std::string> ui;
|
||||
static uint16_t actual;
|
||||
};
|
||||
// FIXME: this stuff shouldn't all be globals
|
||||
|
||||
// GLOBAL CLASS
|
||||
struct ui_globals
|
||||
@ -229,30 +292,23 @@ struct ui_globals
|
||||
static bool has_icons;
|
||||
};
|
||||
|
||||
struct main_filters { static ui::machine_filter::type actual; };
|
||||
|
||||
// Custom filter
|
||||
struct custfltr
|
||||
// Manufacturers
|
||||
struct c_mnfct
|
||||
{
|
||||
static ui::machine_filter::type main;
|
||||
static uint16_t numother;
|
||||
static ui::machine_filter::type other[MAX_CUST_FILTER];
|
||||
static uint16_t mnfct[MAX_CUST_FILTER];
|
||||
static uint16_t screen[MAX_CUST_FILTER];
|
||||
static uint16_t year[MAX_CUST_FILTER];
|
||||
static std::string getname(const char *str);
|
||||
static std::vector<std::string> ui;
|
||||
};
|
||||
|
||||
// Software custom filter
|
||||
struct sw_custfltr
|
||||
// Years
|
||||
struct c_year
|
||||
{
|
||||
static ui::software_filter::type main;
|
||||
static uint16_t numother;
|
||||
static ui::software_filter::type other[MAX_CUST_FILTER];
|
||||
static uint16_t mnfct[MAX_CUST_FILTER];
|
||||
static uint16_t year[MAX_CUST_FILTER];
|
||||
static uint16_t region[MAX_CUST_FILTER];
|
||||
static uint16_t type[MAX_CUST_FILTER];
|
||||
static uint16_t list[MAX_CUST_FILTER];
|
||||
static std::vector<std::string> ui;
|
||||
};
|
||||
|
||||
struct main_filters
|
||||
{
|
||||
static ui::machine_filter::type actual;
|
||||
static std::map<ui::machine_filter::type, ui::machine_filter::ptr> filters;
|
||||
};
|
||||
|
||||
// GLOBAL FUNCTIONS
|
||||
|
@ -2015,7 +2015,7 @@ DRIVER_INIT_MEMBER(neogeo_state, neogeo)
|
||||
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT */
|
||||
CONS( 1990, neogeo, 0, 0, mvs, neogeo_6slot, neogeo_state, neogeo, "SNK", "Neo-Geo", MACHINE_IS_BIOS_ROOT | MACHINE_SUPPORTS_SAVE )
|
||||
CONS( 1990, neogeo, 0, 0, mvs, neogeo_6slot, neogeo_state, neogeo, "SNK", "Neo-Geo MVS", MACHINE_IS_BIOS_ROOT | MACHINE_SUPPORTS_SAVE )
|
||||
CONS( 1990, aes, 0, 0, aes, aes, aes_state, 0, "SNK", "Neo-Geo AES", MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user