mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
90 lines
3.6 KiB
Lua
90 lines
3.6 KiB
Lua
-- Parity test: nothing expensive may ride the FLASH white-out's completion
|
|
-- callback (#610). Transition.WhiteFlash is opaque and paints the whole
|
|
-- 160x144 solid white, so whatever runs from its onDone runs with a blank
|
|
-- white frame as the newest thing the player has been shown. Lighting the
|
|
-- cave is exactly that kind of work: in the ADVANCED colour mode
|
|
-- OverworldState:setDark drops every resident map and rebakes the tileset
|
|
-- atlas pixel by pixel (#383), which on a phone is seconds of frozen white
|
|
-- and reads as a lockup. engine/menus/start_sub_menus.asm .flash clears
|
|
-- wMapPalOffset before PrintText and calls GBPalWhiteOutWithDelay3 last of
|
|
-- all, so the port lights the cave as the message closes the menu and
|
|
-- leaves the blink a plain 7-frame blink with no work attached.
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if not _G.love then _G.love = require("tests.love_stub") end
|
|
local Data = require("src.core.Data")
|
|
if not (Data.maps and Data.maps.PALLET_TOWN) then Data:load() end
|
|
local S = require("tests.harness").suite("parity flash blink bug610")
|
|
local check, eq = S.check, S.eq
|
|
|
|
require("src.render.Font").load(Data)
|
|
local Game = require("src.core.Game")
|
|
local Input = require("src.core.Input")
|
|
local StateStack = require("src.core.StateStack")
|
|
local Renderer = require("src.render.Renderer")
|
|
local SaveData = require("src.core.SaveData")
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local PartyMenu = require("src.ui.PartyMenu")
|
|
local OW = require("src.world.OverworldController")
|
|
|
|
Game.data = Data
|
|
Game.input = Input; Input:init()
|
|
Game.renderer = Renderer; Renderer:init()
|
|
Game.stack = StateStack; StateStack:init()
|
|
Game.save = SaveData.newGame()
|
|
|
|
local function frame(btns)
|
|
Input.pressed = {}
|
|
for _, b in ipairs(btns or {}) do Input.pressed[b] = true; Input.state[b] = true end
|
|
StateStack:update(1 / 60)
|
|
for _, b in ipairs(btns or {}) do Input.state[b] = false end
|
|
end
|
|
local function popAll() while Game.stack:top() do Game.stack:pop() end end
|
|
local function mkMon(species, ...)
|
|
local m = Pokemon.new(Data, species, 20)
|
|
m.moves = {}
|
|
for _, id in ipairs({ ... }) do m.moves[#m.moves + 1] = { id = id, pp = 15 } end
|
|
return m
|
|
end
|
|
-- dismiss exactly one box, leaving whatever it pushed on top
|
|
local function drainOne()
|
|
local box = Game.stack:top()
|
|
local guard = 0
|
|
while Game.stack:top() == box and guard < 400 do
|
|
guard = guard + 1
|
|
frame({ "a" })
|
|
end
|
|
end
|
|
|
|
Game.save.flashLit = false
|
|
Game.save.party = { mkMon("PIKACHU", "FLASH") }
|
|
Game.save.inventory = { BOULDERBADGE = true }
|
|
popAll()
|
|
Game.stack:push(OW, "ROCK_TUNNEL_1F", 15, 4, "down")
|
|
local ow = Game.stack:top()
|
|
eq(ow.dark, true, "ROCK_TUNNEL_1F loads dark before FLASH")
|
|
|
|
local pm = PartyMenu.new(Game)
|
|
Game.stack:push(pm)
|
|
frame({ "a" }) -- open the field-move submenu on PIKACHU
|
|
frame({ "a" }) -- FLASH is the top row now (#768)
|
|
drainOne() -- dismiss _FlashLightsAreaText
|
|
|
|
local blink = Game.stack:top()
|
|
check(blink ~= nil and blink.isOpaque == true and type(blink.frames) == "number",
|
|
"the blink follows the FLASH message")
|
|
-- the invariant this test exists for: the blink carries no work
|
|
eq(blink.onDone, nil, "the FLASH blink has no completion callback (#610)")
|
|
eq(ow.dark, false, "the cave is already lit when the blink starts")
|
|
|
|
local guard = 0
|
|
while Game.stack:top() ~= ow and guard < 240 do
|
|
guard = guard + 1
|
|
frame({})
|
|
end
|
|
eq(Game.stack:top(), ow, "FLASH ends on the map")
|
|
eq(ow.dark, false, "the cave stays lit after the blink")
|
|
eq(Game.save.flashLit, true, "FLASH is recorded on the save")
|
|
|
|
popAll()
|
|
S.finish()
|