summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--language/Chinese_Simplified/strings.po4
-rw-r--r--language/Chinese_Traditional/strings.po4
-rw-r--r--plugins/autofire/autofire_menu.lua172
-rw-r--r--plugins/autofire/autofire_save.lua16
-rw-r--r--plugins/inputmacro/inputmacro_menu.lua48
-rw-r--r--src/frontend/mame/luaengine.cpp16
-rw-r--r--src/frontend/mame/luaengine.h4
-rw-r--r--src/frontend/mame/ui/menu.h2
-rw-r--r--src/frontend/mame/ui/pluginopt.cpp103
-rw-r--r--src/frontend/mame/ui/pluginopt.h7
10 files changed, 277 insertions, 99 deletions
diff --git a/language/Chinese_Simplified/strings.po b/language/Chinese_Simplified/strings.po
index 26832773750..a6acc3d2240 100644
--- a/language/Chinese_Simplified/strings.po
+++ b/language/Chinese_Simplified/strings.po
@@ -6697,7 +6697,7 @@ msgstr "总计发现 %d 符合"
#: plugins/cheatfind/init.lua:623
#, lua-format
msgid "Perform Compare : Slot %d %s Slot %d"
-msgstr "执行比较:插槽 $d %s 插槽 %d"
+msgstr "执行比较:插槽 %d %s 插槽 %d"
#: plugins/cheatfind/init.lua:624
#, lua-format
@@ -6886,7 +6886,7 @@ msgstr "连发按钮"
#: plugins/autofire/autofire_menu.lua:59
#, lua-format
msgid "Press %s to delete"
-msgstr "按下 $s 删除"
+msgstr "按下 %s 删除"
#: plugins/autofire/autofire_menu.lua:68
#, lua-format
diff --git a/language/Chinese_Traditional/strings.po b/language/Chinese_Traditional/strings.po
index f124a63946b..92a58274f58 100644
--- a/language/Chinese_Traditional/strings.po
+++ b/language/Chinese_Traditional/strings.po
@@ -6697,7 +6697,7 @@ msgstr "總計發現 %d 符合"
#: plugins/cheatfind/init.lua:623
#, lua-format
msgid "Perform Compare : Slot %d %s Slot %d"
-msgstr "執行比較:插槽 $d %s 插槽 %d"
+msgstr "執行比較:插槽 %d %s 插槽 %d"
#: plugins/cheatfind/init.lua:624
#, lua-format
@@ -6886,7 +6886,7 @@ msgstr "連射按鈕"
#: plugins/autofire/autofire_menu.lua:59
#, lua-format
msgid "Press %s to delete"
-msgstr "按下 $s 刪除"
+msgstr "按下 %s 刪除"
#: plugins/autofire/autofire_menu.lua:68
#, lua-format
diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua
index c9afa90e94f..18000bfbd99 100644
--- a/plugins/autofire/autofire_menu.lua
+++ b/plugins/autofire/autofire_menu.lua
@@ -15,11 +15,26 @@ local content_height = 0
-- Stack of menus (see MENU_TYPES)
local menu_stack = { MENU_TYPES.MAIN }
+-- Button to select when showing the main menu (so newly added button can be selected)
+local initial_button
+
+-- Saved selection on main menu (to restore after configure menu is dismissed)
+local main_selection_save
+
+-- Whether configure menu is active (so first item can be selected initially)
+local configure_menu_active = false
+
+-- Saved selection on configure menu (to restore after button menu is dismissed)
+local configure_selection_save
+
-- Button being created/edited
local current_button = {}
+-- Initial button to select when opening buttons menu
+local initial_input
+
-- Inputs that can be autofired (to list in BUTTON menu)
-local inputs = {}
+local inputs
-- Returns the section (from MENU_SECTIONS) and the index within that section
local function menu_section(index)
@@ -60,35 +75,54 @@ local function populate_main_menu(buttons)
menu[#menu + 1] = {'---', '', ''}
header_height = #menu
+ -- Use frame rate of first screen or 60Hz if no screens
+ local freq = 60
+ local screen = manager.machine.screens:at(1)
+ if screen then
+ freq = 1 / screen.frame_period
+ end
+
for index, button in ipairs(buttons) do
- -- Assume refresh rate of 60 Hz; maybe better to use screen_device refresh()?
- local rate = 60 / (button.on_frames + button.off_frames)
- -- Round to two decimal places
+ -- Round rate to two decimal places
+ local rate = freq / (button.on_frames + button.off_frames)
rate = math.floor(rate * 100) / 100
- local text = string.format(_('%s [%d Hz]'), _p('input-name', button.button.name), rate)
+ local text = string.format(_('%s [%g Hz]'), _p('input-name', button.button.name), rate)
local subtext = input:seq_name(button.key)
menu[#menu + 1] = {text, subtext, ''}
+ if index == initial_button then
+ main_selection_save = #menu
+ end
end
+ initial_button = nil
content_height = #menu
menu[#menu + 1] = {'---', '', ''}
menu[#menu + 1] = {_('Add autofire button'), '', ''}
- return menu
+
+ local selection = main_selection_save
+ main_selection_save = nil
+ return menu, selection
end
local function handle_main_menu(index, event, buttons)
local section, adjusted_index = menu_section(index)
if section == MENU_SECTIONS.CONTENT then
if event == 'select' then
+ main_selection_save = index
current_button = buttons[adjusted_index]
table.insert(menu_stack, MENU_TYPES.EDIT)
return true
elseif event == 'clear' then
table.remove(buttons, adjusted_index)
+ main_selection_save = index
+ if adjusted_index > #buttons then
+ main_selection_save = main_selection_save - 1
+ end
return true
end
elseif section == MENU_SECTIONS.FOOTER then
if event == 'select' then
+ main_selection_save = index
current_button = create_new_button()
table.insert(menu_stack, MENU_TYPES.ADD)
return true
@@ -103,9 +137,13 @@ local function populate_configure_menu(menu)
local button_name = current_button.button and _p('input-name', current_button.button.name) or _('NOT SET')
local key_name = current_button.key and manager.machine.input:seq_name(current_button.key) or _('NOT SET')
menu[#menu + 1] = {_('Input'), button_name, ''}
+ if not (configure_menu_active or configure_selection_save) then
+ configure_selection_save = #menu
+ end
menu[#menu + 1] = {_('Hotkey'), key_name, ''}
menu[#menu + 1] = {_('On frames'), current_button.on_frames, current_button.on_frames > 1 and 'lr' or 'r'}
menu[#menu + 1] = {_('Off frames'), current_button.off_frames, current_button.off_frames > 1 and 'lr' or 'r'}
+ configure_menu_active = true
end
-- Borrowed from the cheat plugin
@@ -138,7 +176,11 @@ local function handle_configure_menu(index, event)
if index == 1 then
-- Input
if event == 'select' then
+ configure_selection_save = header_height + index
table.insert(menu_stack, MENU_TYPES.BUTTON)
+ if current_button.port and current_button.field then
+ initial_input = {port_name = current_button.port, ioport_field = current_button.button}
+ end
return true
end
elseif index == 2 then
@@ -159,6 +201,9 @@ local function handle_configure_menu(index, event)
elseif event == 'right' then
current_button.on_frames = current_button.on_frames + 1
return true
+ elseif event == 'clear' then
+ current_button.on_frames = 1
+ return true
end
elseif index == 4 then
-- Off frames
@@ -169,6 +214,9 @@ local function handle_configure_menu(index, event)
elseif event == 'right' then
current_button.off_frames = current_button.off_frames + 1
return true
+ elseif event == 'clear' then
+ current_button.off_frames = 1
+ return true
end
end
return false
@@ -185,12 +233,17 @@ local function populate_edit_menu()
menu[#menu + 1] = {'---', '', ''}
menu[#menu + 1] = {_('Done'), '', ''}
- return menu
+
+ local selection = configure_selection_save
+ configure_selection_save = nil
+ return menu, selection, 'lrrepeat'
end
local function handle_edit_menu(index, event, buttons)
local section, adjusted_index = menu_section(index)
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'cancel') then
+ inputs = nil
+ configure_menu_active = false
table.remove(menu_stack)
return true
elseif section == MENU_SECTIONS.CONTENT then
@@ -214,15 +267,21 @@ local function populate_add_menu()
else
menu[#menu + 1] = {_('Cancel'), '', ''}
end
- return menu
+
+ local selection = configure_selection_save
+ configure_selection_save = nil
+ return menu, selection, 'lrrepeat'
end
local function handle_add_menu(index, event, buttons)
local section, adjusted_index = menu_section(index)
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'cancel') then
+ inputs = nil
+ configure_menu_active = false
table.remove(menu_stack)
if is_button_complete(current_button) and (event == 'select') then
- buttons[#buttons + 1] = current_button
+ table.insert(buttons, current_button)
+ initial_button = #buttons
end
return true
elseif section == MENU_SECTIONS.CONTENT then
@@ -236,54 +295,85 @@ end
local function populate_button_menu()
local ioport = manager.machine.ioport
menu = {}
- inputs = {}
menu[#menu + 1] = {_('Select an input for autofire'), '', 'off'}
menu[#menu + 1] = {'---', '', ''}
header_height = #menu
- for port_key, port in pairs(ioport.ports) do
- for field_key, field in pairs(port.fields) do
- if is_supported_input(field) then
- inputs[#inputs + 1] = {
- port_name = port_key,
- field_name = field_key,
- ioport_field = field
- }
+ if not inputs then
+ inputs = {}
+
+ for port_key, port in pairs(ioport.ports) do
+ for field_key, field in pairs(port.fields) do
+ if is_supported_input(field) then
+ inputs[#inputs + 1] = {
+ port_name = port_key,
+ field_name = field_key,
+ ioport_field = field
+ }
+ end
end
end
- end
- local function compare(x, y)
- if x.ioport_field.device.tag < y.ioport_field.device.tag then
- return true
- elseif x.ioport_field.device.tag > y.ioport_field.device.tag then
- return false
+ local function compare(x, y)
+ if x.ioport_field.device.tag < y.ioport_field.device.tag then
+ return true
+ elseif x.ioport_field.device.tag > y.ioport_field.device.tag then
+ return false
+ end
+ groupx = ioport:type_group(x.ioport_field.type, x.ioport_field.player)
+ groupy = ioport:type_group(y.ioport_field.type, y.ioport_field.player)
+ if groupx < groupy then
+ return true
+ elseif groupx > groupy then
+ return false
+ elseif x.ioport_field.type < y.ioport_field.type then
+ return true
+ elseif x.ioport_field.type > y.ioport_field.type then
+ return false
+ else
+ return x.ioport_field.name < y.ioport_field.name
+ end
end
- groupx = ioport:type_group(x.ioport_field.type, x.ioport_field.player)
- groupy = ioport:type_group(y.ioport_field.type, y.ioport_field.player)
- if groupx < groupy then
- return true
- elseif groupx > groupy then
- return false
- elseif x.ioport_field.type < y.ioport_field.type then
- return true
- elseif x.ioport_field.type > y.ioport_field.type then
- return false
- else
- return x.ioport_field.name < y.ioport_field.name
+ table.sort(inputs, compare)
+
+ local i = 1
+ local prev
+ while i <= #inputs do
+ local current = inputs[i]
+ if (not prev) or (prev.ioport_field.device.tag ~= current.ioport_field.device.tag) then
+ table.insert(inputs, i, false)
+ i = i + 2
+ else
+ i = i + 1
+ end
+ prev = current
end
end
- table.sort(inputs, compare)
- for i, input in pairs(inputs) do
- menu[header_height + i] = { _p('input-name', input.ioport_field.name), '', '' }
+ local selection = header_height + 1
+ for i, input in ipairs(inputs) do
+ if input then
+ menu[header_height + i] = { _p('input-name', input.ioport_field.name), '', '' }
+ if initial_input and (initial_input.port_name == input.port_name) and (initial_input.ioport_field.mask == input.ioport_field.mask) and (initial_input.ioport_field.type == input.ioport_field.type) then
+ selection = header_height + i
+ initial_input = nil
+ end
+ else
+ local device = inputs[i + 1].ioport_field.device
+ if device.owner then
+ menu[header_height + i] = {string.format(_('%s [root%s]'), device.name, device.tag), '', 'heading'}
+ else
+ menu[header_height + i] = {string.format(_('[root%s]'), device.tag), '', 'heading'}
+ end
+ end
end
content_height = #menu
+ initial_input = nil
menu[#menu + 1] = {'---', '', ''}
menu[#menu + 1] = {_('Cancel'), '', ''}
- return menu
+ return menu, selection
end
local function handle_button_menu(index, event)
@@ -307,7 +397,7 @@ function lib:init_menu(buttons)
content_height = 0
menu_stack = { MENU_TYPES.MAIN }
current_button = {}
- inputs = {}
+ inputs = nil
end
function lib:populate_menu(buttons)
diff --git a/plugins/autofire/autofire_save.lua b/plugins/autofire/autofire_save.lua
index e75b44c71e3..3692540cd5b 100644
--- a/plugins/autofire/autofire_save.lua
+++ b/plugins/autofire/autofire_save.lua
@@ -50,13 +50,15 @@ end
function lib:load_settings()
local buttons = {}
local json = require('json')
- local file = io.open(get_settings_path() .. get_settings_filename(), 'r')
+ local filename = get_settings_path() .. get_settings_filename()
+ local file = io.open(filename, 'r')
if not file then
return buttons
end
local loaded_settings = json.parse(file:read('a'))
file:close()
if not loaded_settings then
+ emu.print_error(string.format('Error loading autofire settings: error parsing file "%s" as JSON\n', filename))
return buttons
end
for index, button_settings in ipairs(loaded_settings) do
@@ -74,6 +76,7 @@ function lib:save_settings(buttons)
if not attr then
lfs.mkdir(path)
elseif attr.mode ~= 'directory' then
+ emu.print_error(string.format('Error autofire settings macros: "%s" is not a directory\n', path))
return
end
if #buttons == 0 then
@@ -83,11 +86,14 @@ function lib:save_settings(buttons)
local json = require('json')
local settings = serialize_settings(buttons)
local data = json.stringify(settings, {indent = true})
- local file = io.open(path .. get_settings_filename(), 'w')
- if file then
- file:write(data)
- file:close()
+ local filename = path .. get_settings_filename()
+ local file = io.open(filename, 'w')
+ if not file then
+ emu.print_error(string.format('Error saving autofire settings: error opening file "%s" for writing\n', filename))
+ return
end
+ file:write(data)
+ file:close()
end
return lib
diff --git a/plugins/inputmacro/inputmacro_menu.lua b/plugins/inputmacro/inputmacro_menu.lua
index 8b62148ab67..24c8caff29e 100644
--- a/plugins/inputmacro/inputmacro_menu.lua
+++ b/plugins/inputmacro/inputmacro_menu.lua
@@ -114,20 +114,42 @@ function populate_input()
for tag, port in pairs(manager.machine.ioport.ports) do
for name, field in pairs(port.fields) do
if supported(field) then
- input_choices[#input_choices + 1] = field
+ table.insert(input_choices, field)
end
end
end
table.sort(input_choices, compare)
+
+ local index = 1
+ local prev
+ while index <= #input_choices do
+ local current = input_choices[index]
+ if (not prev) or (prev.device.tag ~= current.device.tag) then
+ table.insert(input_choices, index, false)
+ index = index + 2
+ else
+ index = index + 1
+ end
+ prev = current
+ end
end
input_item_first_choice = #items + 1
local selection = input_item_first_choice
for index, field in ipairs(input_choices) do
- items[#items + 1] = { _p('input-name', field.name), '', '' }
- if input_start_field and (field.port.tag == input_start_field.port.tag) and (field.mask == input_start_field.mask) and (field.type == input_start_field.type) then
- selection = #items
- input_start_field = nil
+ if field then
+ items[#items + 1] = { _p('input-name', field.name), '', '' }
+ if input_start_field and (field.port.tag == input_start_field.port.tag) and (field.mask == input_start_field.mask) and (field.type == input_start_field.type) then
+ selection = #items
+ input_start_field = nil
+ end
+ else
+ local device = input_choices[index + 1].device
+ if device.owner then
+ items[#items + 1] = { string.format(_('plugin-inputmacro', '%s [root%s]'), device.name, device.tag), '', 'heading' }
+ else
+ items[#items + 1] = { string.format(_('plugin-inputmacro', '[root%s]'), device.tag), '', 'heading' }
+ end
end
end
input_start_field = nil
@@ -145,6 +167,7 @@ end
local edit_current_macro
local edit_start_selection
local edit_start_step
+local edit_menu_active
local edit_insert_position
local edit_name_buffer
local edit_items
@@ -379,6 +402,10 @@ local function add_edit_items(items)
items[#items + 1] = { _p('plugin-inputmacro', 'Name'), edit_name_buffer and (edit_name_buffer .. '_') or edit_current_macro.name, '' }
edit_items[#items] = { action = 'name' }
+ if not (edit_start_selection or edit_start_step or edit_menu_active) then
+ edit_start_selection = #items
+ end
+ edit_menu_active = true
local binding = edit_current_macro.binding
local activation = binding and input:seq_name(binding) or _p('plugin-inputmacro', '[not set]')
@@ -453,7 +480,9 @@ local function handle_add(index, event)
if handle_edit_items(index, event) then
return true
elseif event == 'cancel' then
+ input_choices = nil
edit_current_macro = nil
+ edit_menu_active = false
edit_items = nil
table.remove(menu_stack)
return true
@@ -462,6 +491,8 @@ local function handle_add(index, event)
table.insert(macros, edit_current_macro)
macros_start_macro = #macros
end
+ input_choices = nil
+ edit_menu_active = false
edit_current_macro = nil
edit_items = nil
table.remove(menu_stack)
@@ -474,7 +505,9 @@ local function handle_edit(index, event)
if handle_edit_items(index, event) then
return true
elseif (event == 'cancel') or ((index == edit_item_exit) and (event == 'select')) then
+ input_choices = nil
edit_current_macro = nil
+ edit_menu_active = false
edit_items = nil
table.remove(menu_stack)
return true
@@ -500,7 +533,7 @@ local function populate_add()
local selection = edit_start_selection
edit_start_selection = nil
- return items, selection
+ return items, selection, 'lrrepeat'
end
local function populate_edit()
@@ -517,7 +550,7 @@ local function populate_edit()
local selection = edit_start_selection
edit_start_selection = nil
- return items, selection
+ return items, selection, 'lrrepeat'
end
@@ -532,7 +565,6 @@ function handle_macros(index, event)
if event == 'select' then
edit_current_macro = new_macro()
edit_insert_position = #edit_current_macro.steps + 1
- edit_start_selection = 1 -- not actually selectable, but it will take the first item
macros_selection_save = index
table.insert(menu_stack, MENU_TYPES.ADD)
return true
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 9169bdc9f50..e8e246b5efc 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -432,7 +432,7 @@ sol::object lua_engine::call_plugin(const std::string &name, sol::object in)
return sol::lua_nil;
}
-std::optional<long> lua_engine::menu_populate(const std::string &menu, std::vector<std::tuple<std::string, std::string, std::string>> &menu_list)
+std::optional<long> lua_engine::menu_populate(const std::string &menu, std::vector<std::tuple<std::string, std::string, std::string> > &menu_list, std::string &flags)
{
std::string field = "menu_pop_" + menu;
sol::object obj = sol().registry()[field];
@@ -446,7 +446,7 @@ std::optional<long> lua_engine::menu_populate(const std::string &menu, std::vect
}
else
{
- std::tuple<sol::table, std::optional<long> > table = res;
+ std::tuple<sol::table, std::optional<long>, std::string> table = res;
for (auto &entry : std::get<0>(table))
{
if (entry.second.is<sol::table>())
@@ -455,27 +455,31 @@ std::optional<long> lua_engine::menu_populate(const std::string &menu, std::vect
menu_list.emplace_back(enttable.get<std::string, std::string, std::string>(1, 2, 3));
}
}
+ flags = std::get<2>(table);
return std::get<1>(table);
}
}
+ flags.clear();
return std::nullopt;
}
-bool lua_engine::menu_callback(const std::string &menu, int index, const std::string &event)
+std::pair<bool, std::optional<long> > lua_engine::menu_callback(const std::string &menu, int index, const std::string &event)
{
std::string field = "menu_cb_" + menu;
- bool ret = false;
+ std::pair<bool, std::optional<long> > ret(false, std::nullopt);
sol::object obj = sol().registry()[field];
- if(obj.is<sol::protected_function>())
+ if (obj.is<sol::protected_function>())
{
auto res = invoke(obj.as<sol::protected_function>(), index, event);
- if(!res.valid())
+ if (!res.valid())
{
sol::error err = res;
osd_printf_error("[LUA ERROR] in menu_callback: %s\n", err.what());
}
else
+ {
ret = res;
+ }
}
return ret;
}
diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h
index 5b945e864c9..f61baa8c083 100644
--- a/src/frontend/mame/luaengine.h
+++ b/src/frontend/mame/luaengine.h
@@ -48,8 +48,8 @@ public:
bool frame_hook();
- std::optional<long> menu_populate(const std::string &menu, std::vector<std::tuple<std::string, std::string, std::string>> &menu_list);
- bool menu_callback(const std::string &menu, int index, const std::string &event);
+ std::optional<long> menu_populate(const std::string &menu, std::vector<std::tuple<std::string, std::string, std::string> > &menu_list, std::string &flags);
+ std::pair<bool, std::optional<long> > menu_callback(const std::string &menu, int index, const std::string &event);
void set_machine(running_machine *machine);
std::vector<std::string> &get_menu() { return m_menu; }
diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h
index d8fcbcd25ea..958c1e86af8 100644
--- a/src/frontend/mame/ui/menu.h
+++ b/src/frontend/mame/ui/menu.h
@@ -37,7 +37,7 @@ class menu
{
public:
// flags for menu items
- enum : unsigned
+ enum : uint32_t
{
FLAG_LEFT_ARROW = 1U << 0,
FLAG_RIGHT_ARROW = 1U << 1,
diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp
index e065582103b..d706780daae 100644
--- a/src/frontend/mame/ui/pluginopt.cpp
+++ b/src/frontend/mame/ui/pluginopt.cpp
@@ -62,15 +62,17 @@ menu_plugin::~menu_plugin()
{
}
-menu_plugin_opt::menu_plugin_opt(mame_ui_manager &mui, render_container &container, char *menu) :
- ui::menu(mui, container),
- m_menu(menu)
+menu_plugin_opt::menu_plugin_opt(mame_ui_manager &mui, render_container &container, std::string_view menu) :
+ ui::menu(mui, container),
+ m_menu(menu),
+ m_process_flags(0U),
+ m_need_idle(false)
{
}
void menu_plugin_opt::handle()
{
- const event *menu_event = process(0);
+ const event *menu_event = process(m_process_flags);
if (menu_event)
{
@@ -105,9 +107,13 @@ void menu_plugin_opt::handle()
key = std::to_string((u32)menu_event->unichar);
break;
default:
- return;
+ if (!m_need_idle)
+ return;
}
- if (mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(menu_event->itemref), key))
+ auto const result = mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(menu_event->itemref), key);
+ if (result.second)
+ set_selection(reinterpret_cast<void *>(uintptr_t(*result.second)));
+ if (result.first)
reset(reset_options::REMEMBER_REF);
else if (menu_event->iptkey == IPT_UI_CANCEL)
stack_pop();
@@ -117,41 +123,78 @@ void menu_plugin_opt::handle()
void menu_plugin_opt::populate(float &customtop, float &custombottom)
{
std::vector<std::tuple<std::string, std::string, std::string>> menu_list;
- auto const sel = mame_machine_manager::instance()->lua()->menu_populate(m_menu, menu_list);
+ std::string flags;
+ auto const sel = mame_machine_manager::instance()->lua()->menu_populate(m_menu, menu_list, flags);
uintptr_t i = 1;
- for(auto &item : menu_list)
+ for (auto &item : menu_list)
{
- const std::string &text = std::get<0>(item);
- const std::string &subtext = std::get<1>(item);
- const std::string &tflags = std::get<2>(item);
-
- uint32_t flags = 0;
- if (tflags == "off")
- flags = FLAG_DISABLE;
- else if (tflags == "heading")
- flags = FLAG_DISABLE | FLAG_UI_HEADING;
- else if (tflags == "l")
- flags = FLAG_LEFT_ARROW;
- else if (tflags == "r")
- flags = FLAG_RIGHT_ARROW;
- else if (tflags == "lr")
- flags = FLAG_RIGHT_ARROW | FLAG_LEFT_ARROW;
-
- if(text == "---")
+ std::string &text = std::get<0>(item);
+ std::string &subtext = std::get<1>(item);
+ std::string_view tflags = std::get<2>(item);
+
+ uint32_t item_flags_or = uint32_t(0);
+ uint32_t item_flags_and = ~uint32_t(0);
+ auto flag_start = tflags.find_first_not_of(' ');
+ while (std::string_view::npos != flag_start)
{
- item_append(menu_item_type::SEPARATOR);
- i++;
+ tflags.remove_prefix(flag_start);
+ auto const flag_end = tflags.find(' ');
+ auto const flag = tflags.substr(0, flag_end);
+ tflags.remove_prefix(flag.length());
+ flag_start = tflags.find_first_not_of(' ');
+
+ if (flag == "off")
+ item_flags_or |= FLAG_DISABLE;
+ else if (flag == "on")
+ item_flags_and &= ~FLAG_DISABLE;
+ else if (flag == "l")
+ item_flags_or |= FLAG_LEFT_ARROW;
+ else if (flag == "r")
+ item_flags_or |= FLAG_RIGHT_ARROW;
+ else if (flag == "lr")
+ item_flags_or |= FLAG_RIGHT_ARROW | FLAG_LEFT_ARROW;
+ else if (flag == "invert")
+ item_flags_or |= FLAG_INVERT;
+ else if (flag == "heading")
+ item_flags_or |= FLAG_DISABLE | FLAG_UI_HEADING;
}
+
+ if (text == "---")
+ item_append(menu_item_type::SEPARATOR);
else
- {
- item_append(text, subtext, flags, reinterpret_cast<void *>(i++));
- }
+ item_append(std::move(text), std::move(subtext), item_flags_or & item_flags_and, reinterpret_cast<void *>(i));
+ ++i;
}
item_append(menu_item_type::SEPARATOR);
if (sel)
set_selection(reinterpret_cast<void *>(uintptr_t(*sel)));
+
+ m_process_flags = 0U;
+ m_need_idle = false;
+ if (!flags.empty())
+ {
+ std::string_view mflags = flags;
+ auto flag_start = mflags.find_first_not_of(' ');
+ while (std::string_view::npos != flag_start)
+ {
+ mflags.remove_prefix(flag_start);
+ auto const flag_end = mflags.find(' ');
+ auto const flag = mflags.substr(0, flag_end);
+ mflags.remove_prefix(flag.length());
+ flag_start = mflags.find_first_not_of(' ');
+
+ if (flag == "lralways")
+ m_process_flags |= PROCESS_LR_ALWAYS;
+ else if (flag == "lrrepeat")
+ m_process_flags |= PROCESS_LR_REPEAT;
+ else if (flag == "customnav")
+ m_process_flags |= PROCESS_CUSTOM_NAV;
+ else if (flag == "idle")
+ m_need_idle = true;
+ }
+ }
}
menu_plugin_opt::~menu_plugin_opt()
diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h
index da2da131792..c639c3caa15 100644
--- a/src/frontend/mame/ui/pluginopt.h
+++ b/src/frontend/mame/ui/pluginopt.h
@@ -16,6 +16,7 @@
#include "ui/ui.h"
#include <string>
+#include <string_view>
#include <vector>
@@ -40,7 +41,7 @@ private:
class menu_plugin_opt : public menu
{
public:
- menu_plugin_opt(mame_ui_manager &mui, render_container &container, char *menu);
+ menu_plugin_opt(mame_ui_manager &mui, render_container &container, std::string_view menu);
virtual ~menu_plugin_opt();
protected:
@@ -50,7 +51,9 @@ private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
- std::string m_menu;
+ std::string const m_menu;
+ uint32_t m_process_flags;
+ bool m_need_idle;
};
} // namespace ui