123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- #include "Common_local.h"
- idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." );
- /*
- =================
- LoadMapLocalizeData
- =================
- */
- typedef idHashTable<idStrList> ListHash;
- void LoadMapLocalizeData(ListHash& listHash) {
- idStr fileName = "map_localize.cfg";
- const char *buffer = NULL;
- idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
- src.LoadMemory( buffer, strlen(buffer), fileName );
- if ( src.IsLoaded() ) {
- idStr classname;
- idToken token;
- while ( src.ReadToken( &token ) ) {
- classname = token;
- src.ExpectTokenString( "{" );
- idStrList list;
- while ( src.ReadToken( &token) ) {
- if ( token == "}" ) {
- break;
- }
- list.Append(token);
- }
- listHash.Set(classname, list);
- }
- }
- fileSystem->FreeFile( (void*)buffer );
- }
- }
- void LoadGuiParmExcludeList(idStrList& list) {
- idStr fileName = "guiparm_exclude.cfg";
- const char *buffer = NULL;
- idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
- src.LoadMemory( buffer, strlen(buffer), fileName );
- if ( src.IsLoaded() ) {
- idStr classname;
- idToken token;
- while ( src.ReadToken( &token ) ) {
- list.Append(token);
- }
- }
- fileSystem->FreeFile( (void*)buffer );
- }
- }
- bool TestMapVal(idStr& str) {
- //Already Localized?
- if(str.Find("#str_") != -1) {
- return false;
- }
- return true;
- }
- bool TestGuiParm(const char* parm, const char* value, idStrList& excludeList) {
- idStr testVal = value;
- //Already Localized?
- if(testVal.Find("#str_") != -1) {
- return false;
- }
- //Numeric
- if(testVal.IsNumeric()) {
- return false;
- }
- //Contains ::
- if(testVal.Find("::") != -1) {
- return false;
- }
- //Contains /
- if(testVal.Find("/") != -1) {
- return false;
- }
- if(excludeList.Find(testVal)) {
- return false;
- }
- return true;
- }
- void GetFileList(const char* dir, const char* ext, idStrList& list) {
- //Recurse Subdirectories
- idStrList dirList;
- Sys_ListFiles(dir, "/", dirList);
- for(int i = 0; i < dirList.Num(); i++) {
- if(dirList[i] == "." || dirList[i] == "..") {
- continue;
- }
- idStr fullName = va("%s/%s", dir, dirList[i].c_str());
- GetFileList(fullName, ext, list);
- }
- idStrList fileList;
- Sys_ListFiles(dir, ext, fileList);
- for(int i = 0; i < fileList.Num(); i++) {
- idStr fullName = va("%s/%s", dir, fileList[i].c_str());
- list.Append(fullName);
- }
- }
- int LocalizeMap(const char* mapName, idLangDict &langDict, ListHash& listHash, idStrList& excludeList, bool writeFile) {
- common->Printf("Localizing Map '%s'\n", mapName);
- int strCount = 0;
-
- idMapFile map;
- if ( map.Parse(mapName, false, false ) ) {
- int count = map.GetNumEntities();
- for ( int j = 0; j < count; j++ ) {
- idMapEntity *ent = map.GetEntity( j );
- if ( ent ) {
- idStr classname = ent->epairs.GetString("classname");
- //Hack: for info_location
- bool hasLocation = false;
- idStrList* list;
- listHash.Get(classname, &list);
- if(list) {
- for(int k = 0; k < list->Num(); k++) {
- idStr val = ent->epairs.GetString((*list)[k], "");
-
- if(val.Length() && classname == "info_location" && (*list)[k] == "location") {
- hasLocation = true;
- }
- if(val.Length() && TestMapVal(val)) {
-
- if(!hasLocation || (*list)[k] == "location") {
- //Localize it!!!
- strCount++;
- ent->epairs.Set( (*list)[k], langDict.AddString( val ) );
- }
- }
- }
- }
- listHash.Get("all", &list);
- if(list) {
- for(int k = 0; k < list->Num(); k++) {
- idStr val = ent->epairs.GetString((*list)[k], "");
- if(val.Length() && TestMapVal(val)) {
- //Localize it!!!
- strCount++;
- ent->epairs.Set( (*list)[k], langDict.AddString( val ) );
- }
- }
- }
- //Localize the gui_parms
- const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm");
- while( kv ) {
- if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) {
- //Localize It!
- strCount++;
- ent->epairs.Set( kv->GetKey(), langDict.AddString( kv->GetValue() ) );
- }
- kv = ent->epairs.MatchPrefix( "gui_parm", kv );
- }
- }
- }
- if(writeFile && strCount > 0) {
- //Before we write the map file lets make a backup of the original
- idStr file = fileSystem->RelativePathToOSPath(mapName);
- idStr bak = file.Left(file.Length() - 4);
- bak.Append(".bak_loc");
- fileSystem->CopyFile( file, bak );
-
- map.Write( mapName, ".map" );
- }
- }
- common->Printf("Count: %d\n", strCount);
- return strCount;
- }
- /*
- =================
- LocalizeMaps_f
- =================
- */
- CONSOLE_COMMAND( localizeMaps, "localize maps", NULL ) {
- if ( args.Argc() < 2 ) {
- common->Printf( "Usage: localizeMaps <count | dictupdate | all> <map>\n" );
- return;
- }
- int strCount = 0;
-
- bool count = false;
- bool dictUpdate = false;
- bool write = false;
- if ( idStr::Icmp( args.Argv(1), "count" ) == 0 ) {
- count = true;
- } else if ( idStr::Icmp( args.Argv(1), "dictupdate" ) == 0 ) {
- count = true;
- dictUpdate = true;
- } else if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) {
- count = true;
- dictUpdate = true;
- write = true;
- } else {
- common->Printf( "Invalid Command\n" );
- common->Printf( "Usage: localizeMaps <count | dictupdate | all>\n" );
- return;
- }
- idLangDict strTable;
- idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger());
- {
- // I think this is equivalent...
- const byte * buffer = NULL;
- int len = fileSystem->ReadFile( filename, (void**)&buffer );
- if ( verify( len > 0 ) ) {
- strTable.Load( buffer, len, filename );
- }
- fileSystem->FreeFile( (void *)buffer );
- // ... to this
- //if ( strTable.Load( filename ) == false) {
- // //This is a new file so set the base index
- // strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000);
- //}
- }
- common->SetRefreshOnPrint( true );
-
- ListHash listHash;
- LoadMapLocalizeData(listHash);
- idStrList excludeList;
- LoadGuiParmExcludeList(excludeList);
- if(args.Argc() == 3) {
- strCount += LocalizeMap(args.Argv(2), strTable, listHash, excludeList, write);
- } else {
- idStrList files;
- GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
- for ( int i = 0; i < files.Num(); i++ ) {
- idStr file = fileSystem->OSPathToRelativePath(files[i]);
- strCount += LocalizeMap(file, strTable, listHash, excludeList, write);
- }
- }
- if(count) {
- common->Printf("Localize String Count: %d\n", strCount);
- }
- common->SetRefreshOnPrint( false );
- if(dictUpdate) {
- strTable.Save( filename );
- }
- }
- /*
- =================
- LocalizeGuis_f
- =================
- */
- CONSOLE_COMMAND( localizeGuis, "localize guis", NULL ) {
- if ( args.Argc() != 2 ) {
- common->Printf( "Usage: localizeGuis <all | gui>\n" );
- return;
- }
- idLangDict strTable;
- idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger());
- {
- // I think this is equivalent...
- const byte * buffer = NULL;
- int len = fileSystem->ReadFile( filename, (void**)&buffer );
- if ( verify( len > 0 ) ) {
- strTable.Load( buffer, len, filename );
- }
- fileSystem->FreeFile( (void *)buffer );
- // ... to this
- //if(strTable.Load( filename ) == false) {
- // //This is a new file so set the base index
- // strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000);
- //}
- }
- idFileList *files;
- if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) {
- idStr game = cvarSystem->GetCVarString( "game_expansion" );
- if(game.Length()) {
- files = fileSystem->ListFilesTree( "guis", "*.gui", true, game );
- } else {
- files = fileSystem->ListFilesTree( "guis", "*.gui", true );
- }
- for ( int i = 0; i < files->GetNumFiles(); i++ ) {
- commonLocal.LocalizeGui( files->GetFile( i ), strTable );
- }
- fileSystem->FreeFileList( files );
- if(game.Length()) {
- files = fileSystem->ListFilesTree( "guis", "*.pd", true, game );
- } else {
- files = fileSystem->ListFilesTree( "guis", "*.pd", true, "d3xp" );
- }
-
- for ( int i = 0; i < files->GetNumFiles(); i++ ) {
- commonLocal.LocalizeGui( files->GetFile( i ), strTable );
- }
- fileSystem->FreeFileList( files );
- } else {
- commonLocal.LocalizeGui( args.Argv(1), strTable );
- }
- strTable.Save( filename );
- }
- CONSOLE_COMMAND( localizeGuiParmsTest, "Create test files that show gui parms localized and ignored.", NULL ) {
- common->SetRefreshOnPrint( true );
- idFile *localizeFile = fileSystem->OpenFileWrite( "gui_parm_localize.csv" );
- idFile *noLocalizeFile = fileSystem->OpenFileWrite( "gui_parm_nolocalize.csv" );
- idStrList excludeList;
- LoadGuiParmExcludeList(excludeList);
- idStrList files;
- GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
- for ( int i = 0; i < files.Num(); i++ ) {
-
- common->Printf("Testing Map '%s'\n", files[i].c_str());
- idMapFile map;
- idStr file = fileSystem->OSPathToRelativePath(files[i]);
- if ( map.Parse(file, false, false ) ) {
- int count = map.GetNumEntities();
- for ( int j = 0; j < count; j++ ) {
- idMapEntity *ent = map.GetEntity( j );
- if ( ent ) {
- const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm");
- while( kv ) {
- if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) {
- idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str());
- localizeFile->Write( out.c_str(), out.Length() );
- } else {
- idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str());
- noLocalizeFile->Write( out.c_str(), out.Length() );
- }
- kv = ent->epairs.MatchPrefix( "gui_parm", kv );
- }
- }
- }
- }
- }
-
- fileSystem->CloseFile( localizeFile );
- fileSystem->CloseFile( noLocalizeFile );
- common->SetRefreshOnPrint( false );
- }
- CONSOLE_COMMAND( localizeMapsTest, "Create test files that shows which strings will be localized.", NULL ) {
- ListHash listHash;
- LoadMapLocalizeData(listHash);
- common->SetRefreshOnPrint( true );
- idFile *localizeFile = fileSystem->OpenFileWrite( "map_localize.csv" );
-
- idStrList files;
- GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
- for ( int i = 0; i < files.Num(); i++ ) {
- common->Printf("Testing Map '%s'\n", files[i].c_str());
- idMapFile map;
- idStr file = fileSystem->OSPathToRelativePath(files[i]);
- if ( map.Parse(file, false, false ) ) {
- int count = map.GetNumEntities();
- for ( int j = 0; j < count; j++ ) {
- idMapEntity *ent = map.GetEntity( j );
- if ( ent ) {
-
- //Temp code to get a list of all entity key value pairs
- /*idStr classname = ent->epairs.GetString("classname");
- if(classname == "worldspawn" || classname == "func_static" || classname == "light" || classname == "speaker" || classname.Left(8) == "trigger_") {
- continue;
- }
- for( int i = 0; i < ent->epairs.GetNumKeyVals(); i++) {
- const idKeyValue* kv = ent->epairs.GetKeyVal(i);
- idStr out = va("%s,%s,%s,%s\r\n", classname.c_str(), kv->GetKey().c_str(), kv->GetValue().c_str(), file.c_str());
- localizeFile->Write( out.c_str(), out.Length() );
- }*/
- idStr classname = ent->epairs.GetString("classname");
-
- //Hack: for info_location
- bool hasLocation = false;
- idStrList* list;
- listHash.Get(classname, &list);
- if(list) {
- for(int k = 0; k < list->Num(); k++) {
- idStr val = ent->epairs.GetString((*list)[k], "");
-
- if(classname == "info_location" && (*list)[k] == "location") {
- hasLocation = true;
- }
- if(val.Length() && TestMapVal(val)) {
-
- if(!hasLocation || (*list)[k] == "location") {
- idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str());
- localizeFile->Write( out.c_str(), out.Length() );
- }
- }
- }
- }
- listHash.Get("all", &list);
- if(list) {
- for(int k = 0; k < list->Num(); k++) {
- idStr val = ent->epairs.GetString((*list)[k], "");
- if(val.Length() && TestMapVal(val)) {
- idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str());
- localizeFile->Write( out.c_str(), out.Length() );
- }
- }
- }
- }
- }
- }
- }
- fileSystem->CloseFile( localizeFile );
- common->SetRefreshOnPrint( false );
- }
- /*
- ===============
- idCommonLocal::LocalizeSpecificMapData
- ===============
- */
- void idCommonLocal::LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs ) {
- idStr out, ws, work;
- idMapFile map;
- if ( map.Parse( fileName, false, false ) ) {
- int count = map.GetNumEntities();
- for ( int i = 0; i < count; i++ ) {
- idMapEntity *ent = map.GetEntity( i );
- if ( ent ) {
- for ( int j = 0; j < replaceArgs.GetNumKeyVals(); j++ ) {
- const idLangKeyValue *kv = replaceArgs.GetKeyVal( j );
- const char *temp = ent->epairs.GetString( kv->key );
- if ( ( temp != NULL ) && *temp ) {
- idStr val = kv->value;
- if ( val == temp ) {
- ent->epairs.Set( kv->key, langDict.AddString( temp ) );
- }
- }
- }
- }
- }
- map.Write( fileName, ".map" );
- }
- }
- /*
- ===============
- idCommonLocal::LocalizeMapData
- ===============
- */
- void idCommonLocal::LocalizeMapData( const char *fileName, idLangDict &langDict ) {
- const char *buffer = NULL;
- idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- common->SetRefreshOnPrint( true );
- if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
- src.LoadMemory( buffer, strlen(buffer), fileName );
- if ( src.IsLoaded() ) {
- common->Printf( "Processing %s\n", fileName );
- idStr mapFileName;
- idToken token, token2;
- idLangDict replaceArgs;
- while ( src.ReadToken( &token ) ) {
- mapFileName = token;
- replaceArgs.Clear();
- src.ExpectTokenString( "{" );
- while ( src.ReadToken( &token) ) {
- if ( token == "}" ) {
- break;
- }
- if ( src.ReadToken( &token2 ) ) {
- if ( token2 == "}" ) {
- break;
- }
- replaceArgs.AddKeyVal( token, token2 );
- }
- }
- common->Printf( " localizing map %s...\n", mapFileName.c_str() );
- LocalizeSpecificMapData( mapFileName, langDict, replaceArgs );
- }
- }
- fileSystem->FreeFile( (void*)buffer );
- }
- common->SetRefreshOnPrint( false );
- }
- /*
- ===============
- idCommonLocal::LocalizeGui
- ===============
- */
- void idCommonLocal::LocalizeGui( const char *fileName, idLangDict &langDict ) {
- idStr out, ws, work;
- const char *buffer = NULL;
- out.Empty();
- int k;
- char ch;
- char slash = '\\';
- char tab = 't';
- char nl = 'n';
- idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
- src.LoadMemory( buffer, strlen(buffer), fileName );
- if ( src.IsLoaded() ) {
- idFile *outFile = fileSystem->OpenFileWrite( fileName );
- common->Printf( "Processing %s\n", fileName );
- const bool captureToImage = false;
- UpdateScreen( captureToImage );
- idToken token;
- while( src.ReadToken( &token ) ) {
- src.GetLastWhiteSpace( ws );
- out += ws;
- if ( token.type == TT_STRING ) {
- out += va( "\"%s\"", token.c_str() );
- } else {
- out += token;
- }
- if ( out.Length() > 200000 ) {
- outFile->Write( out.c_str(), out.Length() );
- out = "";
- }
- work = token.Right( 6 );
- if ( token.Icmp( "text" ) == 0 || work.Icmp( "::text" ) == 0 || token.Icmp( "choices" ) == 0 ) {
- if ( src.ReadToken( &token ) ) {
- // see if already exists, if so save that id to this position in this file
- // otherwise add this to the list and save the id to this position in this file
- src.GetLastWhiteSpace( ws );
- out += ws;
- token = langDict.AddString( token );
- out += "\"";
- for ( k = 0; k < token.Length(); k++ ) {
- ch = token[k];
- if ( ch == '\t' ) {
- out += slash;
- out += tab;
- } else if ( ch == '\n' || ch == '\r' ) {
- out += slash;
- out += nl;
- } else {
- out += ch;
- }
- }
- out += "\"";
- }
- } else if ( token.Icmp( "comment" ) == 0 ) {
- if ( src.ReadToken( &token ) ) {
- // need to write these out by hand to preserve any \n's
- // see if already exists, if so save that id to this position in this file
- // otherwise add this to the list and save the id to this position in this file
- src.GetLastWhiteSpace( ws );
- out += ws;
- out += "\"";
- for ( k = 0; k < token.Length(); k++ ) {
- ch = token[k];
- if ( ch == '\t' ) {
- out += slash;
- out += tab;
- } else if ( ch == '\n' || ch == '\r' ) {
- out += slash;
- out += nl;
- } else {
- out += ch;
- }
- }
- out += "\"";
- }
- }
- }
- outFile->Write( out.c_str(), out.Length() );
- fileSystem->CloseFile( outFile );
- }
- fileSystem->FreeFile( (void*)buffer );
- }
- }
|