mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
170 lines
6.9 KiB
Lua
170 lines
6.9 KiB
Lua
#!/usr/bin/env luajit
|
|
-- pokefirered/src/pokemon_summary_screen.c:1862
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
|
|
local PRET = "../pokefirered"
|
|
local GFX = PRET .. "/graphics/summary_screen/"
|
|
local ROM_SHA1 = "41cb23d8dccc8ebd7c649cd8fbb58eeace6e2fdc"
|
|
|
|
local function slurp(p)
|
|
local f = io.open(p, "rb")
|
|
if not f then return nil end
|
|
local d = f:read("*a")
|
|
f:close()
|
|
return d
|
|
end
|
|
|
|
local tiles = slurp(GFX .. "bg.4bpp")
|
|
local pal = slurp(GFX .. "bg.gbapal")
|
|
local romPresent = slurp(PRET .. "/pokefirered.gba") ~= nil
|
|
if not (tiles and pal and romPresent) then
|
|
print("[skip] " .. PRET .. " summary graphics or ROM not present")
|
|
os.exit(0)
|
|
end
|
|
|
|
local function u16(s, i) return s:byte(i + 1) + s:byte(i + 2) * 256 end
|
|
|
|
-- pokefirered/src/pokemon_summary_screen.c:3276
|
|
local BASE = 345
|
|
local PROGRESS = {
|
|
info = { { 17, 13, 0 }, { 33, 13, 1 }, { 16, 14, 0 }, { 32, 14, 1 }, { 18, 15, 0 }, { 34, 15, 1 },
|
|
{ 20, 16, 0 }, { 36, 16, 1 }, { 18, 17, 0 }, { 34, 17, 1 }, { 21, 18, 0 }, { 37, 18, 1 } },
|
|
moves = { { 49, 13, 0 }, { 65, 13, 1 }, { 1, 14, 0 }, { 19, 14, 1 }, { 49, 15, 0 }, { 65, 15, 1 },
|
|
{ 1, 16, 0 }, { 19, 16, 1 }, { 17, 17, 0 }, { 33, 17, 1 }, { 48, 18, 0 }, { 64, 18, 1 } },
|
|
moves_info_select = { { 1, 13, 0 }, { 1, 14, 0 }, { 1, 15, 0 }, { 1, 16, 0 },
|
|
{ 19, 13, 1 }, { 19, 14, 1 }, { 19, 15, 1 }, { 19, 16, 1 },
|
|
{ 50, 17, 0 }, { 66, 17, 1 }, { 48, 18, 0 }, { 64, 18, 1 } },
|
|
}
|
|
|
|
local function render(binName, progressKind, shiny)
|
|
local map = assert(slurp(GFX .. binName), binName)
|
|
local entries = {}
|
|
for i = 0, 32 * 20 - 1 do entries[i] = u16(map, i * 2) end
|
|
for _, p in ipairs(PROGRESS[progressKind] or {}) do
|
|
entries[p[3] * 32 + p[2]] = p[1] + BASE
|
|
end
|
|
local out = {}
|
|
for ty = 0, 19 do
|
|
for tx = 0, 29 do
|
|
local e = entries[ty * 32 + tx]
|
|
local tile, hf, vf, pn = e % 1024, math.floor(e / 1024) % 2 == 1, math.floor(e / 2048) % 2 == 1, math.floor(e / 4096)
|
|
local bank = pn
|
|
if shiny and pn == 0 then bank = 6 elseif shiny and pn == 1 then bank = 5 end
|
|
for y = 0, 7 do
|
|
for x = 0, 7 do
|
|
local sx, sy = hf and (7 - x) or x, vf and (7 - y) or y
|
|
local b = tiles:byte(tile * 32 + sy * 4 + math.floor(sx / 2) + 1) or 0
|
|
local idx = (sx % 2 == 0) and (b % 16) or math.floor(b / 16)
|
|
if idx ~= 0 then
|
|
out[(ty * 8 + y) * 240 + tx * 8 + x] = u16(pal, bank * 32 + idx * 2) % 32768
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function to15(rgba, i)
|
|
local r, g, b = rgba:byte(i * 4 + 1), rgba:byte(i * 4 + 2), rgba:byte(i * 4 + 3)
|
|
local function c5(v) return math.floor(v * 31 / 255 + 0.5) end
|
|
return c5(r) + c5(g) * 32 + c5(b) * 1024, rgba:byte(i * 4 + 4)
|
|
end
|
|
|
|
local function compare(label, bake, want, w, h, ox, oy, opaque)
|
|
if not bake then check(false, label .. " was baked") return end
|
|
eq(#bake, w * h * 4, label .. " size")
|
|
local bad = 0
|
|
for y = 0, h - 1 do
|
|
for x = 0, w - 1 do
|
|
local c, a = to15(bake, y * w + x)
|
|
local p = want[(y + oy) * 240 + x + ox]
|
|
if p == nil then
|
|
if not opaque and a ~= 0 then bad = bad + 1 end
|
|
elseif a == 0 or c ~= p then
|
|
bad = bad + 1
|
|
end
|
|
end
|
|
end
|
|
eq(bad, 0, label .. " matches pret's tilemap render pixel for pixel")
|
|
end
|
|
|
|
local FileIO = require("src.import.gba.file_io")
|
|
local imports = FileIO.makeImports(PRET .. "/pokefirered.gba", ROM_SHA1, "firered")
|
|
local rom = assert(require("src.import.gba.rom").open(imports, "firered"))
|
|
local mem = { files = {} }
|
|
function mem:write(p, d) self.files[p] = d end
|
|
function mem:exists(p) return self.files[p] ~= nil end
|
|
require("src.import.gba.summary_chrome_extract").run(rom, mem, { cacheRoot = "X" })
|
|
local function baked(name) return mem.files["X/pokemon/summary/" .. name] end
|
|
|
|
print("[test] 1. KNOWN MOVES keeps the picture frame; move detail swaps it")
|
|
for _, shiny in ipairs({ false, true }) do
|
|
local sfx = shiny and "_shiny" or ""
|
|
compare("bg3_info" .. sfx, baked("bg3_info" .. sfx .. ".rgba"), render("moves_info_page.bin", nil, shiny), 240, 160, 0, 0, true)
|
|
compare("bg3_moves" .. sfx, baked("bg3_moves" .. sfx .. ".rgba"), render("moves_page.bin", nil, shiny), 240, 160, 0, 0, true)
|
|
for _, layer in ipairs({ "info", "moves", "moves_info" }) do
|
|
compare("layer_" .. layer .. sfx, baked("layer_" .. layer .. sfx .. ".rgba"),
|
|
render("page_" .. layer .. ".bin", nil, shiny), 240, 160, 0, 0, false)
|
|
end
|
|
for _, kind in ipairs({ "info", "moves", "moves_info_select" }) do
|
|
local base = kind == "moves_info_select" and "moves_page.bin" or "moves_info_page.bin"
|
|
compare("progress_" .. kind .. sfx, baked("progress_" .. kind .. sfx .. ".rgba"),
|
|
render(base, kind, shiny), 48, 16, 104, 0, true)
|
|
end
|
|
end
|
|
check(baked("page_moves.rgba") == nil, "the old move-detail bake under the KNOWN MOVES name is gone")
|
|
check(baked("page_info.rgba") ~= nil, "page_info.rgba still marks the cache ready")
|
|
|
|
print("[test] 2. manifest carries the ROM tables the screen reads")
|
|
local manifest = baked("manifest.lua")
|
|
local m = manifest and load(manifest, "=manifest", "t", {})()
|
|
check(m ~= nil, "the manifest loads")
|
|
if m then
|
|
local n = 0
|
|
for _ in pairs(m.noFlip or {}) do n = n + 1 end
|
|
eq(n, 18, "eighteen species are never flipped")
|
|
eq(m.noFlip and m.noFlip[25], nil, "Pikachu is flipped")
|
|
local lens = {}
|
|
for i, d in ipairs(m.monPicBounce or {}) do lens[i] = #d end
|
|
eq(table.concat(lens, ","), "3,5,7,7", "four pic bounce tables")
|
|
eq(m.monPicBounce and m.monPicBounce[4] and m.monPicBounce[4][1], -5, "the full-HP bounce starts at -5")
|
|
local el = {}
|
|
for i, d in ipairs(m.eggPicShake or {}) do el[i] = #d end
|
|
eq(table.concat(el, ","), "11,11,15", "three egg shake tables")
|
|
eq(m.eggPicShake and m.eggPicShake[3] and m.eggPicShake[3][7], -2, "AlmostReadyToHatch step 7 is -2")
|
|
local c = m.moveTextColors and m.moveTextColors[3]
|
|
check(c and c.fg[1] > 200 and c.fg[2] < 40, "PP colour 3 is red")
|
|
eq(m.coords and m.coords.status and m.coords.status.y, 34, "status is stored as a top-left")
|
|
end
|
|
|
|
print("[test] 3. markings sheet")
|
|
local marks = baked("markings.rgba")
|
|
eq(marks and #marks, 32 * 128 * 4, "sixteen 32x8 marking combos")
|
|
if marks then
|
|
local lit0, lit5 = 0, 0
|
|
for i = 0, 32 * 8 - 1 do
|
|
if marks:byte(i * 4 + 4) > 0 then lit0 = lit0 + 1 end
|
|
if marks:byte((5 * 256 + i) * 4 + 4) > 0 then lit5 = lit5 + 1 end
|
|
end
|
|
check(lit0 > 0 and lit5 > 0, "combos have pixels")
|
|
end
|
|
|
|
print("[test] 4. the imported cache")
|
|
local Cache = require("tests.game3_cache")
|
|
local root = Cache.root("meta.json")
|
|
if not root then
|
|
print("[skip] " .. tostring(Cache.reason))
|
|
else
|
|
for _, name in ipairs({ "bg3_info.rgba", "layer_moves.rgba", "progress_moves_info_select.rgba", "markings.rgba" }) do
|
|
local d = slurp(root .. "/pokemon/summary/" .. name)
|
|
check(d ~= nil and d == baked(name), "the cache's " .. name .. " is the current bake")
|
|
end
|
|
end
|
|
|
|
T.finish("game3_summary_chrome_bake_s3_test")
|