diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index ded4513..a3dd8fb 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -3209,15 +3209,20 @@ void Continuity::reset() ingredientData.clear(); recipes.clear(); + std::string fname; + if(dsq->mod.isActive()) { //load mod ingredients - loadIngredientData(dsq->mod.getPath() + "ingredients.txt"); + fname = dsq->user.localisePath(dsq->mod.getPath() + "ingredients.txt", dsq->mod.getPath()); + loadIngredientData(fname); } //load ingredients for the main game - if(ingredientData.empty() && recipes.empty()) - loadIngredientData("data/ingredients.txt"); + if(ingredientData.empty() && recipes.empty()) { + fname = dsq->user.localisePath("data/ingredients.txt"); + loadIngredientData(fname); + } loadPetData(); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index ff65463..b758879 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -8010,21 +8010,30 @@ void Game::toggleHelpScreen(bool on, const std::string &label) // These say "Mac" but we use them on Linux, too. #if defined(BBGE_BUILD_UNIX) - appendFileToString(data, "data/help_header_mac.txt"); + std::string fname = dsq->user.localisePath("data/help_header_mac.txt"); + appendFileToString(data, fname); #else - appendFileToString(data, "data/help_header.txt"); + std::string fname = dsq->user.localisePath("data/help_header.txt"); + appendFileToString(data, fname); #endif - if (dsq->continuity.hasSong(SONG_BIND)) - appendFileToString(data, "data/help_bindsong.txt"); - if (dsq->continuity.hasSong(SONG_ENERGYFORM)) - appendFileToString(data, "data/help_energyform.txt"); - appendFileToString(data, "data/help_start.txt"); + if (dsq->continuity.hasSong(SONG_BIND)) { + fname = dsq->user.localisePath("data/help_bindsong.txt"); + appendFileToString(data, fname); + } + if (dsq->continuity.hasSong(SONG_ENERGYFORM)) { + fname = dsq->user.localisePath("data/help_energyform.txt"); + appendFileToString(data, fname); + } + fname = dsq->user.localisePath("data/help_start.txt"); + appendFileToString(data, fname); // These say "Mac" but we use them on Linux, too. #if defined(BBGE_BUILD_UNIX) - appendFileToString(data, "data/help_end_mac.txt"); + fname = dsq->user.localisePath("data/help_end_mac.txt"); + appendFileToString(data, fname); #else - appendFileToString(data, "data/help_end.txt"); + fname = dsq->user.localisePath("data/help_end.txt"); + appendFileToString(data, fname); #endif // !!! FIXME: this is such a hack. diff --git a/Aquaria/StatsAndAchievements.cpp b/Aquaria/StatsAndAchievements.cpp index c0c72e1..e820ecc 100644 --- a/Aquaria/StatsAndAchievements.cpp +++ b/Aquaria/StatsAndAchievements.cpp @@ -174,7 +174,8 @@ void StatsAndAchievements::RunFrame() FILE *io = NULL; // Get generic achievement data... - io = fopen("data/achievements.txt", "r"); + std::string fname = dsq->user.localisePath("data/achievements.txt"); + io = fopen(fname.c_str(), "r"); char line[1024]; for (size_t i = 0; i < max_achievements; i++) { @@ -209,7 +210,7 @@ void StatsAndAchievements::RunFrame() unsigned char *buf = new unsigned char[max_achievements]; size_t br = 0; - const std::string fname(core->getUserDataFolder() + "/achievements.bin"); + fname = (core->getUserDataFolder() + "/achievements.bin"); io = fopen(fname.c_str(), "rb"); if (io == NULL) statsValid = true; // nothing to report. diff --git a/Aquaria/StringBank.cpp b/Aquaria/StringBank.cpp index 62dc215..2ccdbc7 100644 --- a/Aquaria/StringBank.cpp +++ b/Aquaria/StringBank.cpp @@ -28,9 +28,13 @@ void StringBank::load() { stringMap.clear(); - _load("data/stringbank.txt"); - if (dsq->mod.isActive()) - _load(dsq->mod.getPath() + "stringbank.txt"); + std::string fname = dsq->user.localisePath("data/stringbank.txt"); + _load(fname); + + if (dsq->mod.isActive()) { + fname = dsq->user.localisePath(dsq->mod.getPath() + "stringbank.txt", dsq->mod.getPath()); + _load(fname); + } } void StringBank::_load(const std::string &file) diff --git a/Aquaria/SubtitlePlayer.cpp b/Aquaria/SubtitlePlayer.cpp index aaf3a84..cf79a27 100644 --- a/Aquaria/SubtitlePlayer.cpp +++ b/Aquaria/SubtitlePlayer.cpp @@ -46,6 +46,7 @@ void SubtitlePlayer::go(const std::string &subs) if (dsq->mod.isActive()) { f = dsq->mod.getPath() + "audio/" + subs + ".txt"; + f = dsq->user.localisePath(f, dsq->mod.getPath()); f = core->adjustFilenameCase(f); if (exists(f)) checkAfter = false; @@ -54,6 +55,7 @@ void SubtitlePlayer::go(const std::string &subs) if (checkAfter) { f = "scripts/vox/" + subs + ".txt"; + f = dsq->user.localisePath(f); f = core->adjustFilenameCase(f); if (!exists(f)) { diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index d8e30d4..1362687 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -33,6 +33,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #endif +#ifdef BBGE_BUILD_UNIX + #include + #include + #include +#endif void UserSettings::save() { @@ -53,6 +58,14 @@ void UserSettings::save() xml_debugLog.SetAttribute("on", system.debugLogOn); } xml_system.InsertEndChild(xml_debugLog); + + if (!system.isSystemLocale) { + TiXmlElement xml_locale("Locale"); + { + xml_locale.SetAttribute("name", system.locale); + } + xml_system.InsertEndChild(xml_locale); + } } doc.InsertEndChild(xml_system); @@ -347,6 +360,12 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) { xml_debugLog->Attribute("on", &system.debugLogOn); } + + TiXmlElement *xml_locale = xml_system->FirstChildElement("Locale"); + if (xml_locale) + { + system.locale = xml_locale->Attribute("name"); + } } TiXmlElement *xml_audio = doc.FirstChildElement("Audio"); @@ -485,6 +504,11 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) readIntAtt(xml_data, "lastSelectedMod", &data.lastSelectedMod); } + if (system.locale.empty()) + getSystemLocale(); + else + debugLog("use user config locale: " + system.locale); + //clearInputCodeMap(); if (doApply) @@ -526,3 +550,66 @@ void UserSettings::apply() #endif } +std::string UserSettings::localisePath(const std::string &path, const std::string &modpath) +{ + if (system.locale.empty()) + return path; + + const std::string fname = path.substr(modpath.length()); + + /* we first try with complete locale name, i.e "locales/en_US/" */ + std::string localisedPath = modpath + "locales/" + system.locale + "/" + fname; + + if (exists(localisedPath.c_str())) + return localisedPath; + + /* ok didn't work, let's retry with only language part of locale name, i.e "locales/en/" */ + const size_t found = system.locale.find('_'); + + /* hmm, seems like we didn't have a full locale name anyway, use original path */ + if (found == string::npos) + return path; + + localisedPath = modpath + "locales/" + system.locale.substr(0,found) + "/" + fname; + + /* hooray we found a file! */ + if (exists(localisedPath.c_str())) + return localisedPath; + + /* seems like we don't have a localized version of the file available, use original path */ + return path; +} + +void UserSettings::getSystemLocale() +{ + system.isSystemLocale = true; + +#ifdef BBGE_BUILD_WINDOWS + LCID lcid = GetThreadLocale(); + + char buf[100]; + char ctry[100]; + + if (GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, sizeof buf) != 0) + { + system.locale = buf; + + if (GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, ctry, sizeof ctry) != 0) + { + system.locale += "_"; + system.locale += ctry; + } + } +#else + system.locale = getenv("LANG"); + + size_t found = system.locale.find('.'); + + if (found != string::npos) + system.locale.resize(found); +#endif + if (system.locale.empty()) + debugLog("could not establish system locale"); + else + debugLog("use system locale: " + system.locale); +} diff --git a/Aquaria/UserSettings.h b/Aquaria/UserSettings.h index d06456e..d1fd4b9 100644 --- a/Aquaria/UserSettings.h +++ b/Aquaria/UserSettings.h @@ -77,8 +77,10 @@ class UserSettings public: struct System { - System() { debugLogOn = 0; } + System() { debugLogOn = 0; isSystemLocale = false; } int debugLogOn; + bool isSystemLocale; + std::string locale; } system; struct Audio @@ -175,4 +177,8 @@ public: void load(bool doApply=true, const std::string &overrideFile=""); void save(); void apply(); + std::string localisePath(const std::string &path, const std::string &modpath=""); + +private: + void getSystemLocale(); };