Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ add_library(${PROJECT_NAME} STATIC
src/transform.h
src/transition.cpp
src/transition.h
src/translation.cpp
src/translation.h
src/util_macro.h
src/utils.cpp
src/utils.h
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ libeasyrpg_player_a_SOURCES = \
src/transform.h \
src/transition.cpp \
src/transition.h \
src/translation.cpp \
src/translation.h \
src/util_macro.h \
src/utils.cpp \
src/utils.h \
Expand Down
25 changes: 19 additions & 6 deletions src/filefinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,14 @@ namespace {
std::string FindFile(FileFinder::DirectoryTree const& tree,
const std::string& dir,
const std::string& name,
char const* exts[])
char const* exts[],
bool translate=false)
{
using namespace FileFinder;

// Avoid searching entirely if there is no active translation
if (translate && Tr::GetCurrentTranslationId().empty()) { return ""; }

#ifdef EMSCRIPTEN
// The php filefinder should have given us an useable path
std::string em_file = MakePath(dir, name);
Expand All @@ -99,9 +103,9 @@ namespace {
return em_file;
#endif

std::string corrected_dir = lcf::ReaderUtil::Normalize(dir);
std::string corrected_dir = lcf::ReaderUtil::Normalize(translate?Tr::GetTranslationDir():dir);
std::string const escape_symbol = Player::escape_symbol;
std::string corrected_name = lcf::ReaderUtil::Normalize(name);
std::string corrected_name = lcf::ReaderUtil::Normalize(translate?MakePath(MakePath(Tr::GetCurrentTranslationId(), dir), name):name);

std::string combined_path = MakePath(corrected_dir, corrected_name);
std::string canon = MakeCanonical(combined_path, 1);
Expand Down Expand Up @@ -229,9 +233,18 @@ namespace {
return normal_search();
}

std::string FindFile(const std::string &dir, const std::string& name, const char* exts[]) {
std::string FindFile(const std::string &dir, const std::string& name, const char* exts[], bool tryTranslate=false) {
// Search for translated resources first.
const std::shared_ptr<FileFinder::DirectoryTree> tree = FileFinder::GetDirectoryTree();
std::string ret = FindFile(*tree, dir, name, exts);
if (tryTranslate) {
std::string ret = FindFile(*tree, dir, name, exts, true);
if (!ret.empty()) {
return ret;
}
}

// Try without translating.
std::string ret = FindFile(*tree, dir, name, exts, false);
if (!ret.empty()) {
return ret;
}
Expand Down Expand Up @@ -685,7 +698,7 @@ std::string FileFinder::FindImage(const std::string& dir, const std::string& nam
#endif

static const char* IMG_TYPES[] = { ".bmp", ".png", ".xyz", NULL };
return FindFile(dir, name, IMG_TYPES);
return FindFile(dir, name, IMG_TYPES, true);
}

std::string FileFinder::FindDefault(const std::string& dir, const std::string& name) {
Expand Down
8 changes: 8 additions & 0 deletions src/game_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,14 @@ std::unique_ptr<lcf::rpg::Map> Game_Map::loadMapFile(int map_id) {
}

void Game_Map::SetupCommon() {
if (!Tr::GetCurrentTranslationId().empty()) {
// Build our map translation id.
std::stringstream ss;
ss << "map" << std::setfill('0') << std::setw(4) << GetMapId() << ".po";

// Translate all messages for this map
Player::translation.RewriteMapMessages(ss.str(), *map);
}
SetNeedRefresh(true);

int current_index = GetMapIndex(GetMapId());
Expand Down
6 changes: 6 additions & 0 deletions src/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
#define MTINI_EXVOCAB_IMPORT_SAVE_HELP_VALUE "Import Existing Save (Multi-Games Only)"
#define MTINI_EXVOCAB_IMPORT_SAVE_TITLE_KEY "Vocab_ImportSave"
#define MTINI_EXVOCAB_IMPORT_SAVE_TITLE_VALUE "Import Save"
#define MTINI_EXVOCAB_TRANSLATE_TITLE_KEY "Vocab_Translate"
#define MTINI_EXVOCAB_TRANSLATE_TITLE_VALUE "Translation"


// Helper: Get the CRC32 of a given file as a hex string
Expand Down Expand Up @@ -218,6 +220,10 @@ std::string Meta::GetExVocabImportSaveTitleText() const {
return GetExVocab(MTINI_EXVOCAB_IMPORT_SAVE_TITLE_KEY, MTINI_EXVOCAB_IMPORT_SAVE_TITLE_VALUE);
}

std::string Meta::GetExVocabTranslateTitleText() const {
return GetExVocab(MTINI_EXVOCAB_TRANSLATE_TITLE_KEY, MTINI_EXVOCAB_TRANSLATE_TITLE_VALUE);
}

std::string Meta::GetExVocab(const std::string& term, const std::string& def_value) const {
if (!Empty()) {
return ini->GetString(canon_ini_lookup, term, def_value);
Expand Down
6 changes: 6 additions & 0 deletions src/meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ class Meta {
* @return the INI-defined value, or the defualt value for this vocabulary term
*/
std::string GetExVocabImportSaveTitleText() const;

/**
* Retrieve the menu item text for Scen_Title translations (languages)
* @return the INI-defined value, or the default value for this vocabulary term
*/
std::string GetExVocabTranslateTitleText() const;


private:
Expand Down
4 changes: 4 additions & 0 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ namespace Player {
int patch;
std::shared_ptr<Meta> meta;
FileExtGuesser::RPG2KFileExtRemap fileext_map;
Translation translation;
int frames;
std::string replay_input_path;
std::string record_input_path;
Expand Down Expand Up @@ -676,6 +677,9 @@ void Player::CreateGameObjects() {
}
escape_char = Utils::DecodeUTF32(Player::escape_symbol).front();

// Check for translation-related directories and load language names.
translation.InitTranslations();

std::string game_path = Main_Data::GetProjectPath();
std::string save_path = Main_Data::GetSavePath();
if (game_path == save_path) {
Expand Down
4 changes: 4 additions & 0 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// Headers
#include "fileext_guesser.h"
#include "meta.h"
#include "translation.h"
#include "game_clock.h"
#include "game_config.h"
#include <vector>
Expand Down Expand Up @@ -348,6 +349,9 @@ namespace Player {
/** File extension rewriter, for non-standard extensions. */
extern FileExtGuesser::RPG2KFileExtRemap fileext_map;

/** Translation manager, including list of languages and current translation. */
extern Translation translation;

/**
* The default speed modifier applied when the speed up button is pressed
* Only used for configuring the speedup, don't read this var directly use
Expand Down
143 changes: 124 additions & 19 deletions src/scene_title.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "meta.h"
#include "output.h"
#include "player.h"
#include "translation.h"
#include "scene_battle.h"
#include "scene_import.h"
#include "scene_load.h"
Expand All @@ -53,6 +54,14 @@ void Scene_Title::Start() {
}

CreateCommandWindow();
CreateTranslationWindow();
CreateHelpWindow();
}

void Scene_Title::CreateHelpWindow() {
help_window.reset(new Window_Help(0, 0, SCREEN_TARGET_WIDTH, 32));
help_window->SetVisible(false);
translate_window->SetHelpWindow(help_window.get());
}


Expand Down Expand Up @@ -109,18 +118,35 @@ void Scene_Title::Update() {
return;
}

command_window->Update();
if (active_window == 0) {
command_window->Update();
} else {
translate_window->Update();
}

if (Input::IsTriggered(Input::DECISION)) {
int index = command_window->GetIndex();
if (index == new_game_index) { // New Game
CommandNewGame();
} else if (index == continue_index) { // Load Game
CommandContinue();
} else if (index == import_index) { // Import (multi-part games)
CommandImport();
} else if (index == exit_index) { // Exit Game
CommandShutdown();
if (active_window == 0) {
int index = command_window->GetIndex();
if (index == indices.new_game) { // New Game
CommandNewGame();
} else if (index == indices.continue_game) { // Load Game
CommandContinue();
} else if (index == indices.import) { // Import (multi-part games)
CommandImport();
} else if (index == indices.translate) { // Choose a Translation (Language)
CommandTranslation();
} else if (index == indices.exit) { // Exit Game
CommandShutdown();
}
} else if (active_window == 1) {
int index = translate_window->GetIndex();
ChangeLanguage(lang_dirs.at(index));
}
} else if (Input::IsTriggered(Input::CANCEL)) {
if (active_window == 1) {
// Switch back
Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Cancel));
HideTranslationWindow();
}
}
}
Expand All @@ -139,29 +165,44 @@ void Scene_Title::CreateTitleGraphic() {
}
}

void Scene_Title::RepositionWindow(Window_Command& window, bool center_vertical) {
if (!center_vertical) {
window.SetX(SCREEN_TARGET_WIDTH / 2 - window.GetWidth() / 2);
window.SetY(SCREEN_TARGET_HEIGHT * 53 / 60 - window.GetHeight());
} else {
window.SetX(SCREEN_TARGET_WIDTH / 2 - window.GetWidth() / 2);
window.SetY(SCREEN_TARGET_HEIGHT / 2 - window.GetHeight() / 2);
}
}

void Scene_Title::CreateCommandWindow() {
// Create Options Window
std::vector<std::string> options;
options.push_back(ToString(lcf::Data::terms.new_game));
options.push_back(ToString(lcf::Data::terms.load_game));

// Reset index to fix issues on reuse.
indices = CommandIndices();

// Set "Import" based on metadata
if (Player::meta->IsImportEnabled()) {
options.push_back(Player::meta->GetExVocabImportSaveTitleText());
import_index = 2;
exit_index = 3;
indices.import = indices.exit;
indices.exit++;
}

// Set "Translate" based on metadata
if (Player::translation.HasTranslations()) {
options.push_back(Player::meta->GetExVocabTranslateTitleText());
indices.translate = indices.exit;
indices.exit++;
}

options.push_back(ToString(lcf::Data::terms.exit_game));

command_window.reset(new Window_Command(options));
if (!Player::hide_title_flag) {
command_window->SetX(SCREEN_TARGET_WIDTH / 2 - command_window->GetWidth() / 2);
command_window->SetY(SCREEN_TARGET_HEIGHT * 53 / 60 - command_window->GetHeight());
} else {
command_window->SetX(SCREEN_TARGET_WIDTH / 2 - command_window->GetWidth() / 2);
command_window->SetY(SCREEN_TARGET_HEIGHT / 2 - command_window->GetHeight() / 2);
}
RepositionWindow(*command_window, Player::hide_title_flag);

// Enable load game if available
continue_enabled = FileFinder::HasSavegame();
if (continue_enabled) {
Expand All @@ -182,6 +223,37 @@ void Scene_Title::CreateCommandWindow() {
command_window->SetVisible(true);
}

void Scene_Title::CreateTranslationWindow() {
// Build a list of 'Default' and all known languages.
std::vector<std::string> lang_names;
lang_names.push_back("Default Language");
lang_dirs.push_back("");
lang_helps.push_back("Play the game in its original language.");

// Push menu entries with the display name, but also save the directory location and help text.
for (const Language& lg : Player::translation.GetLanguages()) {
lang_names.push_back(lg.lang_name);
lang_dirs.push_back(lg.lang_dir);
lang_helps.push_back(lg.lang_desc);
}

translate_window.reset(new Window_Command(lang_names));
translate_window->UpdateHelpFn = [this](Window_Help& win, int index) {
if (index>=0 && index<lang_helps.size()) {
win.SetText(lang_helps[index]);
} else {
win.SetText("");
}
};
RepositionWindow(*translate_window, Player::hide_title_flag);

if (Player::IsRPG2k3E() && lcf::Data::battlecommands.transparency == lcf::rpg::BattleCommands::Transparency_transparent) {
translate_window->SetBackOpacity(128);
}

translate_window->SetVisible(false);
}

void Scene_Title::PlayTitleMusic() {
// Workaround Android problem: BGM doesn't start when game is started again
Main_Data::game_system->BgmStop();
Expand Down Expand Up @@ -227,6 +299,39 @@ void Scene_Title::CommandImport() {
Scene::Push(std::make_shared<Scene_Import>());
}

void Scene_Title::CommandTranslation() {
Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Decision));

// Switch windows
active_window = 1;
command_window->SetVisible(false);
translate_window->SetVisible(true);
help_window->SetVisible(true);
}

void Scene_Title::ChangeLanguage(const std::string& lang_str) {
Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Decision));

// No-op?
if (lang_str == Player::translation.GetCurrentLanguageId()) {
HideTranslationWindow();
return;
}

// First change the language
Player::translation.SelectLanguage(lang_str);

// Now reset the scene (force asset reload)
Scene::Push(std::make_shared<Scene_Title>(), true);
}

void Scene_Title::HideTranslationWindow() {
active_window = 0;
command_window->SetVisible(true);
translate_window->SetVisible(false);
help_window->SetVisible(false);
}

void Scene_Title::CommandShutdown() {
Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Decision));
Transition::instance().InitErase(Transition::TransitionFadeOut, this);
Expand Down
Loading