mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-27 08:51:27 +02:00
Route Gold's title menu and SAVE screen through Strings()
MainMenu.lua's row labels (CONTINUE/NEW GAME/OPTION/EXIT GAME), its clock box's AM/PM half, and its CONTINUE save-summary panel (PLAYER <name>/ BADGES/POKéDEX/TIME, or NO SAVE FILE) were bare literals, invisible to a translation mod's strings registry. SaveMenu.lua's confirm/overwrite/ saving/saved prompts, its YES/NO choice, and its own copy of the same summary panel had the same gap. Both mirror the Gen 1 port's already- translated equivalents (src/ui/TitleState.lua, src/ui/StartMenu.lua), which route every one of these rows through Strings(). SaveMenu's two-line prompts (module-level OVERWRITE_PROMPT/SAVING_PROMPT, plus the dynamically-built "%s saved\nthe game." and the confirm/failed messages) are now single Strings()-resolved strings with an embedded "\n", matching the Gen 1 port's own single-call convention for two-line messages, split into the two-slot table drawPanel's fixed-position Chrome.print calls expect only at draw time -- so a translation sees one whole sentence to reorder, not two independently-translated fragments. Added tests/engine/gen2_main_menu_translation_test.lua and gen2_save_menu_translation_test.lua: drive both screens' drawPanel()/ drawSavePanel() with a mod-loaded Strings catalog and check the translated text reaches Font.draw, plus a vanilla no-mod case proving the fallback is unchanged. Confirmed both catch the regression: reverting either file to its pre-fix content fails the corresponding suite (7 and 15 checks respectively).
This commit is contained in:
+11
-10
@@ -24,6 +24,7 @@ local Logger = require("src.core.Logger")
|
||||
local Music = require("src.core.Music")
|
||||
local Runtime = require("src.mods.Runtime")
|
||||
local Save = require("src.core.gen2.Save")
|
||||
local Strings = require("src.core.Strings")
|
||||
|
||||
local MainMenu = {}
|
||||
MainMenu.__index = MainMenu
|
||||
@@ -73,14 +74,14 @@ local function sameItems(_, items) return items end
|
||||
function MainMenu:buildList()
|
||||
local items = {}
|
||||
if self.hasSave then
|
||||
items[#items + 1] = { label = "CONTINUE", value = "continue" }
|
||||
items[#items + 1] = { label = Strings("CONTINUE"), value = "continue" }
|
||||
end
|
||||
items[#items + 1] = { label = "NEW GAME", value = "new" }
|
||||
items[#items + 1] = { label = "OPTION", value = "option" }
|
||||
items[#items + 1] = { label = Strings("NEW GAME"), value = "new" }
|
||||
items[#items + 1] = { label = Strings("OPTION"), value = "option" }
|
||||
-- Not on the cart: a cartridge is left by switching the console off, and
|
||||
-- there is no console here. Mirrors the Gen 1 port's title menu
|
||||
-- (src/ui/TitleState.lua), which adds the same row for the same reason.
|
||||
items[#items + 1] = { label = "EXIT GAME", value = "exit" }
|
||||
items[#items + 1] = { label = Strings("EXIT GAME"), value = "exit" }
|
||||
-- The same hook name and the same (game, items) payload the Gen 1 title
|
||||
-- menu raises (src/ui/TitleState.lua:openMenu), so one mod's title rows
|
||||
-- serve both games; only the row shape differs, because Chrome.List reads
|
||||
@@ -170,7 +171,7 @@ function MainMenu:drawClockBox()
|
||||
-- minutes; the AM/PM half is drawn by PrintHour itself.
|
||||
local display = hour % 12
|
||||
if display == 0 then display = 12 end
|
||||
local half = hour < 12 and "AM" or "PM"
|
||||
local half = Strings(hour < 12 and "AM" or "PM")
|
||||
Chrome.print(("%s:%s %s"):format(
|
||||
Chrome.number(display, 2), Chrome.number(minute, 2, true), half), 4, 16)
|
||||
end
|
||||
@@ -180,15 +181,15 @@ function MainMenu:drawSavePanel()
|
||||
-- DisplaySaveInfoOnContinue: a box down the right side listing the trainer.
|
||||
Chrome.textbox(4, 0, 14, 9)
|
||||
if not summary then
|
||||
Chrome.print("NO SAVE FILE", 5, 2)
|
||||
Chrome.print(Strings("NO SAVE FILE"), 5, 2)
|
||||
return
|
||||
end
|
||||
Chrome.print("PLAYER " .. summary.name, 5, 2)
|
||||
Chrome.print("BADGES", 5, 4)
|
||||
Chrome.print(Strings("PLAYER %s", summary.name), 5, 2)
|
||||
Chrome.print(Strings("BADGES"), 5, 4)
|
||||
Chrome.printRight(tostring(summary.badges), 17, 4)
|
||||
Chrome.print("POKéDEX", 5, 6)
|
||||
Chrome.print(Strings("POKéDEX"), 5, 6)
|
||||
Chrome.printRight(tostring(summary.caught), 17, 6)
|
||||
Chrome.print("TIME", 5, 8)
|
||||
Chrome.print(Strings("TIME"), 5, 8)
|
||||
Chrome.printRight(("%d:%s"):format(
|
||||
summary.hours, Chrome.number(summary.minutes, 2, true)), 17, 8)
|
||||
end
|
||||
|
||||
+46
-12
@@ -26,6 +26,7 @@
|
||||
local Chrome = require("src.ui.gen2.Chrome")
|
||||
local Save = require("src.core.gen2.Save")
|
||||
local Sound = require("src.core.Sound")
|
||||
local Strings = require("src.core.Strings")
|
||||
|
||||
local SaveMenu = {}
|
||||
SaveMenu.__index = SaveMenu
|
||||
@@ -55,10 +56,43 @@ local TIME_X, TIME_Y = 13, 8
|
||||
local YESNO_X, YESNO_Y, YESNO_W, YESNO_H = 0, 7, 6, 5
|
||||
|
||||
-- AlreadyASaveFileText (AskOverwriteSaveFile, engine/menus/save.asm:47) and
|
||||
-- SavingDontTurnOffThePower's own line, shared with the PC's CHANGE BOX save.
|
||||
-- SavingDontTurnOffThePower's own line, shared with the PC's CHANGE BOX save
|
||||
-- (src/ui/gen2/PcMenu.lua:savePrompt(), which returns this two-slot table
|
||||
-- straight through to its own lines[1]/lines[2] Chrome.print calls, so the
|
||||
-- table shape here is a cross-file contract that must not change).
|
||||
local OVERWRITE_PROMPT = { "There is already a", "save file. Is it" }
|
||||
local SAVING_PROMPT = { "SAVING… DON'T TURN", "OFF THE POWER." }
|
||||
|
||||
-- The same two prompts as a single \n-joined Strings.source() key, used only
|
||||
-- by this screen's own prompt() below (PcMenu keeps reading the untranslated
|
||||
-- table above unchanged). One key lets a translation reorder the whole
|
||||
-- sentence rather than two independently-translated fragments, and lets a
|
||||
-- cart whose own translation shows it on ONE line (German's SAVING prompt
|
||||
-- has no second line at all) say so directly -- the per-line "{RAM:...}"-
|
||||
-- style split load_engine_overrides uses elsewhere requires a non-empty
|
||||
-- override for every line, so it cannot express "this line is blank" the
|
||||
-- way an embedded "\n"-less string can.
|
||||
--
|
||||
-- Written as literals, not `table.concat(OVERWRITE_PROMPT, "\n")`: tools/
|
||||
-- modkit.py's STRINGS_CALL harvester matches a quoted string literal
|
||||
-- immediately inside Strings.source(...)/Strings(...), not an arbitrary
|
||||
-- expression, so a computed argument here would be invisible to every
|
||||
-- translator's `modkit.py translation ... --refresh` scaffold despite the
|
||||
-- runtime lookup working fine -- caught by an independent review. Keep
|
||||
-- these two byte-for-byte in sync with OVERWRITE_PROMPT/SAVING_PROMPT
|
||||
-- above (checked by tests/engine/gen2_save_menu_translation_test.lua).
|
||||
local OVERWRITE_PROMPT_SOURCE = Strings.source("There is already a\nsave file. Is it")
|
||||
local SAVING_PROMPT_SOURCE = Strings.source("SAVING… DON'T TURN\nOFF THE POWER.")
|
||||
|
||||
-- Splits a Strings()-resolved "line one\nline two" into the two-slot table
|
||||
-- drawPanel's fixed-position Chrome.print calls expect; a translation with no
|
||||
-- "\n" at all (single-line messages like "Could not save.") lands whole on
|
||||
-- the first slot, matching the untranslated code's own { text, "" } shape.
|
||||
local function twoLines(text)
|
||||
local first, second = text:match("^(.-)\n(.*)$")
|
||||
return { first or text, second or "" }
|
||||
end
|
||||
|
||||
function SaveMenu:wantsFillScale() return true end
|
||||
function SaveMenu:drawsWidescreen() return true end
|
||||
|
||||
@@ -171,18 +205,18 @@ function SaveMenu:prompt()
|
||||
if self.phase == "overwrite" then
|
||||
-- AlreadyASaveFileText when the file is this player's; AnotherSaveFileText
|
||||
-- when the ID differs. Only the first can happen here.
|
||||
return OVERWRITE_PROMPT
|
||||
return twoLines(Strings(OVERWRITE_PROMPT_SOURCE))
|
||||
end
|
||||
if self.phase == "saving" then
|
||||
return SAVING_PROMPT
|
||||
return twoLines(Strings(SAVING_PROMPT_SOURCE))
|
||||
end
|
||||
if self.phase == "done" then
|
||||
if self.saved then
|
||||
return { self:playerName() .. " saved", "the game." }
|
||||
return twoLines(Strings("%s saved\nthe game.", self:playerName()))
|
||||
end
|
||||
return { "Could not save.", "" }
|
||||
return twoLines(Strings("Could not save."))
|
||||
end
|
||||
return { "Would you like to", "save the game?" }
|
||||
return twoLines(Strings("Would you like to\nsave the game?"))
|
||||
end
|
||||
|
||||
function SaveMenu:drawPanel()
|
||||
@@ -190,10 +224,10 @@ function SaveMenu:drawPanel()
|
||||
local summary = Save.summary(self.save)
|
||||
Chrome.box(PANEL_X, PANEL_Y, PANEL_W, PANEL_H)
|
||||
if summary then
|
||||
Chrome.print("PLAYER " .. summary.name, LABEL_X, LABEL_Y)
|
||||
Chrome.print("BADGES", LABEL_X, LABEL_Y + 2)
|
||||
Chrome.print("POKéDEX", LABEL_X, LABEL_Y + 4)
|
||||
Chrome.print("TIME", LABEL_X, LABEL_Y + 6)
|
||||
Chrome.print(Strings("PLAYER %s", summary.name), LABEL_X, LABEL_Y)
|
||||
Chrome.print(Strings("BADGES"), LABEL_X, LABEL_Y + 2)
|
||||
Chrome.print(Strings("POKéDEX"), LABEL_X, LABEL_Y + 4)
|
||||
Chrome.print(Strings("TIME"), LABEL_X, LABEL_Y + 6)
|
||||
-- PrintNum fills its field from the left, space padded.
|
||||
Chrome.print(Chrome.number(summary.badges, 2), BADGES_X, BADGES_Y)
|
||||
Chrome.print(Chrome.number(summary.caught, 3), DEX_X, DEX_Y)
|
||||
@@ -211,8 +245,8 @@ function SaveMenu:drawPanel()
|
||||
|
||||
if self.phase == "confirm" or self.phase == "overwrite" then
|
||||
Chrome.box(YESNO_X, YESNO_Y, YESNO_W, YESNO_H)
|
||||
Chrome.print("YES", YESNO_X + 2, YESNO_Y + 1)
|
||||
Chrome.print("NO", YESNO_X + 2, YESNO_Y + 3)
|
||||
Chrome.print(Strings("YES"), YESNO_X + 2, YESNO_Y + 1)
|
||||
Chrome.print(Strings("NO"), YESNO_X + 2, YESNO_Y + 3)
|
||||
Chrome.cursor(YESNO_X + 1, YESNO_Y + (self.choice == 1 and 1 or 3))
|
||||
end
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
|
||||
Reference in New Issue
Block a user