mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-19 20:20:19 +02:00
228 lines
6.7 KiB
Lua
228 lines
6.7 KiB
Lua
return function(game)
|
|
local U = dofile("tests/drivers/util.lua")
|
|
local TouchControls = require("src.core.TouchControls")
|
|
local TouchSkin = require("src.core.TouchSkin")
|
|
local Playfield = require("src.render.Playfield")
|
|
|
|
local dir = os.getenv("SHOT_DIR") or "/tmp/skin-cutout"
|
|
local gen2 = game.overworld == nil
|
|
local failures, checks = 0, 0
|
|
|
|
local SKIN = [[
|
|
return {
|
|
name = "containment_probe",
|
|
pages = {
|
|
{
|
|
name = "probe",
|
|
fullScreen = true,
|
|
viewport = { x = 0.25, y = 0.1, w = 0.5, h = 0.6 },
|
|
controls = { { bind = "nul", x = 0.5, y = 0.92, w = 0.04, h = 0.04 } },
|
|
},
|
|
},
|
|
}
|
|
]]
|
|
love.filesystem.createDirectory("skins/containment_probe")
|
|
assert(love.filesystem.write("skins/containment_probe/skin.lua", SKIN))
|
|
|
|
love.window.setMode(1280, 720, { resizable = true, highdpi = true })
|
|
love.graphics.setBackgroundColor(0, 0, 0, 1)
|
|
U.wait(2)
|
|
|
|
local options = gen2 and game.options or game.save.options
|
|
options.touchControls = { enabled = true, skin = "containment_probe" }
|
|
options.tilt = 0
|
|
options.zoom = 0
|
|
options.pipelines = {}
|
|
options.videoMode = "windowed"
|
|
options.faithfulRes = 0
|
|
game:applyOptions()
|
|
love.window.setMode(1280, 720, { resizable = true, highdpi = true })
|
|
U.wait(4)
|
|
|
|
U.log("gen:", gen2 and 2 or 1, "skin:", tostring(TouchControls.skinId),
|
|
"err:", tostring(TouchControls.skinError))
|
|
U.log("drawable:", TouchSkin.drawable(), "hasViewport:", TouchSkin.hasViewport())
|
|
|
|
local function cutoutPx()
|
|
local pw, ph = love.graphics.getPixelDimensions()
|
|
local x, y, w, h = Playfield.cutout(pw, ph)
|
|
return x, y, w, h, pw, ph
|
|
end
|
|
|
|
local cx, cy, cw, ch, pw, ph = cutoutPx()
|
|
if not cx then
|
|
U.log("FAIL no cutout is active; nothing to prove")
|
|
love.event.quit()
|
|
while true do coroutine.yield() end
|
|
end
|
|
U.log(("cutout px: %d,%d %dx%d in %dx%d"):format(cx, cy, cw, ch, pw, ph))
|
|
|
|
local INSET = 4
|
|
local function scan(label, data)
|
|
local w, h = data:getWidth(), data:getHeight()
|
|
local sx, sy = w / pw, h / ph
|
|
local x1, y1 = math.floor(cx * sx) - INSET, math.floor(cy * sy) - INSET
|
|
local x2 = math.ceil((cx + cw) * sx) + INSET
|
|
local y2 = math.ceil((cy + ch) * sy) + INSET
|
|
local bad, firstX, firstY, worst = 0, nil, nil, 0
|
|
local inked = 0
|
|
local step = math.max(2, math.floor(math.min(w, h) / 360))
|
|
for y = 0, h - 1, step do
|
|
for x = 0, w - 1, step do
|
|
local r, g, b = data:getPixel(x, y)
|
|
local lit = math.max(r, g, b)
|
|
local outside = x < x1 or x >= x2 or y < y1 or y >= y2
|
|
if outside then
|
|
if lit > 0.02 then
|
|
bad = bad + 1
|
|
if not firstX then firstX, firstY = x, y end
|
|
if lit > worst then worst = lit end
|
|
end
|
|
elseif lit > 0.02 then
|
|
inked = inked + 1
|
|
end
|
|
end
|
|
end
|
|
checks = checks + 1
|
|
if bad > 0 then
|
|
failures = failures + 1
|
|
U.log(("FAIL %s: %d lit samples outside the cutout (first %d,%d, max %.2f)")
|
|
:format(label, bad, firstX, firstY, worst))
|
|
elseif inked == 0 then
|
|
failures = failures + 1
|
|
U.log("FAIL " .. label .. ": nothing drew inside the cutout either")
|
|
else
|
|
U.log(("ok %s: contained (%d lit samples inside)"):format(label, inked))
|
|
end
|
|
end
|
|
|
|
local pending = nil
|
|
local function probe(label)
|
|
U.wait(2)
|
|
pending = label
|
|
love.graphics.captureScreenshot(function(data)
|
|
scan(pending, data)
|
|
pending = nil
|
|
end)
|
|
for _ = 1, 180 do
|
|
if not pending then break end
|
|
coroutine.yield()
|
|
end
|
|
if pending then
|
|
failures = failures + 1
|
|
U.log("FAIL " .. tostring(pending) .. ": screenshot never arrived")
|
|
pending = nil
|
|
end
|
|
if os.getenv("SHOT_PNG") == "1" then
|
|
U.shot(game, ("%s/%s.png"):format(dir, label:gsub("[^%w]+", "_")))
|
|
end
|
|
end
|
|
|
|
if gen2 then
|
|
for i = 1, 2 do
|
|
probe("gold_boot_" .. i)
|
|
U.wait(60)
|
|
end
|
|
for _ = 1, 240 do
|
|
if game.world and game.world.map then break end
|
|
game.input.pressQueue[#game.input.pressQueue + 1] = "start"
|
|
U.wait(4)
|
|
end
|
|
if game.world and game.world.map then
|
|
probe("gold_overworld")
|
|
local Zoom = require("src.render.Zoom")
|
|
Zoom.allowSurvey = true
|
|
for _, off in ipairs({ -2, -1, 1, 2 }) do
|
|
Zoom.offset = off
|
|
probe("gold_zoom_" .. (off < 0 and "out" or "in") .. math.abs(off))
|
|
end
|
|
Zoom.offset = 0
|
|
local function tap(button, frames)
|
|
game.input.pressQueue[#game.input.pressQueue + 1] = button
|
|
game.input.state[button] = true
|
|
U.wait(2)
|
|
game.input.state[button] = false
|
|
U.wait(frames or 12)
|
|
end
|
|
tap("start", 24)
|
|
probe("gold_start_menu")
|
|
tap("b", 12)
|
|
probe("gold_after_menu")
|
|
else
|
|
U.log("FAIL gold world never booted")
|
|
failures = failures + 1
|
|
end
|
|
else
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
game.save.party = { Pokemon.new(game.data, "CHARIZARD", 50) }
|
|
game.save.player.name = "bryan"
|
|
U.teleport(game, "PALLET_TOWN", 10, 8, "down")
|
|
U.wait(12)
|
|
probe("red_overworld")
|
|
|
|
local Zoom = require("src.render.Zoom")
|
|
local Renderer = require("src.render.Renderer")
|
|
Zoom.allowSurvey = true
|
|
local lo, hi = Zoom.offsetRange(Renderer:fitScale())
|
|
for off = lo, hi do
|
|
Zoom.offset = off
|
|
probe("red_zoom_" .. Zoom.offsetLabel(off))
|
|
end
|
|
Zoom.offset = 0
|
|
|
|
U.tap(game, "start")
|
|
U.wait(20)
|
|
probe("red_start_menu")
|
|
|
|
local function stress(label, mutate)
|
|
local state = game.stack:top()
|
|
local original = state.draw
|
|
state.draw = function(...)
|
|
original(...)
|
|
mutate()
|
|
end
|
|
probe(label)
|
|
state.draw = original
|
|
end
|
|
stress("red_screen_veil", function()
|
|
Renderer.screenVeil = { 1, 0.85 }
|
|
end)
|
|
stress("red_battle_wipe", function()
|
|
Renderer.battleWipe = { style = "spiralin", prog = 0.45 }
|
|
end)
|
|
stress("red_letterbox_paper", function()
|
|
Renderer.extendedWorldBand = true
|
|
end)
|
|
stress("red_ui_anchor", function()
|
|
Renderer.uiCentered = false
|
|
Renderer:setUIAnchor(0, 96, 160, 48, "bottom")
|
|
end)
|
|
U.tap(game, "b")
|
|
U.wait(10)
|
|
|
|
game.save.options.uiLayout = "dynamic"
|
|
game:applyOptions()
|
|
U.tap(game, "start")
|
|
U.wait(20)
|
|
probe("red_dynamic_start_menu")
|
|
U.tap(game, "b")
|
|
U.wait(10)
|
|
game.save.options.uiLayout = "centered"
|
|
game:applyOptions()
|
|
|
|
local Tilt = require("src.render.Tilt")
|
|
game.save.options.tilt = 1
|
|
Tilt.applyOptions(game.save.options)
|
|
U.wait(30)
|
|
probe("red_tilt")
|
|
game.save.options.tilt = 0
|
|
Tilt.applyOptions(game.save.options)
|
|
U.wait(20)
|
|
end
|
|
|
|
U.log(("done: %d/%d frames contained, %d failures")
|
|
:format(checks - failures, checks, failures))
|
|
love.event.quit()
|
|
while true do coroutine.yield() end
|
|
end
|