mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
168 lines
5.7 KiB
Lua
168 lines
5.7 KiB
Lua
-- engine/menus/start_sub_menus.asm:97-104
|
|
-- engine/pokemon/status_screen.asm:82, home/pokemon.asm:186
|
|
-- luajit tests/engine/status_screen_white_hold_2060.lua
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
|
|
local rects = {}
|
|
local color = { 1, 1, 1, 1 }
|
|
love = love or {}
|
|
love.graphics = {
|
|
setColor = function(r, g, b, a) color = { r, g, b, a or 1 } end,
|
|
rectangle = function(_, x, y, w, h)
|
|
rects[#rects + 1] = { x = x, y = y, w = w, h = h, color = color }
|
|
end,
|
|
draw = function() end,
|
|
push = function() end, pop = function() end,
|
|
translate = function() end, scale = function() end,
|
|
}
|
|
|
|
package.loaded["src.render.Font"] = {
|
|
draw = function() end, drawCode = function() end, drawBox = function() end,
|
|
width = function() return 0 end,
|
|
}
|
|
package.loaded["src.render.HudTiles"] = {
|
|
statusTile = function() end, tile = function() end, drawHPBar = function() end,
|
|
}
|
|
package.loaded["src.render.PaletteFX"] = {
|
|
shader = function() return nil end,
|
|
pal = function() return nil end,
|
|
markTrueColor = function() end,
|
|
}
|
|
package.loaded["src.pokemon.Sprites"] = { path = function() return nil, false end }
|
|
local cries = {}
|
|
package.loaded["src.core.Sound"] = {
|
|
play = function() end,
|
|
playCry = function(_, species) cries[#cries + 1] = species end,
|
|
}
|
|
package.loaded["src.mods.Runtime"] = {
|
|
wants = function() return false end,
|
|
wantsHook = function() return false end,
|
|
emit = function() end,
|
|
call = function(_, fallback, ...) return fallback(...) end,
|
|
}
|
|
package.loaded["src.ui.Screens"] = {}
|
|
|
|
local Transition = require("src.render.Transition")
|
|
local SummaryMenu = assert(loadfile("src/ui/SummaryMenu.lua"))()
|
|
|
|
local function mkGame()
|
|
local stack = { states = {} }
|
|
function stack:push(s) self.states[#self.states + 1] = s end
|
|
function stack:pop() return table.remove(self.states) end
|
|
function stack:top() return self.states[#self.states] end
|
|
local input = { pressed = nil }
|
|
function input:wasPressed(b) return self.pressed == b end
|
|
return {
|
|
data = {
|
|
pokemon = { BULBASAUR = { name = "BULBASAUR", dex = 1, types = { "GRASS" } } },
|
|
moves = {},
|
|
statuses = nil,
|
|
},
|
|
save = { player = { id = 1, name = "RED" } },
|
|
stack = stack,
|
|
input = input,
|
|
}
|
|
end
|
|
|
|
local function mkMon()
|
|
return {
|
|
nickname = "SAUR", species = "BULBASAUR", level = 5, exp = 100,
|
|
hp = 10, stats = { hp = 10, attack = 5, defense = 5, speed = 5, special = 5 },
|
|
moves = {},
|
|
}
|
|
end
|
|
|
|
local game = mkGame()
|
|
local mon = mkMon()
|
|
local FRAMES = Transition.flashFrames(game)
|
|
T.check(type(FRAMES) == "number" and FRAMES > 0,
|
|
"Transition.flashFrames reports the white_flash record's frame count")
|
|
|
|
local function step(button)
|
|
game.input.pressed = button
|
|
local top = game.stack:top()
|
|
if top and top.update then top:update(1 / 60) end
|
|
game.input.pressed = nil
|
|
end
|
|
|
|
local function fullScreenRects()
|
|
rects = {}
|
|
local top = game.stack:top()
|
|
if top and top.draw then top:draw() end
|
|
local n = 0
|
|
for _, r in ipairs(rects) do
|
|
if r.x == 0 and r.y == 0 and r.w == 160 and r.h == 144 then n = n + 1 end
|
|
end
|
|
return n
|
|
end
|
|
|
|
-- engine/pokemon/status_screen.asm:82
|
|
local screen = SummaryMenu.new(game, mon)
|
|
game.stack:push(screen)
|
|
T.eq(screen.whiteHold, FRAMES, "SummaryMenu opens with a full white hold")
|
|
T.eq(#cries, 0, "and the cry has not played yet (status_screen.asm:168-172)")
|
|
T.eq(fullScreenRects(), 2,
|
|
"the held frame paints the page and then a white overlay on top")
|
|
|
|
for i = 1, FRAMES - 1 do
|
|
step("a")
|
|
T.eq(screen.whiteHold, FRAMES - i, "the hold burns one frame per update")
|
|
T.eq(screen.page, 1, "A pressed during the hold is eaten, not a page flip")
|
|
T.eq(#cries, 0, "the cry waits for GBPalNormal")
|
|
end
|
|
|
|
step()
|
|
T.eq(screen.whiteHold, 0, "the hold ends after its frame budget")
|
|
T.eq(#cries, 1, "PlayCry fires exactly once, at the end of the hold")
|
|
T.eq(cries[1], "BULBASAUR", "and it is this mon's cry")
|
|
T.eq(fullScreenRects(), 1, "after the hold the page draws with no overlay")
|
|
|
|
step("a")
|
|
T.eq(screen.page, 2, "A flips to page 2 once the hold is over")
|
|
T.eq(#game.stack.states, 1, "the page flip pushes nothing")
|
|
|
|
step("a")
|
|
T.eq(#game.stack.states, 2, "closing page 2 pushes the exit white-out")
|
|
local blink = game.stack:top()
|
|
T.check(blink ~= nil and blink.pages == nil and blink.isOpaque == true
|
|
and type(blink.frames) == "number",
|
|
"the pushed state is the opaque WhiteFlash, not a text box")
|
|
T.eq(blink.frames, FRAMES, "and it holds for the same white_flash budget")
|
|
T.eq(fullScreenRects(), 1, "the exit hold paints solid white over everything")
|
|
|
|
for i = 1, FRAMES - 1 do
|
|
step()
|
|
T.eq(#game.stack.states, 2,
|
|
"the status screen is still on the stack at hold frame " .. i)
|
|
end
|
|
step()
|
|
T.eq(#game.stack.states, 0,
|
|
"the flash and the status screen come off together (status_screen.asm:431)")
|
|
T.eq(#cries, 1, "closing does not replay the cry")
|
|
|
|
-- engine/pokemon/status_screen.asm:172
|
|
local zeroGame = mkGame()
|
|
zeroGame.data.transitions = { white_flash = { kind = "fade", frames = 0 } }
|
|
cries = {}
|
|
T.eq(Transition.flashFrames(zeroGame), 0,
|
|
"a mod can zero the white_flash record's frames")
|
|
local zeroScreen = SummaryMenu.new(zeroGame, mkMon())
|
|
zeroGame.stack:push(zeroScreen)
|
|
T.eq(zeroScreen.whiteHold, 0, "the status screen then opens with no hold")
|
|
T.eq(#cries, 1, "and the cry still plays, immediately on entry")
|
|
T.eq(cries[1], "BULBASAUR", "and it is this mon's cry")
|
|
|
|
zeroGame.input.pressed = nil
|
|
zeroScreen:update(1 / 60)
|
|
T.eq(#cries, 1, "the zero-frame hold does not replay the cry")
|
|
T.eq(zeroScreen.page, 1, "and an idle frame does not flip the page")
|
|
zeroGame.input.pressed = "a"
|
|
zeroScreen:update(1 / 60)
|
|
zeroGame.input.pressed = nil
|
|
T.eq(zeroScreen.page, 2, "input is live at once with no hold to burn")
|
|
|
|
T.finish("status_screen_white_hold_2060")
|