diff options
author | 2021-10-21 04:11:43 +1100 | |
---|---|---|
committer | 2021-10-21 04:11:43 +1100 | |
commit | b1c764415931c9700552cd456bfeb20fe41ba622 (patch) | |
tree | 83484512a26252374612f51d1683ced38b5e5770 /plugins/inputmacro/inputmacro_persist.lua | |
parent | d42a9fd87e737c0526d35624163f110b290c6d79 (diff) |
-plugins: Added an input macro plugin.
-plugins: Sort input selection menus for autofire plugin.
-frontend: Fixed another case where the menus may not automatically
scroll the first item into view.
Diffstat (limited to 'plugins/inputmacro/inputmacro_persist.lua')
-rw-r--r-- | plugins/inputmacro/inputmacro_persist.lua | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/plugins/inputmacro/inputmacro_persist.lua b/plugins/inputmacro/inputmacro_persist.lua new file mode 100644 index 00000000000..04d310faeef --- /dev/null +++ b/plugins/inputmacro/inputmacro_persist.lua @@ -0,0 +1,145 @@ +-- Helpers + +local function settings_path() + return emu.subst_env(manager.machine.options.entries.homepath:value():match('([^;]+)')) .. '/inputmacro/' +end + +local function settings_filename() + return emu.romname() .. '.cfg' +end + +local function make_macro(setting) + if (setting.name == nil) or (setting.binding == nil) or (setting.earlycancel == nil) or (setting.loop == nil) or (setting.steps == nil) then + return nil + end + + local result = { + name = setting.name, + binding = manager.machine.input:seq_from_tokens(setting.binding), + earlycancel = setting.earlycancel, + loop = setting.loop, + steps = { } } + + local ioport = manager.machine.ioport + for i, step in ipairs(setting.steps) do + if step.inputs and step.delay and step.duration then + local s = { + inputs = { }, + delay = step.delay, + duration = step.duration } + for j, input in ipairs(step.inputs) do + if input.port and input.mask and input.type then + local port = ioport.ports[input.port] + if port then + local field = port:field(input.mask) + if field and (field.type == ioport:token_to_input_type(input.type)) then + table.insert(s.inputs, { port = port, field = field }) + end + end + end + end + if #s.inputs > 0 then + table.insert(result.steps, s) + end + end + end + + if result.loop > #result.steps then + result.loop = -1 + end + + if #result.steps > 0 then + return result + else + return nil + end +end + +local function make_settings(macros) + local input = manager.machine.input + local ioport = manager.machine.ioport + local result = { } + for i, macro in ipairs(macros) do + local m = { + name = macro.name, + binding = input:seq_to_tokens(macro.binding), + earlycancel = macro.earlycancel, + loop = macro.loop, + steps = { } } + table.insert(result, m) + for j, step in ipairs(macro.steps) do + local s = { + inputs = { }, + delay = step.delay, + duration = step.duration } + table.insert(m.steps, s) + for k, input in ipairs(step.inputs) do + local b = { + port = input.port.tag, + mask = input.field.mask, + type = ioport:input_type_to_token(input.field.type) } + table.insert(s.inputs, b) + end + end + end + return result +end + + +-- Entry points + +local lib = { } + +function lib:load_settings() + filename = settings_path() .. settings_filename() + local file = io.open(filename, 'r') + if not file then + return { } + end + local json = require('json') + local settings = json.parse(file:read('a')) + file:close() + if not settings then + emu.print_error(string.format('Error loading input macros: error parsing file "%s" as JSON\n', filename)) + return { } + end + + result = { } + for index, setting in ipairs(settings) do + local macro = make_macro(setting) + if macro then + table.insert(result, macro) + end + end + return result +end + +function lib:save_settings(macros) + local path = settings_path() + local stat = lfs.attributes(path) + if not stat then + lfs.mkdir(path) + elseif stat.mode ~= 'directory' then + emu.print_error(string.format('Error saving input macros: "%s" is not a directory\n', path)) + return + end + filename = path .. settings_filename() + + if #macros == 0 then + os.remove(filename) + return + end + + local json = require('json') + local settings = make_settings(macros) + local text = json.stringify(settings, { indent = true }) + local file = io.open(filename, 'w') + if not file then + emu.print_error(string.format('Error saving input macros: error opening file "%s" for writing\n', filename)) + return + end + file:write(text) + file:close() +end + +return lib |