/*
===========================================================================
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 .
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 "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 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