Files
gen1recomp/tests/engine/gen2_lcd_row_plus_one_bug2102.lua
T

143 lines
5.1 KiB
Lua

-- home/lcd.asm:12 (#2102)
package.path = "./?.lua;./?/init.lua;" .. package.path
love = require("tests.love_stub")
local T = require("tests.harness")
local check, eq = T.check, T.eq
local BgEffects = require("src.battle.gen2.BgEffects")
local BattleAnimView = require("src.ui.gen2.BattleAnimView")
local GbcPalette = require("src.render.GbcPalette")
local function byRow(lines)
local rows = {}
for _, line in ipairs(lines) do rows[line.dest] = line end
return rows
end
local function displacement(bg)
local total = 0
for row = bg.lyStart, bg.lyEnd do
local byte = bg.lyBackup[row] or 0
if byte ~= 0 then total = total + 1 end
end
return total
end
local function runToPeak(bg, frames)
local peak, peakRows = -1, nil
for _ = 1, frames do
bg:playFrame()
local d = displacement(bg)
if d > peak then peak, peakRows = d, byRow(BattleAnimView.scanlines(bg)) end
end
return peakRows, peak
end
local function assertBand(label, rows, lyStart, lyEnd, register)
local top = rows[lyStart]
check(top ~= nil and top.src == lyStart and top.dx == 0,
label .. (": drawn row 0x%02x (LY = lyStart) is untouched"):format(lyStart))
local identity = 0
for row = lyStart + 1, lyEnd do
local line = rows[row]
if line and line.src == row and line.dx == 0 then identity = identity + 1 end
end
eq(identity, 0, label .. ": no identity row inside the pic band")
local bottom = rows[lyEnd]
if register == "SCX" then
check(bottom ~= nil and bottom.dx ~= 0,
label .. (": drawn row 0x%02x (LY = lyEnd) is shoved sideways"):format(lyEnd))
else
check(bottom == nil or bottom.src ~= lyEnd,
label .. (": drawn row 0x%02x (LY = lyEnd) is moved or blanked"):format(lyEnd))
end
local below = rows[lyEnd + 1]
check(below ~= nil and below.src == lyEnd + 1 and below.dx == 0,
label .. (": drawn row 0x%02x below the band is untouched"):format(lyEnd + 1))
end
-- engine/battle_anims/bg_effects.asm:1765 BattleBGEffect_BounceDown
do
local bg = BgEffects.new({}, { battleTurn = 0 })
bg:queue("BATTLE_BG_EFFECT_BOUNCE_DOWN", 0, 1, 0)
bg:playFrame()
eq(bg.lyStart, 0x2d, "player BounceDown opens the band at $2d")
eq(bg.lyEnd, 0x5f, "one past $5e")
local rows, peak = runToPeak(bg, 20)
check(peak >= 0x30, ("the peak displaces %d rows"):format(peak))
assertBand("player BounceDown", rows, 0x2d, 0x5f, "SCY")
end
do
local bg = BgEffects.new({}, { battleTurn = 0 })
bg:queue("BATTLE_BG_EFFECT_BOUNCE_DOWN", 0, 0, 0)
bg:playFrame()
eq(bg.lyStart, 0x00, "enemy BounceDown opens the band at $00")
eq(bg.lyEnd, 0x37, "one past $36")
local rows, peak = runToPeak(bg, 20)
check(peak >= 0x30, ("the peak displaces %d rows"):format(peak))
local identity = 0
for row = 1, 0x37 do
local line = rows[row]
if line and line.src == row and line.dx == 0 then identity = identity + 1 end
end
eq(identity, 0, "enemy BounceDown: no identity row inside the pic band")
check(rows[0x37] == nil or rows[0x37].src ~= 0x37,
"enemy BounceDown: drawn row 0x37 (LY = lyEnd) is moved or blanked")
check(rows[0x38] ~= nil and rows[0x38].src == 0x38,
"enemy BounceDown: drawn row 0x38 below the band is untouched")
end
-- engine/battle_anims/bg_effects.asm:1444 BattleBGEffect_BodySlam
do
local bg = BgEffects.new({}, { battleTurn = 0 })
bg:queue("BATTLE_BG_EFFECT_BODY_SLAM", 0, 1, 0)
bg:playFrame()
eq(bg.lcdc, "SCX", "player BodySlam shoves sideways")
local rows = runToPeak(bg, 6)
assertBand("player BodySlam", rows, 0x2d, 0x5f, "SCX")
end
do
local bg = BgEffects.new({}, { battleTurn = 0 })
bg:queue("BATTLE_BG_EFFECT_BODY_SLAM", 0, 0, 0)
bg:playFrame()
eq(bg.lyEnd, 0x37, "enemy BodySlam ends one past $36")
local rows = runToPeak(bg, 6)
check(rows[0] ~= nil and rows[0].dx == 0, "enemy BodySlam: drawn row 0 is untouched")
local identity = 0
for row = 1, 0x37 do
local line = rows[row]
if line and line.dx == 0 then identity = identity + 1 end
end
eq(identity, 0, "enemy BodySlam: no identity row inside the pic band")
check(rows[0x37] ~= nil and rows[0x37].dx ~= 0,
"enemy BodySlam: drawn row 0x37 (LY = lyEnd) is shoved")
check(rows[0x38] ~= nil and rows[0x38].dx == 0,
"enemy BodySlam: drawn row 0x38 is untouched")
end
-- engine/battle_anims/bg_effects.asm:2585 (rBGP band)
do
local base = GbcPalette.BGP_IDENTITY
local bg = { bgp = base, lcdc = "BGP", lyStart = 0x2d, lyEnd = 0x5f, lyBackup = {} }
for row = 0x2d, 0x5e do bg.lyBackup[row] = 0xff end
local rowByte = {}
for _, band in ipairs(BattleAnimView.bgpBands(bg)) do
for _, row in ipairs(band.rows) do rowByte[row] = band.byte end
end
eq(rowByte[0x2d], base, "BGP: drawn row 0x2d (LY = lyStart) keeps wBGP")
eq(rowByte[0x2e], 0xff, "BGP: drawn row 0x2e takes the byte written at LY 0x2d")
eq(rowByte[0x5f], 0xff, "BGP: drawn row 0x5f takes the byte written at LY 0x5e")
eq(rowByte[0x60], base, "BGP: drawn row 0x60 is back on wBGP")
local off = 0
for row = 0x2e, 0x5f do
if rowByte[row] == base then off = off + 1 end
end
eq(off, 0, "BGP: no drawn row inside the band keeps the base palette")
end
T.finish("gen2 lcd row plus one bug 2102")