User File #33199157647249975

Upload All User Files

#33199157647249975 - Super Mario Advance 2 - basic Lua script (BizHawk)

SuperMarioAdvance2(J).lua
1170 downloads
Uploaded 8/26/2016 2:46 AM by Amaraticando (see all 21)
This is not as good as my SMW script, but better than nothing. I've heard that people TASed this game with RAM Watch and nothing else.
-- Compatibility:
gui.pixelText = gui.pixelText or gui.drawText  -- for old versions of BizHawk

-- Definitions:

local IWRAM = {
  trueFrameCounter = 0x2bc2, -- 1 byte
  effectiveFrameCounter = 0x2bc3, -- 1 byte
  cameraX = 0x2bf0, -- 2 bytes
  cameraY = 0x2bf4, -- 2 bytes
  gameClock = 0x54c6, -- 1 byte
  
  marioDirection = 0x3f91, -- 1 byte unsigned
  marioSubspeed = 0x3f94, --1 byte unsigned
  marioXSpeed = 0x3f95, -- 1 byte signed
  marioYSpeed = 0x3f99, -- 1 byte signed
  marioXPosition = 0x3fbc, -- 2 bytes signed
  marioYPosition = 0x3fc0, -- 2 bytes signed
  marioXSubpixel = 0x3fc8, -- 1 byte unsigned
  marioYSubpixel = 0x3fca, -- 1 byte unsigned
  marioPMeter = 0x3fd2, -- 1 byte unsigned
  marioInvincibility = 0x4015, -- 1 byte
  marioTakeoffMeter = 0x401d, -- 1 byte unsigned
  marioPowerup = 0x42e8, -- 1 byte
  
  -- cape
  capeFallPose = 0x3ffa, -- 1 byte
  capeAirCaught = 0x3ffc, -- 1 byte signed
  capeFallTimer = 0x4023, -- 1 byte
  capeSpinTimer = 0x4024, -- 1 byte unsigned
  
  -- timers
  bluePSwitchTimer = 0x402b, -- 1 byte
}

local sprite_colors = {
  [0] = "red", "blue", "green", "yellow", "magenta", "cyan", "violet", "purple", "gold", "orange", "brown", "darkblue"
}

local spriteBlockOffset = 0x36e4
local spriteBlockSize = 100

-- Functions:

local function DisplayClock()
  local trueFrame = mainmemory.read_u8(IWRAM.trueFrameCounter)
  local effectiveFrame = mainmemory.read_u8(IWRAM.effectiveFrameCounter)
  local gameClock = mainmemory.read_u8(IWRAM.gameClock)
  
  gui.text(client.bufferwidth(), 0, string.format("Frame %d, %d", trueFrame, effectiveFrame))
  gui.pixelText(155, 1, gameClock, "red", "black")
end

local function DisplaySpriteInfo()
  local xText, yText, yDelta = client.bufferwidth(), 64, 14
  local cameraX = mainmemory.read_s16_le(IWRAM.cameraX)
  local cameraY = mainmemory.read_s16_le(IWRAM.cameraY)
  
  for slot = 0, 11 do
    local offset = spriteBlockOffset + slot*spriteBlockSize
    local spriteStatus = mainmemory.read_u8(offset + 0x1c)
    
    if spriteStatus ~= 0 then
      local spriteNumber = mainmemory.read_u8(offset + 0x1a)
      local spriteXSpeed = mainmemory.read_s16_le(offset + 0x09)/16
      local spriteYSpeed = mainmemory.read_s16_le(offset + 0x0d)/16
      local spriteXPosition = mainmemory.read_s16_le(offset + 0x02)
      local spriteYPosition = mainmemory.read_s16_le(offset + 0x06)
      local spriteXSubpixel = mainmemory.read_u8(offset + 0x01)
      local spriteYSubpixel = mainmemory.read_u8(offset + 0x05)
      local spriteStunTime = mainmemory.read_u8(offset + 0x22)
      local spriteReleaseTime = mainmemory.read_u8(offset + 0x23)
      
      -- display
      gui.text(xText, yText, string.format("%d: %s(%.2x, %x) %d.%.2x[%d] %d.%.2x[%d]",
        slot, spriteStunTime == 0 and "" or spriteStunTime, spriteNumber, spriteStatus,
        spriteXPosition, spriteXSubpixel, spriteXSpeed, spriteYPosition, spriteYSubpixel, spriteYSpeed),
        sprite_colors[slot] or "white"
      )
      yText = yText + yDelta
      
      local nextSpriteStr = string.format("#%d%s", slot, spriteReleaseTime == 0 and "" or " " .. spriteReleaseTime)
      gui.pixelText(spriteXPosition - cameraX, spriteYPosition - cameraY, nextSpriteStr, sprite_colors[slot] or "white")
    end
  end
