mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-25 23:11:15 +02:00
chris 1.1 hotfix
This commit is contained in:
@@ -37,6 +37,36 @@ eq(crystal.romSha1, GameVersion.VERSIONS.crystal.sha1,
|
||||
eq(crystal.generation, 2, "generation 2")
|
||||
eq(crystal.format, gold.format, "same manifest format as Gold")
|
||||
|
||||
-- ------- 1b. the 1.1 revision's symbol delta
|
||||
|
||||
local rev11
|
||||
for _, revision in ipairs(GameVersion.revisions("crystal")) do
|
||||
if revision.label == "1.1" then rev11 = revision end
|
||||
end
|
||||
check(rev11 ~= nil, "the crystal row names a 1.1 revision")
|
||||
|
||||
if rev11 then
|
||||
check(GameVersion.acceptsSha1("crystal", GameVersion.VERSIONS.crystal.sha1),
|
||||
"the crystal row accepts the canonical 1.0 sha1")
|
||||
check(GameVersion.acceptsSha1("crystal", rev11.sha1),
|
||||
"and the 1.1 sha1 too")
|
||||
|
||||
local overlay = (crystal.symbolRevisions or {})[rev11.sha1]
|
||||
check(type(overlay) == "table",
|
||||
"the manifest carries a symbolRevisions overlay for the 1.1 sha1")
|
||||
if overlay then
|
||||
eq(size(overlay), 1, "with exactly one symbol moved")
|
||||
local moved = overlay.Stadium2N64Attrmap
|
||||
check(type(moved) == "table", "and it names Stadium2N64Attrmap")
|
||||
local base = crystal.symbols.Stadium2N64Attrmap
|
||||
check(base ~= nil, "the base manifest still carries Stadium2N64Attrmap")
|
||||
if moved and base then
|
||||
check(not (moved[1] == base[1] and moved[2] == base[2]),
|
||||
"at a location different from the base symbols entry")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ------- 2. content counts
|
||||
|
||||
eq(size(crystal.maps), 388, "388 maps")
|
||||
|
||||
@@ -68,11 +68,56 @@ eq(GameVersion.ORDER[5], "silver", "silver keeps slot 5")
|
||||
-- ------- 4. sha1 routing
|
||||
|
||||
eq(GameVersion.forSha1("f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"), "crystal",
|
||||
"the retail Crystal sha1 resolves to crystal")
|
||||
"the retail Crystal 1.0 sha1 resolves to crystal")
|
||||
eq(GameVersion.forSha1("f2f52230b536214ef7c9924f483392993e226cfb"), "crystal",
|
||||
"the retail Crystal 1.1 sha1 also resolves to crystal")
|
||||
eq(GameVersion.forSha1("d8b8a3600a465308c9953dfa04f0081c05bdcb94"), "gold",
|
||||
"Gold's sha1 still resolves to gold")
|
||||
eq(GameVersion.forSha1("deadbeef"), nil, "an unknown ROM resolves to nothing")
|
||||
|
||||
-- ------- 4b. revisions / acceptsSha1 / revisionLabel
|
||||
|
||||
local crystalRevisions = GameVersion.revisions("crystal")
|
||||
eq(#crystalRevisions, 2, "crystal lists both accepted revisions")
|
||||
eq(crystalRevisions[1].sha1, "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133",
|
||||
"revision 1 is the 1.0 sha1")
|
||||
eq(crystalRevisions[1].label, "1.0", "revision 1 is labeled 1.0")
|
||||
eq(crystalRevisions[2].sha1, "f2f52230b536214ef7c9924f483392993e226cfb",
|
||||
"revision 2 is the 1.1 sha1")
|
||||
eq(crystalRevisions[2].label, "1.1", "revision 2 is labeled 1.1")
|
||||
|
||||
check(GameVersion.acceptsSha1("crystal", "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"),
|
||||
"crystal accepts the 1.0 sha1")
|
||||
check(GameVersion.acceptsSha1("crystal", "f2f52230b536214ef7c9924f483392993e226cfb"),
|
||||
"crystal accepts the 1.1 sha1")
|
||||
check(not GameVersion.acceptsSha1("crystal", "deadbeef"),
|
||||
"crystal rejects an unknown sha1")
|
||||
|
||||
eq(GameVersion.revisionLabel("crystal", "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"),
|
||||
"1.0", "revisionLabel resolves the 1.0 hash")
|
||||
eq(GameVersion.revisionLabel("crystal", "f2f52230b536214ef7c9924f483392993e226cfb"),
|
||||
"1.1", "revisionLabel resolves the 1.1 hash")
|
||||
eq(GameVersion.revisionLabel("crystal", "deadbeef"), nil,
|
||||
"revisionLabel is nil for an unrecognized hash")
|
||||
|
||||
local goldRevisions = GameVersion.revisions("gold")
|
||||
eq(#goldRevisions, 1, "gold synthesizes a single revision entry")
|
||||
eq(goldRevisions[1].sha1, GameVersion.info("gold").sha1,
|
||||
"the synthesized entry carries gold's canonical sha1")
|
||||
check(GameVersion.acceptsSha1("gold", GameVersion.info("gold").sha1),
|
||||
"gold accepts its own canonical sha1")
|
||||
check(not GameVersion.acceptsSha1("gold", "deadbeef"),
|
||||
"gold rejects an unknown sha1")
|
||||
eq(GameVersion.revisionLabel("gold", GameVersion.info("gold").sha1), nil,
|
||||
"gold's synthesized entry carries no label")
|
||||
|
||||
local redRevisions = GameVersion.revisions("red")
|
||||
eq(#redRevisions, 1, "red synthesizes a single revision entry")
|
||||
check(GameVersion.acceptsSha1("red", GameVersion.info("red").sha1),
|
||||
"red accepts its own canonical sha1")
|
||||
eq(GameVersion.forSha1(GameVersion.info("red").sha1), "red",
|
||||
"and forSha1 still resolves red through the synthesized entry")
|
||||
|
||||
-- ------- 5. set / get round trip
|
||||
|
||||
local savedCurrent = GameVersion.get()
|
||||
|
||||
@@ -110,6 +110,56 @@ check(not silverSet["assets/generated/trade/game_boy.png"],
|
||||
check(CacheContract.VERSION_REQUIRED_FILES.yellow ~= nil,
|
||||
"Yellow has version-specific required outputs")
|
||||
|
||||
-- Revisioned cache markers: Crystal accepts either the 1.0 or the 1.1 cart.
|
||||
local CRYSTAL_1_0 = "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"
|
||||
local CRYSTAL_1_1 = "f2f52230b536214ef7c9924f483392993e226cfb"
|
||||
|
||||
eq(CacheContract.markerFor("crystal", CRYSTAL_1_1),
|
||||
CacheContract.FORMAT .. CRYSTAL_1_1,
|
||||
"markerFor with an explicit sha1 uses that sha1, not the canonical one")
|
||||
eq(CacheContract.markerFor("crystal"), CacheContract.FORMAT .. CRYSTAL_1_0,
|
||||
"markerFor with no sha1 still defaults to the canonical (1.0) sha1")
|
||||
|
||||
check(CacheContract.markerMatches("crystal", CacheContract.FORMAT .. CRYSTAL_1_0),
|
||||
"a marker written from the 1.0 hash matches crystal")
|
||||
check(CacheContract.markerMatches("crystal", CacheContract.FORMAT .. CRYSTAL_1_1),
|
||||
"a marker written from the 1.1 hash also matches crystal")
|
||||
check(not CacheContract.markerMatches("crystal",
|
||||
CacheContract.FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"),
|
||||
"a marker written from Red's hash does not match crystal")
|
||||
check(not CacheContract.markerMatches("red", CacheContract.FORMAT .. CRYSTAL_1_1),
|
||||
"a marker written from Crystal's 1.1 hash does not match red")
|
||||
|
||||
local crystalFs = { prefix = "crystal-marker-test/", files = {} }
|
||||
function crystalFs.exists(path) return crystalFs.files[crystalFs.prefix .. path] ~= nil end
|
||||
function crystalFs.read(path) return crystalFs.files[crystalFs.prefix .. path] end
|
||||
function crystalFs.write(path, value)
|
||||
crystalFs.files[crystalFs.prefix .. path] = value
|
||||
return true
|
||||
end
|
||||
function crystalFs.remove(path) crystalFs.files[crystalFs.prefix .. path] = nil end
|
||||
|
||||
local crystalRequired = CacheContract.requiredFilesFor("crystal")
|
||||
for _, path in ipairs(crystalRequired) do
|
||||
crystalFs.files["crystal/" .. path] = true
|
||||
end
|
||||
local published11 = CacheContract.publish("crystal", crystalFs, CRYSTAL_1_1)
|
||||
check(published11, "publishing with the 1.1 sha1 succeeds")
|
||||
eq(crystalFs.files["crystal/" .. CacheContract.MARKER_PATH],
|
||||
CacheContract.FORMAT .. CRYSTAL_1_1, "the marker records the 1.1 sha1")
|
||||
check(CacheContract.isReady("crystal", crystalFs),
|
||||
"a cache published with the 1.1 sha1 still reads ready for crystal")
|
||||
|
||||
crystalFs.files["crystal/" .. CacheContract.MARKER_PATH] =
|
||||
CacheContract.FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"
|
||||
check(not CacheContract.isReady("crystal", crystalFs),
|
||||
"a marker from another version's hash does not read ready for crystal")
|
||||
|
||||
check(CacheContract.markerMatches("blue", CacheContract.markerFor("blue")),
|
||||
"blue's own marker still matches blue")
|
||||
check(not CacheContract.markerMatches("blue", CacheContract.markerFor("red")),
|
||||
"red's marker still does not match blue")
|
||||
|
||||
-- A throwing adapter must not strand the process in its temporary prefix.
|
||||
local throwingFs = { prefix = "before/" }
|
||||
function throwingFs.exists() error("probe failed") end
|
||||
|
||||
@@ -194,6 +194,21 @@ if not cache then
|
||||
cache = home .. "/Library/Application Support/LOVE/crystal-dev/crystal"
|
||||
end
|
||||
|
||||
local GameVersion = require("src.core.GameVersion")
|
||||
local CacheContract = require("src.import.CacheContract")
|
||||
|
||||
local function crystalCacheRevision()
|
||||
local fs = { prefix = "", read = function(rel) return readFile(cache .. "/" .. rel) end }
|
||||
local marker = CacheContract.readMarker("crystal", fs)
|
||||
if not marker then return "1.0" end
|
||||
for _, revision in ipairs(GameVersion.revisions("crystal")) do
|
||||
if marker == CacheContract.markerFor("crystal", revision.sha1) then
|
||||
return revision.label or "1.0"
|
||||
end
|
||||
end
|
||||
return "1.0"
|
||||
end
|
||||
|
||||
local function loadCache(rel)
|
||||
local chunk = loadfile(cache .. "/data/generated/" .. rel .. ".lua")
|
||||
if not chunk then return nil end
|
||||
@@ -338,7 +353,7 @@ local MAPS = {
|
||||
{ "centerAttrmap", "mobile_center_attrmap", 360,
|
||||
"gfx/mobile/mobile_center.attrmap" },
|
||||
{ "stadium2N64Tilemap", "stadium2_n64_tilemap", 360,
|
||||
"gfx/mobile/stadium2_n64.tilemap" },
|
||||
"revision" },
|
||||
{ "stadium2N64Attrmap", "stadium2_n64_attrmap", 360,
|
||||
"gfx/mobile/stadium2_n64.attrmap" },
|
||||
{ "dialpadTilemap", "dialpad_tilemap", 360, "gfx/mobile/dialpad.tilemap" },
|
||||
@@ -408,6 +423,14 @@ else
|
||||
|
||||
for _, row in ipairs(MAPS) do
|
||||
local key, file, bytes, source = row[1], row[2], row[3], row[4]
|
||||
local revisionLabel
|
||||
if key == "stadium2N64Tilemap" then
|
||||
-- ../pokecrystal/mobile/mobile_5c.asm:869
|
||||
revisionLabel = crystalCacheRevision()
|
||||
source = revisionLabel == "1.1"
|
||||
and "gfx/mobile/stadium2_n64_corrupt.tilemap"
|
||||
or "gfx/mobile/stadium2_n64.tilemap"
|
||||
end
|
||||
local entry = maps[key]
|
||||
local rel = "assets/generated/mobile/" .. file .. ".bin"
|
||||
if type(entry) ~= "table" then
|
||||
@@ -425,7 +448,10 @@ else
|
||||
check(true, "no ../pokecrystal: " .. source .. " not diffed (SKIP)")
|
||||
else
|
||||
check(blob == want:sub(1, bytes),
|
||||
"it is ../pokecrystal/" .. source .. " byte for byte")
|
||||
"it is ../pokecrystal/" .. source .. " byte for byte"
|
||||
.. (revisionLabel
|
||||
and (" (cache built from Crystal " .. revisionLabel .. ")")
|
||||
or ""))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user