mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
07e55935cf
Added emulated time recording as well as wall clock time. Fixed recording time for multiple software items per system. An incorrect constraint on the database table meant that time was only being recorded for a single software item per system. Detect the "empty" driver so the time spent at the selection menu isn't recorded (you'd get multiple entries for this due to the way options leak when returning to the system selection menu). Included schema migration code to update existing timer plugin databases. Also replaced some unnecessary floating point code with integer maths, added log messages, and made the plugin unload unload its database access code during emulation. Changed other plugins' use of paths with trailing slashes as this causes stat to fail on Windows.
155 lines
3.6 KiB
Lua
155 lines
3.6 KiB
Lua
-- license:BSD-3-Clause
|
|
-- copyright-holders:Vas Crabb
|
|
|
|
|
|
-- 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),
|
|
bindingcfg = 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 ipt = {
|
|
port = input.port,
|
|
mask = input.mask,
|
|
type = ioport:token_to_input_type(input.type) }
|
|
local port = ioport.ports[input.port]
|
|
if port then
|
|
local field = port:field(input.mask)
|
|
if field and (field.type == ipt.type) then
|
|
ipt.field = field
|
|
end
|
|
end
|
|
table.insert(s.inputs, ipt)
|
|
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 = macro.bindingcfg,
|
|
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,
|
|
mask = input.mask,
|
|
type = ioport:input_type_to_token(input.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', 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', 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', filename))
|
|
return
|
|
end
|
|
file:write(text)
|
|
file:close()
|
|
end
|
|
|
|
return lib
|