plugins: Simplify logic in autofire and inputmacro plugins to try and avoid leaking state across sessions.

This commit is contained in:
Vas Crabb 2021-11-04 09:55:26 +11:00
parent e44d51c21f
commit 8c6cb643e3
4 changed files with 52 additions and 64 deletions

View File

@ -62,7 +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
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
@ -169,7 +169,7 @@ local function handle_configure_menu(index, event)
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
if current_button.port and current_button.button then
initial_input = current_button.button
end
return true
@ -298,7 +298,8 @@ local function populate_button_menu()
local function action(field)
if field then
current_button.port = field.port.tag
current_button.field = field.name
current_button.mask = field.mask
current_button.type = field.type
current_button.button = field
end
initial_input = nil

View File

@ -10,19 +10,20 @@ end
local function initialize_button(settings)
if settings.port and settings.mask and settings.type and settings.key and settings.on_frames and settings.off_frames then
local ioport = manager.machine.ioport
local new_button = {
port = settings.port,
mask = settings.mask,
type = ioport:token_to_input_type(settings.type),
key = manager.machine.input:seq_from_tokens(settings.key),
on_frames = settings.on_frames,
off_frames = settings.off_frames,
counter = 0
}
local ioport = manager.machine.ioport
local port = ioport.ports[settings.port]
if port then
local field = port:field(settings.mask)
if field and (field.type == ioport:token_to_input_type(settings.type)) then
new_button.field = field.name
if field and (field.type == new_button.type) then
new_button.button = field
return new_button
end

View File

@ -13,69 +13,50 @@ function autofire.startplugin()
-- List of autofire buttons, each being a table with keys:
-- 'port' - port name of the button being autofired
-- 'field' - field name of the button being autofired
-- 'key' - input_code of the keybinding
-- 'mask' - mask of the button field being autofired
-- 'type' - input type of the button being autofired
-- 'key' - input_seq of the keybinding
-- 'on_frames' - number of frames button is pressed
-- 'off_frames' - number of frames button is released
-- 'button' - reference to ioport_field
-- 'counter' - position in autofire cycle
local buttons = {}
local current_rom = nil
local function process_button(button)
local pressed = manager.machine.input:seq_pressed(button.key)
if pressed then
local state = button.counter < button.on_frames and 1 or 0
button.counter = (button.counter + 1) % (button.on_frames + button.off_frames)
return state
else
button.counter = 0
return 0
end
end
local function button_states_key(button)
return button.port .. '\0' .. button.field
end
local menu_handler
local function process_frame()
local input = manager.machine.input
local function process_button(button)
local pressed = input:seq_pressed(button.key)
if pressed then
local state = button.counter < button.on_frames and 1 or 0
button.counter = (button.counter + 1) % (button.on_frames + button.off_frames)
return state
else
button.counter = 0
return 0
end
end
-- Resolves conflicts between multiple autofire keybindings for the same button.
local button_states = {}
for i, button in ipairs(buttons) do
local state = button_states[button_states_key(button)]
if not state then
state = 0
end
state = process_button(button) | state
button_states[button_states_key(button)] = state
local key = button.port .. '\0' .. button.mask .. '.' .. button.type
local state = button_states[key] or { 0, button.button }
state[1] = process_button(button) | state[1]
button_states[key] = state
end
for i, button in ipairs(buttons) do
button.button:set_value(button_states[button_states_key(button)])
end
end
local function reinit_buttons()
for i, button in ipairs(buttons) do
button.counter = 0
button.button = manager.machine.ioport.ports[button.port].fields[button.field]
for i, state in pairs(button_states) do
state[2]:set_value(state[1])
end
end
local function load_settings()
if current_rom == emu.romname() then
reinit_buttons()
else
local loader = require('autofire/autofire_save')
if loader then
buttons = loader:load_settings()
end
end
current_rom = emu.romname()
local menu_handler = require('autofire/autofire_menu')
if menu_handler then
menu_handler:init_menu(buttons)
local loader = require('autofire/autofire_save')
if loader then
buttons = loader:load_settings()
end
end
@ -84,10 +65,12 @@ function autofire.startplugin()
if saver then
saver:save_settings(buttons)
end
menu_handler = nil
buttons = {}
end
local function menu_callback(index, event)
local menu_handler = require('autofire/autofire_menu')
if menu_handler then
return menu_handler:handle_menu_event(index, event, buttons)
else
@ -96,7 +79,12 @@ function autofire.startplugin()
end
local function menu_populate()
local menu_handler = require('autofire/autofire_menu')
if not menu_handler then
menu_handler = require('autofire/autofire_menu')
if menu_handler then
menu_handler:init_menu(buttons)
end
end
if menu_handler then
return menu_handler:populate_menu(buttons)
else
@ -104,8 +92,8 @@ function autofire.startplugin()
end
end
emu.register_frame_done(process_frame)
emu.register_start(load_settings)
emu.register_frame(process_frame)
emu.register_prestart(load_settings)
emu.register_stop(save_settings)
emu.register_menu(menu_callback, menu_populate, _p('plugin-autofire', 'Autofire'))
end

View File

@ -30,7 +30,6 @@ function inputmacro.startplugin()
]]
local macros = { }
local active_inputs = { }
local shortname
local menu
local input
@ -99,12 +98,11 @@ function inputmacro.startplugin()
end
local function start()
menu = nil
active_inputs = { }
input = manager.machine.input
if shortname ~= emu.romname() then
local persister = require('inputmacro/inputmacro_persist')
macros = persister.load_settings()
shortname = emu.romname()
end
local persister = require('inputmacro/inputmacro_persist')
macros = persister.load_settings()
end
local function stop()
@ -124,8 +122,8 @@ function inputmacro.startplugin()
return menu:populate()
end
emu.register_frame_done(process_frame)
emu.register_start(start)
emu.register_frame(process_frame)
emu.register_prestart(start)
emu.register_stop(stop)
emu.register_menu(menu_callback, menu_populate, _p('plugin-inputmacro', 'Input Macros'))
end