419 lines
11 KiB
Lua
419 lines
11 KiB
Lua
-- license:BSD-3-Clause
|
|
-- copyright-holders:Vas Crabb
|
|
|
|
|
|
-- Constants
|
|
|
|
local MENU_TYPES = { HELPERS = 0, ADD = 1, EDIT = 2, INPUT = 3 }
|
|
|
|
|
|
-- Globals
|
|
|
|
local commonui
|
|
local helpers
|
|
local menu_stack
|
|
|
|
local helpers_start_helper -- really for the helpers menu, but have to be declared local before edit menu functions
|
|
local helpers_item_first_helper
|
|
local helpers_selection_save
|
|
|
|
|
|
-- Helpers
|
|
|
|
local function new_helper()
|
|
return {
|
|
binding = nil,
|
|
bindingcfg = '',
|
|
axis = { port = nil, mask = nil, type = nil, field = nil },
|
|
button = { port = nil, mask = nil, type = nil, field = nil } }
|
|
end
|
|
|
|
local function input_display_name(input)
|
|
if input.field then
|
|
return input.field.name
|
|
elseif input.port then
|
|
return _p('plugin-offscreenreload', 'n/a')
|
|
else
|
|
return _p('plugin-offscreenreload', '[not set]')
|
|
end
|
|
end
|
|
|
|
|
|
-- Input menu
|
|
|
|
local input_menu
|
|
local input_start_field
|
|
|
|
local function start_input_menu(handler, title, filter, start_field)
|
|
local function action(field)
|
|
if field then
|
|
handler(field)
|
|
end
|
|
table.remove(menu_stack)
|
|
input_menu = nil
|
|
input_start_field = nil
|
|
end
|
|
|
|
if not commonui then
|
|
commonui = require('commonui')
|
|
end
|
|
input_menu = commonui.input_selection_menu(action, title, filter)
|
|
input_start_field = start_field
|
|
table.insert(menu_stack, MENU_TYPES.INPUT)
|
|
end
|
|
|
|
local function handle_input(index, action)
|
|
return input_menu:handle(index, action)
|
|
end
|
|
|
|
local function populate_input()
|
|
return input_menu:populate(input_start_field)
|
|
end
|
|
|
|
|
|
-- Add/edit menus
|
|
|
|
local edit_current_helper
|
|
local edit_start_selection
|
|
local edit_menu_active
|
|
local edit_items
|
|
local edit_item_delete
|
|
local edit_item_exit
|
|
local edit_switch_poller
|
|
|
|
local function current_helper_complete()
|
|
if not edit_current_helper.binding then
|
|
return false
|
|
end
|
|
if not edit_current_helper.axis.field then
|
|
return false
|
|
end
|
|
if not edit_current_helper.button.field then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function handle_edit_items(index, event)
|
|
if edit_switch_poller then
|
|
if edit_switch_poller:poll() then
|
|
if edit_switch_poller.sequence then
|
|
edit_current_helper.binding = edit_switch_poller.sequence
|
|
edit_current_helper.bindingcfg = manager.machine.input:seq_to_tokens(edit_switch_poller.sequence)
|
|
end
|
|
edit_switch_poller = nil
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local command = edit_items[index]
|
|
|
|
if (event ~= 'select') or (not command) then
|
|
return false
|
|
elseif command.action == 'binding' then
|
|
if not commonui then
|
|
commonui = require('commonui')
|
|
end
|
|
edit_switch_poller = commonui.switch_polling_helper()
|
|
return true
|
|
elseif command.action == 'axis' then
|
|
local function handler(field)
|
|
local device = field.device.tag
|
|
local player = field.player
|
|
local guessbutton = false
|
|
if (not edit_current_helper.axis) or (not edit_current_helper.axis.field) then
|
|
guessbutton = true
|
|
elseif (edit_current_helper.axis.field.device.tag ~= field) or (edit_current_helper.axis.field.player ~= player) then
|
|
guessbutton = true
|
|
end
|
|
|
|
edit_current_helper.axis.port = field.port.tag
|
|
edit_current_helper.axis.mask = field.mask
|
|
edit_current_helper.axis.type = field.type
|
|
edit_current_helper.axis.field = field
|
|
|
|
if guessbutton then
|
|
local ioport = manager.machine.ioport
|
|
local b1type = ioport:token_to_input_type('P1_BUTTON1')
|
|
local done = false
|
|
for i, port in pairs(ioport.ports) do
|
|
if port.device.tag == device then
|
|
for j, f in pairs(port.fields) do
|
|
if (f.player == player) and (f.type == b1type) then
|
|
edit_current_helper.button.port = f.port.tag
|
|
edit_current_helper.button.mask = f.mask
|
|
edit_current_helper.button.type = f.type
|
|
edit_current_helper.button.field = f
|
|
done = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if done then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local function filter(field)
|
|
if (not field.is_analog) or field.analog_wraps then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
start_input_menu(handler, _p('plugin-offscreenreload', 'Set Axis'), filter, edit_current_helper.axis.field)
|
|
edit_start_selection = index
|
|
return true
|
|
elseif command.action == 'button' then
|
|
local function handler(field)
|
|
edit_current_helper.button.port = field.port.tag
|
|
edit_current_helper.button.mask = field.mask
|
|
edit_current_helper.button.type = field.type
|
|
edit_current_helper.button.field = field
|
|
end
|
|
local function filter(field)
|
|
if field.is_analog or field.is_toggle then
|
|
return false
|
|
elseif (field.type_class == 'config') or (field.type_class == 'dipswitch') then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
start_input_menu(handler, _p('plugin-offscreenreload', 'Set Trigger'), filter, edit_current_helper.axis.button)
|
|
edit_start_selection = index
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function add_edit_items(items)
|
|
edit_items = { }
|
|
local input = manager.machine.input
|
|
|
|
local binding = edit_current_helper.binding
|
|
local activation = binding and input:seq_name(binding) or _p('plugin-offscreenreload', '[not set]')
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Reload combination'), activation, edit_switch_poller and 'lr' or '' })
|
|
edit_items[#items] = { action = 'binding' }
|
|
if not (edit_start_selection or edit_menu_active) then
|
|
edit_start_selection = #items
|
|
end
|
|
edit_menu_active = true
|
|
|
|
local axisname = input_display_name(edit_current_helper.axis)
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Axis input'), axisname, '' })
|
|
edit_items[#items] = { action = 'axis' }
|
|
|
|
local buttonname = input_display_name(edit_current_helper.button)
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Trigger input'), buttonname, '' })
|
|
edit_items[#items] = { action = 'button' }
|
|
end
|
|
|
|
local function handle_add(index, event)
|
|
local handled, selection = handle_edit_items(index, event)
|
|
if handled then
|
|
return true, selection
|
|
elseif event == 'back' then
|
|
edit_current_helper = nil
|
|
edit_menu_active = false
|
|
edit_items = nil
|
|
table.remove(menu_stack)
|
|
return true, selection
|
|
elseif (index == edit_item_exit) and (event == 'select') then
|
|
if current_helper_complete() then
|
|
table.insert(helpers, edit_current_helper)
|
|
helpers_start_helper = #helpers
|
|
end
|
|
edit_current_helper = nil
|
|
edit_menu_active = false
|
|
edit_items = nil
|
|
table.remove(menu_stack)
|
|
return true, selection
|
|
end
|
|
return false, selection
|
|
end
|
|
|
|
local function handle_edit(index, event)
|
|
local handled, selection = handle_edit_items(index, event)
|
|
if handled then
|
|
return true, selection
|
|
elseif (index == edit_item_delete) and (event == 'select') then
|
|
local helper = helpers_selection_save - helpers_item_first_helper + 1
|
|
table.remove(helpers, helper)
|
|
if helper > #helpers then
|
|
helpers_selection_save = helpers_selection_save - 1
|
|
end
|
|
edit_current_macro = nil
|
|
edit_menu_active = false
|
|
edit_items = nil
|
|
table.remove(menu_stack)
|
|
return true, selection
|
|
elseif (event == 'back') or ((index == edit_item_exit) and (event == 'select')) then
|
|
edit_current_helper = nil
|
|
edit_menu_active = false
|
|
edit_items = nil
|
|
table.remove(menu_stack)
|
|
return true, selection
|
|
end
|
|
return false, selection
|
|
end
|
|
|
|
local function populate_add()
|
|
local items = { }
|
|
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Add Reload Helper'), '', 'off' })
|
|
table.insert(items, { '---', '', '' })
|
|
|
|
add_edit_items(items)
|
|
|
|
table.insert(items, { '---', '', '' })
|
|
if current_helper_complete() then
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Create'), '', '' })
|
|
else
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Cancel'), '', '' })
|
|
end
|
|
edit_item_exit = #items
|
|
|
|
local selection = edit_start_selection
|
|
edit_start_selection = nil
|
|
if edit_switch_poller then
|
|
return edit_switch_poller:overlay(items, selection, '')
|
|
else
|
|
return items, selection, 'lrrepeat'
|
|
end
|
|
end
|
|
|
|
local function populate_edit()
|
|
local items = { }
|
|
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Edit Reload Helper'), '', 'off' })
|
|
table.insert(items, { '---', '', '' })
|
|
|
|
add_edit_items(items)
|
|
|
|
table.insert(items, { '---', '', '' })
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Delete reload helper'), '', '' })
|
|
edit_item_delete = #items
|
|
|
|
table.insert(items, { '---', '', '' })
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Done'), '', '' })
|
|
edit_item_exit = #items
|
|
|
|
local selection = edit_start_selection
|
|
edit_start_selection = nil
|
|
if edit_switch_poller then
|
|
return edit_switch_poller:overlay(items, selection, 'lrrepeat')
|
|
else
|
|
return items, selection, 'lrrepeat'
|
|
end
|
|
end
|
|
|
|
|
|
-- Helpers menu
|
|
|
|
local helpers_item_add
|
|
|
|
function handle_helpers(index, event)
|
|
if index == helpers_item_add then
|
|
if event == 'select' then
|
|
edit_current_helper = new_helper()
|
|
helpers_selection_save = index
|
|
table.insert(menu_stack, MENU_TYPES.ADD)
|
|
return true
|
|
end
|
|
elseif index >= helpers_item_first_helper then
|
|
local helper = index - helpers_item_first_helper + 1
|
|
if event == 'select' then
|
|
edit_current_helper = helpers[helper]
|
|
helpers_selection_save = index
|
|
table.insert(menu_stack, MENU_TYPES.EDIT)
|
|
return true
|
|
elseif event == 'clear' then
|
|
table.remove(helpers, helper)
|
|
if #helpers > 0 then
|
|
helpers_selection_save = index
|
|
if helper > #helpers then
|
|
helpers_selection_save = helpers_selection_save - 1
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function populate_helpers()
|
|
local input = manager.machine.input
|
|
local ioport = manager.machine.ioport
|
|
local items = { }
|
|
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Off-Screen Reload Helper'), '', 'off' })
|
|
table.insert(items, { string.format(_p('plugin-offscreenreload', 'Press %s to delete'), manager.ui:get_general_input_setting(ioport:token_to_input_type('UI_CLEAR'))), '', 'off' })
|
|
table.insert(items, { '---', '', '' })
|
|
|
|
helpers_item_first_helper = #items + 1
|
|
if #helpers > 0 then
|
|
for index, helper in ipairs(helpers) do
|
|
local bindingname = input:seq_name(helper.binding)
|
|
local axisname = input_display_name(helper.axis)
|
|
local buttonname = input_display_name(helper.button)
|
|
table.insert(items, { string.format(_p('plugin-offscreenreload', '%s/%s'), axisname, buttonname), bindingname, '' })
|
|
if helpers_start_helper == index then
|
|
helpers_selection_save = #items
|
|
end
|
|
end
|
|
else
|
|
table.insert(items, { _p('plugin-offscreenreload', '[no reload helpers]'), '', 'off' })
|
|
end
|
|
helpers_start_helper = nil
|
|
|
|
table.insert(items, { '---', '', '' })
|
|
table.insert(items, { _p('plugin-offscreenreload', 'Add reload helper'), '', '' })
|
|
helpers_item_add = #items
|
|
|
|
local selection = helpers_selection_save
|
|
helpers_selection_save = nil
|
|
return items, selection
|
|
end
|
|
|
|
|
|
-- Entry points
|
|
|
|
local lib = { }
|
|
|
|
function lib:init(h)
|
|
helpers = h
|
|
menu_stack = { MENU_TYPES.HELPERS }
|
|
end
|
|
|
|
function lib:handle_event(index, event)
|
|
local current = menu_stack[#menu_stack]
|
|
if current == MENU_TYPES.HELPERS then
|
|
return handle_helpers(index, event)
|
|
elseif current == MENU_TYPES.ADD then
|
|
return handle_add(index, event)
|
|
elseif current == MENU_TYPES.EDIT then
|
|
return handle_edit(index, event)
|
|
elseif current == MENU_TYPES.INPUT then
|
|
return handle_input(index, event)
|
|
end
|
|
end
|
|
|
|
function lib:populate()
|
|
local current = menu_stack[#menu_stack]
|
|
if current == MENU_TYPES.HELPERS then
|
|
return populate_helpers()
|
|
elseif current == MENU_TYPES.ADD then
|
|
return populate_add()
|
|
elseif current == MENU_TYPES.EDIT then
|
|
return populate_edit()
|
|
elseif current == MENU_TYPES.INPUT then
|
|
return populate_input()
|
|
end
|
|
end
|
|
|
|
return lib
|