some of the tricks i found so far: (i use the "lazymacro" syntax)
the fastest way of running to the right is (<Y)[(>Y)]16|>, it's 2 pixels faster than just using (>Y).
if you're running right without y for a certain amount of time and you want to change the direction, try
+Y <<>|< or +Y <<>>|< or +Y <<<>>|<
if you're running to the right with full speed, you can stop movement very fast with +Y <<><!
in level 4, you can jump through the spikes which hang from the ceiling, i do abuse that in 4-3.
hitting ramps at the top can have unexpected effects.
it may be possible to influence the "behaviour" of ramps by changing roadrunners position by a few pixels. (at least in one case thats possible, in 5-3 there is one ramp where i had to do that)
-------------
i tried using zsnes, but it didn't record anything after i stopped my movie for the first time. i got 1-1 done even 7 frames faster there
-------------
some people wanted to see an "all flags run". i created a small lua script (which can for sure be improved by a lot) which helps if you want to create a map.
best method would be to move road runner, but i couldnt figure out how to change his y-position.
before using it, you must disable all graphic layers except BG1 and BG4 (and you must be in level 1-1). everything should work well. There are some minor distortions in the map, and it won't show the elevators. You might be able to improve it.
require "gd"
levelname="level1-1"
y = 544 --highest x/y value camx2 can reach in normal gameplay
x = 9344 --found by running completely to the lowest right corner of the map
--must be adjusted manually
upperblacksize=13 --found by taking screenshots
lowerblacksize=16 --and a little trial-and-error
xsize=256
ysize=224
realysize = ysize - upperblacksize - lowerblacksize
gridx=200
gridy=150
camx1 = 0x7E0050
camx2 = 0x7E0054
posx1 = 0x7E031C
posx2 = 0x7E17A2
posy1 = 0x7E194C
posy2 = 0x7E0038
posy3 = 0x7E03AA
camy1 = 0x7E007A
camy2 = 0x7E0056
xspeed = 0x7E04C6
yspeed = 0x7E0554
image = gd.createFromPng(string.format("%s.png",levelname))
if(image == nil) then
image = gd.createTrueColor(x + xsize, y + ysize - lowerblacksize - upperblacksize)
end
mycolor = image:colorAllocate(255,0,255)
takingpicture = false
function writeposition(x, y)
memory.writeshort(posx1, x)
memory.writeshort(posx2, x)
memory.writeshort(posy1, y)
memory.writeshort(posy2, y)
memory.writeshort(posy3, y)
end
function setgroundflag()
memory.writebyte(0x7E144D, 0)
memory.writebyte(0x7E144D, 1)
end
function movetozerozero()
currentposx=memory.readshort(posx1)
currentposy=memory.readshort(posy1)
while currentposx >= 8 do
writeposition(currentposx - 8, currentposy)
setgroundflag()
currentposx = currentposx - 8
snes9x.frameadvance()
end
while currentposy >= 8 do
writeposition(currentposx, currentposy - 8)
setgroundflag()
currentposy = currentposy - 8
snes9x.frameadvance()
end
end
function takenextpicture()
if not(takingpicture) then
takingpicture = true
lastimage = gui.gdscreenshot()
if not(lastimage==nil) then
lastshot = gd.createFromGdStr(lastimage)
currentcamx = memory.readshort(camx2)
currentcamy = memory.readshort(camy2)
--gd.copy(dstImage, srcImage, dstX, dstY, srcX, srcY, w, h)
--insert the last picture into what we got so far
if movingdirection==-1 then xcorrection=0 else xcorrection=-16 end
gd.copy (image, lastshot, currentcamx + xcorrection, currentcamy - upperblacksize, 0, upperblacksize, xsize, ysize - upperblacksize - lowerblacksize)
end
--gui.text(int x, int y, string msg)
--draw current position onto the game screen so you know where something is still missing
for i = 0, 1 do
for j = 0, 1 do
stringtodraw = string.format("(%i/%i)",(i+math.floor(currentcamx / gridx))*gridx, (j+math.floor(currentcamy/gridy))*gridy)
gui.text(-currentcamx % gridx + i*gridx, -currentcamy % gridy + j*gridy, stringtodraw)
end
end
takingpicture=false
end
end
function writepicture()
image:png(string.format("%s.png",levelname))
--gdImage:line(x1, y1, x2, y2, color)
--i think there is a much better way for that as presented here, but at least it works
image2 = gd.createFromPng(string.format("%s.png",levelname))
for i = 0, math.ceil(x / gridx) do
for j = 0, math.ceil(y / gridy) do
image2:line(i*gridx, (j+1)*gridy, (i+1)*gridx, (j+1)*gridy, mycolor)
image2:line((i+1)*gridx, j*gridy, (i+1)*gridx, (j+1)*gridy, mycolor)
--gdImage:string(font, x, y, string, color)
stringtodraw = string.format("(%i/%i)", i*gridx, j*gridy)
image2:string(gd.FONT_LARGE, i*gridx, j*gridy, stringtodraw,mycolor)
end
end
image2:png(string.format("%s-sectioned.png",levelname))
end
--now move him all over the screen
movetozerozero()
emu.registerafter(takenextpicture)
emu.registerexit(writepicture)
movingdirection=1
currentposx=memory.readshort(posx1)
currentposy=memory.readshort(posy1)
--this massively increases consumed ram
--snes9x.speedmode("maximum")
repeat
writeposition(currentposx + 8, currentposy)
currentposx = currentposx + 8
snes9x.frameadvance()
currentcamx=memory.readshort(camx2)
until currentcamx>=x
j=1
currentcamx=memory.readshort(camx2)
currentcamy=memory.readshort(camy2)
while currentcamy < y do
movingdirection = movingdirection * -1
currentposy = currentposy + 96
writeposition(currentposx, currentposy)
snes9x.frameadvance()
repeat
if movingdirection==1 then
writeposition(x + xsize, currentposy)
else
writeposition(40, currentposy)
end
snes9x.frameadvance()
currentcamx=memory.readshort(camx2)
until ((currentcamx>=x and movingdirection==1) or (currentcamx==0 and movingdirection==-1))
end
movingdirection = movingdirection * -1
writeposition(currentposx, currentposy)
snes9x.frameadvance()
repeat
if movingdirection==1 then
writeposition(x + xsize, currentposy)
else
writeposition(40, currentposy)
end
snes9x.frameadvance()
currentcamx=memory.readshort(camx2)
until ((currentcamx>=x and movingdirection==1) or (currentcamx==0 and movingdirection==-1))
movingdirection=1
emu.registerafter(nil)
--snes9x.speedmode("normal")