mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 15:41:39 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
514
Code/Tools/WWConfig/Locale_API.cpp
Normal file
514
Code/Tools/WWConfig/Locale_API.cpp
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S *
|
||||
******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Tools/WWConfig/Locale_API.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Ian_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Modtime: 1/09/02 11:02a $
|
||||
* $Revision: 2 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <wtypes.h>
|
||||
#include "locale.h"
|
||||
#include "locale_api.h"
|
||||
#include "rawfile.h"
|
||||
#include "wwconfig_ids.h"
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* DEFINES */
|
||||
/****************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NOTE: if USE_MULTI_FILE_FORMAT is "true", then a .lOC file must be in
|
||||
// the same directory as this file.
|
||||
//----------------------------------------------------------------------------
|
||||
#define USE_MULTI_FILE_FORMAT FALSE
|
||||
|
||||
#define LANGUAGE_IS_DBCS(l) (((l)==IDL_JAPANESE)||((l)==IDL_KOREAN)||((l)==IDL_CHINESE)) // [OYO]
|
||||
#define CODEPAGE_IS_DBCS(C) ((C==932)||(C==949)||(C==950)) // [OYO]
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* GLOBAL VARIABLES */
|
||||
/****************************************************************************/
|
||||
CHAR LanguageFile[ _MAX_PATH ];
|
||||
void * LocaleFile = NULL;
|
||||
int CodePage = GetACP();
|
||||
int LanguageID = 0;
|
||||
|
||||
/****************************************************************************/
|
||||
/* LOCALE API */
|
||||
/****************************************************************************/
|
||||
WCHAR * Remove_Quotes_Around_String ( WCHAR *old_string );
|
||||
void * Load_File ( const CHAR *filename, long *filesize );
|
||||
|
||||
//=============================================================================
|
||||
// These are wrapper functions around the LOCALE_ functions. I made these to
|
||||
// make using the single vs. multi language files more transparent to the program.
|
||||
//=============================================================================
|
||||
|
||||
bool Locale_Use_Multi_Language_Files ( void )
|
||||
{
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* initialization */
|
||||
/****************************************************************************/
|
||||
|
||||
int Locale_Init ( int language, char *file )
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Check for a file passed in.
|
||||
//-------------------------------------------------------------------------
|
||||
if( file == NULL || file[0] == '/0' ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialize settings.
|
||||
//-------------------------------------------------------------------------
|
||||
strcpy( LanguageFile, file );
|
||||
LanguageID = language;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// If language == -1, then set based on CodePage.
|
||||
//-------------------------------------------------------------------------
|
||||
if( LanguageID == -1 ) {
|
||||
|
||||
switch( CodePage ) {
|
||||
|
||||
// Japanese
|
||||
case 932:
|
||||
LanguageID = IDL_JAPANESE;
|
||||
break;
|
||||
|
||||
// Korean
|
||||
case 949:
|
||||
LanguageID = IDL_KOREAN;
|
||||
break;
|
||||
|
||||
// Chinese
|
||||
case 950:
|
||||
LanguageID = IDL_CHINESE;
|
||||
break;
|
||||
|
||||
// English, French, and German
|
||||
case 1252:
|
||||
{
|
||||
LANGID langid = GetSystemDefaultLangID();
|
||||
WORD plangid = PRIMARYLANGID( langid );
|
||||
|
||||
switch( plangid ) {
|
||||
|
||||
// German
|
||||
case 0x07:
|
||||
LanguageID = IDL_GERMAN;
|
||||
break;
|
||||
|
||||
// French
|
||||
case 0x0c:
|
||||
LanguageID = IDL_FRENCH;
|
||||
break;
|
||||
|
||||
// English
|
||||
case 0x09:
|
||||
default:
|
||||
LanguageID = IDL_ENGLISH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LanguageID = IDL_ENGLISH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Check for valid LanguageID range.
|
||||
//-------------------------------------------------------------------------
|
||||
if( LanguageID < 0 || LanguageID >= LOCALE_LANGUAGE_COUNT ) {
|
||||
LanguageID = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Use English in the situation where Chinese, Korean, or Japanese was
|
||||
// requested but not available.
|
||||
//-------------------------------------------------------------------------
|
||||
if( LANGUAGE_IS_DBCS( LanguageID ) && !CODEPAGE_IS_DBCS( CodePage )) {
|
||||
LanguageID = IDL_ENGLISH;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialize the lx object.
|
||||
//-------------------------------------------------------------------------
|
||||
LOCALE_init();
|
||||
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Set bank to use and load the appropriate table.
|
||||
//---------------------------------------------------------------------
|
||||
LOCALE_setbank(0);
|
||||
result = LOCALE_loadtable( LanguageFile, LanguageID );
|
||||
|
||||
#else
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Create a file buffer that holds all the strings in the file.
|
||||
//---------------------------------------------------------------------
|
||||
long filesize;
|
||||
HRSRC hRsrc;
|
||||
HGLOBAL hGlobal;
|
||||
int PrimaryLanguage = LANG_NEUTRAL;
|
||||
int SubLanguage = SUBLANG_DEFAULT;
|
||||
HMODULE module = GetModuleHandle( NULL );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Find the string file in this program's resources.
|
||||
//-------------------------------------------------------------------------
|
||||
switch( LanguageID ) {
|
||||
|
||||
// Japanese
|
||||
case IDL_JAPANESE:
|
||||
PrimaryLanguage = LANG_JAPANESE;
|
||||
SubLanguage = SUBLANG_DEFAULT;
|
||||
break;
|
||||
|
||||
// Korean
|
||||
case IDL_KOREAN:
|
||||
PrimaryLanguage = LANG_KOREAN;
|
||||
SubLanguage = SUBLANG_DEFAULT;
|
||||
break;
|
||||
|
||||
// Chinese
|
||||
case IDL_CHINESE:
|
||||
PrimaryLanguage = LANG_CHINESE;
|
||||
SubLanguage = SUBLANG_DEFAULT;
|
||||
break;
|
||||
|
||||
// German
|
||||
case IDL_GERMAN:
|
||||
PrimaryLanguage = LANG_GERMAN;
|
||||
SubLanguage = SUBLANG_GERMAN;
|
||||
break;
|
||||
|
||||
// French
|
||||
case IDL_FRENCH:
|
||||
PrimaryLanguage = LANG_FRENCH;
|
||||
SubLanguage = SUBLANG_FRENCH;
|
||||
break;
|
||||
|
||||
// English
|
||||
case IDL_ENGLISH:
|
||||
PrimaryLanguage = LANG_ENGLISH;
|
||||
SubLanguage = SUBLANG_ENGLISH_US;
|
||||
break;
|
||||
|
||||
default:
|
||||
PrimaryLanguage = LANG_ENGLISH;
|
||||
SubLanguage = SUBLANG_ENGLISH_US;
|
||||
break;
|
||||
}
|
||||
|
||||
hRsrc = FindResourceEx( module, RT_RCDATA, "STRINGS", MAKELANGID( PrimaryLanguage, SubLanguage ));
|
||||
if ( hRsrc == NULL ) {
|
||||
hRsrc = FindResourceEx( module, RT_RCDATA, "STRINGS", MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ));
|
||||
}
|
||||
if ( hRsrc ) {
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Load the resource, lock the memory, grab a DC.
|
||||
//---------------------------------------------------------------------
|
||||
hGlobal = LoadResource( module, hRsrc );
|
||||
filesize = SizeofResource( module, hRsrc );
|
||||
|
||||
LocaleFile = (void*)malloc( filesize + 1 );
|
||||
memset( LocaleFile, '\0', filesize + 1 );
|
||||
memcpy( LocaleFile, (const void *)hGlobal, filesize );
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Free DS and memory used.
|
||||
//---------------------------------------------------------------------
|
||||
UnlockResource( hGlobal );
|
||||
FreeResource( hGlobal );
|
||||
}
|
||||
|
||||
if( LocaleFile == NULL ) {
|
||||
LocaleFile = Load_File( LanguageFile, &filesize );
|
||||
}
|
||||
|
||||
if( LocaleFile != NULL ) {
|
||||
result = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* restore */
|
||||
/************************************************************************/
|
||||
|
||||
void Locale_Restore ( void )
|
||||
{
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
LOCALE_freetable();
|
||||
LOCALE_restore();
|
||||
#else
|
||||
if( LocaleFile ) {
|
||||
free( LocaleFile );
|
||||
LocaleFile = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Load_File -- Allocates a buffer and loads the file into it. *
|
||||
* *
|
||||
* Get a string usine Resource ID and a buffer. *
|
||||
* *
|
||||
* INPUT: int StringID -- The resource number of the string. *
|
||||
* CHAR *String -- The buffer to place the text in. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the buffer. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/10/2001 MML : Created. *
|
||||
*==============================================================================*/
|
||||
|
||||
const CHAR* Locale_GetString( int StringID, CHAR *String )
|
||||
{
|
||||
static CHAR buffer[ _MAX_PATH ];
|
||||
static WCHAR wide_buffer[ _MAX_PATH ];
|
||||
|
||||
memset( buffer, '\0', _MAX_PATH );
|
||||
memset( wide_buffer, '\0', _MAX_PATH );
|
||||
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
|
||||
#else
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
|
||||
#endif
|
||||
|
||||
Remove_Quotes_Around_String( wide_buffer );
|
||||
WideCharToMultiByte( CodePage, 0, wide_buffer, _MAX_PATH, buffer, _MAX_PATH, NULL, NULL );
|
||||
|
||||
if( String != NULL ) {
|
||||
strncpy( String, buffer, _MAX_PATH );
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Load_File -- Allocates a buffer and loads the file into it. *
|
||||
* *
|
||||
* Get a string usine Resource ID and a buffer. *
|
||||
* *
|
||||
* INPUT: int StringID -- The resource number of the string. *
|
||||
* WCHAR *String -- The buffer to place the text in. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the buffer. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/10/2001 MML : Created. *
|
||||
*==============================================================================*/
|
||||
|
||||
const WCHAR* Locale_GetString( int StringID, WCHAR *String )
|
||||
{
|
||||
static WCHAR wide_buffer[ _MAX_PATH ];
|
||||
|
||||
memset( wide_buffer, '\0', _MAX_PATH );
|
||||
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
|
||||
#else
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
|
||||
#endif
|
||||
|
||||
Remove_Quotes_Around_String( wide_buffer );
|
||||
|
||||
if( String != NULL ) {
|
||||
wcsncpy( String, wide_buffer, _MAX_PATH );
|
||||
}
|
||||
return wide_buffer;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Load_File -- Allocates a buffer and loads the file into it. *
|
||||
* *
|
||||
* Get a string usine Resource ID and a buffer. *
|
||||
* *
|
||||
* INPUT: int StringID -- The resource number of the string. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the buffer. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/10/2001 MML : Created. *
|
||||
*==============================================================================*/
|
||||
|
||||
const WCHAR* Locale_GetString( int StringID )
|
||||
{
|
||||
static WCHAR wide_buffer[ _MAX_PATH ];
|
||||
|
||||
memset( wide_buffer, '\0', _MAX_PATH );
|
||||
|
||||
#if( USE_MULTI_FILE_FORMAT )
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
|
||||
#else
|
||||
wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
|
||||
#endif
|
||||
|
||||
Remove_Quotes_Around_String( wide_buffer );
|
||||
|
||||
return wide_buffer;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* formating strings */
|
||||
/****************************************************************************/
|
||||
|
||||
WCHAR *Remove_Quotes_Around_String ( WCHAR *old_string )
|
||||
{
|
||||
WCHAR wide_buffer[ _MAX_PATH * 3 ];
|
||||
WCHAR * letter = old_string;
|
||||
int length;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// If string is not NULL...
|
||||
//----------------------------------------------------------------------
|
||||
if ( *letter == '"' ) {
|
||||
|
||||
letter++;
|
||||
wcscpy( wide_buffer, letter );
|
||||
|
||||
length = wcslen( wide_buffer );
|
||||
|
||||
if ( wide_buffer[ wcslen( wide_buffer )-1 ] == '"' ) {
|
||||
wide_buffer[ wcslen( wide_buffer )-1 ] = '\0';
|
||||
}
|
||||
wcscpy( old_string, wide_buffer );
|
||||
}
|
||||
|
||||
return( old_string );
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Load_File -- Allocates a buffer and loads the file into it. *
|
||||
* *
|
||||
* This is the C++ replacement for the Load_Alloc_Data function. It will *
|
||||
* allocate the memory big enough to hold the file & read the file into it. *
|
||||
* *
|
||||
* INPUT: file -- The file to read. *
|
||||
* mem -- The memory system to use for allocation. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the allocated and filled memory block. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*==============================================================================*/
|
||||
|
||||
void * Load_File ( const char *filename, long *filesize )
|
||||
{
|
||||
int size, bytes_read;
|
||||
void *ptr = NULL;
|
||||
// StandardFileClass file;
|
||||
RawFileClass file;
|
||||
|
||||
if ( filename == NULL || filename[0] == '\0' ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Open file in READ ONLY mode. If fails, exit.
|
||||
//-------------------------------------------------------------------------
|
||||
// file.Open( filename, MODE_READ_ONLY );
|
||||
file.Open( filename, FileClass::READ );
|
||||
// if( !file.Query_Open()) {
|
||||
if( !file.Is_Open()) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Get filesize and create a buffer.
|
||||
//-------------------------------------------------------------------------
|
||||
// size = file.Query_Size();
|
||||
size = file.Size();
|
||||
ptr = (void*)malloc(size + 1);
|
||||
if ( !ptr ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Read data into the buffer, close the file.
|
||||
//-------------------------------------------------------------------------
|
||||
memset( ptr, '\0', size + 1 );
|
||||
// bytes_read = file.Read( ptr, size );
|
||||
bytes_read = file.Read( ptr, size );
|
||||
// file.Close();
|
||||
file.Close();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Check return bytes. It should match the file size.
|
||||
//-------------------------------------------------------------------------
|
||||
assert( bytes_read == size );
|
||||
if ( bytes_read != size ) {
|
||||
free(ptr);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if ( filesize != NULL ) {
|
||||
*filesize = (long)size;
|
||||
}
|
||||
return( ptr );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user