User File #639136599850152052

Upload All User Files

#639136599850152052 - Serious Sam Advance - Speed X and Y by coordinates calculation

Serious Sam Advance (USA) (En,Fr,De).lua
51 downloads
Uploaded 5/6/2026 10:26 AM by Dimon12321 (see all 96)
Since GBA allocates the memory dynamically, X and Y position RAM addresses are different on each level. At the beginning, you have a bunch of commented vars. If you want to watch my TAS of a specific level, uncomment the respective lines and comment others. The script could be universal, but you have to find the RAM address resembling the level number to change RAM addresses accordingly. I didn't find it necessary, because, in case of an improvement, all further level coordinates have to be searched again.
-- Addresses for player's coordinates
-- Level 1
-- local xAddress = 0x0358F6
-- local yAddress = 0x0358FA
-- Level 2
-- local xAddress = 0x0392BE
-- local yAddress = 0x0392C2
-- local angleAddr = 0x0392FB
-- Level 3
-- local xAddress = 0x03C186
-- local yAddress = 0x03C18A
-- local angleAddr = 0x03C1C3
-- Level 4
-- local xAddress = 0x03CBFE
-- local yAddress = 0x03CC02
-- local angleAddr = 0x03CC3B
-- Level 5
-- local xAddress = 0x03D67E
-- local yAddress = 0x03D682
-- local angleAddr = 0x03D6BB
-- Level 6
-- local xAddress = 0x02CD0E
-- local yAddress = 0x02CD12
-- local angleAddr = 0x02CD4B
-- Level 7
-- local xAddress = 0x03D356
-- local yAddress = 0x03D35A
-- local angleAddr = 0x03D40D
-- Level 8
-- local xAddress = 0x03768A
-- local yAddress = 0x03768E
-- local angleAddr = 0x035A1F
-- Level 9
-- local xAddress = 0x037002
-- local yAddress = 0x037006
-- local angleAddr = 0x03703F
-- Level 10
-- local xAddress = 0x02B0BA
-- local yAddress = 0x02B0BE
-- local angleAddr = 0x02B0F7
-- Level 11
-- local xAddress = 0x03ADA2
-- local yAddress = 0x03ADA6
-- local angleAddr = 0x03ADDF
-- Level 12
local xAddress = 0x034472
local yAddress = 0x03446E
local angleAddr = 0x0344AB

-- Initialize variable
local prevX = memory.read_s16_le(xAddress, "WRAM")
local prevY = memory.read_s16_le(yAddress, "WRAM")
local currX = 0
local currY = 0
local angle = 0
local angleDegrees = 0

local speedPerFrame = 0
local speedX = 0
local speedY = 0
local cycleFrames = 1

function readSigned16(address)
    return memory.read_s16_le(address, "WRAM")
end

-- Convert 0..255 to 0..359
function convertAngle(rawAngle)
    return (rawAngle * 360) / 256
end

function calculateVelocity(currX, currY)
    local deltaX = currX - prevX
    local deltaY = currY - prevY
    local speed = math.sqrt(deltaX^2 + deltaY^2)

    speedX = math.abs(deltaX / cycleFrames)
    speedY = math.abs(deltaY / cycleFrames)
    speedPerFrame = speed / cycleFrames

    prevX = currX
    prevY = currY
end

function printSpeeds()
    gui.text(0, 60, "Total: " .. string.format("%.2f", speedPerFrame))
    gui.text(0, 80, "Sp. X: " .. string.format("%.2f", speedX))
    gui.text(0, 100, "Sp. Y: " .. string.format("%.2f", speedY))
    gui.text(0, 120, "Angle: " .. string.format("%d", angleDegrees))
end

function calculateFrameCycle(isLaggedFrame)
    if isLaggedFrame then
        cycleFrames = cycleFrames + 1
    else
        cycleFrames = 1
    end
end

while true do
    local isLagged = emu.islagged()

    if not isLagged then
        currX = readSigned16(xAddress)
        currY = readSigned16(yAddress)

        angle = memory.read_u8(angleAddr, "WRAM")
        angleDegrees = convertAngle(angle)

        calculateVelocity(currX, currY)
    end

    printSpeeds()
    calculateFrameCycle(isLagged)

    emu.frameadvance()
end