Merge pull request #1780 from bryanthaboi/dev

gender name string
This commit is contained in:
bryanthaboi
2026-08-24 13:08:31 -04:00
committed by GitHub
4 changed files with 54 additions and 9 deletions
+9 -1
View File
@@ -9,6 +9,9 @@ local GameVersion = require("src.core.GameVersion")
local CacheContract = {}
CacheContract.FORMAT = "rom-cache-v10:"
CacheContract.VERSION_FORMAT = {
crystal = "rom-cache-v10-crystal2:",
}
CacheContract.MARKER_PATH = "rom-cache.complete"
CacheContract.REQUIRED_FILES = {
@@ -136,8 +139,13 @@ function CacheContract.requiredFilesFor(version)
return CacheContract.REQUIRED_FILES, false
end
function CacheContract.formatFor(version)
return CacheContract.VERSION_FORMAT[version] or CacheContract.FORMAT
end
function CacheContract.markerFor(version, sha1)
return CacheContract.FORMAT .. (sha1 or GameVersion.info(version).sha1)
return CacheContract.formatFor(version)
.. (sha1 or GameVersion.info(version).sha1)
end
function CacheContract.markerMatches(version, marker)
+4 -1
View File
@@ -2849,7 +2849,10 @@ function RomExtractorGen2:decodeGen2Text(bank, address, charmap, buffers)
out[#out + 1] = "\f"
elseif b == 0x55 then
out[#out + 1] = "\v"
elseif b == 0x52 then
elseif b == 0x52
or (b == 0x14 and inString and self.edition == "crystal") then
-- ../pokecrystal/constants/charmap.asm:6 <PLAY_G>,
-- ../pokecrystal/home/text.asm:243,380 PlaceGenderedPlayerName
out[#out + 1] = "{PLAYER}"
elseif b == 0x53 then
out[#out + 1] = "{RIVAL}"
+12 -7
View File
@@ -114,21 +114,26 @@ check(CacheContract.VERSION_REQUIRED_FILES.yellow ~= nil,
local CRYSTAL_1_0 = "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"
local CRYSTAL_1_1 = "f2f52230b536214ef7c9924f483392993e226cfb"
local CRYSTAL_FORMAT = CacheContract.formatFor("crystal")
eq(CacheContract.markerFor("crystal", CRYSTAL_1_1),
CacheContract.FORMAT .. CRYSTAL_1_1,
CRYSTAL_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,
eq(CacheContract.markerFor("crystal"), CRYSTAL_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),
check(CacheContract.markerMatches("crystal", CRYSTAL_FORMAT .. CRYSTAL_1_0),
"a marker written from the 1.0 hash matches crystal")
check(CacheContract.markerMatches("crystal", CacheContract.FORMAT .. CRYSTAL_1_1),
check(CacheContract.markerMatches("crystal", CRYSTAL_FORMAT .. CRYSTAL_1_1),
"a marker written from the 1.1 hash also matches crystal")
check(not CacheContract.markerMatches("crystal",
CacheContract.FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"),
CRYSTAL_FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"),
"a marker written from Red's hash does not match crystal")
check(not CacheContract.markerMatches("red", CacheContract.FORMAT .. CRYSTAL_1_1),
check(not CacheContract.markerMatches("red", CRYSTAL_FORMAT .. CRYSTAL_1_1),
"a marker written from Crystal's 1.1 hash does not match red")
check(not CacheContract.markerMatches("crystal",
CacheContract.FORMAT .. CRYSTAL_1_0),
"a crystal marker written on the shared format no longer matches")
local crystalFs = { prefix = "crystal-marker-test/", files = {} }
function crystalFs.exists(path) return crystalFs.files[crystalFs.prefix .. path] ~= nil end
@@ -146,7 +151,7 @@ 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")
CRYSTAL_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")
+29
View File
@@ -91,6 +91,35 @@ do
:format(extra))
end
-- ---- the gendered player name ---------------------------------------------
-- ../pokecrystal/constants/charmap.asm:6 <PLAY_G> ($14),
-- ../pokecrystal/home/text.asm:243,380 PlaceGenderedPlayerName
do
local Extractor = require("src.import.RomExtractorGen2")
local charmap = manifest("tools/rom_manifest_crystal.json").charmap
local function decode(edition, bytes)
local rom = {}
function rom:byte(_, address) return bytes[address] or 0x50 end
function rom:word(_, address)
return (bytes[address] or 0) + (bytes[address + 1] or 0) * 0x100
end
local extractor = setmetatable({ rom = rom, edition = edition }, Extractor)
return extractor:decodeGen2Text(0, 0, charmap)
end
local H, i, comma, space, bang = 0x87, 0xa8, 0xf4, 0x7f, 0xe7
local inString = { [0] = 0x00, H, i, comma, space, 0x14, bang, 0x57 }
eq(decode("crystal", inString), "Hi, {PLAYER}!",
"an in-string $14 decodes as the player's name")
eq(decode("gold", inString), "Hi, !",
"and only on Crystal, which is the only edition that writes one")
local command = { [0] = 0x14, 0x03, 0x00, H, i, 0x57 }
eq(decode("crystal", command), "{STRBUF}Hi",
"a $14 outside a string is still TX_STRINGBUFFER and eats its buffer id")
end
-- ---- the slots RomText fills ----------------------------------------------
-- decodeGen2Text emits {USER}, {TARGET} and {ENEMY} for the three names
-- PlaceMoveUsersName / PlaceMoveTargetsName / PlaceEnemysName write at