mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
3252a3f2c9
game3 prints every string with the US cart's Latin font, and FrlgFont has
no glyph for a kana, so a Japanese translation of FireRed would print
blank. The US cart still carries its Japanese fonts, which its text
printer draws for a string in Japanese mode (pokefirered/src/text.c:141,
:227): pret builds them into the US ROM, with the normal font's width
table.
The font extractor now bakes both, the normal font from its eight-to-a-row
layout (DecompressGlyph_Normal, text.c:1452) with its widths and the small
one sixteen to a row (DecompressGlyph_Small, text.c:1372), as
chrome/fonts/japanese_{normal,small}_{fg,shadow}.rgba and
japanese_widths.lua. LeafGreen's addresses follow the same -0x24 shift as
the rest of text.o. Cache version 120 re-imports existing caches.
FrlgFont numbers a Japanese character by its byte in the Japanese block of
pokefirered/charmap.txt (kana 01-A0, the full-width space, !?。ー), plus
the symbols the font keeps at the Latin block's codes in their full-width
forms (digits, letters, 『』「」, 円, /, :), offset past the Latin
glyphs. A character with no Latin glyph draws from the Japanese sheet, at
the width the cart gives it (the table for the normal font, 8px for the
small one). Latin text is drawn as before.
153 lines
5.4 KiB
Lua
153 lines
5.4 KiB
Lua
local U = require("tests.drivers.util")
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_import_fresh_cache"
|
|
|
|
local failures = 0
|
|
local function result(ok, label)
|
|
print((ok and "PASS " or "FAIL ") .. label)
|
|
if not ok then failures = failures + 1 end
|
|
return ok
|
|
end
|
|
|
|
local function finish()
|
|
if failures == 0 then
|
|
print("PASS import_fresh_cache")
|
|
love.event.quit(0)
|
|
else
|
|
print("FAIL import_fresh_cache failures=" .. failures)
|
|
love.event.quit(1)
|
|
end
|
|
end
|
|
|
|
return function(game)
|
|
for _ = 1, 900 do
|
|
if game.phase == "boot" and game.boot then break end
|
|
U.wait(1)
|
|
end
|
|
result(game.phase == "boot" and game.boot ~= nil,
|
|
"the fresh cache booted past the launcher, phase=" .. tostring(game.phase))
|
|
|
|
local Versions = require("src.import.gba.versions")
|
|
local CacheContract = require("src.import.CacheContract")
|
|
local CacheFs = require("src.import.CacheFs")
|
|
|
|
result(type(Versions.CACHE_VERSION) == "number",
|
|
"the importer is at cache version " .. tostring(Versions.CACHE_VERSION))
|
|
result(CacheContract.cacheVersionCurrent("firered", CacheFs) == true,
|
|
"the mounted cache is stamped at the current version")
|
|
local complete, missing = CacheContract.allRequiredFilesExist("firered", CacheFs)
|
|
result(complete == true,
|
|
"every required key is in the mounted cache, missing=" .. tostring(missing))
|
|
result(CacheContract.isReady("firered", CacheFs) == true,
|
|
"CacheContract calls the mounted cache ready")
|
|
|
|
game:_handleBootAction({ action = "new_game", name = "RED" })
|
|
U.wait(240)
|
|
|
|
local Runtime = require("src.core.game3.runtime")
|
|
local Dataset = require("src.core.game3.dataset")
|
|
local Player = require("src.core.game3.player")
|
|
local Map = require("src.core.game3.map")
|
|
local StartMenu = require("src.ui.game3.start_menu")
|
|
|
|
local session = Runtime.getSession()
|
|
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
|
|
print("[driver] new game: map=" .. tostring(Map.current) ..
|
|
" at (" .. tostring(Player.cellX) .. "," .. tostring(Player.cellY) .. ")")
|
|
result(Map.current ~= nil, "the player stands on a map, map=" .. tostring(Map.current))
|
|
|
|
U.wait(30)
|
|
result(U.shot(game, DIR .. "/import_fresh_cache_01_players_room.png"),
|
|
"the bedroom shot reached disk")
|
|
|
|
local function walkTo(tx, ty, limit)
|
|
local stuck = 0
|
|
for _ = 1, limit or 40 do
|
|
local x, y = Player.cellX, Player.cellY
|
|
if x == tx and y == ty then return true end
|
|
local dir
|
|
if x ~= tx and (stuck % 2 == 0 or y == ty) then
|
|
dir = (tx > x) and "right" or "left"
|
|
elseif y ~= ty then
|
|
dir = (ty > y) and "down" or "up"
|
|
else
|
|
dir = (tx > x) and "right" or "left"
|
|
end
|
|
U.hold(game, dir, 12)
|
|
for _ = 1, 20 do
|
|
if not Player.moving then break end
|
|
U.wait(2)
|
|
end
|
|
U.wait(4)
|
|
if Player.cellX == x and Player.cellY == y then
|
|
stuck = stuck + 1
|
|
if stuck > 10 then return false end
|
|
else
|
|
stuck = 0
|
|
end
|
|
end
|
|
return Player.cellX == tx and Player.cellY == ty
|
|
end
|
|
|
|
local function stepThrough(dir, id, tries)
|
|
for _ = 1, tries or 12 do
|
|
if Map.current == id then break end
|
|
U.hold(game, dir, 12)
|
|
U.wait(30)
|
|
end
|
|
U.wait(40)
|
|
return Map.current == id
|
|
end
|
|
|
|
-- src/field_control_avatar.c:924
|
|
walkTo(10, 2, 30)
|
|
stepThrough("left", "FR_PLAYERS_HOUSE_1F", 10)
|
|
print("[driver] down the stairs: map=" .. tostring(Map.current) ..
|
|
" at (" .. tostring(Player.cellX) .. "," .. tostring(Player.cellY) .. ")")
|
|
result(Map.current == "FR_PLAYERS_HOUSE_1F",
|
|
"the stairs warped to the ground floor, map=" .. tostring(Map.current))
|
|
|
|
-- src/field_control_avatar.c:825
|
|
walkTo(9, 8, 30)
|
|
walkTo(4, 8, 30)
|
|
stepThrough("down", "FR_PALLET_TOWN", 10)
|
|
print("[driver] out the front door: map=" .. tostring(Map.current) ..
|
|
" at (" .. tostring(Player.cellX) .. "," .. tostring(Player.cellY) .. ")")
|
|
result(Map.current == "FR_PALLET_TOWN",
|
|
"the front door warped to Pallet Town, map=" .. tostring(Map.current))
|
|
U.wait(30)
|
|
result(U.shot(game, DIR .. "/import_fresh_cache_02_pallet_town.png"),
|
|
"the Pallet Town shot reached disk")
|
|
|
|
local cache = Dataset.cache()
|
|
local function sized(rel)
|
|
local ok, data = pcall(function() return cache:read("data/generated/gba/" .. rel) end)
|
|
if ok and type(data) == "string" then return #data end
|
|
return 0
|
|
end
|
|
-- src/text.c:227 the Japanese normal font
|
|
result(sized("chrome/fonts/japanese_normal_fg.rgba") == 256 * 512 * 4,
|
|
"the engine reads the Japanese font out of the fresh cache")
|
|
-- src/braille_text.c:15
|
|
result(sized("chrome/fonts/braille_fg.rgba") == 256 * 64 * 4,
|
|
"the engine reads the braille sheet out of the fresh cache")
|
|
-- src/seagallop.c:41
|
|
result(sized("seagallop/wb.rgba") == 256 * 256 * 4,
|
|
"the engine reads the seagallop water out of the fresh cache")
|
|
-- src/pokedex_screen.c:2901
|
|
result(sized("pokemon/pokedex/footprints/1.rgba") > 0,
|
|
"the engine reads a dex footprint out of the fresh cache")
|
|
-- src/script_menu.c:505
|
|
result(sized("scripts/multichoice.lua") > 0,
|
|
"the engine reads the multichoice lists out of the fresh cache")
|
|
|
|
U.tap(game, "start")
|
|
U.wait(45)
|
|
result(StartMenu.isOpen(), "the start menu drew from the fresh cache chrome")
|
|
result(U.shot(game, DIR .. "/import_fresh_cache_03_start_menu.png"),
|
|
"the start menu shot reached disk")
|
|
U.tap(game, "b")
|
|
U.wait(20)
|
|
|
|
finish()
|
|
end
|