Added my converted ButtonCount.lua script (Original here: http://code.google.com/p/brandon-evans-tas/source/browse/Lua/ButtonCount.lua)
-As you'll recall, the script has 3 methods of keeping track of input: --1. Tracking the button counts in real time. This took some minor adjustments, but seems to work fine. --2. Parsing the button presses from a loaded, read-only TAS file when starting the script, if possible. ---This works well enough after a good amount of refactoring, but I only have it rigged to work for NES. ---As always, note that this method is very slow for big movies, which is why we only use it once. --3. Caching the counts when saving a state and loading them when loading a state. ---savestate.registerload and savestate.registersave are not currently supported by BizHawk, so this is not functioning at all. -I propose that a function called movie.getframe(frame) be added that gets status of all of the buttons, just like joypad.get(), for a given frame of a movie. --This makes the would make method 2 trivial and fast. --It would allow me to generalize the function for all platforms easily. ---Certainly there might be some discrepancies about which buttons should be disallowed, if any (Is Reset a button press?), but still. --If this method could somehow work for non-readonly movies, then I'd be able to use the movie to get the counts when I load a state that doesn't have cached data. ---Trust me when I tell you that this would be immensely useful for minimum button TASing. The process would be seamless, and all of these methods combined would provide perfect accuracy while being fairly efficient and only using intensive routines when absolutely necessary. Note: Earlier, I came up with the idea for a function that lets you set what frame of the movie you are on, which would be useful for endless TASes like we've already discussed, adelikat. Do you still think this is worth having?
This commit is contained in:
parent
36c4dee7b8
commit
d1b00e6d4d
|
@ -0,0 +1,145 @@
|
|||
--Written by Brandon Evans
|
||||
|
||||
--You can change the position of the text here.
|
||||
local x = 0
|
||||
local y = 36
|
||||
|
||||
local holds = 0
|
||||
local pressed = {}
|
||||
local presses = 0
|
||||
local states = {}
|
||||
|
||||
function table.copy(t)
|
||||
local t2 = {}
|
||||
for k, v in pairs(t) do
|
||||
t2[k] = v
|
||||
end
|
||||
return t2
|
||||
end
|
||||
|
||||
function counts()
|
||||
--Display the counts of the holds and the presses.
|
||||
gui.text(x, y, 'Holds: ' .. holds)
|
||||
gui.text(x, y + 14, 'Presses: ' .. presses)
|
||||
end
|
||||
|
||||
function load(slot)
|
||||
--As Lua starts counting from 1, and there may be a slot 0, increment.
|
||||
slot = slot + 1
|
||||
if not states[slot] or not states[slot].holds then
|
||||
gui.text(x, y + 28, 'No data loaded from slot ' .. tostring(slot - 1))
|
||||
counts()
|
||||
return
|
||||
end
|
||||
--Load the data if there is any available for this slot.
|
||||
holds = states[slot].holds
|
||||
pressed = table.copy(states[slot].pressed)
|
||||
presses = states[slot].presses
|
||||
gui.text(x, y + 28, 'Data loaded from slot ' .. tostring(slot - 1))
|
||||
counts()
|
||||
end
|
||||
|
||||
function parse()
|
||||
--If there is an open, read-only TAS file, parse it for the initial data.
|
||||
if not movie.isloaded() then
|
||||
return false
|
||||
end
|
||||
local fh = io.open(movie.filename())
|
||||
if not fh or movie.mode() == 'record' or movie.filename():match(
|
||||
'.%.(%w+)$'
|
||||
) ~= 'tas' then
|
||||
return false
|
||||
end
|
||||
local frame = -1
|
||||
local last = {}
|
||||
local match = {
|
||||
'Up', 'Down', 'Left', 'Right', 'Start', 'Select', 'B', 'A'
|
||||
}
|
||||
--Parse up until two frames before the current one.
|
||||
while frame ~= emu.framecount() - 2 do
|
||||
line = fh:read()
|
||||
if not line then
|
||||
break
|
||||
end
|
||||
--This is only a frame if it starts with a vertical bar.
|
||||
if string.sub(line, 0, 1) == '|' then
|
||||
frame = frame + 1
|
||||
local player = -1
|
||||
--Split up the sections by a vertical bar.
|
||||
for section in string.gmatch(line, '[^|]+') do
|
||||
player = player + 1
|
||||
--Only deal with actual players.
|
||||
if player ~= 0 then
|
||||
local button = 0
|
||||
--Run through all the buttons.
|
||||
for text in string.gmatch(section, '.') do
|
||||
button = button + 1
|
||||
local name = 'P' .. player .. ' ' .. match[button]
|
||||
local pressed = false
|
||||
--Check if this button is pressed.
|
||||
if text ~= ' ' and text ~= '.' then
|
||||
holds = holds + 1
|
||||
--If the button was not previously pressed,
|
||||
--increment.
|
||||
if not last[name] then
|
||||
presses = presses + 1
|
||||
end
|
||||
pressed = true
|
||||
end
|
||||
----Mark this button as pressed or not pressed.
|
||||
last[name] = pressed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function save(slot)
|
||||
--As Lua starts counting from 1, and there may be a slot 0, increment.
|
||||
slot = slot + 1
|
||||
while table.maxn(states) < slot do
|
||||
table.insert(states, {})
|
||||
end
|
||||
--Mark the current data as the data for this slot.
|
||||
states[slot].holds = holds
|
||||
states[slot].buttons = table.copy(buttons)
|
||||
states[slot].presses = presses
|
||||
gui.text(x, y + 28, 'Data saved to slot ' .. tostring(slot - 1))
|
||||
counts()
|
||||
end
|
||||
|
||||
if parse() then
|
||||
gui.text(x, y + 28, 'Movie parsed for data')
|
||||
else
|
||||
gui.text(x, y + 28, 'No movie parsed for data')
|
||||
end
|
||||
if savestate.registerload then
|
||||
savestate.registerload(load)
|
||||
savestate.registersave(save)
|
||||
end
|
||||
|
||||
while true do
|
||||
--If this is the first frame, reset the data.
|
||||
if emu.framecount() == 0 then
|
||||
holds = 0
|
||||
pressed = {}
|
||||
presses = 0
|
||||
end
|
||||
local buttons = joypad.get()
|
||||
--Run through all of the pressed buttons.
|
||||
for button, value in pairs(buttons) do
|
||||
if value then
|
||||
holds = holds + 1
|
||||
--If in the previous frame the button was not pressed, increment.
|
||||
if not pressed[button] then
|
||||
presses = presses + 1
|
||||
end
|
||||
end
|
||||
--Mark this button as pressed or not pressed.
|
||||
pressed[button] = value
|
||||
end
|
||||
counts()
|
||||
emu.frameadvance()
|
||||
end
|
Loading…
Reference in New Issue