Files
gen1recomp/tests/engine/crystal_map_name_sign_speed_bug1994.lua

149 lines
5.0 KiB
Lua

-- ../pokecrystal/engine/events/map_name_sign.asm:41-44
-- ../pokecrystal/engine/events/map_name_sign.asm:99-107
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local check, eq = T.check, T.eq
love = love or require("tests.love_stub")
package.loaded["src.core.GameVersion"] = {
engine = function() return "crystal" end,
}
package.loaded["src.render.Assets"] = {
register = function() end,
resolve = function(path) return path end,
exists = function() return false end,
image = function() error("no sheet in the fixture cache") end,
}
package.loaded["src.render.GbcPalette"] = {
available = function() return false end,
with = function(_, body) body() end,
}
package.loaded["src.render.Font"] = {
ttfActive = function() return false end,
encode = function(text)
local out = {}
for i = 1, #tostring(text) do out[i] = string.byte(text, i) end
return out
end,
width = function(text) return #tostring(text) * 8 end,
draw = function() end,
}
package.loaded["src.world.gen2.MapNameSign"] = nil
local Sign = require("src.world.gen2.MapNameSign")
local World = {}
World.__index = World
function World.new(game)
return setmetatable({
game = game,
map = { id = "ROUTE_29",
def = { landmark = "LANDMARK_ROUTE_29", environment = "ROUTE" } },
mapSignState = { prev = "LANDMARK_NEW_BARK_TOWN" },
}, World)
end
function World:currentLandmarkId() return "LANDMARK_ROUTE_29" end
function World:landmarkName() return "ROUTE 29" end
local function raise(game)
local w = World.new(game)
Sign.init(w)
return w
end
local function gameAt(speed)
return { logicSpeed = function() return speed end }
end
local FixedStep = require("src.core.FixedStep")
local STEP = FixedStep.STEP
local function renderedFramesToClear(w, speed, limit)
local steps, maxPerFrame = 0, 0
FixedStep:init(function() steps = steps + 1 Sign.tick(w) end)
FixedStep.maxAccum = FixedStep.catchupLimit(speed)
for frame = 1, limit do
local before = steps
Sign.frame(w)
FixedStep:update(STEP, speed)
maxPerFrame = math.max(maxPerFrame, steps - before)
if w.mapSign == nil then return frame, steps, maxPerFrame end
end
return nil, steps, maxPerFrame
end
local one = raise(gameAt(1))
if check(one.mapSign ~= nil, "the sign comes up at 1X") then
eq(one.mapSign.timer, 60, "wLandmarkSignTimer starts at 60")
eq(one.mapSign.shown, false, "and the window is still off screen")
for _ = 1, 20 do Sign.frame(one) end
eq(one.mapSign.timer, 50, "twenty real frames are ten HandleMap calls")
eq(one.mapSign.shown, true, "shown from the second call")
end
-- ../pokecrystal/engine/overworld/events.asm:177-191
FixedStep.clock = function() return 0 end
for _, speed in ipairs({ 1, 4, 10, 20, 200 }) do
local w = raise(gameAt(speed))
local frame, steps, maxPerFrame = renderedFramesToClear(w, speed, 2000)
eq(frame, 122, ("%dX: the sign clears on rendered frame 122"):format(speed))
eq(steps, 122 * speed,
("%dX: the logic ran %d steps"):format(speed, speed * 122))
eq(maxPerFrame, speed, ("%dX: %d steps a rendered frame"):format(speed, speed))
end
FixedStep.clock = nil
local hidden = raise(gameAt(1))
for _ = 1, 3 do Sign.frame(hidden) end
eq(hidden.mapSign.shown, false, "frames 1-3: the first call returns before drawing")
Sign.frame(hidden)
eq(hidden.mapSign.shown, true, "frame 4: the second call sets hWY = $70")
for _ = 5, 120 do Sign.frame(hidden) end
check(hidden.mapSign ~= nil and hidden.mapSign.shown, "frame 120: last visible")
Sign.frame(hidden)
check(hidden.mapSign ~= nil, "frame 121: the 61st call has not landed yet")
Sign.frame(hidden)
eq(hidden.mapSign, nil, "frame 122: a = 0, .disappear")
local bare = raise(nil)
local bareFrame = renderedFramesToClear(bare, 1, 400)
eq(bareFrame, 122, "no game object: the same 122 real frames")
-- ../pokecrystal/home/window.asm:42
for _, speed in ipairs({ 1, 4, 10, 200 }) do
local talked = raise(gameAt(speed))
talked.textbox = true
Sign.tick(talked)
eq(talked.mapSign, nil,
"a text box takes the sign down on the first tick at " .. speed .. "X")
end
-- ../pokecrystal/data/maps/setup_scripts.asm:32-56
local fading = raise(gameAt(1))
fading.mapSetup = { phase = "in" }
for _ = 1, 200 do Sign.frame(fading) end
eq(fading.mapSign.timer, 60, "a map setup fade freezes the countdown")
fading.mapSetup = nil
for _ = 1, 4 do Sign.frame(fading) end
eq(fading.mapSign.timer, 58, "and it runs on once the fade is gone")
-- ../pokecrystal/engine/overworld/events.asm:284-285
local pushed = raise(gameAt(10))
for _ = 1, 30 do Sign.frame(pushed) end
check(pushed.mapSign ~= nil, "the sign survives 30 real frames at 10X")
Sign.cancel(pushed)
eq(pushed.mapSign, nil, "and a player event still clears it outright")
local stateful = raise(gameAt(4))
Sign.frame(stateful)
eq(Sign.state(stateful).frames, nil,
"the frame counter does not reach the saved crystal state")
eq(Sign.state(stateful).shown, nil, "nor does the shown flag")
check(stateful.mapSign and stateful.mapSign.frames ~= nil,
"they live on world.mapSign")
T.finish("crystal map name sign speed bug 1994")