end

local function DisplayTimers()
  local xText, yText, height = 0, 160, 14
  local format = string.format
  local read = mainmemory.read_u8
  
  local effectiveFrame = mainmemory.read_u8(IWRAM.effectiveFrameCounter)
  
  local DisplayCounter = function(label, address, default, mult, frame, color)
    local value = read(address)
    
    if value == default then return end
    yText = yText + height
    local color = color or 0xffffffff
    
    gui.text(xText, yText, format("%s: %d", label, (value * mult) - frame), color)
  end
  
  DisplayCounter("Invinc.", IWRAM.marioInvincibility, 0, 1, 0)
  DisplayCounter("Pow", IWRAM.bluePSwitchTimer, 0, 4, effectiveFrame % 4, "blue")
end

local function DisplayMarioInfo()
  local xText, yText, yDelta = 0, 64, 14
  
  local marioPowerup = mainmemory.read_u8(IWRAM.marioPowerup)
  local marioXPosition = mainmemory.read_s16_le(IWRAM.marioXPosition)
  local marioYPosition = mainmemory.read_s16_le(IWRAM.marioYPosition)
  local marioXSubpixel = mainmemory.read_u8(IWRAM.marioXSubpixel)
  local marioYSubpixel = mainmemory.read_u8(IWRAM.marioYSubpixel)
  local marioXSpeed = mainmemory.read_s8(IWRAM.marioXSpeed)
  local marioYSpeed = mainmemory.read_s8(IWRAM.marioYSpeed)
  local marioPMeter = mainmemory.read_u8(IWRAM.marioPMeter)
  local marioTakeoffMeter = mainmemory.read_u8(IWRAM.marioTakeoffMeter)
  local marioDirection = mainmemory.read_u8(IWRAM.marioDirection)
  local marioSubspeed = mainmemory.read_u8(IWRAM.marioSubspeed)
  local cameraX = mainmemory.read_s16_le(IWRAM.cameraX)
  local cameraY = mainmemory.read_s16_le(IWRAM.cameraY)
  
  gui.text(xText, yText, string.format("Meter %d, %d %s", marioPMeter, marioTakeoffMeter, marioDirection == 0 and "<-" or "->"))
  yText = yText + yDelta
  gui.text(xText, yText, string.format("Pos %d.%.2x, %d.%.2x", marioXPosition, marioXSubpixel, marioYPosition, marioYSubpixel))
  yText = yText + yDelta
  gui.text(xText, yText, string.format("Speed %+2d%s, %d", marioXSpeed, marioSubspeed == 0 and "" or "*", marioYSpeed))
  yText = yText + yDelta
  
  if marioPowerup == 2 then
    local capeFallPose = mainmemory.read_u8(IWRAM.capeFallPose)
    local capeAirCaught = mainmemory.read_s8(IWRAM.capeAirCaught)
    local capeFallTimer = mainmemory.read_u8(IWRAM.capeFallTimer)
    local capeSpinTimer = mainmemory.read_u8(IWRAM.capeSpinTimer)
    
    gui.text(xText, yText, string.format("Cape (%d, %d)/(%d, %d)", capeSpinTimer, capeFallTimer, capeFallPose, capeAirCaught), "gold")
    yText = yText + yDelta
  end
  
  gui.text(xText, yText, string.format("Camera %d, %d", cameraX, cameraY))
end

-- Callbacks and settings
if client.SetClientExtraPadding then  -- check it, because of old versions of BizHawk
  client.SetClientExtraPadding(0, 0, 324, 0)
end

event.onexit(function()
  if client.SetClientExtraPadding then  -- check it, because of old versions of BizHawk
    client.SetClientExtraPadding(0, 0, 0, 0)
  end
end)

while true do
  DisplayClock()
  DisplayMarioInfo()
  DisplaySpriteInfo()
  DisplayTimers()
  
  emu.frameadvance()
end