| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376 |
- /*
- ** 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 S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : LevelEdit *
- * *
- * $Archive:: /Commando/Code/wwtranslatedb/translatedb.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 1/28/02 4:05p $*
- * *
- * $Revision:: 18 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "translatedb.h"
- #include <windows.h>
- #include <string.h>
- #include "persist.h"
- #include "persistfactory.h"
- #include "chunkio.h"
- #include "translatedbids.h"
- #include "rawfile.h"
- #include "textfile.h"
- #include "tdbcategories.h"
- #include "definition.h"
- #include "definitionmgr.h"
- #include "definitionclassids.h"
- ///////////////////////////////////////////////////////////////////////
- // Local prototypes
- ///////////////////////////////////////////////////////////////////////
- static int Build_List_From_String (const char *buffer, const char *delimiter, StringClass **string_list);
- ///////////////////////////////////////////////////////////////////////
- // Global singleton instance
- ///////////////////////////////////////////////////////////////////////
- TranslateDBClass _TheTranslateDB;
- ///////////////////////////////////////////////////////////////////////
- // Static member initialization
- ///////////////////////////////////////////////////////////////////////
- TDB_OBJ_LIST TranslateDBClass::m_ObjectList;
- HashTemplateClass<StringClass,TDBObjClass*> TranslateDBClass::m_ObjectHash;
- TDB_CATEGORY_LIST TranslateDBClass::m_CategoryList;
- uint32 TranslateDBClass::m_VersionNumber = 100;
- uint32 TranslateDBClass::m_LanguageID = TranslateDBClass::LANGID_ENGLISH;
- bool TranslateDBClass::IsSingleLanguageExport = false;
- TranslateDBClass::FILTER_OPT TranslateDBClass::FilterType = FILTER_DISABLED;
- uint32 TranslateDBClass::FilterCategoryID = 0xFFFFFFFF;
- ///////////////////////////////////////////////////////////////////////
- // Constants
- ///////////////////////////////////////////////////////////////////////
- enum
- {
- CHUNKID_VARIABLES = 0x07141200,
- CHUNKID_OBJECTS,
- CHUNKID_CATEGORIES
- };
- enum
- {
- VARID_VERSION_NUMBER = 0x01,
- VARID_LANGUAGE_ID
- };
- const WCHAR * STRING_NOT_FOUND = L"TDBERR";
- const char * ENGLISH_STRING_NOT_FOUND = "TDBERR";
- ///////////////////////////////////////////////////////////////////////
- //
- // Chunk_ID
- //
- ///////////////////////////////////////////////////////////////////////
- uint32
- TranslateDBClass::Chunk_ID (void) const
- {
- return CHUNKID_TRANSLATE_DB;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Initialize
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Initialize (void)
- {
- m_ObjectList.Set_Growth_Step (1000);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Shutdown
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Shutdown (void)
- {
- Free_Objects ();
- Free_Categories ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Free_Categories
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Free_Categories (void)
- {
- //
- // Loop over and free all the translation categories
- //
- for (int index = 0; index < m_CategoryList.Count (); index ++) {
- TDBCategoryClass *category = m_CategoryList[index];
- if (category != NULL) {
- delete category;
- }
- }
-
- m_CategoryList.Delete_All ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Free_Objects
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Free_Objects (void)
- {
- //
- // Loop over and free all the translation objects
- //
- for (int index = 0; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *translate_obj = m_ObjectList[index];
- if (translate_obj != NULL) {
- delete translate_obj;
- }
- }
- m_ObjectList.Delete_All ();
- // Remove the stuff from the hash table as well..
- m_ObjectHash.Remove_All();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Contains_Data
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Contains_Data (void) const
- {
- return true;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Save
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Save (ChunkSaveClass &csave)
- {
- bool retval = true;
- csave.Begin_Chunk (CHUNKID_VARIABLES);
- WRITE_MICRO_CHUNK (csave, VARID_VERSION_NUMBER, m_VersionNumber);
- WRITE_MICRO_CHUNK (csave, VARID_LANGUAGE_ID, m_LanguageID);
- csave.End_Chunk ();
- csave.Begin_Chunk (CHUNKID_CATEGORIES);
- //
- // Loop over and save all the translation categories
- //
- for (int index = 0; index < m_CategoryList.Count (); index ++) {
- TDBCategoryClass *category = m_CategoryList[index];
- //
- // Save this category
- //
- if (category != NULL) {
- csave.Begin_Chunk (category->Get_Factory ().Chunk_ID ());
- category->Get_Factory ().Save (csave, category);
- csave.End_Chunk ();
- }
- }
- csave.End_Chunk ();
-
- csave.Begin_Chunk (CHUNKID_OBJECTS);
- //
- // Loop over and save all the translation objects
- //
- for (index = 0; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *translate_obj = m_ObjectList[index];
- //
- // Save this translation object
- //
- if (translate_obj != NULL) {
-
- //
- // Check to ensure this category isn't filtered out...
- //
- bool is_equal = (translate_obj->Get_Category_ID () == FilterCategoryID);
- if ( FilterType == FILTER_DISABLED ||
- (FilterType == FILTER_IF_EQUAL && is_equal == false) ||
- (FilterType == FILTER_IF_NOT_EQUAL && is_equal))
- {
- csave.Begin_Chunk (translate_obj->Get_Factory ().Chunk_ID ());
- translate_obj->Get_Factory ().Save (csave, translate_obj);
- csave.End_Chunk ();
- }
- }
- }
- csave.End_Chunk ();
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Load (ChunkLoadClass &cload)
- {
- Free_Objects ();
- Free_Categories ();
- bool retval = true;
- while (cload.Open_Chunk ()) {
- switch (cload.Cur_Chunk_ID ()) {
-
- //
- // Load all the presets from this chunk
- //
- case CHUNKID_VARIABLES:
- retval &= Load_Variables (cload);
- break;
- case CHUNKID_OBJECTS:
- retval &= Load_Objects (cload);
- break;
- case CHUNKID_CATEGORIES:
- retval &= Load_Categories (cload);
- break;
- }
- cload.Close_Chunk ();
- }
- Validate_Data ();
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Categories
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Load_Categories (ChunkLoadClass &cload)
- {
- bool retval = true;
- while (cload.Open_Chunk ()) {
- //
- // Load this object from the chunk (if possible)
- //
- PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
- if (factory != NULL) {
- TDBCategoryClass *category = (TDBCategoryClass *)factory->Load (cload);
- if (category != NULL) {
- Add_Category (category, false);
- }
- }
- cload.Close_Chunk ();
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Objects
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Load_Objects (ChunkLoadClass &cload)
- {
- bool retval = true;
- while (cload.Open_Chunk ()) {
- //
- // Load this object from the chunk (if possible)
- //
- PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
- if (factory != NULL) {
- TDBObjClass *translate_obj = (TDBObjClass *)factory->Load (cload);
- if (translate_obj != NULL) {
- Add_Object (translate_obj);
- }
- }
- cload.Close_Chunk ();
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Variables
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Load_Variables (ChunkLoadClass &cload)
- {
- bool retval = true;
- while (cload.Open_Micro_Chunk ()) {
- switch (cload.Cur_Micro_Chunk_ID ()) {
- READ_MICRO_CHUNK (cload, VARID_VERSION_NUMBER, m_VersionNumber);
- READ_MICRO_CHUNK (cload, VARID_LANGUAGE_ID, m_LanguageID);
- }
-
- cload.Close_Micro_Chunk ();
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Validate_Data
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Validate_Data (void)
- {
- if (m_CategoryList.Count () == 0) {
- //
- // Create the default category
- //
- TDBCategoryClass *category = new TDBCategoryClass;
- category->Set_Name ("Default");
- m_CategoryList.Add (category);
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Export_Table
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Export_Table (const char *filename)
- {
- //
- // Create the file
- //
- HANDLE file = ::CreateFile (filename,
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- 0L,
- NULL);
- WWASSERT (file != INVALID_HANDLE_VALUE);
- if (file != INVALID_HANDLE_VALUE) {
- TextFileClass file_obj;
- file_obj.Attach (file);
- //
- // Loop over all the translation objects and write a tab delimited
- // entry for each one
- //
- for (int index = 0; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *object = m_ObjectList[index];
- if (object != NULL && object->As_StringTwiddlerClass () == NULL) {
-
- StringClass english_string = object->Get_English_String ();
- int length = english_string.Get_Length ();
- for (int index = 0; index < length; index ++) {
- if (english_string[index] == '\n') {
- english_string[index] = ' ';
- }
- }
- //
- // Lookup the string's category
- //
- StringClass category_name;
- TDBCategoryClass *category = Find_Category (object->Get_Category_ID ());
- if (category != NULL) {
- category_name = category->Get_Name ();
- }
- //
- // Lookup the string's sound preset
- //
- StringClass sound_preset_name;
- DefinitionClass *definition = DefinitionMgrClass::Find_Definition (object->Get_Sound_ID (), false);
- if (definition != NULL) {
- sound_preset_name = definition->Get_Name ();
- }
- //
- // Write a tab delimited entry for this object
- //
- StringClass text_entry;
- text_entry = category_name;
- text_entry += "\t";
- text_entry += object->Get_ID_Desc ();
- text_entry += "\t";
- text_entry += english_string;
- text_entry += "\t";
- text_entry += sound_preset_name;
- file_obj.Write_Line (text_entry);
- }
- }
- //
- // Close the file
- //
- file_obj.Detach ();
- ::CloseHandle (file);
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Export_C_Header
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Export_C_Header (const char *filename)
- {
- //
- // Create the file
- //
- HANDLE file = ::CreateFile (filename,
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- 0L,
- NULL);
- WWASSERT (file != INVALID_HANDLE_VALUE);
- if (file != INVALID_HANDLE_VALUE) {
- TextFileClass file_obj;
- file_obj.Attach (file);
- //
- // Wtite the 'C' style header framework
- //
- file_obj.Write_Line ("#if defined(_MSC_VER)");
- file_obj.Write_Line ("#pragma once");
- file_obj.Write_Line ("#endif");
- file_obj.Write_Line ("");
- file_obj.Write_Line ("#ifndef __STRING_IDS_H");
- file_obj.Write_Line ("#define __STRING_IDS_H");
- file_obj.Write_Line ("");
- StringClass version_line;
- version_line.Format ("#define STRINGS_VER %d", m_VersionNumber);
- file_obj.Write_Line (version_line);
- file_obj.Write_Line ("");
- file_obj.Write_Line ("// TRANSLATEDB: Begin ID Block");
- //
- // Loop over all the translation objects and write a #define to the
- // header file for each one...
- //
- for (int index = 0; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *object = m_ObjectList[index];
- if (object != NULL) {
-
- //
- // Write a #define for this object's ID
- //
- StringClass id_entry;
- id_entry.Format ("#define %s %d", (const char *)object->Get_ID_Desc (), object->Get_ID ());
- file_obj.Write_Line (id_entry);
- }
- }
- file_obj.Write_Line ("// TRANSLATEDB: End ID Block");
- file_obj.Write_Line ("");
- file_obj.Write_Line ("#endif //__STRING_IDS_H");
- //
- // Close the file
- //
- file_obj.Detach ();
- ::CloseHandle (file);
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Import_C_Header
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Import_C_Header (const char *filename)
- {
- //
- // Create the file
- //
- HANDLE file = ::CreateFile (filename,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- 0L,
- NULL);
- WWASSERT (file != INVALID_HANDLE_VALUE);
- if (file != INVALID_HANDLE_VALUE) {
- TextFileClass file_obj;
- file_obj.Attach (file);
- StringClass line;
- bool found_id_block = false;
- //
- // Look for the start of the ID block
- //
- while (found_id_block == false && file_obj.Read_Line (line)) {
- found_id_block = (line.Compare_No_Case ("// TRANSLATEDB: Begin ID Block") == 0);
- }
- if (found_id_block) {
-
- //
- // Read each ID define from the header file
- //
- bool found_end_block = false;
- while (found_end_block == false && file_obj.Read_Line (line)) {
- if (::strnicmp (line, "#define ", 8) == 0) {
-
- //
- // Break the #define into its parts
- //
- int word_breaks[4] = { 0 };
- int curr_break = 0;
- //
- // Find out where each word begins and ends
- //
- int count = line.Get_Length ();
- for (int index = 8; curr_break < 4 && index < count; index ++) {
- bool is_whitespace = (line[index] == ' ' || line[index] == '\t');
-
- if (is_whitespace == (curr_break & 1) || index == count - 1) {
- word_breaks[curr_break ++] = index;
- }
- }
- //
- // Did we encounter the right number of words?
- //
- if (curr_break == 4) {
-
- //
- // Isolate the words
- //
- char id_desc_text[64] = { 0 };
- char id_text[64] = { 0 };
- ::strncpy (id_desc_text, line.Peek_Buffer () + word_breaks[0], word_breaks[1] - word_breaks[0]);
- ::strncpy (id_text, line.Peek_Buffer () + word_breaks[2], word_breaks[3] - word_breaks[2]);
- //
- // Convert the ID string to a number
- //
- uint32 id = ::atoi (id_text);
- //
- // Do we already have this object?
- //
- TDBObjClass *object = Find_Object (id);
- if (object == NULL) {
- object = Find_Object (id_desc_text);
- if (object == NULL) {
- //
- // If we didn't already have this object, then create
- // a new object and add it to the system
- //
- object = new TDBObjClass;
- object->Set_ID_Desc (id_desc_text);
- Add_Object (object);
- }
- }
- }
- } else {
-
- //
- // Check for block-end conditions
- //
- found_end_block = (line.Compare_No_Case ("// TRANSLATEDB: End ID Block") == 0);
- }
- }
- }
- //
- // Close the file
- //
- file_obj.Detach ();
- ::CloseHandle (file);
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Object_Count
- //
- ///////////////////////////////////////////////////////////////////////
- int
- TranslateDBClass::Get_Object_Count (void)
- {
- return m_ObjectList.Count ();
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Object
- //
- ///////////////////////////////////////////////////////////////////////
- TDBObjClass *
- TranslateDBClass::Get_Object (int index)
- {
- TDBObjClass *object = NULL;
-
- WWASSERT (index >= 0 && index < m_ObjectList.Count ());
- if (index >= 0 && index < m_ObjectList.Count ()) {
- object = m_ObjectList[index];
- }
- return object;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Unique_ID
- //
- ///////////////////////////////////////////////////////////////////////
- uint32
- TranslateDBClass::Find_Unique_ID (void)
- {
- uint32 new_id = ID_MIN + m_ObjectList.Count ();
- //
- // Return the 'id' of the first empty slot in the list
- //
- for (int index = 0; index < m_ObjectList.Count (); index ++) {
- if (m_ObjectList[index] == NULL) {
- new_id = (ID_MIN + index);
- break;
- }
- }
- return new_id;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Add_Category
- //
- ///////////////////////////////////////////////////////////////////////
- TDBCategoryClass *
- TranslateDBClass::Add_Category (const char *name)
- {
- //
- // Create the new category
- //
- TDBCategoryClass *category = new TDBCategoryClass;
- category->Set_Name (name);
- //
- // Add the category to our list and return a pointer to the caller
- //
- Add_Category (category);
- return category;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Add_Category
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Add_Category (TDBCategoryClass *new_category, bool assign_id)
- {
- bool retval = false;
- WWASSERT (new_category != NULL);
- if (new_category != NULL) {
- //
- // Assign this category an ID (if necessary)
- //
- if (assign_id && new_category->Get_ID () == 0) {
- uint32 new_id = 1;
- for (int index = 0; index < m_CategoryList.Count (); index ++) {
- uint32 curr_id = m_CategoryList[index]->Get_ID ();
- new_id = max (curr_id + 1, new_id);
- }
- new_category->Set_ID (new_id);
- }
- //
- // Add the new category to our list
- //
- m_CategoryList.Add (new_category);
- retval = true;
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Remove_Category
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Remove_Category (int index)
- {
- bool retval = false;
- //
- // Make sure this index is in our range
- //
- WWASSERT (index >= 0 && index < m_CategoryList.Count ());
- if (index >= 0 && index < m_CategoryList.Count ()) {
-
- //
- // Free the object that was in this slot
- //
- TDBCategoryClass *category = m_CategoryList[index];
- if (category != NULL) {
- //
- // Remove all objects from the category
- //
- int category_id = category->Get_ID ();
- for ( TDBObjClass *object = Get_First_Object (category_id);
- object != NULL;
- object = Get_Next_Object (category_id, object))
- {
- object->Set_Category_ID (CATEGORY_DEFAULT);
- }
- delete category;
- }
- //
- // Remove the entry from our list
- //
- m_CategoryList.Delete (index);
- retval = true;
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Add_Object
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Add_Object (TDBObjClass *new_obj)
- {
- bool retval = false;
- WWASSERT (new_obj != NULL);
- if (new_obj != NULL) {
- //
- // Try to find an unused ID for the object (if necessary)
- //
- if (new_obj->Get_ID () < ID_MIN) {
- new_obj->Set_ID (Find_Unique_ID ());
- }
- //
- // Determine where in the list this object should
- // be inserted
- //
- int new_id = new_obj->Get_ID ();
- int obj_index = new_id - ID_MIN;
- //
- // Grow the list up to the number of elements we need
- //
- while (m_ObjectList.Count () <= obj_index) {
- m_ObjectList.Add (NULL);
- }
-
- //
- // Add the object to our list
- //
- m_ObjectList[obj_index] = new_obj;
- // Insert object to the hash table as well...
- StringClass lower_case_name(new_obj->Get_ID_Desc(),true);
- _strlwr(lower_case_name.Peek_Buffer());
- m_ObjectHash.Insert(lower_case_name,new_obj);
- retval = true;
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Remove_Object
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- TranslateDBClass::Remove_Object (int index)
- {
- bool retval = false;
- //
- // Make sure this index is in our range
- //
- WWASSERT (index >= 0 && index < m_ObjectList.Count ());
- if (index >= 0 && index < m_ObjectList.Count ()) {
-
- //
- // Free the object that was in this slot
- //
- TDBObjClass *object = m_ObjectList[index];
- if (object != NULL) {
- // Remove the object from the hash table
- StringClass lower_case_name(object->Get_ID_Desc(),true);
- _strlwr(lower_case_name.Peek_Buffer());
- m_ObjectHash.Remove(lower_case_name);
- delete object;
- }
- //
- // Remove the pointer from the list and re-assign IDs
- //
- m_ObjectList[index] = NULL;
- retval = true;
- }
- return retval;
- }
- //////////////////////////////////////////////////////////////
- //
- // Remove_All
- //
- //////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Remove_All (void)
- {
- Free_Objects ();
- return ;
- }
- //////////////////////////////////////////////////////////////
- //
- // Get_Version_Number
- //
- //////////////////////////////////////////////////////////////
- uint32
- TranslateDBClass::Get_Version_Number (void)
- {
- return m_VersionNumber;
- }
- //////////////////////////////////////////////////////////////
- //
- // Update_Version
- //
- //////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Update_Version (void)
- {
- m_VersionNumber ++;
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Category_Count
- //
- ///////////////////////////////////////////////////////////////////////
- int
- TranslateDBClass::Get_Category_Count (void)
- {
- return m_CategoryList.Count ();
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Category
- //
- ///////////////////////////////////////////////////////////////////////
- TDBCategoryClass *
- TranslateDBClass::Get_Category (int index)
- {
- TDBCategoryClass *category = NULL;
-
- WWASSERT (index >= 0 && index < m_CategoryList.Count ());
- if (index >= 0 && index < m_CategoryList.Count ()) {
- category = m_CategoryList[index];
- }
- return category;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Category
- //
- ///////////////////////////////////////////////////////////////////////
- TDBCategoryClass *
- TranslateDBClass::Find_Category (uint32 id)
- {
- TDBCategoryClass *category = NULL;
- //
- // Loop over all the categories until we've found a matching ID
- //
- for (int index = 0; index < m_CategoryList.Count (); index ++) {
- if (m_CategoryList[index]->Get_ID () == id) {
- category = m_CategoryList[index];
- break;
- }
- }
- return category;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Category
- //
- ///////////////////////////////////////////////////////////////////////
- TDBCategoryClass *
- TranslateDBClass::Find_Category (const char *name)
- {
- TDBCategoryClass *category = NULL;
- //
- // Loop over all the categories until we've found a matching name
- //
- for (int index = 0; index < m_CategoryList.Count (); index ++) {
- if (m_CategoryList[index]->Get_Name ().Compare_No_Case (name) == 0) {
- category = m_CategoryList[index];
- break;
- }
- }
- return category;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_First_Object
- //
- ///////////////////////////////////////////////////////////////////////
- TDBObjClass *
- TranslateDBClass::Get_First_Object (uint32 category_id)
- {
- TDBObjClass *object = NULL;
- //
- // Loop over the objects we know about and return the first
- // one that matches the given category ID
- //
- for (int index = 0; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *curr_obj = m_ObjectList[index];
- if (curr_obj != NULL) {
- //
- // Does this object belong to the category we are enumerating?
- //
- if (curr_obj->Get_Category_ID () == category_id) {
- object = curr_obj;
- break;
- }
- }
- }
- return object;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Next_Object
- //
- ///////////////////////////////////////////////////////////////////////
- TDBObjClass *
- TranslateDBClass::Get_Next_Object (uint32 category_id, TDBObjClass *curr_obj)
- {
- //
- // Sanity check
- //
- if (curr_obj == NULL) {
- return NULL;
- }
- TDBObjClass *object = NULL;
- //
- // Determine where in the list to start looking
- //
- int start_index = (curr_obj->Get_ID () - ID_MIN) + 1;
- //
- // Loop over the objects we know about and return the first
- // one that matches the given category ID
- //
- for (int index = start_index; index < m_ObjectList.Count (); index ++) {
- TDBObjClass *curr_obj = m_ObjectList[index];
- if (curr_obj != NULL) {
- //
- // Does this object belong to the category we are enumerating?
- //
- if (curr_obj->Get_Category_ID () == category_id) {
- object = curr_obj;
- break;
- }
- }
- }
- return object;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Convert_Chars_To_Newline
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- Convert_Chars_To_Newline (StringClass &string)
- {
- StringClass retval;
-
- int count = string.Get_Length ();
- //
- // Copy characters between the strings
- //
- for (int index = 0; index < count; index ++) {
-
- if (index + 1 < count && string[index] == '\\' && string[index + 1] == 'n') {
- retval += '\n';
- index ++;
- } else {
- retval += string[index];
- }
- }
- string = retval;
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Import_Strings
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Import_Strings (const char *filename)
- {
- //
- // Open the file
- //
- HANDLE file = ::CreateFile ( filename,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- 0L,
- NULL);
- WWASSERT (file != INVALID_HANDLE_VALUE);
- if (file != INVALID_HANDLE_VALUE) {
- //
- // Attach this file to a text file class for easier parsing
- //
- TextFileClass file_obj;
- file_obj.Attach (file);
- //
- // Keep reading data from the file until we've reached the end
- // of the file or the data becomes corrupt
- //
- bool keep_going = true;
- StringClass line;
- while (keep_going && file_obj.Read_Line (line)) {
-
- //
- // Convert the string to an array of values
- //
- StringClass *value_array = NULL;
- int value_count = Build_List_From_String (line, "\t", &value_array);
- //
- // We can't keep going unless we've got at least 3 columns of information
- //
- if (value_count >= 3) {
-
- //
- // Lookup the category this entry belongs to
- //
- TDBCategoryClass *category = Find_Category (value_array[0]);
- //
- // Create the entry
- //
- TDBObjClass *new_obj = new TDBObjClass;
- new_obj->Set_Category_ID (category ? category->Get_ID () : 0);
- new_obj->Set_ID_Desc (value_array[1]);
-
- //
- // Set the english string
- //
- StringClass english_string = value_array[2];
- ::Convert_Chars_To_Newline (english_string);
- new_obj->Set_English_String (english_string);
- //
- // If necessary, lookup the sound definition that goes with this new entry
- // and plug in its ID.
- //
- if (value_count >= 4) {
- DefinitionClass *definition = DefinitionMgrClass::Find_Typed_Definition (value_array[3], CLASSID_SOUND, false);
- if (definition != NULL) {
- new_obj->Set_Sound_ID (definition->Get_ID ());
- }
- }
- //
- // Add this object to the database
- //
- Add_Object (new_obj);
- }
- //
- // Cleanup
- //
- if (value_array != NULL) {
- delete [] value_array;
- value_array = NULL;
- }
- }
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Build_List_From_String
- //
- ///////////////////////////////////////////////////////////////////////
- int Build_List_From_String
- (
- const char * buffer,
- const char * delimiter,
- StringClass ** string_list
- )
- {
- int count = 0;
- WWASSERT (buffer != NULL);
- WWASSERT (delimiter != NULL);
- WWASSERT (string_list != NULL);
- if ((buffer != NULL) &&
- (delimiter != NULL) &&
- (string_list != NULL))
- {
- int delim_len = ::strlen (delimiter);
- //
- // Determine how many entries there will be in the list
- //
- for (const char *entry = buffer;
- (entry != NULL) && (entry[1] != 0);
- entry = ::strstr (entry, delimiter))
- {
-
- //
- // Move past the current delimiter (if necessary)
- //
- if ((::strnicmp (entry, delimiter, delim_len) == 0) && (count > 0)) {
- entry += delim_len;
- }
- // Increment the count of entries
- count ++;
- }
-
- if (count > 0) {
- //
- // Allocate enough StringClass objects to hold all the strings in the list
- //
- (*string_list) = new StringClass[count];
-
- //
- // Parse the string and pull out its entries.
- //
- count = 0;
- for (entry = buffer;
- (entry != NULL) && (entry[1] != 0);
- entry = ::strstr (entry, delimiter))
- {
-
- //
- // Move past the current delimiter (if necessary)
- //
- if ((::strnicmp (entry, delimiter, delim_len) == 0) && (count > 0)) {
- entry += delim_len;
- }
- //
- // Copy this entry into its own string
- //
- StringClass entry_string = entry;
- char *delim_start = ::strstr (entry_string, delimiter);
- if (delim_start != NULL) {
- delim_start[0] = 0;
- }
- //
- // Add this entry to our list
- //
- if ((entry_string.Get_Length () > 0) || (count == 0)) {
- (*string_list)[count++] = entry_string;
- }
- }
- } else if (delim_len > 0) {
- count = 1;
- (*string_list) = new StringClass[count];
- (*string_list)[0] = buffer;
- }
-
- }
- //
- // Return the number of entries in our list
- //
- return count;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Set_Export_Filter
- //
- ///////////////////////////////////////////////////////////////////////
- void
- TranslateDBClass::Set_Export_Filter (FILTER_OPT filter, uint32 category_id)
- {
- FilterType = filter;
- FilterCategoryID = category_id;
- return ;
- }
|