2010-03-20 13:11:46 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2010-04-11 03:25:06 +02:00
// Copyright (C) 2001-2008 Martio Figueroa
2010-03-20 13:11:46 +01:00
//
2010-03-21 06:33:13 +01:00
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
2010-03-20 13:11:46 +01:00
// License, or (at your option) any later version
// ==============================================================
# include "lang.h"
# include <stdexcept>
# include "logger.h"
# include "util.h"
# include "platform_util.h"
2010-12-09 21:41:11 +01:00
# include "game_constants.h"
# include "game_util.h"
2011-06-08 09:18:06 +02:00
# include "platform_common.h"
2011-10-25 20:39:11 +02:00
# include "conversion.h"
# include "gl_wrap.h"
# include "core_data.h"
# include "renderer.h"
2010-03-20 13:11:46 +01:00
# include "leak_dumper.h"
using namespace std ;
using namespace Shared : : Util ;
using namespace Shared : : Platform ;
namespace Glest { namespace Game {
2011-11-02 18:17:28 +01:00
const char * DEFAULT_LANGUAGE = " english " ;
2010-03-20 13:11:46 +01:00
// =====================================================
// class Lang
// =====================================================
2011-06-08 09:18:06 +02:00
Lang : : Lang ( ) {
language = " " ;
is_utf8_language = false ;
}
Lang & Lang : : getInstance ( ) {
2010-03-20 13:11:46 +01:00
static Lang lang ;
return lang ;
2010-03-21 06:33:13 +01:00
}
2010-03-20 13:11:46 +01:00
2011-11-02 18:17:28 +01:00
void Lang : : loadStrings ( const string & uselanguage , bool loadFonts ) {
bool languageChanged = ( uselanguage ! = this - > language ) ;
this - > language = uselanguage ;
loadStrings ( uselanguage , strings , true ) ;
2011-10-25 20:39:11 +02:00
if ( languageChanged = = true ) {
Font : : resetToDefaults ( ) ;
Lang & lang = Lang : : getInstance ( ) ;
if ( lang . hasString ( " FONT_BASE_SIZE " ) ) {
Font : : baseSize = strToInt ( lang . get ( " FONT_BASE_SIZE " ) ) ;
}
if ( lang . hasString ( " FONT_SCALE_SIZE " ) ) {
Font : : scaleFontValue = strToFloat ( lang . get ( " FONT_SCALE_SIZE " ) ) ;
}
if ( lang . hasString ( " FONT_SCALE_CENTERH_FACTOR " ) ) {
Font : : scaleFontValueCenterHFactor = strToFloat ( lang . get ( " FONT_SCALE_CENTERH_FACTOR " ) ) ;
}
if ( lang . hasString ( " FONT_CHARCOUNT " ) ) {
// 256 for English
// 30000 for Chinese
Font : : charCount = strToInt ( lang . get ( " FONT_CHARCOUNT " ) ) ;
}
if ( lang . hasString ( " FONT_TYPENAME " ) ) {
Font : : fontTypeName = lang . get ( " FONT_TYPENAME " ) ;
}
if ( lang . hasString ( " FONT_CHARSET " ) ) {
// Example values:
// DEFAULT_CHARSET (English) = 1
// GB2312_CHARSET (Chinese) = 134
Shared : : Platform : : charSet = strToInt ( lang . get ( " FONT_CHARSET " ) ) ;
}
if ( lang . hasString ( " FONT_MULTIBYTE " ) ) {
Font : : fontIsMultibyte = strToBool ( lang . get ( " FONT_MULTIBYTE " ) ) ;
}
if ( lang . hasString ( " FONT_RIGHTTOLEFT " ) ) {
Font : : fontIsRightToLeft = strToBool ( lang . get ( " FONT_RIGHTTOLEFT " ) ) ;
}
if ( lang . hasString ( " MEGAGLEST_FONT " ) ) {
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese
# if defined(WIN32)
string newEnvValue = " MEGAGLEST_FONT= " + lang . get ( " MEGAGLEST_FONT " ) ;
_putenv ( newEnvValue . c_str ( ) ) ;
# else
setenv ( " MEGAGLEST_FONT " , lang . get ( " MEGAGLEST_FONT " ) . c_str ( ) , 0 ) ;
# endif
}
// if( lang.hasString("FONT_YOFFSET_FACTOR")) {
// FontMetrics::DEFAULT_Y_OFFSET_FACTOR = strToFloat(lang.get("FONT_YOFFSET_FACTOR"));
// }
# if defined(WIN32)
// Win32 overrides for fonts (just in case they must be different)
if ( lang . hasString ( " FONT_BASE_SIZE_WINDOWS " ) ) {
// 256 for English
// 30000 for Chinese
Font : : baseSize = strToInt ( lang . get ( " FONT_BASE_SIZE_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_SCALE_SIZE_WINDOWS " ) ) {
Font : : scaleFontValue = strToFloat ( lang . get ( " FONT_SCALE_SIZE_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_SCALE_CENTERH_FACTOR_WINDOWS " ) ) {
Font : : scaleFontValueCenterHFactor = strToFloat ( lang . get ( " FONT_SCALE_CENTERH_FACTOR_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_HEIGHT_TEXT_WINDOWS " ) ) {
2011-10-25 22:34:13 +02:00
Font : : langHeightText = lang . get ( " FONT_HEIGHT_TEXT_WINDOWS " , Font : : langHeightText . c_str ( ) ) ;
2011-10-25 20:39:11 +02:00
}
if ( lang . hasString ( " FONT_CHARCOUNT_WINDOWS " ) ) {
// 256 for English
// 30000 for Chinese
Font : : charCount = strToInt ( lang . get ( " FONT_CHARCOUNT_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_TYPENAME_WINDOWS " ) ) {
Font : : fontTypeName = lang . get ( " FONT_TYPENAME_WINDOWS " ) ;
}
if ( lang . hasString ( " FONT_CHARSET_WINDOWS " ) ) {
// Example values:
// DEFAULT_CHARSET (English) = 1
// GB2312_CHARSET (Chinese) = 134
Shared : : Platform : : charSet = strToInt ( lang . get ( " FONT_CHARSET_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_MULTIBYTE_WINDOWS " ) ) {
Font : : fontIsMultibyte = strToBool ( lang . get ( " FONT_MULTIBYTE_WINDOWS " ) ) ;
}
if ( lang . hasString ( " FONT_RIGHTTOLEFT_WINDOWS " ) ) {
Font : : fontIsRightToLeft = strToBool ( lang . get ( " FONT_RIGHTTOLEFT_WINDOWS " ) ) ;
}
if ( lang . hasString ( " MEGAGLEST_FONT_WINDOWS " ) ) {
//setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese
string newEnvValue = " MEGAGLEST_FONT= " + lang . get ( " MEGAGLEST_FONT_WINDOWS " ) ;
_putenv ( newEnvValue . c_str ( ) ) ;
}
// if( lang.hasString("FONT_YOFFSET_FACTOR_WINDOWS")) {
// FontMetrics::DEFAULT_Y_OFFSET_FACTOR = strToFloat(lang.get("FONT_YOFFSET_FACTOR_WINDOWS"));
// }
// end win32
# endif
2011-11-01 22:47:34 +01:00
if ( loadFonts ) {
CoreData & coreData = CoreData : : getInstance ( ) ;
coreData . loadFonts ( ) ;
}
2011-10-25 20:39:11 +02:00
}
2011-04-05 20:39:47 +02:00
}
2011-11-02 18:17:28 +01:00
void Lang : : loadStrings ( const string & uselanguage , Properties & properties , bool fileMustExist ) {
2011-04-05 20:39:47 +02:00
properties . clear ( ) ;
2010-12-09 21:41:11 +01:00
string data_path = getGameReadWritePath ( GameConstants : : path_data_CacheLookupKey ) ;
2011-11-02 18:17:28 +01:00
//string languageFile = data_path + "data/lang/" + uselanguage + ".lng";
string languageFile = getGameCustomCoreDataPath ( data_path , " data/lang/ " + uselanguage + " .lng " ) ;
2011-04-05 20:39:47 +02:00
if ( fileMustExist = = false & & fileExists ( languageFile ) = = false ) {
return ;
}
2011-06-08 09:18:06 +02:00
is_utf8_language = valid_utf8_file ( languageFile . c_str ( ) ) ;
2011-04-05 20:39:47 +02:00
properties . load ( languageFile ) ;
2010-03-20 13:11:46 +01:00
}
2011-06-08 09:18:06 +02:00
bool Lang : : isUTF8Language ( ) const {
return is_utf8_language ;
}
2010-03-20 13:11:46 +01:00
void Lang : : loadScenarioStrings ( const string & scenarioDir , const string & scenarioName ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] scenarioDir = [%s] scenarioName = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , scenarioDir . c_str ( ) , scenarioName . c_str ( ) ) ;
2010-04-11 03:25:06 +02:00
2011-03-13 09:23:43 +01:00
string currentPath = scenarioDir ;
endPathWithSlash ( currentPath ) ;
string scenarioFolder = currentPath + scenarioName + " / " ;
2010-04-11 03:25:06 +02:00
string path = scenarioFolder + scenarioName + " _ " + language + " .lng " ;
2010-03-20 13:11:46 +01:00
if ( EndsWith ( scenarioDir , " .xml " ) = = true ) {
2010-04-11 03:25:06 +02:00
scenarioFolder = extractDirectoryPathFromFile ( scenarioDir ) ;
path = scenarioFolder + scenarioName + " _ " + language + " .lng " ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] path = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , path . c_str ( ) ) ;
2010-03-20 13:11:46 +01:00
}
2010-03-21 06:33:13 +01:00
2010-03-20 13:11:46 +01:00
scenarioStrings . clear ( ) ;
2010-03-21 06:33:13 +01:00
2010-03-20 13:11:46 +01:00
//try to load the current language first
2010-03-21 06:33:13 +01:00
if ( fileExists ( path ) ) {
2010-03-20 13:11:46 +01:00
scenarioStrings . load ( path ) ;
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] path not found [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , path . c_str ( ) ) ;
2010-03-20 13:11:46 +01:00
//try english otherwise
2010-04-11 03:25:06 +02:00
path = scenarioFolder + scenarioName + " _english.lng " ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] path = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , path . c_str ( ) ) ;
2010-04-11 03:25:06 +02:00
2010-03-20 13:11:46 +01:00
if ( fileExists ( path ) ) {
scenarioStrings . load ( path ) ;
}
}
}
2011-11-02 18:17:28 +01:00
bool Lang : : hasString ( const string & s , string uselanguage , bool fallbackToDefault ) {
bool result = false ;
2011-01-14 18:57:37 +01:00
try {
2011-11-02 18:17:28 +01:00
if ( uselanguage ! = " " ) {
//printf("#a fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str());
if ( otherLanguageStrings . find ( uselanguage ) = = otherLanguageStrings . end ( ) ) {
loadStrings ( uselanguage , otherLanguageStrings [ uselanguage ] , false ) ;
2011-04-05 20:39:47 +02:00
}
2011-11-02 18:17:28 +01:00
string result2 = otherLanguageStrings [ uselanguage ] . getString ( s ) ;
//printf("#b result2 [%s]\n",result2.c_str());
result = true ;
2011-04-05 20:39:47 +02:00
}
else {
2011-11-02 18:17:28 +01:00
string result2 = strings . getString ( s ) ;
result = true ;
2011-04-05 20:39:47 +02:00
}
2011-01-14 18:57:37 +01:00
}
catch ( exception & ex ) {
if ( strings . getpath ( ) ! = " " ) {
2011-11-02 18:17:28 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] for uselanguage [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) , uselanguage . c_str ( ) ) ;
}
//printf("#1 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str());
if ( fallbackToDefault = = true & & uselanguage ! = DEFAULT_LANGUAGE & & this - > language ! = DEFAULT_LANGUAGE ) {
result = hasString ( s , DEFAULT_LANGUAGE , false ) ;
}
else {
2011-01-14 18:57:37 +01:00
}
}
2011-11-02 18:17:28 +01:00
return result ;
2011-01-14 18:57:37 +01:00
}
2011-04-05 20:39:47 +02:00
bool Lang : : isLanguageLocal ( string compareLanguage ) const {
return ( compareLanguage = = language ) ;
}
2011-11-02 18:17:28 +01:00
string Lang : : get ( const string & s , string uselanguage , bool fallbackToDefault ) {
2011-04-05 20:39:47 +02:00
try {
string result = " " ;
2011-11-02 18:17:28 +01:00
if ( uselanguage ! = " " ) {
if ( otherLanguageStrings . find ( uselanguage ) = = otherLanguageStrings . end ( ) ) {
loadStrings ( uselanguage , otherLanguageStrings [ uselanguage ] , false ) ;
2011-04-05 20:39:47 +02:00
}
2011-11-02 18:17:28 +01:00
result = otherLanguageStrings [ uselanguage ] . getString ( s ) ;
2011-04-05 20:39:47 +02:00
replaceAll ( result , " \\ n " , " \n " ) ;
}
else {
result = strings . getString ( s ) ;
replaceAll ( result , " \\ n " , " \n " ) ;
}
2010-07-03 08:48:24 +02:00
return result ;
2010-03-20 13:11:46 +01:00
}
2010-10-06 22:22:06 +02:00
catch ( exception & ex ) {
if ( strings . getpath ( ) ! = " " ) {
2011-11-02 18:17:28 +01:00
if ( fallbackToDefault = = false | | SystemFlags : : VERBOSE_MODE_ENABLED ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] uselanguage [%s] text [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) , uselanguage . c_str ( ) , s . c_str ( ) ) ;
}
//printf("#2 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str());
if ( fallbackToDefault = = true & & uselanguage ! = DEFAULT_LANGUAGE & & this - > language ! = DEFAULT_LANGUAGE ) {
return get ( s , DEFAULT_LANGUAGE , false ) ;
2010-10-06 22:22:06 +02:00
}
2011-11-02 18:17:28 +01:00
2010-03-20 13:11:46 +01:00
return " ??? " + s + " ??? " ;
}
}
2010-10-06 22:22:06 +02:00
string Lang : : getScenarioString ( const string & s ) {
2010-03-20 13:11:46 +01:00
try {
2011-09-16 05:17:49 +02:00
string result = scenarioStrings . getString ( s ) ;
replaceAll ( result , " \\ n " , " \n " ) ;
return result ;
2010-03-20 13:11:46 +01:00
}
2010-10-06 22:22:06 +02:00
catch ( exception & ex ) {
if ( scenarioStrings . getpath ( ) ! = " " ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
}
2010-03-20 13:11:46 +01:00
return " ??? " + s + " ??? " ;
}
}
} } //end namespace