mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
150 lines
4.2 KiB
Lua
150 lines
4.2 KiB
Lua
-- Driver: boots straight into an online arena battle (POKEPORT_ARENA_SPEC),
|
|
-- plays it against an in-process headless guest over Net.loopbackPair, and
|
|
-- screenshots the battle and the launcher the arena returns to.
|
|
--
|
|
-- SHOT_DIR=/tmp/shots POKEPORT_ARENA_SPEC=tests/drivers/arena_boot_spec.lua \
|
|
-- POKEPORT_DRIVER=tests/drivers/arena_boot_loopback.lua love .
|
|
|
|
return function(game)
|
|
local U = dofile("tests/drivers/util.lua")
|
|
local DIR = os.getenv("SHOT_DIR") or "/tmp/shots"
|
|
os.execute('mkdir -p "' .. DIR .. '" 2>/dev/null')
|
|
|
|
local ctx = _G.POKEPORT_ARENA_TEST
|
|
if not ctx then
|
|
U.log("FAIL POKEPORT_ARENA_SPEC did not run (no loopback context)")
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
|
|
local arena = game.stack.states[1]
|
|
U.log("arena state:", tostring(arena and arena.screenId),
|
|
"stage:", tostring(arena and arena.stage))
|
|
if not (arena and arena.screenId == "ArenaState") then
|
|
U.log("FAIL the game did not boot into ArenaState")
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
if arena.stage ~= "running" then
|
|
U.log("FAIL the arena battle did not construct")
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
|
|
local shots = {
|
|
[60] = DIR .. "/arena_0_battle.png",
|
|
[400] = DIR .. "/arena_1_turns.png",
|
|
}
|
|
|
|
local function verify()
|
|
local ok = true
|
|
for _, path in pairs(shots) do
|
|
local f = io.open(path, "rb")
|
|
if f then
|
|
f:close()
|
|
U.log("captured", path)
|
|
else
|
|
ok = false
|
|
U.log("FAIL screenshot did not reach disk:", path)
|
|
end
|
|
end
|
|
U.log("arena finished: host result", tostring(ctx.result),
|
|
"guest result", tostring(ctx.guestResult))
|
|
if ctx.result ~= "win" and ctx.result ~= "lose" and ctx.result ~= "draw" then
|
|
ok = false
|
|
U.log("FAIL the arena reported no battle result")
|
|
end
|
|
return ok
|
|
end
|
|
|
|
local baseDraw = love.draw
|
|
local launcherShot, launcherFrames = false, 0
|
|
love.draw = function()
|
|
baseDraw()
|
|
if ctx.result and not launcherShot then
|
|
launcherFrames = launcherFrames + 1
|
|
if launcherFrames > 45 then
|
|
launcherShot = true
|
|
love.graphics.captureScreenshot(function(imagedata)
|
|
local encoded = imagedata:encode("png")
|
|
local path = DIR .. "/arena_2_launcher.png"
|
|
local f = io.open(path, "wb")
|
|
if f then
|
|
f:write(encoded:getString())
|
|
f:close()
|
|
U.log("captured", path)
|
|
else
|
|
U.log("FAIL screenshot did not reach disk:", path)
|
|
end
|
|
love.event.quit(verify() and 0 or 1)
|
|
end)
|
|
end
|
|
end
|
|
end
|
|
|
|
local LinkBattle = require("src.link.LinkBattle")
|
|
local SaveData = require("src.core.SaveData")
|
|
|
|
local guestInput = {
|
|
pressed = { a = true },
|
|
state = {},
|
|
pressQueue = {},
|
|
wasPressed = function(_, button) return button == "a" end,
|
|
isDown = function() return false end,
|
|
step = function() end,
|
|
}
|
|
local guestStack = { list = {} }
|
|
function guestStack:push(state, ...)
|
|
table.insert(self.list, state)
|
|
if state.enter then state:enter(...) end
|
|
end
|
|
function guestStack:pop() return table.remove(self.list) end
|
|
function guestStack:top() return self.list[#self.list] end
|
|
function guestStack:update(dt)
|
|
local top = self:top()
|
|
if top and top.update then top:update(dt) end
|
|
end
|
|
|
|
local guestGame = {
|
|
data = game.data,
|
|
input = guestInput,
|
|
stack = guestStack,
|
|
save = SaveData.newGame(),
|
|
}
|
|
local guest, why = LinkBattle.newGuest(guestGame, ctx.guestNet, {
|
|
myParty = ctx.guestParty,
|
|
theirParty = ctx.hostParty,
|
|
theirName = "RED",
|
|
seed = ctx.seed,
|
|
verdict = "full",
|
|
strict = true,
|
|
keepNetOpen = true,
|
|
})
|
|
if not guest then
|
|
U.log("FAIL headless guest could not start:", tostring(why))
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
guest.onFinish = function(result) ctx.guestResult = result end
|
|
guestStack:push(guest)
|
|
U.log("headless guest running")
|
|
|
|
for step = 1, 8000 do
|
|
table.insert(game.input.pressQueue, "a")
|
|
guestStack:update(1 / 60)
|
|
if shots[step] then game.capturePath = shots[step] end
|
|
coroutine.yield()
|
|
if ctx.result then break end
|
|
end
|
|
|
|
if not ctx.result then
|
|
U.log("FAIL the arena battle never finished")
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
|
|
while true do
|
|
coroutine.yield()
|
|
end
|
|
end
|