Files
gen1recomp/tests/engine/trade_art_import.lua
T
2026-08-24 09:33:51 +02:00

95 lines
3.7 KiB
Lua

-- The trade cinematic's Game Boy / cable / ball / bubble art must come out
-- of the ROM importer, not just the developer-only Python path (#750).
-- RomExtractor:extractTradeArt reads five symbols -- gfx/trade.asm
-- TradingAnimationGraphics(+2), engine/gfx/mon_icons.asm TradeBubbleIconGFX,
-- and the data/tilemaps.asm GameBoyTiles / LinkCableTiles id lists -- so
-- every shipped manifest has to carry them, the manifest generator has to
-- keep them on a regen, and RomImporter has to force pre-#750 caches to
-- re-import. Addresses below were byte-verified against the canonical
-- Red/Blue/Yellow ROMs (each payload occurs exactly once) and match
-- pokered.sym / pokeblue.sym.
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local function readFile(path)
local handle = io.open(path, "r")
if not handle then return nil end
local text = handle:read("*a")
handle:close()
return text
end
-- Red and Blue place the trade art identically; Yellow shifted it.
local RED_BLUE = {
GameBoyTiles = { 30, 23584 }, -- 1e:5c20
LinkCableTiles = { 30, 23632 }, -- 1e:5c50
TradeBubbleIconGFX = { 28, 23129 }, -- 1c:5a59
TradingAnimationGraphics = { 14, 27070 }, -- 0e:69be
TradingAnimationGraphics2 = { 14, 27854 }, -- 0e:6cce
}
local YELLOW = {
GameBoyTiles = { 30, 23932 },
LinkCableTiles = { 30, 23980 },
TradeBubbleIconGFX = { 28, 23302 },
TradingAnimationGraphics = { 14, 27240 },
TradingAnimationGraphics2 = { 14, 28024 },
}
local MANIFESTS = {
{ "tools/rom_manifest.json", RED_BLUE },
{ "tools/rom_manifest_blue.json", RED_BLUE },
{ "tools/rom_manifest_yellow.json", YELLOW },
}
for _, spec in ipairs(MANIFESTS) do
local path, expected = spec[1], spec[2]
local text = readFile(path)
T.check(text ~= nil, path .. " is readable")
if text then
for name, location in pairs(expected) do
local bank, addr = text:match(
'"' .. name .. '"%s*:%s*%[%s*(%d+)%s*,%s*(%d+)%s*%]')
T.eq(bank, tostring(location[1]),
path .. ": " .. name .. " bank")
T.eq(addr, tostring(location[2]),
path .. ": " .. name .. " address")
end
end
end
-- the manifests are generated, so the generator has to keep asking for the
-- symbols or the next regen silently drops the trade art again
local gen = readFile("tools/make_rom_manifest.py")
T.check(gen ~= nil, "tools/make_rom_manifest.py is readable")
if gen then
for name in pairs(RED_BLUE) do
T.check(gen:find('"' .. name .. '"', 1, true) ~= nil,
"a regenerated manifest keeps " .. name)
end
end
-- extractTradeArt exists, extractField calls it, and the field table
-- publishes the paths the same way the Python path's field.py does, so
-- TradeAnim's `game.data.field.tradeArt` lookup lands on both build paths
local extractor = readFile("src/import/RomExtractor.lua")
T.check(extractor ~= nil, "src/import/RomExtractor.lua is readable")
if extractor then
T.check(extractor:find("function RomExtractor:extractTradeArt", 1, true) ~= nil,
"RomExtractor has extractTradeArt")
T.check(extractor:find("self:extractTradeArt()", 1, true) ~= nil,
"extractField runs it")
T.check(extractor:find("data.tradeArt = tradeArt", 1, true) ~= nil,
"field.lua publishes tradeArt")
end
-- a cache imported before #750 has none of the art; the shared readiness
-- contract is what makes it re-import.
local CacheContract = require("src.import.CacheContract")
local required = {}
for _, path in ipairs(CacheContract.requiredFiles("red")) do required[path] = true end
T.eq(required["assets/generated/trade/game_boy.png"], true,
"required-file contract makes pre-#750 caches re-import the trade art")
T.finish("trade art import")