Files
gen1recomp/tests/engine/frame_cap_display.lua
T

123 lines
4.4 KiB
Lua

package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local FrameCap = require("src.core.FrameCap")
local RefreshRate = require("src.core.RefreshRate")
RefreshRate.reset()
T.eq(FrameCap.DISPLAY, 0, "DISPLAY is the zero cap")
T.eq(FrameCap.CYCLE[#FrameCap.CYCLE], FrameCap.DISPLAY,
"and it is the last stop on the cycle ring")
T.eq(#FrameCap.CYCLE, #FrameCap.STEPS + 1,
"the ring is the steps plus that one stop")
T.eq(FrameCap.normalize(0), FrameCap.DISPLAY, "a stored 0 is DISPLAY")
T.eq(FrameCap.normalize(-5), FrameCap.DISPLAY, "and so is a negative cap")
T.eq(FrameCap.normalize(1), 30, "a positive cap below the floor still clamps")
T.eq(FrameCap.normalize(9999), 160, "and one above the ceiling still clamps")
T.eq(FrameCap.normalize(nil), 60, "nil is still the 60 default")
T.eq(FrameCap.normalize("junk"), 60, "and so is garbage")
T.eq(FrameCap.label(0), "DISPLAY", "the row prints DISPLAY for the zero cap")
T.eq(FrameCap.label(60), "60", "and plain numbers for the rest")
T.eq(FrameCap.cycle(160, 1), FrameCap.DISPLAY, "the ceiling cycles to DISPLAY")
T.eq(FrameCap.cycle(FrameCap.DISPLAY, 1), 30, "which then wraps to the floor")
T.eq(FrameCap.cycle(30, -1), FrameCap.DISPLAY, "and back down again")
T.eq(FrameCap.cycle(FrameCap.DISPLAY, -1), 160, "DISPLAY steps down to 160")
local before = FrameCap.current
FrameCap.apply(FrameCap.DISPLAY)
T.eq(FrameCap.current, 0, "apply stores the uncapped value as-is")
FrameCap.apply(before)
FrameCap.migrated = false
local opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "an unknown refresh leaves the 60 default alone")
T.eq(FrameCap.current, 60, "and paces to it")
local function measure(hz)
RefreshRate.reset()
for _ = 1, 31 do RefreshRate.sample(1 / hz) end
end
measure(90)
T.eq(RefreshRate.mismatch(), 90, "90Hz is not a multiple of 60")
T.eq(FrameCap.label(0), "DISPLAY (90HZ)", "so the row names the panel rate")
T.eq(FrameCap.label(60), "60 (90HZ)", "beside whatever the cap reads")
FrameCap.migrated = false
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, FrameCap.DISPLAY, "the untouched 60 default moves to DISPLAY")
T.eq(FrameCap.current, 0, "and the loop stops pacing")
T.eq(opts.fpsCapMigrated, true, "and stamps the marker that says it ran")
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "a later 60 is never rewritten")
T.eq(FrameCap.current, 60, "and paces to it")
FrameCap.migrated = false
opts = { fpsCap = 60, fpsCapMigrated = true }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "a 60 picked after the migration ran survives the next boot")
T.eq(FrameCap.current, 60, "which is the cap that session paces to")
FrameCap.migrated = false
opts = { fpsCap = 144 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 144, "a cap that is not the default is never migrated")
measure(144)
T.eq(RefreshRate.mismatch(), 144, "144Hz is no multiple of 60 either")
FrameCap.migrated = false
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "but a panel above the beat range keeps the shipped cap")
T.eq(opts.fpsCapMigrated, nil, "and is not marked migrated, so a slower panel still is")
measure(75)
FrameCap.migrated = false
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, FrameCap.DISPLAY, "75Hz has the same halved beat as 90 and migrates")
measure(120)
T.eq(RefreshRate.mismatch(), nil, "120Hz shows 60Hz logic 1:1")
T.eq(FrameCap.label(60), "60", "so the row says nothing about it")
FrameCap.migrated = false
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "and the 60 default stays put")
measure(59.94)
T.eq(RefreshRate.mismatch(), nil, "a 59.94Hz panel is within a hertz of 60")
measure(59)
T.eq(RefreshRate.hz(), 60, "the integer 59 a driver reports for it reads as 60")
T.eq(RefreshRate.period(), 1 / 60, "so the step period snapped to is the 60Hz one")
T.eq(RefreshRate.mismatch(), nil, "and it is no mismatch")
FrameCap.migrated = false
opts = { fpsCap = 60 }
FrameCap.applyOptions(opts)
T.eq(opts.fpsCap, 60, "nor does it move the cap")
measure(60.3)
T.eq(RefreshRate.hz(), 60, "a measured 60.3 quantizes to the panel's 60")
measure(59.7)
T.eq(RefreshRate.hz(), 60, "and so does a measured 59.7")
measure(89.8)
T.eq(RefreshRate.hz(), 90, "while a measured 89.8 is a 90Hz panel")
T.eq(RefreshRate.period(), 1 / 90, "with the 90Hz period, not the measurement's")
RefreshRate.reset()
FrameCap.migrated = false
FrameCap.apply(before)
T.finish("frame cap display")