mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-03 08:07:07 -04:00
143 lines
5.3 KiB
Lua
143 lines
5.3 KiB
Lua
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
love = love or require("tests.love_stub")
|
|
|
|
local T = require("tests.harness")
|
|
local Font = require("src.render.Font")
|
|
Font.load({ font = require("tests.fixture_data.font") })
|
|
local TextBox = require("src.render.TextBox")
|
|
local Version = require("src.core.GameVersion")
|
|
local Timing = require("src.core.Timing")
|
|
package.loaded["src.core.Sound"] = { play = function() end, playPress = function() end }
|
|
|
|
local function make(text, opts, save)
|
|
local pressed, pops, calls = false, 0, 0
|
|
local game = {
|
|
data = {}, save = save or { options = { textSpeed = 1 } },
|
|
input = { wasPressed = function(_, key) return pressed == key end,
|
|
isDown = function() return false end },
|
|
stack = { pop = function() pops = pops + 1 end },
|
|
}
|
|
local box = TextBox.new(game, text, function() calls = calls + 1 end, opts)
|
|
return box, function(key)
|
|
pressed = key or false
|
|
box:update(1 / 60)
|
|
pressed = false
|
|
end, function() return pops, calls end
|
|
end
|
|
|
|
local function prompt(box, tick)
|
|
for _ = 1, 200 do
|
|
if box.waiting or box.done then return true end
|
|
tick()
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function advance(box, tick, key)
|
|
for _ = 1, Timing.TEXT_PRE_ADVANCE do tick() end
|
|
tick(key or "a")
|
|
end
|
|
|
|
local function rows(box, expected, label)
|
|
T.eq(#box.shown, #expected, label .. " physical row count")
|
|
for i, text in ipairs(expected) do
|
|
T.same(box.shown[i], Font.encode(text), label .. " glyph row " .. i)
|
|
end
|
|
T.same(box:visibleText(), expected, label .. " visibleText")
|
|
local drawCode, drawBox = Font.drawCode, Font.drawBox
|
|
local drawn = {}
|
|
Font.drawCode = function(code, x, y)
|
|
drawn[#drawn + 1] = { code = code, x = x, y = y }
|
|
end
|
|
Font.drawBox = function() end
|
|
local blink = box.blink
|
|
box.blink = 30
|
|
box:draw()
|
|
box.blink = blink
|
|
Font.drawCode, Font.drawBox = drawCode, drawBox
|
|
local want = {}
|
|
for i, text in ipairs(expected) do
|
|
local x = box.textX
|
|
for _, code in ipairs(Font.encode(text)) do
|
|
want[#want + 1] = { code = code, x = x, y = i == 1 and box.line1Y or box.line2Y }
|
|
x = x + Font.advanceOf(code)
|
|
end
|
|
end
|
|
T.same(drawn, want, label .. " drawn glyph positions")
|
|
end
|
|
|
|
-- pokered/home/text.asm:262
|
|
for _, edition in ipairs({ "red", "blue", "yellow" }) do
|
|
Version.set(edition)
|
|
local box, tick, counts = make("A\vB{DONE}")
|
|
T.check(prompt(box, tick), edition .. " reaches cont")
|
|
T.check(box.waiting and box.contAdvance, edition .. " waits before scrolling")
|
|
rows(box, { "A" }, edition .. " before cont")
|
|
tick("a")
|
|
T.check(box.waiting, edition .. " protected wait rejects early A")
|
|
advance(box, tick, "b")
|
|
T.eq(box.holdFrames, Timing.TEXT_SCROLL_PAIR, edition .. " scroll timing")
|
|
T.same(box.shown, { {}, {} }, edition .. " old upper row cleared before typing")
|
|
for _ = 1, Timing.TEXT_SCROLL_PAIR do tick() end
|
|
T.eq(box.charIndex, 0, edition .. " scroll hold suppresses typing")
|
|
T.check(prompt(box, tick), edition .. " completes after one cont press")
|
|
T.check(box.done and not box.waiting, edition .. " has no extra cont prompt")
|
|
rows(box, { "", "B" }, edition .. " single-row cont")
|
|
tick("a")
|
|
local pops, calls = counts()
|
|
T.eq(pops, 1, edition .. " closes once")
|
|
T.eq(calls, 1, edition .. " resumes callback once")
|
|
rows(make("A\vB{DONE}", { instant = true }), { "", "B" }, edition .. " instant cont")
|
|
local plain, plainTick = make("A\nB{DONE}")
|
|
T.check(prompt(plain, plainTick) and plain.done, edition .. " ordinary line has no cont wait")
|
|
rows(plain, { "A", "B" }, edition .. " ordinary line")
|
|
end
|
|
|
|
Version.set("red")
|
|
for _, case in ipairs({
|
|
{ "A\nB\vC", { "B", "C" }, "two-row cont" },
|
|
{ "\vB", { "", "B" }, "leading cont" },
|
|
{ "A\v\vB", { "", "B" }, "empty cont" },
|
|
{ "A\vB\vC", { "B", "C" }, "successive cont" },
|
|
}) do
|
|
local box, tick = make(case[1])
|
|
for _ = 1, 4 do
|
|
T.check(prompt(box, tick), case[3] .. " reaches next prompt")
|
|
if box.done then break end
|
|
advance(box, tick)
|
|
end
|
|
T.check(box.done, case[3] .. " completes")
|
|
rows(box, case[2], case[3])
|
|
rows(make(case[1], { instant = true }), case[2], case[3] .. " instant")
|
|
end
|
|
|
|
local para, tick = make("X\fA\vB")
|
|
T.check(prompt(para, tick) and not para.contAdvance, "para waits before clearing")
|
|
advance(para, tick)
|
|
T.eq(para.holdFrames, Timing.TEXT_PAGE_CLEAR, "para clear timing")
|
|
for _ = 1, Timing.TEXT_PAGE_CLEAR do tick() end
|
|
T.check(prompt(para, tick) and para.contAdvance, "para restarts at a one-row cont")
|
|
rows(para, { "A" }, "para restarts at top")
|
|
advance(para, tick)
|
|
T.check(prompt(para, tick) and para.done, "para then cont completes")
|
|
rows(para, { "", "B" }, "para then cont")
|
|
|
|
for _, edition in ipairs({ "gold", "firered" }) do
|
|
Version.set(edition)
|
|
local box, tick = make("A\vB")
|
|
T.check(prompt(box, tick) and box.contAdvance, edition .. " reaches cont")
|
|
advance(box, tick)
|
|
T.check(prompt(box, tick) and box.done, edition .. " completes cont")
|
|
rows(box, { "A", "B" }, edition .. " existing row semantics")
|
|
rows(make("A\vB", { instant = true }), { "A", "B" }, edition .. " instant unchanged")
|
|
end
|
|
|
|
Version.set("red")
|
|
local save2, tick2 = make("A\vB", nil, { generation = 2, options = { textSpeed = 1 } })
|
|
T.check(prompt(save2, tick2), "Gen 2 save reaches cont under default version")
|
|
advance(save2, tick2)
|
|
T.check(prompt(save2, tick2), "Gen 2 save completes cont")
|
|
rows(save2, { "A", "B" }, "Gen 2 save unchanged")
|
|
|
|
T.finish("text_cont_single_row_bug2634")
|