| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864 |
- /*
- ** Command & Conquer Generals(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/>.
- */
- /* Copyright (C) Electronic Arts Canada Inc. 1998-1999. All rights reserved. */
- #include <string.h>
- #include <assert.h>
- #include "gimex.h" /* for file and memory IO only */
- #include "locale.h"
- #include "wnd_file.h"
- /*************************************************************************/
- /* File Format Structures */
- /*************************************************************************/
- #define LOCALEFILE_HEADERCHUNKID 0x48434f4c /* 'LOCH' */
- #define LOCALEFILE_INDEXCHUNKID 0x49434f4c /* 'LOCI' */
- #define LOCALEFILE_LANGUAGECHUNKID 0x4c434f4c /* 'LOCL' */
- typedef struct
- {
- unsigned int ChunkID; /* 'LOCH' LOCALEFILE_HEADERCHUNKID */
- unsigned int ChunkSize; /* size of chunk in bytes */
- unsigned int Flags; /* 0=no index chunk present,1=index chunk present */
- unsigned int LanguageCount; /* number of language chunks in this file */
- /* unsigned int LanguageOffset[LanguageCount]; \\ offsets in bytes from start of file to language chunk */
- } LOCALEFILE_HEADERCHUNK;
- /* offset LOCALEFILE_HEADERCHUNK_LANGUAGE_OFFSET bytes from the start of the chunk to the language offset table */
- #define LOCALEFILE_HEADERCHUNK_LANGUAGE_OFFSET sizeof(LOCALEFILE_HEADERCHUNK)
- typedef struct
- {
- unsigned int ChunkID; /* 'LOCI' LOCALEFILE_INDEXCHUNKID */
- unsigned int ChunkSize; /* size of chunk in bytes */
- unsigned int StringCount; /* number of string ids in this chunk (same value in all language chunks) */
- unsigned int pad; /* must be zero */
- /* STRINGID StringID[StringCount]; */
- /* { */
- /* unsigned short ID; \\ id that user gives to look up value */
- /* unsigned short Index; \\ index to look up value in language chunks */
- /* } */
- } LOCALEFILE_INDEXCHUNK;
- /* offset LOCALEFILE_INDEXCHUNK_STRINGID_OFFSET bytes from the start of the chunk to the string id table */
- #define LOCALEFILE_INDEXCHUNK_STRINGID_OFFSET sizeof(LOCALEFILE_INDEXCHUNK)
- typedef struct
- {
- unsigned int ChunkID; /* 'LOCL' LOCALEFILE_LANGUAGECHUNKID */
- unsigned int ChunkSize; /* size of chunk in bytes including this header and all string data */
- unsigned int LanguageID; /* language strings are in for this bank */
- unsigned int StringCount; /* number of strings in this chunk */
- /* unsigned int StringOffset[StringCount]; \\ offsets in bytes from start of chunk to string */
- /* const char* Data[StringCount]; \\ StringCount null terminated strings */
- } LOCALEFILE_LANGUAGECHUNK;
- /* offset LOCALEFILE_LANGUAGECHUNK_STRING_OFFSETbytes from the start of the chunk to the string offset table */
- #define LOCALEFILE_LANGUAGECHUNK_STRING_OFFSET sizeof(LOCALEFILE_LANGUAGECHUNK)
- /*************************************************************************/
- /* LOCALE_INSTANCE declaration */
- /*************************************************************************/
- typedef LOCALEFILE_HEADERCHUNK HEADER;
- typedef LOCALEFILE_INDEXCHUNK INDEX;
- typedef LOCALEFILE_LANGUAGECHUNK BANK;
- typedef struct
- {
- int BankIndex; /* current language bank set (0..BANK_COUNT-1) */
- BANK* pBank[LOCALE_BANK_COUNT]; /* array of string banks */
- INDEX* pIndex[LOCALE_BANK_COUNT]; /* array of string indices */
- } LOCALE_INSTANCE;
- static LOCALE_INSTANCE *lx = NULL;
- /*************************************************************************/
- /* initialization/restore */
- /*************************************************************************/
- /* helper function to make assertions for initialization clearer */
- int LOCALE_isinitialized( void )
- {
- if ( lx == NULL ) {
- // TRACE("LOCALE API is not initialized - call LOCALE_init before calling LOCALE functions\n");
- }
- return( lx != NULL );
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_init - Init the localization module
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; int LOCALE_init(void)
- ;
- ; DESCRIPTION
- ;
- ; Initilizes everything needed to use the locale API. Can only be called
- ; once until LOCALE_restore is called.
- ;
- ; Returns non-zero if everything went ok.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_restore
- ;
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- int LOCALE_init(void)
- {
- int ok = 0;
- /* ensure locale module is NOT already initialized */
- ASSERT(lx == NULL); /* can only call LOCALE_init after a restore or once, cannot double init locale API */
- /* allocate instance */
- lx = (LOCALE_INSTANCE*)galloc(sizeof(LOCALE_INSTANCE));
- if (lx != NULL) {
- memset(lx, 0, sizeof(LOCALE_INSTANCE));
- ok = 1;
- }
- return ok;
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_restore - Free resources used by the locale module
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; void LOCALE_restore(void)
- ;
- ; DESCRIPTION
- ;
- ; Restores all resources used by the locale API. Can only be called after
- ; LOCALE_init, and only once.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_init
- ;
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- void LOCALE_restore(void)
- {
- int i;
- if( lx != NULL ) {
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- ASSERT(lx != NULL);
- /* free any language tables */
- for (i = 0; i < LOCALE_BANK_COUNT; i++) {
- if (lx->pBank[i]) {
- LOCALE_setbank(i);
- LOCALE_freetable();
- }
- }
- /* free instance */
- gfree(lx);
- lx = NULL;
- }
- }
- /*************************************************************************/
- /* attributes */
- /*************************************************************************/
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_setbank - Set the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; void LOCALE_setbank(BankIndex)
- ; int BankIndex; Number between 0 and LOCALE_BANK_COUNT - 1
- ;
- ; DESCRIPTION
- ;
- ; Sets the current bank to be active. All functions will now use this
- ; bank for strings. A bank is slot where a string table is loaded.
- ; More than one bank can have a table loaded but the locale functions
- ; only work on one bank at a time, the active bank set by this function.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_getbank
- ;
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- void LOCALE_setbank(int BankIndex)
- {
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- lx->BankIndex = BankIndex;
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_getbank - Get the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; int LOCALE_getbank(void)
- ;
- ; DESCRIPTION
- ;
- ; Returns the bank index of the current bank.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_setbank
- ;
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- int LOCALE_getbank(void)
- {
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- return lx->BankIndex;
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_getbanklanguageid - Get the language id for the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; int LOCALE_getbanklanguageid(void)
- ;
- ; DESCRIPTION
- ;
- ; Returns the language id of the current bank. This id will match
- ; the lanugage id in the header file generated by Locomoto
- ;
- ; SEE ALSO
- ;
- ; LOCALE_loadtable
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- int LOCALE_getbanklanguageid(void)
- {
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- ASSERT(lx->pBank[lx->BankIndex]); /* must load a table into bank before calling this function */
- return (int)(lx->pBank[lx->BankIndex]->LanguageID);
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_getbankstringcount - Get the string count for the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; int LOCALE_getbankstringcount(void)
- ;
- ; DESCRIPTION
- ;
- ; Returns the number of strings in the current bank. If zero is
- ; returned then this bank is empty.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_loadtable
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- int LOCALE_getbankstringcount(void)
- {
- int StringCount = 0;
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- if (lx->pBank[lx->BankIndex]) {
- StringCount = lx->pBank[lx->BankIndex]->StringCount;
- }
- return StringCount;
- }
- /*************************************************************************/
- /* operations */
- /*************************************************************************/
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_loadtable - Load a string table into the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; int LOCALE_loadtable(pathname, languageid)
- ;
- ; const char* pathname; // pathname of .loc file to load
- ; int languageid; // language id to load (from .h file)
- ;
- ; DESCRIPTION
- ;
- ; Loads the specified language from the string file into the
- ; current bank. Returns non zero if the operation was succesful.
- ; The bank must be free before you can call LOCALE_loadtable. To
- ; free a bank use the LOCALE_freetable function. To determine
- ; if the bank is free use the LOCALE_getbankstringcount function.
- ;
- ; The languageid value is available in the .h file created by
- ; locomoto.
- ;
- ; Returns non-zero if everthing is ok.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_freetable, LOCALE_getbankstringcount
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- static int readheader( GSTREAM* g )
- {
- int ok = 0;
- /* read file header */
- LOCALEFILE_HEADERCHUNK header;
- int HeaderChunkSize = sizeof(LOCALEFILE_HEADERCHUNK);
- // VERIFY(gread(g, &header, HeaderChunkSize) == HeaderChunkSize);
- if( gread(g, &header, HeaderChunkSize) != HeaderChunkSize ) {
- return ok;
- }
- Msg( __LINE__, __FILE__, "readheader - HeaderChunkSize = %d.", HeaderChunkSize );
- Msg( __LINE__, __FILE__, "readheader - header.LanguageCount = %d.", header.LanguageCount );
- Msg( __LINE__, __FILE__, "readheader - header.Flags = %d.", header.Flags );
- ASSERT( header.ChunkID == LOCALEFILE_HEADERCHUNKID ); /* ensure that this is a valid .loc file */
- /* read index chunk if present */
- if ( header.Flags == 1 ) {
- int IndexChunkSize;
- int IndexChunkPos = header.ChunkSize;
- /* read index chunk size */
- // VERIFY(gseek(g, IndexChunkPos + 4));
- if( !gseek( g, IndexChunkPos + 4)) {
- return ok;
- }
- Msg( __LINE__, __FILE__, "readheader - seek to = %d.", IndexChunkPos + 4 );
- // VERIFY(gread(g, &IndexChunkSize, 4) == 4);
- if( gread( g, &IndexChunkSize, 4) != 4 ) {
- return ok;
- }
- Msg( __LINE__, __FILE__, "readheader - IndexChunkSize = %d.", IndexChunkSize );
- /* alloc and read index chunk */
- lx->pIndex[lx->BankIndex] = (LOCALEFILE_INDEXCHUNK *)galloc((long)IndexChunkSize );
- if (lx->pIndex[lx->BankIndex]) {
- // VERIFY(gseek(g, IndexChunkPos));
- gseek( g, IndexChunkPos );
- Msg( __LINE__, __FILE__, "readheader - seek to = %d.", IndexChunkPos );
- // VERIFY(gread(g, lx->pIndex[lx->BankIndex], IndexChunkSize) == IndexChunkSize);
- if ( gread(g, lx->pIndex[lx->BankIndex], IndexChunkSize ) != IndexChunkSize ) {
- return ok;
- }
- Msg( __LINE__, __FILE__, "readheader - IndexChunkSize = %d.", IndexChunkSize );
- ASSERT( lx->pIndex[lx->BankIndex]->ChunkID == LOCALEFILE_INDEXCHUNKID );
- ok = 1;
- }
- }
- Msg( __LINE__, __FILE__, "readheader - exiting." );
- return ok;
- }
- static int readstrings( GSTREAM* g, int LanguageID )
- {
- Msg( __LINE__, __FILE__, "readstrings:: g ok? %d.", ((g!= NULL)?1:0));
- int ok = 0;
- int LanguageChunkOffsetPos = 16 + LanguageID*4;
- int LanguageChunkPos = 0;
- int LanguageChunkSize = -1;
- /* read offset to language chunk */
- // VERIFY(gseek(g, (int)LanguageChunkOffsetPos));
- // VERIFY(gread(g, &LanguageChunkPos, 4) == 4);
- if( !gseek( g, (int)LanguageChunkOffsetPos )) {
- return ok;
- }
- if( gread( g, &LanguageChunkPos, 4 ) != 4 ) {
- return ok;
- }
- /* read language chunk size */
- // VERIFY(gseek(g, LanguageChunkPos + 4));
- // VERIFY(gread(g, &LanguageChunkSize, 4) == 4);
- if( !gseek( g, LanguageChunkPos + 4 )) {
- return ok;
- }
- if( gread( g, &LanguageChunkSize, 4 ) != 4 ) {
- return ok;
- }
- Msg( __LINE__, __FILE__, "readstrings::LanguageChunkOffsetPos = %d.", LanguageChunkOffsetPos );
- Msg( __LINE__, __FILE__, "readstrings::LanguageChunkPos = %d.", LanguageChunkPos );
- Msg( __LINE__, __FILE__, "readstrings::LanguageChunkSize = %d.", LanguageChunkSize );
- /* alloc and read language chunk */
- lx->pBank[lx->BankIndex] = (LOCALEFILE_LANGUAGECHUNK *)galloc((long)LanguageChunkSize);
- if (lx->pBank[lx->BankIndex]) {
- Msg( __LINE__, __FILE__, "readstrings:: A." );
- // VERIFY(gseek(g, LanguageChunkPos));
- // VERIFY(gread(g, lx->pBank[lx->BankIndex], LanguageChunkSize) == LanguageChunkSize);
- if( !gseek( g, LanguageChunkPos )) {
- return ok;
- }
- if( gread( g, lx->pBank[lx->BankIndex], LanguageChunkSize ) != LanguageChunkSize ) {
- return ok;
- }
-
- ASSERT(lx->pBank[lx->BankIndex]->ChunkID == LOCALEFILE_LANGUAGECHUNKID);
- ok = 1;
- }
- return ok;
- }
- int LOCALE_loadtable(const char* PathName, int LanguageID)
- {
- int ok = 0;
- GSTREAM* g;
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- ASSERT(lx->pBank[lx->BankIndex] == NULL); /* bank must be empty before loading a new table */
- ASSERT(lx->pIndex[lx->BankIndex] == NULL); /* bank must be empty before loading a new table */
- g = gopen( PathName );
- if( g != NULL ) {
- Msg( __LINE__, __FILE__, "LOCALE_loadtable-- file opened." );
- if( readheader(g)) {
- Msg( __LINE__, __FILE__, "LOCALE_loadtable-- readstrings." );
- ok = readstrings( g, LanguageID );
- Msg( __LINE__, __FILE__, "LOCALE_loadtable-- ok = %d ).", ok );
- }
- gclose(g);
- }
- return ok;
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_purgetable - OBSOLETE
- ;
- ; Make all references to LOCALE_freetable
- ;
- ; END ABSTRACT
- ;
- */
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_freetable - Free the string table in the current bank
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; void LOCALE_freetable(void)
- ;
- ; DESCRIPTION
- ;
- ; Frees the table loaded in the current bank. There must be a
- ; table loaded in the current bank. Use LOCALE_getbankstringcount
- ; to determine if the bank is free or not.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_loadtable, LOCALE_getbankstringcount
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- void LOCALE_freetable(void)
- {
- if( lx != NULL ) {
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- ASSERT(lx->pBank[lx->BankIndex]); /* table must be loaded before calling this function */
- /* free string bank */
- gfree(lx->pBank[lx->BankIndex]);
- lx->pBank[lx->BankIndex] = NULL;
- /* if the bank has an index loaded, free that as well */
- if (lx->pIndex[lx->BankIndex]) {
- gfree(lx->pIndex[lx->BankIndex]);
- lx->pIndex[lx->BankIndex] = NULL;
- }
- }
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_getstring - Return the specified string from the current bank
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; const char* LOCALE_getstring( StringID )
- ; int StringID; ID of string to return
- ;
- ; DESCRIPTION
- ;
- ; Returns the string specified from the current bank. There must
- ; be a string table loaded into the current bank. Use the String
- ; ID specified in the header file created by Locomoto. Note that
- ; the string pointer is a const pointer. Do not modify the string
- ; or the Locale library may return invalid results.
- ;
- ; If the .loc file was created with an index StringID can be any
- ; valid integer in the range 0..65535. If no index was created
- ; with the .loc file StringID will be a zero based array index.
- ;
- ; String is returned by const for a reason. Bad things will happen
- ; if you modify it. You have been warned.
- ;
- ; SEE ALSO
- ;
- ; LOCALE_loadtable, LOCALE_getbankstringcount
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ;
- ; END ABSTRACT
- ;
- */
- #include <stdlib.h> // for bsearch function
- static int compare ( const void* arg1, const void* arg2 )
- {
- const unsigned short* s1 = (const unsigned short*)(arg1);
- const unsigned short* s2 = (const unsigned short*)(arg2);
- return (*s1) - (*s2);
- }
- static int getstringbyindex( unsigned short key, const INDEX* pIndex )
- {
- int index = 0;
- unsigned short* result;
- unsigned char* base; /* pointer to base of string id table */
- ASSERT(LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- ASSERT(pIndex != NULL); /* index not loaded - .loc file must have index created (use -i option) */
- base = ((unsigned char*)pIndex) + LOCALEFILE_INDEXCHUNK_STRINGID_OFFSET;
- result = (unsigned short*)bsearch((unsigned char *)&key, base, pIndex->StringCount, 4, compare);
- if (result != NULL) {
- /* index is the second unsigned short */
- ++result;
- index = *result;
- } else {
- index = -1;
- }
- return index;
- }
- const char* LOCALE_getstring( int StringID )
- {
- const char* p; /* pointer to string, NULL if string cannot be found */
- Msg( __LINE__, __FILE__, "Locale_getstring::( %d ).", StringID );
- ASSERT( LOCALE_isinitialized()); /* must call LOCALE_init before calling this function */
- /* get string array index from the index if it exists */
- if ( lx->pIndex[ lx->BankIndex ] != NULL ) {
- StringID = getstringbyindex((unsigned short)StringID, lx->pIndex[lx->BankIndex]);
- }
- Msg( __LINE__, __FILE__, "Locale_getstring::( %d ).", StringID );
- Msg( __LINE__, __FILE__, "Locale_getstring::( lx->BankIndex = %d ).", lx->BankIndex );
- Msg( __LINE__, __FILE__, "Locale_getstring::( lx->pBank[lx->BankIndex]->StringCount = %d ).", lx->pBank[lx->BankIndex]->StringCount );
- if ((StringID >= 0) && (StringID < (int)(lx->pBank[lx->BankIndex]->StringCount ))) {
- Msg( __LINE__, __FILE__, "Locale_getstring:: A" );
- unsigned int offset;
- p = (const char*)(lx->pBank[lx->BankIndex]);
- Msg( __LINE__, __FILE__, "Locale_getstring:: B" );
- offset = *(unsigned int*)(p + LOCALEFILE_LANGUAGECHUNK_STRING_OFFSET + StringID*4);
- Msg( __LINE__, __FILE__, "Locale_getstring:: C" );
- p += offset;
- Msg( __LINE__, __FILE__, "Locale_getstring:: D" );
- } else {
- p = NULL;
- }
- Msg( __LINE__, __FILE__, L"%s", 1252, (wchar_t *)p );
- return p;
- }
- /*
- ;
- ; ABSTRACT
- ;
- ; LOCALE_getstr - return selected string from the specified .loc file
- ;
- ;
- ; SUMMARY
- ;
- ; #include "realfont.h"
- ;
- ; const char* LOCALE_getstr(stringid)
- ;
- ; int stringid; // string id to return
- ;
- ; DESCRIPTION
- ;
- ; Returns the string identified by stringid from the specified
- ; .loc file. Use the string ID specified in the header file created
- ; by Locomoto. Note that the string pointer is a const pointer. Do
- ; not modify the string or the Locale library may return invalid results.
- ;
- ; If your strings are Unicode strings, cast the result to a const USTR *.
- ;
- ; If the .loc file was created with an index stringid can be any
- ; valid integer in the range 0..65535. If no index was created
- ; with the .loc file stringid will be a zero based array index.
- ;
- ; String is returned by const for a reason. Bad things will happen
- ; if you modify it. You have been warned.
- ;
- ; SEE ALSO
- ;
- ; EXAMPLE
- ;
- ; locale_eg.c
- ;
- ; <HTML A HREF="locale_eg.c">Download the source<HTML /A>
- ; <HTML A HREF="locale_eg.csv">locale_eg.csv<HTML /A> (example data)
- ;
- ; END ABSTRACT
- ;
- */
- int LOCALElanguageid = 0;
- const char* LOCALE_getstr( const void* pLocFile, int StringID )
- {
- const char* p; /* pointer to string, NULL if string cannot be found */
- HEADER* pHeader;
- BANK* pBank;
- ASSERT(pLocFile != NULL);
- pHeader = (LOCALEFILE_HEADERCHUNK*)(pLocFile);
- ASSERT(pHeader->ChunkID == LOCALEFILE_HEADERCHUNKID);
- ASSERT(pHeader->LanguageCount >= 1);
- if( pHeader->Flags == 1 ) {
- /* file has an index */
- INDEX* pIndex = (INDEX*)((unsigned char*)(pLocFile) + pHeader->ChunkSize);
- StringID = getstringbyindex((unsigned short)StringID, pIndex);
- }
- /* get pointer to string bank */
- {
- int offset = *((int*)(pLocFile) + 4 + LOCALElanguageid);
- pBank = (BANK*)((unsigned char*)(pLocFile) + offset);
- }
-
- if ((StringID >= 0) && (StringID < (int)(pBank->StringCount))) {
- unsigned int offset;
- p = (const char*)(pBank);
- offset = *(unsigned int*)(p + LOCALEFILE_LANGUAGECHUNK_STRING_OFFSET + StringID*4);
- p += offset;
- } else {
- p = NULL;
- }
- return p;
- }
|