-- license:BSD-3-Clause -- copyright-holders:Jack Li local exports = {} exports.name = 'autofire' exports.version = '0.0.3' exports.description = 'Autofire plugin' exports.license = 'The BSD 3-Clause License' exports.author = { name = 'Jack Li' } local autofire = exports 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 -- '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 function process_frame() -- 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 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] 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) end end local function save_settings() local saver = require('autofire/autofire_save') if saver then saver:save_settings(buttons) end 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 return false end end local function menu_populate() local menu_handler = require('autofire/autofire_menu') if menu_handler then return menu_handler:populate_menu(buttons) else return {{_('Failed to load autofire menu'), '', ''}} end end emu.register_frame_done(process_frame) emu.register_start(load_settings) emu.register_stop(save_settings) emu.register_menu(menu_callback, menu_populate, _('Autofire')) end return exports