--Marble Madness camhack script for Aglar's run.
--Script by TheAxeMan
--
--I usually put the rewind code in a separate module but combined it here for distribution.
--
--This module is designed to provide "frame rewind" where
--holding down R and pressing frame advance once will bring
--you back one frame. You should be able to pick up from
--there with no trouble.
--"Hex edit bytes $0B8E and $0B8F in the rom from B5 80 to A9 01.
--That makes the screen scroll while the marble is falling.
--http://tasvideos.org/forum/viewtopic.php?p=259828#259828
messagesToDisplay = {}
dispCount = 0
newframe = false
gui.register(
function()
dispCount = dispCount+1
for i,m in pairs(messagesToDisplay) do
gui.text(m.x, m.y, m.text)
end;
newframe = false
end
)
local function addMessage(x, y, text)
table.insert(messagesToDisplay, {x=x, y=y, text=text})
end;
local function clearMessages()
messagesToDisplay = {}
end;
local function readRewindButton()
keysPressed = input.get()
return keysPressed["R"];
end;
rewindSaveStateBuffer = {}
rewindInputBuffer = {}
rewindBufferDepth = 0
rewindLastFramecount = movie.framecount()
--This gets set to "rewind" when rewinding
rewindLastFrameAction = "advance"
function manageRewind()
if readRewindButton() then
if rewindBufferDepth > 2 then
addMessage(10,10, "rewinding")
local loadIndex = movie.framecount()-2
savestate.load(rewindSaveStateBuffer[loadIndex])
joypad.set(1, rewindInputBuffer[loadIndex+1])
rewindBufferDepth = rewindBufferDepth-1
--FCEU.frameadvance()
--clearMessages()
--newframe=true
elseif rewindBufferDepth <= 2 then
local loadIndex = movie.framecount()-1
savestate.load(rewindSaveStateBuffer[loadIndex])
--joypad.set(1, rewindInputBuffer[loadIndex])
addMessage(10,10, "end of buffer")
end;
else
--Add to buffer
local bufferIndex = movie.framecount()
if rewindSaveStateBuffer[bufferIndex] == nil then
rewindSaveStateBuffer[bufferIndex] = savestate.create()
end;
savestate.save(rewindSaveStateBuffer[bufferIndex])
rewindInputBuffer[bufferIndex] = joypad.read(1)
rewindBufferDepth = rewindBufferDepth + 1
end;
addMessage(10,20, "Buffer depth is "..rewindBufferDepth)
end;
function frameAdvanceWithRewind()
FCEU.frameadvance()
manageRewind();
clearMessages()
newframe=true
end;
function pauseWithRewind()
FCEU.pause()
manageRewind();
end;
FCEU.pause()
while true do
--Aggressively move screen down
scrollpos = 50
--Be less aggressive at beginning of intermediate race
if movie.framecount() > 3050 and movie.framecount() < 3480 then scrollpos=100 end;
--Don't do this during part of aerial race
if movie.framecount() > 5100 and movie.framecount() < 5460 then scrollpos=300 end;
--if movie.framecount() > 5100 and movie.framecount() < 6000 then scrollpos=300 end;
--In the Silly race everything you know is wrong
if movie.framecount() > 6500 and movie.framecount() < 7800 then scrollpos = 300 end;
--Disable during Ultimate race to avoid desync
if movie.framecount() > 8400 then scrollpos=300 end;
relpos = memory.readbyte(0x0450)
if relpos > scrollpos then
memory.writebyte(0x0450, 155)
end;
--Special aerial fix
if movie.framecount() == 5500 then
memory.writebyte(0x00A0, 0x33)
end;
--In the Silly race everything you know is wrong
if movie.framecount() > 6500 and movie.framecount() < 7800 then
--This forces screen to just keep scrolling.
memory.writebyte(0x0458, 127)
end;
frameAdvanceWithRewind()
end;