Files
gen1recomp/tests/engine/diploma_test.lua
T

152 lines
5.2 KiB
Lua

-- Diploma screen rendering and dismiss tests (engine/events/diploma.asm).
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local Data = T.fixtures.load()
local S = require("tests.harness").suite("diploma")
local check, eq = S.check, S.eq
local Game = require("src.core.Game")
local Input = require("src.core.Input")
local StateStack = require("src.core.StateStack")
local SaveData = require("src.core.SaveData")
local Diploma = require("src.ui.Diploma")
Game.data = Data
Data.palettes = {
palettes = {
MEWMON = { {255,255,255}, {180,180,180}, {90,90,90}, {0,0,0} }
}
}
Game.input = Input; Input:init()
Game.stack = StateStack; StateStack:init()
Game.save = SaveData.newGame()
Game.save.player.name = "ASH"
require("src.render.Font").load(Data)
local done = false
local diploma = Diploma.new(Game, function() done = true end)
Game.stack:push(diploma)
check(diploma.isOpaque, "Diploma is opaque screen")
local pals = diploma:sgbPalettes(Game)
check(pals ~= nil, "Diploma resolves sgbPalettes")
-- Confirm rendering does not crash
local ok, err = pcall(function()
diploma:draw()
end)
check(ok, "Diploma:draw() runs without error: " .. tostring(err))
local PaletteFX = require("src.render.PaletteFX")
local Sprites = require("src.pokemon.Sprites")
local SpriteRenderer = require("src.render.SpriteRenderer")
local GameVersion = require("src.core.GameVersion")
local fakePic = setmetatable({ w = 40, h = 56 }, {
__index = {
getDimensions = function(s) return s.w, s.h end,
getWidth = function(s) return s.w end,
getHeight = function(s) return s.h end,
},
})
local origPlayerPic, origObp = Sprites.playerPic, SpriteRenderer.obpImage
local origScissor, origDraw = love.graphics.setScissor, love.graphics.draw
local origMode, origIsBlue = PaletteFX.mode, GameVersion.isBlue
local bakes, scissors, picDraws = {}, {}, {}
Sprites.playerPic = function() return "fake/player.png", false end
SpriteRenderer.obpImage = function(path, ramp, group)
bakes[#bakes + 1] = { path = path, ramp = ramp, group = group }
return fakePic
end
love.graphics.setScissor = function(...)
scissors[#scissors + 1] = { ... }
end
love.graphics.draw = function(img, a, b)
if img == fakePic then picDraws[#picDraws + 1] = { a, b } end
end
local function renderIn(mode, pass)
bakes, scissors, picDraws = {}, {}, {}
PaletteFX.mode = mode
PaletteFX.clearSpriteRedraws()
PaletteFX.setPass(pass)
local okR, errR = pcall(Diploma.render, Game)
check(okR, "Diploma.render under " .. tostring(mode) .. "/"
.. tostring(pass) .. ": " .. tostring(errR))
local redraws = {}
for _, r in ipairs(PaletteFX.uiSpriteRedraws()) do redraws[#redraws + 1] = r end
PaletteFX.setPass(nil)
PaletteFX.clearSpriteRedraws()
return redraws
end
local function noNarrowScissor(label)
for _, s in ipairs(scissors) do
local x, w = s[1], s[3]
check(x == nil or x + w >= 155,
label .. ": scissor never clips the pic short of x 155")
end
end
local r = renderIn("sgb", "ui")
noNarrowScissor("sgb")
eq(#picDraws, 1, "sgb draws the player pic once")
eq(picDraws[1] and picDraws[1][1], 115, "pic x 115 (diploma.asm:44 +33)")
eq(picDraws[1] and picDraws[1][2], 80, "pic y 80")
eq(bakes[1] and bakes[1].group, "diploma", "sgb keeps the OBP0 $90 DMG bake")
eq(#r, 0, "sgb records no OBJ-ramp redraw")
GameVersion.isBlue = function() return false end
r = renderIn("ogred", "ui")
noNarrowScissor("ogred")
eq(bakes[1] and bakes[1].group, "diploma_og", "OG RED bakes the OBJ ramp")
local c = PaletteFX.OG_RED_SOFT_OBJ
local ramp = bakes[1] and bakes[1].ramp or {}
check(ramp[2] == c[1] and ramp[3] == c[2] and ramp[4] == c[3],
"OG RED OBP0 $90 maps colors 1-3 to OBJ shades 0, 1, 2")
check(r[1] and r[1].image == fakePic and r[1].x == 115 and r[1].y == 80,
"OG RED replays the pic at (115, 80) after the zone pass")
check(r[2] and r[2].clip and r[2].clip[1] == 115 and r[2].clip[2] == 80
and r[2].clip[3] == 40 and r[2].clip[4] == 56,
"OG RED replays the BG text over the pic, clipped to the pic")
local canvasSets = 0
local origSetCanvas = love.graphics.setCanvas
love.graphics.setCanvas = function(c)
if c then canvasSets = canvasSets + 1 end
return origSetCanvas(c)
end
renderIn("ogred", "ui")
eq(canvasSets, 0, "OG RED reuses the cached text overlay on a second draw")
Game.save.player.name = "RED"
renderIn("ogred", "ui")
eq(canvasSets, 1, "a changed player name rebuilds the text overlay once")
Game.save.player.name = "ASH"
love.graphics.setCanvas = origSetCanvas
GameVersion.isBlue = function() return true end
r = renderIn("ogred", "ui")
eq(bakes[1] and bakes[1].group, "diploma_og_blue",
"OG BLUE bakes under a version-distinct cache group")
check(bakes[1] and bakes[1].ramp[3] == PaletteFX.GBC_OBJ_BLUE[2],
"OG BLUE uses Blue's OBJ ramp")
GameVersion.isBlue = origIsBlue
r = renderIn("ogred", nil)
eq(bakes[1] and bakes[1].group, "diploma", "printer path keeps the DMG bake")
eq(#r, 0, "printer path records no redraw")
Sprites.playerPic, SpriteRenderer.obpImage = origPlayerPic, origObp
love.graphics.setScissor, love.graphics.draw = origScissor, origDraw
PaletteFX.mode = origMode
-- Confirm dismissal on A or B press
Input.pressed = { a = true }
diploma:update()
check(done, "Diploma calls onDone on A press")
eq(Game.stack:top(), nil, "Diploma pops from stack")
S.finish()