summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/autofire/autofire_menu.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/autofire/autofire_menu.lua')
-rw-r--r--plugins/autofire/autofire_menu.lua266
1 files changed, 102 insertions, 164 deletions
diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua
index 18000bfbd99..c53dd711f53 100644
--- a/plugins/autofire/autofire_menu.lua
+++ b/plugins/autofire/autofire_menu.lua
@@ -1,5 +1,8 @@
local lib = {}
+-- Common UI helper library
+local commonui
+
-- Set of all menus
local MENU_TYPES = { MAIN = 0, EDIT = 1, ADD = 2, BUTTON = 3 }
@@ -27,14 +30,17 @@ local configure_menu_active = false
-- Saved selection on configure menu (to restore after button menu is dismissed)
local configure_selection_save
+-- Helper for polling for hotkeys
+local hotkey_poller
+
-- 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
+-- Handler for BUTTON menu
+local input_menu
-- Returns the section (from MENU_SECTIONS) and the index within that section
local function menu_section(index)
@@ -56,12 +62,7 @@ local function create_new_button()
end
local function is_button_complete(button)
- return button.port and button.field and button.key and button.on_frames and button.off_frames and button.button and button.counter
-end
-
-local function is_supported_input(ioport_field)
- -- IPT_BUTTON1 through IPT_BUTTON16 in ioport_type enum (ioport.h)
- return ioport_field.type >= 64 and ioport_field.type <= 79
+ return button.port and button.mask and button.type and button.key and button.on_frames and button.off_frames and button.button and button.counter
end
-- Main menu
@@ -70,9 +71,9 @@ local function populate_main_menu(buttons)
local ioport = manager.machine.ioport
local input = manager.machine.input
local menu = {}
- menu[#menu + 1] = {_('Autofire buttons'), '', 'off'}
- menu[#menu + 1] = {string.format(_('Press %s to delete'), input:seq_name(ioport:type_seq(ioport:token_to_input_type('UI_CLEAR')))), '', 'off'}
- menu[#menu + 1] = {'---', '', ''}
+ table.insert(menu, {_p('plugin-autofire', 'Autofire buttons'), '', 'off'})
+ table.insert(menu, {string.format(_p('plugin-autofire', 'Press %s to delete'), manager.ui:get_general_input_setting(ioport:token_to_input_type('UI_CLEAR'))), '', 'off'})
+ table.insert(menu, {'---', '', ''})
header_height = #menu
-- Use frame rate of first screen or 60Hz if no screens
@@ -82,22 +83,30 @@ local function populate_main_menu(buttons)
freq = 1 / screen.frame_period
end
- for index, button in ipairs(buttons) do
- -- 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 [%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
+ if #buttons > 0 then
+ for index, button in ipairs(buttons) do
+ -- Round rate to two decimal places
+ local rate = freq / (button.on_frames + button.off_frames)
+ rate = math.floor(rate * 100) / 100
+ local text
+ if button.button then
+ text = string.format(_p('plugin-autofire', '%s [%g Hz]'), button.button.name, rate)
+ else
+ text = string.format(_p('plugin-autofire', 'n/a [%g Hz]'), rate)
+ end
+ table.insert(menu, {text, input:seq_name(button.key), ''})
+ if index == initial_button then
+ main_selection_save = #menu
+ end
end
+ else
+ table.insert(menu, {_p('plugin-autofire', '[no autofire buttons]'), '', 'off'})
end
initial_button = nil
content_height = #menu
- menu[#menu + 1] = {'---', '', ''}
- menu[#menu + 1] = {_('Add autofire button'), '', ''}
+ table.insert(menu, {'---', '', ''})
+ table.insert(menu, {_p('plugin-autofire', 'Add autofire button'), '', ''})
local selection = main_selection_save
main_selection_save = nil
@@ -134,67 +143,61 @@ end
-- Add/edit menus (mostly identical)
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, ''}
+ local button_name
+ if current_button.button then
+ button_name = current_button.button.name
+ elseif current_button.port then
+ button_name = _p('plugin-autofire', 'n/a')
+ else
+ button_name = _p('plugin-autofire', '[not set]')
+ end
+ local key_name = current_button.key and manager.machine.input:seq_name(current_button.key) or _p('plugin-autofire', '[not set]')
+ table.insert(menu, {_p('plugin-autofire', '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'}
+ table.insert(menu, {_p('plugin-autofire', 'Hotkey'), key_name, hotkey_poller and 'lr' or ''})
+ table.insert(menu, {_p('plugin-autofire', 'On frames'), tostring(current_button.on_frames), current_button.on_frames > 1 and 'lr' or 'r'})
+ table.insert(menu, {_p('plugin-autofire', 'Off frames'), tostring(current_button.off_frames), current_button.off_frames > 1 and 'lr' or 'r'})
configure_menu_active = true
end
--- Borrowed from the cheat plugin
-local function poll_for_hotkey()
- local input = manager.machine.input
- local poller = input:switch_sequence_poller()
- manager.machine:popmessage(_('Press button for hotkey or wait to leave unchanged'))
- manager.machine.video:frame_update()
- poller:start()
- local time = os.clock()
- local clearmsg = true
- while (not poller:poll()) and (poller.modified or (os.clock() < time + 1)) do
- if poller.modified then
- if not poller.valid then
- manager.machine:popmessage(_('Invalid sequence entered'))
- clearmsg = false
- break
+local function handle_configure_menu(index, event)
+ if hotkey_poller then
+ -- special handling for polling for hotkey
+ if hotkey_poller:poll() then
+ if hotkey_poller.sequence then
+ current_button.key = hotkey_poller.sequence
+ current_button.key_cfg = manager.machine.input:seq_to_tokens(hotkey_poller.sequence)
end
- manager.machine:popmessage(input:seq_name(poller.sequence))
- manager.machine.video:frame_update()
+ hotkey_poller = nil
+ return true
end
+ return false
end
- if clearmsg then
- manager.machine:popmessage()
- end
- return poller.valid and poller.sequence or nil
-end
-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}
+ if current_button.port and current_button.button then
+ initial_input = current_button.button
end
return true
end
elseif index == 2 then
-- Hotkey
if event == 'select' then
- local keycode = poll_for_hotkey()
- if keycode then
- current_button.key = keycode
- return true
+ if not commonui then
+ commonui = require('commonui')
end
+ hotkey_poller = commonui.switch_polling_helper()
+ return true
end
elseif index == 3 then
-- On frames
- manager.machine:popmessage(_('Number of frames button will be pressed'))
+ manager.machine:popmessage(_p('plugin-autofire', 'Number of frames button will be pressed'))
if event == 'left' then
current_button.on_frames = current_button.on_frames - 1
return true
@@ -207,7 +210,7 @@ local function handle_configure_menu(index, event)
end
elseif index == 4 then
-- Off frames
- manager.machine:popmessage(_('Number of frames button will be released'))
+ manager.machine:popmessage(_p('plugin-autofire', 'Number of frames button will be released'))
if event == 'left' then
current_button.off_frames = current_button.off_frames - 1
return true
@@ -224,25 +227,28 @@ end
local function populate_edit_menu()
local menu = {}
- menu[#menu + 1] = {_('Edit autofire button'), '', 'off'}
- menu[#menu + 1] = {'---', '', ''}
+ table.insert(menu, {_p('plugin-autofire', 'Edit autofire button'), '', 'off'})
+ table.insert(menu, {'---', '', ''})
header_height = #menu
populate_configure_menu(menu)
content_height = #menu
- menu[#menu + 1] = {'---', '', ''}
- menu[#menu + 1] = {_('Done'), '', ''}
+ table.insert(menu, {'---', '', ''})
+ table.insert(menu, {_p('plugin-autofire', 'Done'), '', ''})
local selection = configure_selection_save
configure_selection_save = nil
- return menu, selection, 'lrrepeat'
+ if hotkey_poller then
+ return hotkey_poller:overlay(menu, selection, 'lrrepeat')
+ else
+ return menu, selection, 'lrrepeat'
+ end
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
+ if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then
configure_menu_active = false
table.remove(menu_stack)
return true
@@ -254,29 +260,32 @@ end
local function populate_add_menu()
local menu = {}
- menu[#menu + 1] = {_('Add autofire button'), '', 'off'}
- menu[#menu + 1] = {'---', '', ''}
+ table.insert(menu, {_p('plugin-autofire', 'Add autofire button'), '', 'off'})
+ table.insert(menu, {'---', '', ''})
header_height = #menu
populate_configure_menu(menu)
content_height = #menu
- menu[#menu + 1] = {'---', '', ''}
+ table.insert(menu, {'---', '', ''})
if is_button_complete(current_button) then
- menu[#menu + 1] = {_('Create'), '', ''}
+ table.insert(menu, {_p('plugin-autofire', 'Create'), '', ''})
else
- menu[#menu + 1] = {_('Cancel'), '', ''}
+ table.insert(menu, {_p('plugin-autofire', 'Cancel'), '', ''})
end
local selection = configure_selection_save
configure_selection_save = nil
- return menu, selection, 'lrrepeat'
+ if hotkey_poller then
+ return hotkey_poller:overlay(menu, selection, 'lrrepeat')
+ else
+ return menu, selection, 'lrrepeat'
+ end
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
+ if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then
configure_menu_active = false
table.remove(menu_stack)
if is_button_complete(current_button) and (event == 'select') then
@@ -293,103 +302,32 @@ end
-- Button selection menu
local function populate_button_menu()
- local ioport = manager.machine.ioport
- menu = {}
- menu[#menu + 1] = {_('Select an input for autofire'), '', 'off'}
- menu[#menu + 1] = {'---', '', ''}
- header_height = #menu
-
- 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
-
- 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
- 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
+ local function is_supported_input(ioport_field)
+ -- IPT_BUTTON1 through IPT_BUTTON16 in ioport_type enum (ioport.h)
+ return ioport_field.type >= 64 and ioport_field.type <= 79
end
- 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
+ local function action(field)
+ if field then
+ current_button.port = field.port.tag
+ current_button.mask = field.mask
+ current_button.type = field.type
+ current_button.button = field
end
+ initial_input = nil
+ input_menu = nil
+ table.remove(menu_stack)
end
- content_height = #menu
- initial_input = nil
-
- menu[#menu + 1] = {'---', '', ''}
- menu[#menu + 1] = {_('Cancel'), '', ''}
- return menu, selection
+ if not commonui then
+ commonui = require('commonui')
+ end
+ input_menu = commonui.input_selection_menu(action, _p('plugin-autofire', 'Select an input for autofire'), is_supported_input)
+ return input_menu:populate(initial_input)
end
local function handle_button_menu(index, event)
- local section, adjusted_index = menu_section(index)
- if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'cancel') then
- table.remove(menu_stack)
- return true
- elseif (section == MENU_SECTIONS.CONTENT) and (event == 'select') then
- local selected_input = inputs[adjusted_index]
- current_button.port = selected_input.port_name
- current_button.field = selected_input.field_name
- current_button.button = selected_input.ioport_field
- table.remove(menu_stack)
- return true
- end
- return false
+ return input_menu:handle(index, event)
end
function lib:init_menu(buttons)
@@ -397,7 +335,7 @@ function lib:init_menu(buttons)
content_height = 0
menu_stack = { MENU_TYPES.MAIN }
current_button = {}
- inputs = nil
+ input_menu = nil
end
function lib:populate_menu(buttons)