I'm working on improving the previous submission by Aglar since I finished Duck Tales 2 with feos.
I'm
currently 15 frames ahead after leaving the icy stage at level 4 (I had to sacrifice 3 frame to manipulate away the hockey enemy).
Now if this wouldn't be enough, the way the game calculates the Y sub position is ridiculous.
A:AB X:00 Y:00 S:BB P:nvUbdIZC $E9ED:20 A1 F2 JSR $F2A1
A:AB X:00 Y:00 S:B9 P:nvUbdIZC $F2A1:BD 60 06 LDA $0660,X @ $0660 = #$15 -- load y sub 1
A:15 X:00 Y:00 S:B9 P:nvUbdIzC $F2A4:38 SEC -- set carry flag
A:15 X:00 Y:00 S:B9 P:nvUbdIzC $F2A5:FD B0 07 SBC $07B0,X @ $07B0 = #$55 -- Y sub 1 - Y sub 2 - ~C
A:C0 X:00 Y:00 S:B9 P:NvUbdIzc $F2A8:9D 60 06 STA $0660,X @ $0660 = #$15 -- store y sub 1
A:C0 X:00 Y:00 S:B9 P:NvUbdIzc $F2AB:BD 40 06 LDA $0640,X @ $0640 = #$AB -- load Y pos
A:AB X:00 Y:00 S:B9 P:NvUbdIzc $F2AE:FD C0 07 SBC $07C0,X @ $07C0 = #$04 -- vertical boost - Y sub 2 -~C
A:A6 X:00 Y:00 S:B9 P:NvUbdIzC $F2B1:9D 40 06 STA $0640,X @ $0640 = #$AB -- store y pos
A:A6 X:00 Y:00 S:B9 P:NvUbdIzC $F2B4:60 RTS (from $F2A1) -----------------
Y sub 1 changes on every in-game frame even when you are on ground. Y sub 2 changes only when you are jumping/falling. Needless to say, it's possible to abuse higher jumps and lower jumps. However I have no idea how to calculate it since the jump length depends on time of jumping, length of jumping and previous jumps.
And here is a lua script.
-- HUD (all functions except stuff()) by Pasky13
-- rest made by mostly feos and MESHUGGAH
local camx
lastXpos = 0
lastYpos = 0
function findbit(p)
return 2 ^ (p - 1)
end
function hasbit(x, p)
return x % (p + p) >= p
end
local function hex(val)
val = string.format("%X",val)
if string.len(val) == 1 then
val = "0" .. val
end
return val
end
local function axis(x,y,color)
gui.line(x,y-16,x,y+16,color)
gui.line(x-16,y,x+16,y,color)
end
local function camera()
camx = memory.readbyte(0xF2) + (memory.readbyte(0xF3) * 256)
end
local function player()
local x = (memory.readbyte(0x720) + memory.readbyte(0x730) * 256) - camx
local y = memory.readbyte(0x640)
local offset = memory.readbytesigned(0x7D0)
local action = memory.readbyte(0x620)
if hasbit(action,findbit(3)) == true then
axis(x,y,"#FF0000")
else
axis(x,y,"#FFB000")
end
end
local function objects()
for i = 1,15,1 do
if memory.readbytesigned(0x700 + i) < 0 then
local x = (memory.readbyte(0x720 + i) + memory.readbyte(0x730 + i) * 256) - camx
local y = memory.readbyte(0x640 + i)
local fill = "#FF0000FF"
local outl = "#FF000030"
local xrad = 0
local yrad = 0
local enemy = false
local offset = 0
local etype = memory.readbytesigned(0x7D0 + i)
if etype < 0 then
if bit.band(etype,0x70) == 0 then
fill = "#FFFF00FF"
outl = "#FFFF0030"
else
enemy = true
end
offset = bit.band(etype,0x7F)
if enemy == true then
if memory.readbyte(0x620) == 3 then
offset = offset + 7
end
end
xrad = rom.readbyte(0x1F4C8 + offset)
yrad = rom.readbyte(0x1F4A8 + offset)
if xrad < 0x50 then
gui.box(x+xrad,y+yrad,x-xrad,y-yrad,outl,fill)
end
else
offset = memory.readbyte(0x610 + i)
xrad = rom.readbyte(0x18675 + offset)
offset = bit.band(memory.readbyte(0x7D0+i),0x7F)
yrad = rom.readbyte(0x1F4A8 + offset)
if xrad < 0x50 then
gui.box(x+xrad,y+yrad,x-xrad,y-yrad,outl,fill)
end
end
--gui.text(x,y,"E" .. hex(i) .. "/" .. hex(offset) .. "/" .. hex(xrad) .. "/" .. hex(yrad))
end
end
end
function Stuff()
camera()
player()
objects()
local Xpos = memory.readbyte(0x720) + memory.readbyte(0x730) * 0x100 + memory.readbyte(0x670)/400
local Ypos = memory.readbyte(0x640) + memory.readbyte(0x7B0)/400
local YposSub = memory.readbyte(0x660)/400
camx = memory.readbyte(0xF2) + memory.readbyte(0xF3) * 0x100
local Ycam = memory.readbyte(0xF1)
local timer = memory.readbyte(0x92)
local timer2 = memory.readbyte(0x95)
local RNG = memory.readbyte(0x90)
local bossHP = memory.readbyte(0xB1)
local bossInv = memory.readbyte(0x6FF)
local Xspd = Xpos - lastXpos
local Yspd = Ypos - lastYpos
gui.text(75, 8, string.format("Tmr: %3d:%3d\nRNG: later, ok?\nHP: %d\nInv: %d",timer,timer2,bossHP,bossInv))
for i = 0, 16 do
id = memory.readbyte(0x620+i)
xSub = memory.readbyte(0x670+i)
scrnX = memory.readbyte(0x650+i)
x = memory.readbyte(0x720+i) + memory.readbyte(0x730+i)*256 - camx
ySub = memory.readbyte(0x7B0+i) -- or 660
y = memory.readbyte(0x640+i)
state = memory.readbyte(0x710+i)
if x<0>242 then x=242 end
if id>0 and i>0 then
gui.text(x-6, y-2, string.format("%X",id), "#ffffffa0")
end
if i == 0 then gui.text(scrnX-10, Ypos+10, string.format("%.2f\n%.2f",Xspd,Yspd), "#ffff00ff") end
end
gui.text( 0, 8, string.format(
"X: %.2f\nY: %.2f",Xpos,Ypos
))
gui.text(150,8, string.format("Ysub: %.2f", YposSub))
-- if memory.readbyte(0x80) == 2 then gui.box(1,1,256,256,"#FFFF00FF") end
lastXpos = Xpos
lastYpos = Ypos
end
emu.registerafter(Stuff)
edit: lua script modified