mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
110 lines
4.4 KiB
Lua
110 lines
4.4 KiB
Lua
-- Does pret's EVENT_* numbering actually match the cart's?
|
|
--
|
|
-- luajit tests/gold_flag_names_test.lua
|
|
--
|
|
-- tests/drivers/gold/flag_names.lua lets the Gold bot route assert
|
|
-- postconditions by name (EVENT_BEAT_FALKNER rather than 1213). That is only
|
|
-- sound if pret's const_def order in constants/event_flags.asm is the order the
|
|
-- retail ROM's scripts use -- and src/import/RomExtractorGen2.lua:3234 says
|
|
-- outright that it may not be, which is why extractInitialEvents reads the ids
|
|
-- off the cart rather than hardcoding them.
|
|
--
|
|
-- That warning is exactly what makes this test necessary: the two orderings
|
|
-- being equal is a fact about today's pokegold, not a guarantee. The check
|
|
-- replays pret's InitializeEventsScript body name-by-name against the ids the
|
|
-- extractor pulled from the ROM for the same script. They cover ids from 37 to
|
|
-- 1915 across every const_next region, so agreement across all of them is
|
|
-- strong evidence for the whole table, not just its head.
|
|
--
|
|
-- If pret renumbers, this goes red and the fix is to regenerate:
|
|
-- luajit tools/goldwalk/gen_flags.lua
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local S = require("tests.harness").suite("gold flag names")
|
|
local check, eq = S.check, S.eq
|
|
|
|
local names = dofile("tests/drivers/gold/flag_names.lua")
|
|
|
|
check(names.events.EVENT_BEAT_FALKNER ~= nil, "EVENT_* table is populated")
|
|
check(names.engine.ENGINE_ZEPHYRBADGE ~= nil, "ENGINE_* table is populated")
|
|
|
|
-- The eight Johto badges are consecutive bits of wJohtoBadges. Note the order
|
|
-- is the BITFIELD's, not the order a player earns them: MINERALBADGE (Jasmine)
|
|
-- sits at bit 4 and STORMBADGE (Chuck) at bit 5, while the walkthrough beats
|
|
-- Chuck first and Jasmine second (asm-walk sections 08 then 09). A route that
|
|
-- assumed "5th gym beaten == bit 5" would gate Surf and Fly on the wrong bit,
|
|
-- so pin the layout rather than just the presence.
|
|
local badges = {
|
|
"ENGINE_ZEPHYRBADGE", "ENGINE_HIVEBADGE", "ENGINE_PLAINBADGE",
|
|
"ENGINE_FOGBADGE", "ENGINE_MINERALBADGE", "ENGINE_STORMBADGE",
|
|
"ENGINE_GLACIERBADGE", "ENGINE_RISINGBADGE",
|
|
}
|
|
for i = 2, #badges do
|
|
eq(names.engine[badges[i]], names.engine[badges[i - 1]] + 1,
|
|
badges[i] .. " follows " .. badges[i - 1])
|
|
end
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- The cart cross-check
|
|
-- ---------------------------------------------------------------------------
|
|
-- Needs both a Gold cache (for the ROM-derived ids) and a pokegold checkout
|
|
-- (for the names). Either missing degrades to the fixture checks above rather
|
|
-- than failing, the same way tests/gen2_map_callbacks_test.lua handles it.
|
|
|
|
local cache = os.getenv("GOLD_CACHE")
|
|
if not cache then
|
|
cache = (os.getenv("HOME") or "") .. "/Library/Application Support/LOVE/gold-dev/gold"
|
|
end
|
|
local POKEGOLD = os.getenv("POKEGOLD") or "../pokegold"
|
|
|
|
local initialPath = cache .. "/data/generated/initial_events.lua"
|
|
local stdScripts = POKEGOLD .. "/engine/events/std_scripts.asm"
|
|
|
|
local function readable(path)
|
|
local fh = io.open(path, "r")
|
|
if not fh then return false end
|
|
fh:close()
|
|
return true
|
|
end
|
|
|
|
if not readable(initialPath) then
|
|
check(true, "gold cache absent : name table checked, cart cross-check SKIPPED")
|
|
S.finish()
|
|
return
|
|
end
|
|
if not readable(stdScripts) then
|
|
check(true, "pokegold absent : name table checked, cart cross-check SKIPPED")
|
|
S.finish()
|
|
return
|
|
end
|
|
|
|
local Flags = dofile("tools/goldwalk/flags.lua")
|
|
local romIds = assert(loadfile(initialPath))().flags
|
|
local pretNames = Flags.setEventsOf(stdScripts, "InitializeEventsScript")
|
|
|
|
eq(#pretNames, #romIds,
|
|
"InitializeEventsScript sets the same number of flags in pret and the cart")
|
|
|
|
local mismatches, span = {}, { lo = math.huge, hi = -math.huge }
|
|
for i, name in ipairs(pretNames) do
|
|
local want, got = names.events[name], romIds[i]
|
|
if got then
|
|
span.lo, span.hi = math.min(span.lo, got), math.max(span.hi, got)
|
|
end
|
|
if want ~= got then
|
|
mismatches[#mismatches + 1] =
|
|
("#%d %s pret=%s cart=%s"):format(i, name, tostring(want), tostring(got))
|
|
end
|
|
end
|
|
|
|
if #mismatches > 0 then
|
|
-- Print the first few: the whole list is one-per-flag noise, and the head is
|
|
-- enough to see whether it is a wholesale shift or a single retired const.
|
|
for i = 1, math.min(5, #mismatches) do print(" " .. mismatches[i]) end
|
|
end
|
|
eq(#mismatches, 0,
|
|
("pret numbering == cart numbering across ids %d..%d")
|
|
:format(span.lo, span.hi))
|
|
|
|
S.finish()
|