Edited from inconsistent' s speed calc script.
function mainmemory.read_s1616_le(address) -- Signed fixed point 16.16 little endian
local readEd = mainmemory.read_s32_le(address) / 0x10000 -- read val
local powrEd = 10^4 -- decimals
return math.floor(readEd * powrEd) / powrEd -- only 3 powrEd decimals
end
function memory.read_s1616_le(address) -- Signed fixed point 16.16 little endian
local readEd = memory.read_s32_le(address) / 0x10000 -- read val
local powrEd = 10^4 -- decimals
return math.floor(readEd * powrEd) / powrEd -- only 3 powrEd decimals
end
local prevX = 0
local prevY = 0
local prevZ = 0
local prevFrameCount = emu.framecount()
while true do
memory.usememorydomain("Main RAM")
xPointer = memory.read_s32_le(0x236238) + 0x6C
local xPos = mainmemory.read_s1616_le(xPointer & 0xFFFFFF)
local yPos = mainmemory.read_s1616_le(xPointer + 4 & 0xFFFFFF)
local zPos = mainmemory.read_s1616_le(xPointer + 8 & 0xFFFFFF)
local currentX = memory.read_s1616_le(xPointer & 0xFFFFFF)
local currentY = memory.read_s1616_le(xPointer + 4 & 0xFFFFFF)
local currentZ = memory.read_s1616_le(xPointer + 8 & 0xFFFFFF)
local VelX = mainmemory.read_s1616_le(xPointer + 2576 & 0xFFFFFF)
local VelY = mainmemory.read_s1616_le(xPointer + 2580 & 0xFFFFFF)
local VelZ = mainmemory.read_s1616_le(xPointer + 2584 & 0xFFFFFF)
local rotationY = mainmemory.read_s1616_le(xPointer - 60 & 0xFFFFFF)
local Boost = memory.read_s32_le(xPointer + 1836 & 0xFFFFFF)
local currentFrameCount = emu.framecount()
local frameDifference = currentFrameCount - prevFrameCount
-- calculate horizontal speed
local speed = 0
if frameDifference ~= 0 then
local deltaX = currentX - prevX -- delta means change in value
local deltaZ = currentZ - prevZ -- delta means change in value
local distance = math.sqrt(deltaX * deltaX + deltaZ * deltaZ)
-- pythagorean theorem
speed = (distance / frameDifference)
-- if you don't want it to round down, then remove math.floor
-- speed = distance / frameDifference
end
-- calculate vertical speed
local speedY = 0
if frameDifference ~= 0 then
local deltaY = currentY - prevY
speedY = (deltaY / frameDifference)
-- no pythagorean theorem because Y = one axis
end
-- calculate horizontal speed
local velocity = 0
if frameDifference ~= 0 then
local deltaXvel = VelX - prevX -- delta means change in value
local deltaZvel = VelZ - prevZ -- delta means change in value
local Veldistance = math.sqrt(deltaXvel * deltaXvel + deltaZvel * deltaZvel)
-- pythagorean theorem
velocity = math.floor(Veldistance / frameDifference + 0.5)
-- if you don't want it to round down, then remove math.floor
-- speed = distance / frameDifference
end
-- displays
gui.drawText(1, 180, "Horizontal Speed: " .. speed, "white", "black", 12)
gui.drawText(1, 195, "Vertical Speed: " .. speedY, "white", "black", 12)
gui.drawText(1, 210, "X: " .. xPos, "white", "black", 12)
gui.drawText(1, 225, "Y: " .. yPos, "white", "black", 12)
gui.drawText(1, 240, "Z: " .. zPos, "white", "black", 12)
gui.drawText(1, 255, "xVel: " .. VelX, "white", "black", 12)
gui.drawText(1, 270, "yVel: " .. VelY, "white", "black", 12)
gui.drawText(1, 285, "zVel: " .. VelZ, "white", "black", 12)
gui.drawText(1, 300, "Facing Angle: " .. rotationY, "white", "black", 12)
-- update previous
prevX = currentX
prevY = currentY
prevZ = currentZ
prevFrameCount = currentFrameCount
clampedSpeed = math.min(math.max(Boost, 0), 85000)
gui.drawRectangle(1, 315, clampedSpeed * 0.0028, 10, 0xC0FFFFFF, 0xC0FF0000)
emu.frameadvance() -- needed to not crash
end