Files
gen1recomp/tests/save_compat/gen2_tile_rom_test.lua
T
2026-10-01 17:30:52 -04:00

76 lines
3.2 KiB
Lua

package.path = "./?.lua;./?/init.lua;" .. package.path
love = love or require("tests.love_stub")
local T = require("tests.harness")
local Ctx = require("src.save_convert.Gen2MapContext")
local Extractor = require("src.import.RomExtractorGen2")
local Json = require("src.link.Json")
local Vm = require("src.script.gen2.Vm")
local Events = require("src.world.gen2.Events")
local function read(path)
local f = io.open(path, "rb")
if not f then return nil end
local text = f:read("*a")
f:close()
return text
end
local cases = {
{ "gold", "../pokegold/pokegold.gbc", 18 },
{ "silver", "../pokegold/pokesilver.gbc", 18 },
{ "crystal", "../pokecrystal/pokecrystal.gbc", 24 },
}
for _, row in ipairs(cases) do
local version, path = row[1], row[2]
local rom = read(os.getenv("GEN2_" .. version:upper() .. "_ROM") or path)
if rom then
local manifest = assert(Json.decode(assert(read("tools/rom_manifest_" .. version .. ".json"))))
local extractor = Extractor.new(rom, manifest)
extractor.write = function() end
local maps = extractor:extractMaps()
local scripts = extractor:extractScriptsAndText(maps, {}).scripts
local data = { maps = maps, scripts = scripts }
local count = 0
for id, def in pairs(maps) do
for _, callback in ipairs(def.callbacks or {}) do
if callback.callback == "MAPCALLBACK_TILES" and id ~= "PLAYERS_HOUSE_2F" then
count = count + 1
for pattern = 0, 3 do
local state = { events = {}, engineFlags = {} }
for i = 0, 255 do
state.events[i] = pattern == 0 and 0 or pattern == 1 and 255 or (i * 71 + pattern * 49) % 256
end
for i = 0, 200 do state.engineFlags[i] = pattern == 1 or pattern > 1 and i % pattern == 0 end
local patched = {}
for i, block in ipairs(def.blocks) do patched[i] = block end
local vm = Vm.new(scripts, {}, Events.new():restore(state.events), {
getEngineFlag = function(flag) return state.engineFlags[flag] end,
changeBlock = function(x, y, block) patched[y * def.width + x + 1] = block end,
})
T.eq(vm:runCallback(callback.scriptKey), true, version .. " " .. id .. " original callback runs in the runtime")
local callbacks, blocks = def.callbacks, def.blocks
for y = 0, def.height * 2 - 1, 2 do
for x = 0, def.width * 2 - 1, 2 do
local actual = assert(Ctx.reposition(data, version, def.group, def.map, x, y, state))
def.callbacks, def.blocks = {}, patched
local expected = assert(Ctx.reposition(data, version, def.group, def.map, x, y, {}))
def.callbacks, def.blocks = callbacks, blocks
local off = Ctx.offsetsFor(version).screenSave
T.eq(table.concat(actual.writes[off], ","), table.concat(expected.writes[off], ","),
version .. " " .. id .. " window matches the runtime callback at " .. x .. "," .. y)
end
end
end
end
end
end
T.eq(count, row[3], version .. " covers every non-bedroom tile callback")
else
io.write("SKIP " .. version .. " original-ROM callback checks: ROM not available\n")
end
end
T.finish()