Adding one frame of delay is simple enough.
Adding two frames or more usually requires a table and functions specifically built for it.
An extremely messy way to add two frames of delay would be the following:
Language: lua
local OldVal_TwoFramesAgo= 0
local OldVal_OneFrameAgo= 0
while true do
gui.text(15,15,OldVal_TwoFramesAgo)
OldVal_TwoFramesAgo= OldVal_OneFrameAgo
OldVal_OneFrameAgo= memory.readbyte(0x0000)
emu.frameadvance()
end
The extremely messy way requires five lines every time you want to grab just one more value. It's extremely messy. Also, loadstates will show you stuff from before the load until enough frames pass.
Less messy sorts of ways would require making a few functions specifically to handle these things for you:
Language: lua
local ReadTheseAddresses= {0x0000,0x0005,0x0103,0x0244} -- and so on
local MemoryHistory= {}
local function StoreStuff()
local fc= emu.framecount()
MemoryHistory[fc]= {}
for i= 1, #ReadTheseAddresses do
local addr= ReadTheseAddresses[i]
MemoryHistory[fc][addr]= memory.readbyte(addr)
end
end
local function ReadOldByte(address,FramesInPast)
local t= MemoryHistory[emu.framecount() - FramesInPast]
if t then return t[address] end
end
while true do
StoreStuff()
gui.text(15,15,ReadOldByte(0x0000,2) or "nil")
emu.frameadvance()
end
But at least you'll have a complete history of select memory addresses. If the value hasn't been read up by the lua script, ReadOldByte should return
nil, which needs to be checked for to avoid other errors. Also, it's just one more line to add for each address you want to check, as well as a quick addition to a list, rather than five (
or more) lines per address you want to look at.
These are actually more general techniques than anything specific for emulation. It's less to do with the functions handed to you by FCEUX or other emulators and more to do with knowing what you can do in lua. It takes a lot of practice understanding lua as a whole before you can come up with an arbitrary way of delaying the display as infinitely as you like.
Then again, knowing what functions are available takes a bit of memorization as well. I've used
emu.framecount and
memory.readbyte here. In any case, if you can read and understand the code here, especially with my lack of comments in there, that might help give some idea what lua can do. And you'll also know what to change in my sample code to get any amount of delay you like.
For TASing, you usually want the most up-to-date internal stuff displayed, even if it's wildly out of sync with the game's display. If you plan to make a few videos, syncing up the lua with the game's display does have advantages, though.