Files
gen1recomp/tests/engine/textbox_sfx_speed_bug2087_test.lua

155 lines
4.5 KiB
Lua

-- home/delay.asm:15
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")
local Sound = require("src.core.Sound")
local TextBox = require("src.render.TextBox")
Sound.setRate(1)
local function stub(dur, playFor)
local src = { playing = true, steps = 0, stopped = false }
src.getDuration = function() return dur end
src.getPitch = function() return 1 end
src.isPlaying = function(self)
return self.playing and (not playFor or self.steps < playFor)
end
src.stop = function(self) self.stopped = true; self.playing = false end
return src
end
local function newGame(speed)
local game = {
save = { player = {}, options = { textSpeed = "FAST" } },
data = { audio = { fanfares = {}, sfx = {} }, text = {} },
logicSpeed = function() return speed end,
}
game.stack = {
states = {},
push = function(self, s) table.insert(self.states, s) end,
pop = function(self) return table.remove(self.states) end,
top = function(self) return self.states[#self.states] end,
}
game.input = {
queue = {},
wasPressed = function(self, btn) return self.queue[btn] or false end,
isDown = function(self, btn) return self.queue[btn] or false end,
}
return game
end
local budget = Sound.waitFrames(stub(1))
eq(budget, 62, "a 1 s sfx is 60 logic frames plus margin at 1X")
do
local game = newGame(4)
local src = stub(1, 240)
local box = TextBox.new(game, "Hi.", nil, { preSound = function() return src end })
game.stack:push(box)
local held = 0
for _ = 1, 1000 do
if not box.preSound then break end
box:update(1 / 60)
if not box.preSound then break end
src.steps = src.steps + 1
held = held + 1
end
check(not src.stopped, "at 4X the preSound gate never stops a source still playing")
eq(held, 240, "the gate holds every logic step of the sound's real length")
eq(box.preSrc, nil, "and releases once the source goes quiet")
end
do
local game = newGame(4)
local src = stub(1)
local box = TextBox.new(game, "Hi.", nil, { preSound = function() return src end })
game.stack:push(box)
local held = 0
for _ = 1, budget * 4 + 200 do
box:update(1 / 60)
if not box.preSound then break end
held = held + 1
end
check(src.stopped, "at 4X the safety stop still lands on a stuck source")
eq(held, budget * 4 - 1, "after the same wall time, four times the logic steps")
end
do
local game = newGame(1)
local src = stub(1)
local box = TextBox.new(game, "Hi.", nil, { preSound = function() return src end })
game.stack:push(box)
local held = 0
for _ = 1, budget + 200 do
box:update(1 / 60)
if not box.preSound then break end
held = held + 1
end
check(src.stopped, "at 1X a stuck source is stopped")
eq(held, budget - 1, "after exactly the frame budget")
end
do
local game = newGame(0 / 0)
local src = stub(1)
local box = TextBox.new(game, "Hi.", nil, { preSound = function() return src end })
game.stack:push(box)
box:update(1 / 60)
eq(box.preSrcLeft, budget - 1, "a NaN speed decrements by a whole frame")
end
-- engine/items/item_effects.asm:1807
do
local game = newGame(4)
local src = stub(1, 240)
local box = TextBox.new(game, "Hi.", nil, {
auto = { wait = false, delay = 0, sound = function() return src end },
})
game.stack:push(box)
local frames = 0
while not box.done and frames < 600 do
box:update(1 / 60)
frames = frames + 1
end
check(box.done, "the box finishes typing")
local held = 0
for _ = 1, 1000 do
if #game.stack.states == 0 then break end
box:update(1 / 60)
if #game.stack.states == 0 then break end
src.steps = src.steps + 1
held = held + 1
end
check(not src.stopped, "at 4X the auto gate never stops a source still playing")
eq(held, 240, "the auto gate holds every logic step of the sound's real length")
eq(#game.stack.states, 0, "and the box pops once the source goes quiet")
end
do
local game = newGame(4)
local src = stub(1)
local box = TextBox.new(game, "Hi.", nil, {
auto = { wait = false, delay = 0, sound = function() return src end },
})
game.stack:push(box)
local frames = 0
while not box.done and frames < 600 do
box:update(1 / 60)
frames = frames + 1
end
local held = 0
for _ = 1, budget * 4 + 200 do
box:update(1 / 60)
if #game.stack.states == 0 then break end
held = held + 1
end
check(src.stopped, "at 4X a stuck auto source is still stopped")
eq(held, budget * 4 - 1, "after four times the logic steps")
end
T.finish("textbox_sfx_speed_bug2087")