mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-25 23:11:15 +02:00
Give Gen 2 the ROM text table Gen 1 has had all along
Gold and Silver had no label-keyed string table at all. The manifests carried no text section, RomExtractorGen2 had no extractText, and game.data.text was never assigned, so every call through src/core/RomText.lua fell back to the literal written beside it. The only Gen 2 text the cache held was the script text in data/generated/text.lua, keyed by bank:address for the overworld VM, which nothing can look a battle line up in. make_gold_manifest.py now walks data/text/'s five dialogue files for their labels, the way make_rom_manifest.text_metadata walks pokered's, and embeds each one's symbol. 889 labels, all of them resolving in both editions. make_silver_manifest.py inherits the list unchanged and re-resolves the addresses from pokesilver.sym. RomExtractorGen2:extractText decodes them into data/generated/rom_text.lua. The mechanism is the one extractOakSpeech already used for _OakText1-7: resolve the label, decode from the cart, key by name. What is new is that the list comes from the manifest rather than being written out in Lua, so all of data/text/ arrives instead of seven strings. decodeGen2Text also emits the three runtime name slots it used to drop. PlaceMoveUsersName, PlaceMoveTargetsName and PlaceEnemysName (home/text.asm) substitute a battler's name as the line prints, so <USER>, <TARGET> and <ENEMY> are markers, not glyphs. Skipped as control glyphs, SubTookDamageText decoded as "The SUBSTITUTE / took damage for" with nothing after it. Game2:load assigns the table to self.data.text, which is what makes the existing shared RomText helper work on Gold and Silver at all. The new cache file is listed in the Gold override rather than bumping CACHE_FORMAT, so caches built before this stage re-import themselves and Red, Blue and Yellow are left alone.
This commit is contained in:
@@ -943,6 +943,12 @@ function Game2:load()
|
||||
self.data.gen2Scripts = loadGenerated("data/generated/scripts.lua")
|
||||
self.data.gen2StdScripts = loadGenerated("data/generated/std_scripts.lua")
|
||||
self.data.gen2Text = loadGenerated("data/generated/text.lua")
|
||||
-- The engine's own strings, keyed by the disassembly's label. gen2Text
|
||||
-- above is the script text and is keyed by bank:address for the overworld
|
||||
-- VM, so the two are different tables and both are loaded. This one is
|
||||
-- what src/core/RomText.lua reads, which is why it lands on `text`: that
|
||||
-- helper is shared with Gen 1 and looks up data.text[label].
|
||||
self.data.text = loadGenerated("data/generated/rom_text.lua") or {}
|
||||
-- data/generated/events.lua: the side tables a script command NAMES rather
|
||||
-- than carries -- the phone book, the in-game trades, the elevator's floor
|
||||
-- labels, the decoration descriptions. Keyed for World's own `eventTables`
|
||||
|
||||
@@ -27,7 +27,7 @@ RomExtractorGen2.__index = RomExtractorGen2
|
||||
-- scripts, pokemon, moves, items, marts, encounters, trainers, pokedex,
|
||||
-- landmarks, intro movie, menu gfx, title, credits, diploma, trade animation,
|
||||
-- audio, stubs
|
||||
local STAGE_COUNT = 26
|
||||
local STAGE_COUNT = 27
|
||||
local Opcodes = require("src.script.gen2.Opcodes")
|
||||
|
||||
-- BG palette slots inside one loaded 8-palette set (constants/tileset_constants.asm
|
||||
@@ -136,6 +136,18 @@ local TEXT_NO_GLYPH = {
|
||||
[0x13] = true, [0x15] = true,
|
||||
}
|
||||
|
||||
-- The three runtime name slots. PlaceMoveUsersName, PlaceMoveTargetsName and
|
||||
-- PlaceEnemysName (home/text.asm:302, :307, :327) swap these for a battler's
|
||||
-- own name as the line prints, so they are markers rather than glyphs. They
|
||||
-- decode to the same shape Gen 1 uses, which src/core/RomText.lua already
|
||||
-- fills in argument order. Dropped, SubTookDamageText read "took damage
|
||||
-- for" with nothing after it.
|
||||
local NAME_SLOT = {
|
||||
["<USER>"] = "{USER}",
|
||||
["<TARGET>"] = "{TARGET}",
|
||||
["<ENEMY>"] = "{ENEMY}",
|
||||
}
|
||||
|
||||
local ROOF_TILES = 9
|
||||
local SPRITEDATA_LENGTH = 6
|
||||
|
||||
@@ -2596,6 +2608,8 @@ function RomExtractorGen2:decodeGen2Text(bank, address, charmap, buffers)
|
||||
out[#out + 1] = ch
|
||||
elseif ch == "<……>" or b == 0x56 then
|
||||
out[#out + 1] = "……"
|
||||
elseif NAME_SLOT[ch] then
|
||||
out[#out + 1] = NAME_SLOT[ch]
|
||||
elseif not ch then
|
||||
out[#out + 1] = ("{BYTE:%02X}"):format(b)
|
||||
end
|
||||
@@ -3698,6 +3712,37 @@ function RomExtractorGen2:splashGfx()
|
||||
}
|
||||
end
|
||||
|
||||
-- The engine's own strings, keyed by the label the disassembly gives them.
|
||||
--
|
||||
-- This is what extractOakSpeech has always done for _OakText1-7: resolve the
|
||||
-- label, decode from the cart, key by name. What is new is that the list of
|
||||
-- labels comes from the manifest instead of being written out here, so all of
|
||||
-- data/text/ arrives rather than seven strings. Gen 1 has had the same table
|
||||
-- since RomExtractor:extractText; this is the Gen 2 side of it, and it is
|
||||
-- what lets src/core/RomText.lua work on Gold and Silver at all.
|
||||
--
|
||||
-- Written as `rom_text` rather than `text`: data/generated/text.lua is
|
||||
-- already the script text, keyed by bank:address for the overworld VM, and
|
||||
-- these are a different table with different keys.
|
||||
function RomExtractorGen2:extractText()
|
||||
self:beginStage("Dialogue")
|
||||
local charmap = self.manifest.charmap or {}
|
||||
local labels = (self.manifest.text or {}).labels or {}
|
||||
local texts = {}
|
||||
for index, label in ipairs(labels) do
|
||||
local location = self.symbols[label]
|
||||
-- A label the manifest names but the symbol table does not carry would
|
||||
-- be a generator bug, not a cart difference: make_gold_manifest.py
|
||||
-- resolves every one of these before it writes the list.
|
||||
if location then
|
||||
texts[label] = self:decodeGen2Text(location[1], location[2], charmap)
|
||||
end
|
||||
self:tick("Dialogue", index, #labels)
|
||||
end
|
||||
self:write("rom_text", texts)
|
||||
return texts
|
||||
end
|
||||
|
||||
-- OakSpeech (engine/menus/intro_menu.asm): named _OakText* strings plus the
|
||||
-- POKEMON_PROF / CAL trainer pics shown before NamePlayer. Also pulls
|
||||
-- Shrink1/2 pics and the GameFreak splash sheets for the boot cinema.
|
||||
@@ -6283,6 +6328,7 @@ function RomExtractorGen2:run()
|
||||
results.sprites = self:extractSprites()
|
||||
results.stdScripts = self:extractStdScripts()
|
||||
results.scripts = self:extractScriptsAndText(results.maps, results.stdScripts)
|
||||
results.text = self:extractText()
|
||||
results.pokemon = self:extractPokemon()
|
||||
results.moves = self:extractMoves()
|
||||
results.items = self:extractItems()
|
||||
|
||||
@@ -104,6 +104,12 @@ local VERSION_REQUIRED_FILES_OVERRIDE = {
|
||||
"data/generated/sprites.lua", -- OW sheets (Chris + NPCs)
|
||||
"data/generated/scripts.lua", -- disassembled map scripts
|
||||
"data/generated/text.lua", -- decoded Gen 2 dialogue strings
|
||||
-- The engine's own strings, keyed by label rather than by address. A
|
||||
-- cache built before RomExtractorGen2:extractText has none, and every
|
||||
-- line that reads through src/core/RomText.lua would silently keep
|
||||
-- printing its Lua fallback, so this re-imports those caches rather than
|
||||
-- bumping CACHE_FORMAT and dragging Red, Blue and Yellow through it too.
|
||||
"data/generated/rom_text.lua",
|
||||
"data/generated/pokemon.lua",
|
||||
"data/generated/tilesets.lua",
|
||||
"data/generated/audio.lua",
|
||||
|
||||
Reference in New Issue
Block a user