Started working on UI localization

This commit is contained in:
Vladislav Khorev committed 2026-07-07 13:46:28 +03:00
1 parent ef5b142425
commit 08eac60657
14 files changed
+570 -72

No files matched your search

+10
View File
@@ -968,6 +968,16 @@ namespace ZL
// Suppress all input while portrait overlay is shown
//if (mobileIsPortrait) continue;
// Ignore pointer input until the initial loading screen has finished.
// Otherwise a click on the loading screen (e.g. at the spot where a
// main-menu button will later be) gets delivered to the menu UI as
// soon as it appears underneath, triggering that button unintentionally.
if (!loadingCompleted &&
(event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP || event.type == SDL_FINGERMOTION ||
event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP)) {
continue;
}
#ifdef __ANDROID__
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
Environment::exitGameLoop = true;
+99 -69
View File
@@ -111,74 +111,89 @@ namespace ZL {
localizedLocationName["location_dorm"][Language::English] = "Dormitory, 1st floor";
}
std::shared_ptr<UiNode> MenuManager::loadLocalizedUi(const std::string& basePath, const std::string& zipFile) {
static const std::string marker = "resources/w/ui/";
if (basePath.rfind(marker, 0) == 0) {
const std::string localizedPath = "resources/w/ui_" + languageToCode(g_currentLanguage) + "/" + basePath.substr(marker.size());
try {
return loadUiFromFile(localizedPath, renderer, zipFile);
} catch (const std::exception&) {
// Localized screen not available — fall back to the base path below.
}
}
return loadUiFromFile(basePath, renderer, zipFile);
}
void MenuManager::loadUiRoots(const std::string& zipFile) {
hudRoot = loadLocalizedUi("resources/w/ui/hud_step0.json", zipFile);
hudStep1Root = loadLocalizedUi("resources/w/ui/hud_step1.json", zipFile);
hudStep2Root = loadLocalizedUi("resources/w/ui/hud_step2.json", zipFile);
hudStep3Root = loadLocalizedUi("resources/w/ui/hud_step3.json", zipFile);
hudStep4Root = loadLocalizedUi("resources/w/ui/hud_step4.json", zipFile);
hudStep5aRoot = loadLocalizedUi("resources/w/ui/hud_step5a.json", zipFile);
hudStep5bRoot = loadLocalizedUi("resources/w/ui/hud_step5b.json", zipFile);
hudStep5abRoot = loadLocalizedUi("resources/w/ui/hud_step5ab.json", zipFile);
hudUniExtRoot = loadLocalizedUi("resources/w/ui/hud_uni_ext.json", zipFile);
hudUniIntStep10Root = loadLocalizedUi("resources/w/ui/hud_uni_int_step10.json", zipFile);
hudUniIntStep11Root = loadLocalizedUi("resources/w/ui/hud_uni_int_step11.json", zipFile);
hudUniIntStep12Root = loadLocalizedUi("resources/w/ui/hud_uni_int_step12.json", zipFile);
hudUniIntStep13Root = loadLocalizedUi("resources/w/ui/hud_uni_int_step13.json", zipFile);
hudUniIntFullRoot = loadLocalizedUi("resources/w/ui/hud_uni_int_full.json", zipFile);
hudUniIntDarkFullRoot = loadLocalizedUi("resources/w/ui/hud_uni_int_dark_full.json", zipFile);
hudUniExtDarkRoot = loadLocalizedUi("resources/w/ui/hud_uni_ext_dark.json", zipFile);
hudCutsceneRoot_ = loadLocalizedUi("resources/w/ui/hud_cutscene.json", zipFile);
hudTopHintRoot_ = loadLocalizedUi("resources/w/ui/hud_top_hint01.json", zipFile);
phoneMainRoot = loadLocalizedUi("resources/w/ui/screen_phone.json", zipFile);
phoneMainHintARoot = loadLocalizedUi("resources/w/ui/screen_phone_hint001.json", zipFile);
phoneMainHintBRoot = loadLocalizedUi("resources/w/ui/screen_phone_hint002.json", zipFile);
phoneMainHintABRoot = loadLocalizedUi("resources/w/ui/screen_phone_hint001_002.json", zipFile);
phoneBankRoot = loadLocalizedUi("resources/w/ui/screen_phone_bank.json", zipFile);
phoneVideoRoot = loadLocalizedUi("resources/w/ui/screen_phone_video.json", zipFile);
phoneMapDormRoot = loadLocalizedUi("resources/w/ui/screen_phone_map_dorm.json", zipFile);
phoneMapUniRoot = loadLocalizedUi("resources/w/ui/screen_phone_map_uni.json", zipFile);
verticalPhoneMainRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone.json", zipFile);
verticalPhoneMainHintARoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_hint001.json", zipFile);
verticalPhoneMainHintBRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_hint002.json", zipFile);
verticalPhoneMainHintABRoot= loadLocalizedUi("resources/w/ui/portrait_screen_phone_hint001_002.json", zipFile);
verticalPhoneBankRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_bank.json", zipFile);
verticalPhoneVideoRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_video.json", zipFile);
verticalPhoneMapDormRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_map_dorm.json", zipFile);
verticalPhoneMapUniRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_map_uni.json", zipFile);
phoneChatListRoot = loadLocalizedUi("resources/w/ui/screen_phone_chat_list.json", zipFile);
phoneChatListHintRoot = loadLocalizedUi("resources/w/ui/screen_phone_chat_list_hint001.json", zipFile);
verticalPhoneChatListRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_chat_list.json", zipFile);
verticalPhoneChatListHintRoot = loadLocalizedUi("resources/w/ui/portrait_screen_phone_chat_list_hint001.json", zipFile);
phoneChat1Root = loadLocalizedUi("resources/w/ui/screen_phone_chat1.json", zipFile);
phoneChat2Root = loadLocalizedUi("resources/w/ui/screen_phone_chat2.json", zipFile);
phoneChat3Root = loadLocalizedUi("resources/w/ui/screen_phone_chat3.json", zipFile);
verticalPhoneChat1Root = loadLocalizedUi("resources/w/ui/portrait_screen_phone_chat1.json", zipFile);
verticalPhoneChat2Root = loadLocalizedUi("resources/w/ui/portrait_screen_phone_chat2.json", zipFile);
verticalPhoneChat3Root = loadLocalizedUi("resources/w/ui/portrait_screen_phone_chat3.json", zipFile);
modalMenuRoot = loadLocalizedUi("resources/w/ui/screen_modal_menu.json", zipFile);
newInventoryRoot = loadLocalizedUi("resources/w/ui/screen_inventory.json", zipFile);
portraitInventoryListRoot = loadLocalizedUi("resources/w/ui/portrait_screen_inventory.json", zipFile);
portraitInventoryItemRoot = loadLocalizedUi("resources/w/ui/portrait_screen_inventory_item.json", zipFile);
questJournalRoot = loadLocalizedUi("resources/w/ui/screen_journal.json", zipFile);
portraitQuestJournalListRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal.json", zipFile);
portraitQuestJournalItemRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal_item.json", zipFile);
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile);
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.json", zipFile);
settingsScreenRoot = loadLocalizedUi("resources/w/ui/screen_settings.json", zipFile);
languageScreenRoot = loadLocalizedUi("resources/w/ui/screen_language.json", zipFile);
loadSavedGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_load.json", zipFile);
saveGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_save.json", zipFile);
}
void MenuManager::setup(Inventory& inv, const std::string& zipFile) {
inventory = &inv;
hudRoot = loadUiFromFile("resources/w/ui/hud_step0.json", renderer, zipFile);
hudStep1Root = loadUiFromFile("resources/w/ui/hud_step1.json", renderer, zipFile);
hudStep2Root = loadUiFromFile("resources/w/ui/hud_step2.json", renderer, zipFile);
hudStep3Root = loadUiFromFile("resources/w/ui/hud_step3.json", renderer, zipFile);
hudStep4Root = loadUiFromFile("resources/w/ui/hud_step4.json", renderer, zipFile);
hudStep5aRoot = loadUiFromFile("resources/w/ui/hud_step5a.json", renderer, zipFile);
hudStep5bRoot = loadUiFromFile("resources/w/ui/hud_step5b.json", renderer, zipFile);
hudStep5abRoot = loadUiFromFile("resources/w/ui/hud_step5ab.json", renderer, zipFile);
hudUniExtRoot = loadUiFromFile("resources/w/ui/hud_uni_ext.json", renderer, zipFile);
hudUniIntStep10Root = loadUiFromFile("resources/w/ui/hud_uni_int_step10.json", renderer, zipFile);
hudUniIntStep11Root = loadUiFromFile("resources/w/ui/hud_uni_int_step11.json", renderer, zipFile);
hudUniIntStep12Root = loadUiFromFile("resources/w/ui/hud_uni_int_step12.json", renderer, zipFile);
hudUniIntStep13Root = loadUiFromFile("resources/w/ui/hud_uni_int_step13.json", renderer, zipFile);
hudUniIntFullRoot = loadUiFromFile("resources/w/ui/hud_uni_int_full.json", renderer, zipFile);
hudUniIntDarkFullRoot = loadUiFromFile("resources/w/ui/hud_uni_int_dark_full.json", renderer, zipFile);
hudUniExtDarkRoot = loadUiFromFile("resources/w/ui/hud_uni_ext_dark.json", renderer, zipFile);
hudCutsceneRoot_ = loadUiFromFile("resources/w/ui/hud_cutscene.json", renderer, zipFile);
hudTopHintRoot_ = loadUiFromFile("resources/w/ui/hud_top_hint01.json", renderer, zipFile);
phoneMainRoot = loadUiFromFile("resources/w/ui/screen_phone.json", renderer, zipFile);
phoneMainHintARoot = loadUiFromFile("resources/w/ui/screen_phone_hint001.json", renderer, zipFile);
phoneMainHintBRoot = loadUiFromFile("resources/w/ui/screen_phone_hint002.json", renderer, zipFile);
phoneMainHintABRoot = loadUiFromFile("resources/w/ui/screen_phone_hint001_002.json", renderer, zipFile);
phoneBankRoot = loadUiFromFile("resources/w/ui/screen_phone_bank.json", renderer, zipFile);
phoneVideoRoot = loadUiFromFile("resources/w/ui/screen_phone_video.json", renderer, zipFile);
phoneMapDormRoot = loadUiFromFile("resources/w/ui/screen_phone_map_dorm.json", renderer, zipFile);
phoneMapUniRoot = loadUiFromFile("resources/w/ui/screen_phone_map_uni.json", renderer, zipFile);
verticalPhoneMainRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone.json", renderer, zipFile);
verticalPhoneMainHintARoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_hint001.json", renderer, zipFile);
verticalPhoneMainHintBRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_hint002.json", renderer, zipFile);
verticalPhoneMainHintABRoot= loadUiFromFile("resources/w/ui/portrait_screen_phone_hint001_002.json", renderer, zipFile);
verticalPhoneBankRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_bank.json", renderer, zipFile);
verticalPhoneVideoRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_video.json", renderer, zipFile);
verticalPhoneMapDormRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_map_dorm.json", renderer, zipFile);
verticalPhoneMapUniRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_map_uni.json", renderer, zipFile);
phoneChatListRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list.json", renderer, zipFile);
phoneChatListHintRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list_hint001.json", renderer, zipFile);
verticalPhoneChatListRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat_list.json", renderer, zipFile);
verticalPhoneChatListHintRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat_list_hint001.json", renderer, zipFile);
phoneChat1Root = loadUiFromFile("resources/w/ui/screen_phone_chat1.json", renderer, zipFile);
phoneChat2Root = loadUiFromFile("resources/w/ui/screen_phone_chat2.json", renderer, zipFile);
phoneChat3Root = loadUiFromFile("resources/w/ui/screen_phone_chat3.json", renderer, zipFile);
verticalPhoneChat1Root = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat1.json", renderer, zipFile);
verticalPhoneChat2Root = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat2.json", renderer, zipFile);
verticalPhoneChat3Root = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat3.json", renderer, zipFile);
modalMenuRoot = loadUiFromFile("resources/w/ui/screen_modal_menu.json", renderer, zipFile);
newInventoryRoot = loadUiFromFile("resources/w/ui/screen_inventory.json", renderer, zipFile);
portraitInventoryListRoot = loadUiFromFile("resources/w/ui/portrait_screen_inventory.json", renderer, zipFile);
portraitInventoryItemRoot = loadUiFromFile("resources/w/ui/portrait_screen_inventory_item.json", renderer, zipFile);
questJournalRoot = loadUiFromFile("resources/w/ui/screen_journal.json", renderer, zipFile);
portraitQuestJournalListRoot = loadUiFromFile("resources/w/ui/portrait_screen_journal.json", renderer, zipFile);
portraitQuestJournalItemRoot = loadUiFromFile("resources/w/ui/portrait_screen_journal_item.json", renderer, zipFile);
mainMenuRoot = loadUiFromFile("resources/w/ui/screen_main_menu.json", renderer, zipFile);
aboutScreenRoot = loadUiFromFile("resources/w/ui/screen_about.json", renderer, zipFile);
settingsScreenRoot = loadUiFromFile("resources/w/ui/screen_settings.json", renderer, zipFile);
languageScreenRoot = loadUiFromFile("resources/w/ui/screen_language.json", renderer, zipFile);
loadSavedGameScreenRoot = loadUiFromFile("resources/w/ui/screen_load.json", renderer, zipFile);
saveGameScreenRoot = loadUiFromFile("resources/w/ui/screen_save.json", renderer, zipFile);
loadUiRoots(zipFile);
texObjectiveCompleted_ = renderer.textureManager.LoadFromPng("resources/w/ui/img/journal/quest_objective_completed.png", zipFile, true);
texObjectiveBlank_ = renderer.textureManager.LoadFromPng("resources/w/ui/img/journal/quest_objective_blank.png", zipFile, true);
@@ -407,10 +422,6 @@ namespace ZL {
Environment::setFullscreen(!Environment::isFullscreen);
refreshFullscreenToggle();
});
uiManager.setTextButtonCallback("languageButton", [this](const std::string&) {
showLanguageScreen();
});
}
void MenuManager::showLanguageScreen() {
@@ -434,6 +445,25 @@ namespace ZL {
void MenuManager::reloadLocalizedGameContent() {
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
gameState_.questJournal.reloadDefinitionsPreservingState("resources/config/quests.json", CONST_ZIP_FILE);
// Screens below the Language screen on the menu stack hold onto their old
// (pre-reload) UiNode instances, so simply reopening Language on top of
// them would leave Main Menu / Settings / the pause menu showing stale
// text once the player steps back. Instead, unwind the whole chain and
// replay it with freshly (re)loaded, localized roots.
const bool wasInMainMenu = (uiState_ == GameUiState::MainMenu);
if (!wasInMainMenu) {
// Reached via the in-game pause menu (Modal -> Settings -> Language).
// Fully unwind back to the untouched gameplay HUD underneath — it
// isn't rebuilt here, only the pause/settings/language chain above it.
const int depth = uiManager.menuStackSize();
for (int i = 0; i < depth; ++i) uiManager.popMenu();
}
loadUiRoots(CONST_ZIP_FILE);
showMainMenu();
}
void MenuManager::showLoadGameScreen()
+2
View File
@@ -122,6 +122,8 @@ namespace ZL {
void applyHudForCurrentState();
void refreshQuestJournalUi();
void reloadLocalizedGameContent();
std::shared_ptr<UiNode> loadLocalizedUi(const std::string& basePath, const std::string& zipFile);
void loadUiRoots(const std::string& zipFile);
void selectQuestByIndex(int index);
void refreshItemPickupHud();
void setupStep5Callbacks();