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

79 lines
2.2 KiB
Lua

local D = {}
local indexes = setmetatable({}, { __mode = "k" })
function D.regionsFor(gen, version)
local mod = require("src.save_convert.regions.gen" .. gen)
return mod.layouts[version] or mod.layouts.default
end
function D.index(regions, block)
indexes[regions] = indexes[regions] or {}
local key = block or "*"
local idx = indexes[regions][key]
if idx then return idx end
local list = {}
for _, r in ipairs(regions) do
if (block == nil and r.block == nil) or r.block == block then list[#list + 1] = r end
end
table.sort(list, function(a, b) return a.size > b.size end)
idx = {}
for _, r in ipairs(list) do
for o = r.offset, r.offset + r.size - 1 do idx[o] = r end
end
indexes[regions][key] = idx
return idx
end
function D.regionAt(regions, offset, block)
return D.index(regions, block)[offset]
end
local UNMAPPED = { name = "unmapped", tier = "?" }
function D.diff(a, b, regions, opts)
opts = opts or {}
local idx = D.index(regions, opts.block)
local base = opts.base or 0
local byName, order = {}, {}
local n = math.max(#a, #b)
for i = 1, n do
local x, y = a:byte(i), b:byte(i)
if x ~= y then
local off = base + i - 1
local r = idx[off] or UNMAPPED
if opts.includeDerived or not r.derived then
local e = byName[r.name]
if not e then
e = { name = r.name, tier = r.tier, ids = r.ids, count = 0, first = off, last = off,
derived = r.derived, sample = {} }
byName[r.name] = e
order[#order + 1] = e
end
e.count = e.count + 1
e.last = off
if #e.sample < 4 then
e.sample[#e.sample + 1] = ("%X:%s>%s"):format(off, x and ("%02X"):format(x) or "--",
y and ("%02X"):format(y) or "--")
end
end
end
end
return order
end
function D.format(entries, limit)
local out = {}
for i, e in ipairs(entries) do
if limit and i > limit then
out[#out + 1] = ("... +%d more regions"):format(#entries - limit)
break
end
out[#out + 1] = ("%s[%s%s] %dB 0x%X-0x%X %s"):format(e.name, e.tier or "?", e.ids and (" " .. e.ids) or "",
e.count, e.first, e.last, table.concat(e.sample, ","))
end
return table.concat(out, "; ")
end
return D