mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
141 lines
4.8 KiB
Lua
141 lines
4.8 KiB
Lua
-- home/text.asm:209 PromptText, :221 DoneText; constants/charmap.asm:12
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
love = love or require("tests.love_stub")
|
|
|
|
local Json = require("src.link.Json")
|
|
local Extractor = require("src.import.RomExtractor")
|
|
local TextBox = require("src.render.TextBox")
|
|
local Sound = require("src.core.Sound")
|
|
local romText = require("src.core.RomText")
|
|
|
|
local presses = 0
|
|
local realPress, realPlay = Sound.playPress, Sound.play
|
|
Sound.playPress = function() presses = presses + 1 return nil end
|
|
Sound.play = function() return nil end
|
|
|
|
local function manifest(path)
|
|
local file = assert(io.open(path, "r"))
|
|
local data = assert(Json.decode(file:read("*a")))
|
|
file:close()
|
|
return data
|
|
end
|
|
|
|
local charmap = manifest("tools/rom_manifest.json").charmap
|
|
eq(charmap["74"], "<PK><MN>",
|
|
"the manifest maps $4A to the two-tile ligature, not POKeMON")
|
|
eq(manifest("tools/rom_manifest_blue.json").charmap["74"], "<PK><MN>",
|
|
"Blue's manifest too")
|
|
eq(manifest("tools/rom_manifest_yellow.json").charmap["74"], "<PK><MN>",
|
|
"and Yellow's")
|
|
|
|
local function decode(bytes)
|
|
local rom = {}
|
|
function rom:byte(_, address) return bytes[address] or 0x50 end
|
|
local extractor = setmetatable({ rom = rom, manifest = { charmap = charmap } },
|
|
Extractor)
|
|
return extractor:decodeTextCommands(
|
|
{ bank = 0, address = 0, name = "_Test" }, {})
|
|
end
|
|
|
|
local H, i = 0x87, 0xa8
|
|
eq(decode({ [0] = 0x00, H, i, 0x57 }), "Hi{DONE}", "a `done` text carries {DONE}")
|
|
eq(decode({ [0] = 0x00, H, i, 0x58 }), "Hi{PROMPT}",
|
|
"a `prompt` text carries {PROMPT}")
|
|
-- data/text/text_3.asm:32
|
|
eq(decode({ [0] = 0x00, H, i, 0x50, 0x50 }), "Hi{DONE}",
|
|
"a text_end text is a done too")
|
|
eq(decode({ [0] = 0x00, H, i, 0x5F }), "Hi",
|
|
"<DEXEND> stays unmarked for DexEntryMenu")
|
|
eq(decode({ [0] = 0x50 }), "", "an empty text stays empty")
|
|
eq(decode({ [0] = 0x00, 0x4A, 0x57 }), "<PK><MN>{DONE}",
|
|
"$4A decodes to the ligature, whole, not a {PK><MN} token")
|
|
eq(decode({ [0] = 0x00, 0x52, 0x57 }), "{PLAYER}{DONE}",
|
|
"a lone <NAME> entry is still a token")
|
|
|
|
eq(TextBox.ending("Hi{DONE}"), "done", "TextBox reads {DONE}")
|
|
eq(TextBox.ending("Hi{PROMPT}"), "prompt", "and {PROMPT}")
|
|
eq(TextBox.ending("Hi"), nil, "and nothing for an untagged text")
|
|
|
|
local function newGame()
|
|
local game = {
|
|
save = { player = {}, options = { textSpeed = "FAST" }, generation = 1 },
|
|
data = { text = {} },
|
|
}
|
|
game.stack = {
|
|
states = {},
|
|
push = function(self, s) table.insert(self.states, s) end,
|
|
pop = function(self) return table.remove(self.states) end,
|
|
top = function(self) return self.states[#self.states] end,
|
|
}
|
|
game.input = {
|
|
queue = {},
|
|
wasPressed = function(self, btn) return self.queue[btn] or false end,
|
|
isDown = function(self, btn) return self.queue[btn] or false end,
|
|
}
|
|
return game
|
|
end
|
|
|
|
local function finished(text, opts)
|
|
local game = newGame()
|
|
local box = TextBox.new(game, text, nil, opts)
|
|
game.stack:push(box)
|
|
local frames = 0
|
|
while not box.done and frames < 600 do
|
|
box:update(1 / 60)
|
|
frames = frames + 1
|
|
end
|
|
presses = 0
|
|
game.input.queue.a = true
|
|
box:update(1 / 60)
|
|
return box, presses
|
|
end
|
|
|
|
-- text/Route25.asm:153
|
|
do
|
|
local box, beeps = finished("SEA COTTAGE\nBILL lives here!{DONE}")
|
|
eq(box.waitButton, true, "an extracted `done` text is a WaitButton box")
|
|
-- home/text_script.asm:96 -> home/joypad2.asm:71-72
|
|
check(box:arrowVisible(), "and still blinks the arrow WaitForTextScrollButtonPress draws")
|
|
eq(select(2, box:arrowPos()), 128, "at hlcoord 18,16")
|
|
-- SFX_PRESS_AB lives only in ManualTextScroll, home/joypad2.asm:90-92
|
|
eq(beeps, 0, "and closes silently")
|
|
eq(box.pages[1][1], "SEA COTTAGE", "the marker never reaches the glyphs")
|
|
eq(box.pages[1][2], "BILL lives here!", "on either line")
|
|
end
|
|
|
|
do
|
|
local box, beeps = finished("SEA COTTAGE\nBILL lives here!{PROMPT}")
|
|
eq(box.waitButton, false, "an extracted `prompt` text blinks")
|
|
check(box:arrowVisible(), "and shows the cursor")
|
|
eq(beeps, 1, "and beeps on the press")
|
|
eq(box.pages[1][2], "BILL lives here!", "with the marker stripped")
|
|
end
|
|
|
|
do
|
|
local box = finished("Hi")
|
|
check(box:arrowVisible(), "an untagged text keeps the blinking default")
|
|
end
|
|
|
|
Sound.playPress, Sound.play = realPress, realPlay
|
|
|
|
do
|
|
local pages = TextBox.paginate("Choose a\n<PK><MN> BOX.{DONE}", 18)
|
|
eq(pages[1][1], "Choose a", "paginate drops the terminator")
|
|
eq(pages[1][2], "<PK><MN> BOX.", "and keeps the ligature")
|
|
eq(TextBox.paginate("Take your time.{PROMPT}", 18)[1][1], "Take your time.",
|
|
"for {PROMPT} as well")
|
|
end
|
|
|
|
do
|
|
local data = { text = { _PotionText = "{RAM:wcf4b} recovered\nby {NUM}!{DONE}" } }
|
|
eq(romText(data, "_PotionText", "fallback", "POLIWHIRL", 4),
|
|
"POLIWHIRL recovered\nby 4!{DONE}",
|
|
"RomText does not count the terminator as a slot")
|
|
end
|
|
|
|
T.finish("gen1 text terminator bug2116")
|