mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-05 00:47:49 -04:00
122 lines
6.8 KiB
Lua
122 lines
6.8 KiB
Lua
local U = require("tests.drivers.util")
|
|
|
|
return function(game)
|
|
local deadline = love.timer.getTime() + 25
|
|
local originalOptions, originalSaveOptions, originalWrite
|
|
local originalSessionOptions, originalSessionEngine
|
|
local Input = require("src.core.Input")
|
|
local Controls = require("src.ui.game3.controls_menu")
|
|
local BagMenu = require("src.ui.game3.bag_menu")
|
|
local Stack = require("src.ui.game3.stack")
|
|
local Options = require("src.core.game3.options")
|
|
local ok, err = xpcall(function()
|
|
local identity = os.getenv("POKEPORT_IDENTITY") or ""
|
|
assert(identity ~= "" and identity ~= "pokemon-love2d", "isolated READY identity required")
|
|
local out = assert(os.getenv("POKEPORT_SHOT_DIR"), "shot directory required")
|
|
local function wait(n)
|
|
for _ = 1, n do assert(love.timer.getTime() < deadline, "H17 watchdog"); U.wait(1) end
|
|
end
|
|
local function untilReady(fn, label)
|
|
for _ = 1, 1600 do if fn() then return end; wait(1) end
|
|
error("H17 did not settle: " .. label)
|
|
end
|
|
untilReady(function() return game.phase == "boot" and game.boot end, "native boot")
|
|
game:_handleBootAction({action = "new_game", name = "MAY", gender = 1})
|
|
untilReady(function() return game.session and game.phase == "field" end, "native field")
|
|
local Fade = require("src.ui.game3.fade")
|
|
local function uncovered() return not Fade.isActive() and Fade.t == 0 and not Fade.lockInput end
|
|
untilReady(uncovered, "uncovered new field")
|
|
local version = require("src.core.GameVersion").get()
|
|
assert(version == "emerald" or version == "firered" or version == "leafgreen", "native RSE/FRLG route required")
|
|
originalOptions, originalSaveOptions = game.options, game.save and game.save.options
|
|
originalWrite = rawget(game, "writeOptions")
|
|
originalSessionOptions, originalSessionEngine = game.session.options, game.session.engineOptions
|
|
local detached = {}
|
|
for k, v in pairs(game.options or {}) do if k ~= "bindings" then detached[k] = v end end
|
|
local blockId = Options.blockId(game.session)
|
|
detached[blockId] = {}
|
|
for k, v in pairs(originalSessionOptions) do detached[blockId][k] = v end
|
|
game.options = detached
|
|
Options.bind(game.session, detached)
|
|
if version ~= "emerald" then assert(Options.ensure(game.session).buttonMode == 0, "first FRLG capture must exercise default Help mode") end
|
|
if game.save then game.save.options = detached end
|
|
local writes = 0
|
|
game.writeOptions = function() writes = writes + 1 end
|
|
Input:applyBindings(nil); Input:reset()
|
|
Stack.clear()
|
|
local function shot(name, id)
|
|
wait(8)
|
|
untilReady(uncovered, "uncovered " .. name)
|
|
assert(Stack.top() and Stack.top().id == id, "intended screenshot screen missing")
|
|
assert(U.still(game, out .. "/" .. name .. ".png"), "capture did not reach disk")
|
|
assert(love.timer.getTime() < deadline, "capture deadline")
|
|
end
|
|
local function tap(btn)
|
|
Input:overlayPressed(btn); wait(1); Input:overlayReleased(btn); wait(1)
|
|
end
|
|
local function bind(id)
|
|
Controls.show({game = game}); wait(4)
|
|
local bm = assert(Controls._bm)
|
|
for i, row in ipairs(bm.items) do if row.button.id == id then bm.index = i end end
|
|
tap("a"); assert(bm.capture and not bm.pending, "actual Controls did not arm")
|
|
game:gamepadpressed(nil, "leftshoulder"); wait(1)
|
|
assert(bm.pending and bm.pending.value == "leftshoulder", "candidate must wait for release")
|
|
game:gamepadreleased(nil, "leftshoulder"); wait(1)
|
|
assert(not bm.capture and game.options.bindings[id].pad == "leftshoulder", "actual released binding was not stored")
|
|
assert(not Input:isDown("a") and not Input:isDown("l"), "capture release left gameplay hold")
|
|
end
|
|
bind("a")
|
|
assert(detached.bindings.l.pad == "a" and writes == 1, "actual A/L swap or deferred write failed")
|
|
shot("01-controls-A-on-LB", "controls")
|
|
tap("b"); assert(not Controls.open, "Controls close failed")
|
|
assert(Input.padBindings.leftshoulder == "a" and Input.padBindings.a == "l", "closed menu did not apply actual swap")
|
|
local Bag = require("src.core.game3.bag")
|
|
local Items = require("src.core.game3.items_data")
|
|
Options.set(game.session, "buttonMode", 1)
|
|
local session = {version = version, party = game.session.party, bag = Bag.new()}
|
|
Options.bind(session, detached)
|
|
assert(session.options == game.session.options and Options.lrMode(game.session), "actual game and Bag must share canonical LR options")
|
|
local keyItem
|
|
for id = 1, 376 do if Items.pocketOf(id) == "KEY_ITEMS" then keyItem = id; break end end
|
|
assert(keyItem, "required real ROM key item missing")
|
|
session.bag.pockets.KEY_ITEMS = {{id = keyItem, qty = 1}}
|
|
BagMenu.show(session, {pocket = "KEY_ITEMS"}); BagMenu.settle(); wait(4)
|
|
assert(BagMenu.currentPocket() == "KEY_ITEMS" and BagMenu.mode == "list", "real LR bag did not settle")
|
|
game:gamepadpressed(nil, "leftshoulder"); wait(1)
|
|
game:gamepadreleased(nil, "leftshoulder"); wait(4)
|
|
assert(BagMenu.currentPocket() == "KEY_ITEMS" and BagMenu.mode == "action", "configured LB A was consumed as pocket L")
|
|
shot("02-LR-key-item-action-with-LB", "bag")
|
|
BagMenu.close(); Input:reset()
|
|
detached.bindings = nil; Input:applyBindings(nil)
|
|
bind("speedUp")
|
|
assert(detached.bindings.l.pad == "triggerright", "actual SPEED+/L swap missing")
|
|
tap("b")
|
|
local Speed = require("src.core.GameSpeed")
|
|
local key = Speed.optionKey(game:speedCategory())
|
|
local expected = Speed.cycle(detached[key], 1)
|
|
game:gamepadpressed(nil, "leftshoulder"); wait(1)
|
|
game:gamepadreleased(nil, "leftshoulder"); wait(1)
|
|
assert(detached[key] == expected and not Input:isDown("l"), "explicit native shoulder speed action failed")
|
|
Controls.show({game = game}); wait(4)
|
|
for i, row in ipairs(Controls._bm.items) do if row.button.id == "speedUp" then Controls._bm.index = i end end
|
|
shot("03-controls-SPEED-plus-on-LB", "controls")
|
|
tap("b")
|
|
BagMenu.show(session, {pocket = "KEY_ITEMS"}); BagMenu.settle(); wait(4)
|
|
game:gamepadaxis(nil, "triggerright", 1); wait(1)
|
|
game:gamepadaxis(nil, "triggerright", 0); wait(8)
|
|
local priorPocket = version == "emerald" and "BERRY_POUCH" or "ITEMS"
|
|
assert(BagMenu.currentPocket() == priorPocket, "moved L on old R2 did not reach edition-specific actual LR bag consumer")
|
|
print("PASS H17 real Controls capture/release/swap, LR Bag A consumer, native explicit SPEED+ and moved L")
|
|
end, debug.traceback)
|
|
BagMenu.close(); Controls.close()
|
|
if originalOptions then
|
|
game.options = originalOptions
|
|
if game.save then game.save.options = originalSaveOptions end
|
|
game.writeOptions = originalWrite
|
|
game.session.options, game.session.engineOptions = originalSessionOptions, originalSessionEngine
|
|
Input:applyBindings(originalOptions.bindings); Input:reset()
|
|
end
|
|
if not ok then print("FAIL H17 " .. tostring(err)) end
|
|
love.event.quit(ok and 0 or 1)
|
|
end
|