mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-28 23:00:21 -04:00
109 lines
4.6 KiB
Lua
109 lines
4.6 KiB
Lua
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
|
|
local Constants = require("src.core.game3.constants")
|
|
local MovementEmerald = require("src.import.gba.movement_emerald")
|
|
local ExtractScripts = require("src.import.gba.extract_scripts")
|
|
local OwExtract = require("src.import.gba.ow_extract")
|
|
local GameVersion = require("src.core.GameVersion")
|
|
|
|
local em = Constants.of("emerald")
|
|
local fr = Constants.of("firered")
|
|
local EM = em.movement.byId.MOVEMENT_ACTION_
|
|
local FR = fr.movement.byId.MOVEMENT_ACTION_
|
|
|
|
local M = MovementEmerald.forGame("emerald")
|
|
eq(M.game, "emerald", "table game")
|
|
eq(M.stepEnd, 0xFE, "emerald MOVEMENT_ACTION_STEP_END")
|
|
|
|
local emIds = 0
|
|
local frNames = {}
|
|
for id, name in pairs(FR) do frNames[name] = id end
|
|
local shared, rse, maxRse = 0, 0, 0
|
|
local seenCanon = {}
|
|
for raw, name in pairs(EM) do
|
|
emIds = emIds + 1
|
|
local v = M.toCanon[raw]
|
|
check(v ~= nil, name .. " translates")
|
|
eq(MovementEmerald.nameOf(v), name, name .. " round trips by name")
|
|
check(not seenCanon[v], name .. " canonical id is unique")
|
|
seenCanon[v] = true
|
|
if frNames[name] then
|
|
shared = shared + 1
|
|
eq(v, fr:id("movement", name), name .. " keeps the FireRed number")
|
|
else
|
|
rse = rse + 1
|
|
check(v >= MovementEmerald.RSE_BASE, name .. " is in the RSE-only range")
|
|
if v > maxRse then maxRse = v end
|
|
end
|
|
end
|
|
eq(emIds, 160, "every Emerald MOVEMENT_ACTION id covered")
|
|
eq(M.count, 160, "table count")
|
|
eq(rse, MovementEmerald.canon().rseCount, "RSE-only count")
|
|
eq(shared + rse, 160, "shared + RSE-only")
|
|
eq(maxRse, MovementEmerald.RSE_BASE + rse - 1, "RSE-only ids are dense from 0x100")
|
|
|
|
eq(M.toCanon[em:id("movement", "MOVEMENT_ACTION_WALK_NORMAL_DOWN")], 0x10, "EM walk_normal_down 0x08 -> FR 0x10")
|
|
eq(M.toCanon[em:id("movement", "MOVEMENT_ACTION_WALK_SLOW_DOWN")],
|
|
fr:id("movement", "MOVEMENT_ACTION_WALK_SLOW_DOWN"), "EM walk_slow_down -> FR walk_slow_down")
|
|
eq(M.toCanon[0xFE], 0xFE, "step_end stays 0xFE")
|
|
eq(MovementEmerald.canonOf("MOVEMENT_ACTION_EMOTE_HEART"), MovementEmerald.RSE_BASE, "first RSE-only action")
|
|
eq(MovementEmerald.canonOf("MOVEMENT_ACTION_FIGURE_8"), MovementEmerald.RSE_BASE + rse - 1, "last RSE-only action")
|
|
|
|
local out, unknown = M.translate({ 0x08, 0x58, 0xFE })
|
|
eq(out[1], 0x10, "translate walk")
|
|
eq(out[2], MovementEmerald.canonOf("MOVEMENT_ACTION_EMOTE_HEART"), "translate emote heart")
|
|
eq(out[3], 0xFE, "translate end")
|
|
eq(unknown, nil, "no unknown bytes")
|
|
local _, bad = M.translate({ 0xF0, 0xFE })
|
|
eq(bad and bad[1], 0xF0, "undefined action byte reported")
|
|
|
|
check(ExtractScripts.movementTable("firered") == nil, "FireRed movement bytes are stored raw")
|
|
check(ExtractScripts.movementTable("leafgreen") == nil, "LeafGreen movement bytes are stored raw")
|
|
check(ExtractScripts.movementTable("emerald") == M, "Emerald movement bytes are translated")
|
|
|
|
local big = {}
|
|
for i = 1, 600 do big["g3:" .. string.format("%08x", i)] = { { op = "end", n = i } } end
|
|
local src = ExtractScripts.serializeChunked(big)
|
|
local back = assert(load(src, "@chunked", "t", {}))()
|
|
local n = 0
|
|
for k, v in pairs(back) do
|
|
n = n + 1
|
|
if v[1].n ~= tonumber(k:sub(4), 16) then check(false, "chunked value " .. k) end
|
|
end
|
|
eq(n, 600, "chunked serializer round trips every key")
|
|
eq(select(2, src:gsub("%(function%(T%)", "")), 3, "600 entries split into 3 chunks")
|
|
|
|
local bytes = {}
|
|
local function put(off, ...)
|
|
for i, b in ipairs({ ... }) do bytes[off + i - 1] = b end
|
|
end
|
|
put(0, 0, 89, 1, 90, 63, 91, 2, 92, 111, 112, 3, 93, 137, 138, 191, 192)
|
|
put(16, 100, 105, 101, 106, 102, 107, 103, 108, 111, 112, 104, 109, 137, 138, 191, 192)
|
|
put(32, 230, 231, 235, 236)
|
|
put(36, 0, 1, 1, 2, 63, 4, 2, 8, 111, 16, 89, 1, 90, 2, 91, 4, 92, 8, 112, 16)
|
|
local fake = { get = function(_, o) return bytes[o] or 0 end }
|
|
local spec = {
|
|
genders = 2,
|
|
stateNames = { "NORMAL", "MACH_BIKE", "ACRO_BIKE", "SURFING", "UNDERWATER", "FIELD_MOVE", "FISHING", "WATERING" },
|
|
player = 0, player_states = 8, rival = 16, rival_states = 8,
|
|
link_frlg = 32, link_rs = 34, state_flags = 36, state_flag_count = 5,
|
|
}
|
|
local av = OwExtract.readAvatars(fake, spec)
|
|
eq(av.player[1].state, "NORMAL", "state name")
|
|
eq(av.player[3].male, 63, "acro bike male")
|
|
eq(av.player[8].female, 192, "watering female")
|
|
eq(av.rival[4].female, 108, "rival surfing female")
|
|
eq(av.linkRs.female, 236, "link RS female")
|
|
eq(av.stateFlags.female[5].gfx, 112, "female underwater state row")
|
|
eq(av.stateFlags.female[5].flag, 16, "underwater flag bit")
|
|
|
|
local prev = GameVersion.get()
|
|
GameVersion.set("firered")
|
|
eq(OwExtract.readAvatars(fake), nil, "FireRed has no avatar table key")
|
|
GameVersion.set(prev)
|
|
|
|
T.finish("game3_movement_emerald_test")
|