| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656 |
- /*
- ** 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/>.
- */
- //
- // loadsave.cpp
- //
- #include "stdAfx.h"
- #include "iff.h"
- #include "TransDB.h"
- #include "noxstringdlg.h"
- #define FORM_NOXDB MakeID ('N','X','D','B')
- #define FORM_LABEL MakeID ('N','L','B','L')
- #define FORM_TEXT MakeID ('N','T','X','T')
- #define FORM_TRANS MakeID ('N','T','R','N')
- #define CHUNK_COMMENT MakeID ('C','M','N','T')
- #define CHUNK_CONTEXT MakeID ('C','T','X','T')
- #define CHUNK_SPEAKER MakeID ('S','P','K','R')
- #define CHUNK_LISTENER MakeID ('L','T','N','R')
- #define CHUNK_TEXT MakeID ('T','E','X','T')
- #define CHUNK_WAVE MakeID ('W','A','V','E')
- #define CHUNK_WAVE_INFO MakeID ('W','V','I','N')
- #define CHUNK_INFO MakeID ('I','N','F','O')
- #define CHUNK_NAME MakeID ('N','A','M','E')
- #define MAX_BUFFER (100*1024)
- static OLECHAR buffer[MAX_BUFFER];
- typedef struct
- {
- int num_labels;
- int next_id;
- } DBINFO;
- typedef struct
- {
- int max_len;
- } LBINFO;
- typedef struct
- {
- int id;
- int revision;
- } TXINFO;
- typedef struct
- {
- LangID lang;
- int revision;
- } TRINFO;
- typedef struct
- {
- int valid;
- DWORD lo;
- DWORD hi;
- } WVINFO;
- static int writeString ( IFF_FILE *iff, OLECHAR *string, int chunk_id )
- {
- int len = (wcslen ( string ) );
- int bytes = (len+1)*sizeof(OLECHAR);
- if ( len )
- {
- IFF_NEWCHUNK ( iff, chunk_id, error );
- IFF_WRITE ( iff, string, bytes, error);
- IFF_CloseChunk ( iff );
- }
- return TRUE;
- error:
- return FALSE;
- }
- static int readString ( IFF_FILE *iff, OLECHAR *string )
- {
- *string = 0;
- IFF_READ ( iff, string, iff->ChunkSize, error);
- return TRUE;
- error:
- return FALSE;
- }
- static int writeTransForm ( IFF_FILE *iff, Translation *trans )
- {
- TRINFO trinfo;
- WVINFO wvinfo;
- if ( !IFF_NewForm ( iff, FORM_TRANS ))
- {
- goto error;
- }
-
- trinfo.lang = trans->GetLangID ();
- trinfo.revision = trans->Revision ();
-
- if ( !IFF_NewChunk ( iff, CHUNK_INFO ))
- {
- goto error;
- }
-
- IFF_Write ( iff, &trinfo, sizeof ( trinfo ));
-
- IFF_CloseChunk ( iff );
- writeString ( iff, trans->Get (), CHUNK_TEXT );
- writeString ( iff, trans->Comment (), CHUNK_COMMENT );
- if ( (wvinfo.valid = trans->WaveInfo.Valid()) )
- {
- wvinfo.lo = trans->WaveInfo.Lo ();
- wvinfo.hi = trans->WaveInfo.Hi ();
-
- if ( !IFF_NewChunk ( iff, CHUNK_WAVE_INFO ))
- {
- goto error;
- }
-
- IFF_Write ( iff, &wvinfo, sizeof ( wvinfo ));
-
- IFF_CloseChunk ( iff );
- }
- IFF_CloseForm ( iff );
- return TRUE;
- error:
- return FALSE;
- }
- static int writeTextForm ( IFF_FILE *iff, NoxText *text )
- {
- TXINFO txinfo;
- WVINFO wvinfo;
- if ( !IFF_NewForm ( iff, FORM_TEXT ))
- {
- goto error;
- }
-
- txinfo.id = text->ID ();
- txinfo.revision = text->Revision ();
-
- if ( !IFF_NewChunk ( iff, CHUNK_INFO ))
- {
- goto error;
- }
-
- IFF_Write ( iff, &txinfo, sizeof ( txinfo ));
-
- IFF_CloseChunk ( iff );
- writeString ( iff, text->Get (), CHUNK_TEXT );
- writeString ( iff, text->Wave (), CHUNK_WAVE );
- if ( (wvinfo.valid = text->WaveInfo.Valid()) )
- {
- wvinfo.lo = text->WaveInfo.Lo ();
- wvinfo.hi = text->WaveInfo.Hi ();
-
- if ( !IFF_NewChunk ( iff, CHUNK_WAVE_INFO ))
- {
- goto error;
- }
-
- IFF_Write ( iff, &wvinfo, sizeof ( wvinfo ));
-
- IFF_CloseChunk ( iff );
- }
- IFF_CloseForm ( iff );
- return TRUE;
- error:
- return FALSE;
- }
- int WriteMainDB(TransDB *db, const char *filename, CNoxstringDlg *dlg )
- {
- NoxText *text;
- NoxLabel *label;
- ListSearch sh_label;
- ListSearch sh_text;
- int count = 0;
- IFF_FILE *iff = NULL;
- DBINFO dbinfo;
- int ok = FALSE;
- if ( dlg )
- {
- dlg->InitProgress ( db->NumLabels ());
- }
- if ( !( iff = IFF_New ( filename )))
- {
- goto error;
- }
- if ( !IFF_NewForm ( iff, FORM_NOXDB ) )
- {
- goto error;
- }
-
- dbinfo.next_id = db->ID ();
- dbinfo.num_labels = db->NumLabels ();
- if ( !IFF_NewChunk ( iff, CHUNK_INFO ))
- {
- goto error;
- }
- IFF_Write ( iff, &dbinfo, sizeof ( dbinfo ));
- IFF_CloseChunk ( iff );
- IFF_CloseForm ( iff );
- text = db->FirstObsolete ( sh_text );
- while ( text )
- {
- if ( !writeTextForm ( iff, text ) )
- {
- goto error;
- }
- text = db->NextObsolete ( sh_text );
- }
-
- label = db->FirstLabel ( sh_label );
- while ( label )
- {
- LBINFO lbinfo;
- if ( !IFF_NewForm ( iff, FORM_LABEL ))
- {
- goto error;
- }
- lbinfo.max_len = label->MaxLen ();
- if ( !IFF_NewChunk ( iff, CHUNK_INFO ))
- {
- goto error;
- }
-
- IFF_Write ( iff, &lbinfo, sizeof ( lbinfo ));
-
- IFF_CloseChunk ( iff );
- writeString ( iff, label->Name (), CHUNK_NAME );
- writeString ( iff, label->Comment (), CHUNK_COMMENT );
- writeString ( iff, label->Context (), CHUNK_CONTEXT );
- writeString ( iff, label->Speaker (), CHUNK_SPEAKER );
- writeString ( iff, label->Listener (), CHUNK_LISTENER );
- IFF_CloseForm ( iff );
- text = label->FirstText ( sh_text );
- while ( text )
- {
- Translation *trans;
- ListSearch sh_trans;
- if ( !writeTextForm ( iff, text ) )
- {
- goto error;
- }
-
- trans = text->FirstTranslation ( sh_trans );
- while ( trans )
- {
- if ( !writeTransForm ( iff, trans ) )
- {
- goto error;
- }
- trans = text->NextTranslation ( sh_trans );
- }
- text = label->NextText ( sh_text );
- }
- count++;
- if ( dlg )
- {
- dlg->SetProgress ( count );
- }
- label = db->NextLabel ( sh_label );
- }
- ok = TRUE;
- db->ClearChanges ();
-
- error:
- if ( iff )
- {
- IFF_Close ( iff );
- }
- return ok;
- }
- int LoadMainDB(TransDB *db, const char *filename, void (*cb) (void) )
- {
- NoxLabel *label = NULL;
- NoxText *text = NULL;
- Translation *trans = NULL;
- int count = 0;
- IFF_FILE *iff = NULL;
- DBINFO dbinfo;
- int ok = FALSE;
- if ( !(iff = IFF_Load ( filename ) ) )
- {
- goto error;
- }
- if ( !IFF_NextForm ( iff ) || iff->FormID != FORM_NOXDB )
- {
- goto error;
- }
- dbinfo.next_id = -1;
- dbinfo.num_labels = 0;
- while ( IFF_NextChunk ( iff ))
- {
- switch (iff->ChunkID )
- {
- case CHUNK_INFO:
- IFF_READ ( iff, &dbinfo, sizeof ( dbinfo ), error );
- break;
- }
- }
- db->SetID ( dbinfo.next_id );
- while ( IFF_NextForm ( iff ) )
- {
- switch ( iff->FormID )
- {
- case FORM_LABEL:
- {
- LBINFO lbinfo;
- // new label
- if ( text )
- {
- if ( label )
- {
- label->AddText ( text );
- }
- else
- {
- db->AddObsolete ( text );
- }
- text = NULL;
- }
- if ( label )
- {
- count++;
- db->AddLabel ( label );
- label = NULL;
- if ( cb )
- {
- cb ();
- }
- }
- if ( ! (label = new NoxLabel ()))
- {
- goto error;
- }
- while ( IFF_NextChunk ( iff ))
- {
- switch ( iff->ChunkID )
- {
- case CHUNK_INFO:
- IFF_READ ( iff, &lbinfo, sizeof (lbinfo), error );
- label->SetMaxLen ( lbinfo.max_len );
- break;
- case CHUNK_COMMENT:
- readString ( iff, buffer );
- label->SetComment ( buffer );
- break;
- case CHUNK_CONTEXT:
- readString ( iff, buffer );
- label->SetContext ( buffer );
- break;
- case CHUNK_SPEAKER:
- readString ( iff, buffer );
- label->SetSpeaker ( buffer );
- break;
- case CHUNK_LISTENER:
- readString ( iff, buffer );
- label->SetListener ( buffer );
- break;
- case CHUNK_NAME:
- readString ( iff, buffer );
- label->SetName ( buffer );
- break;
- }
- }
- break;
- }
- case FORM_TEXT:
- {
- TXINFO txinfo;
- if ( text )
- {
- if ( label )
- {
- label->AddText ( text );
- }
- else
- {
- db->AddObsolete ( text );
- }
- text = NULL;
- }
- if ( ! (text = new NoxText ()))
- {
- goto error;
- }
- while ( IFF_NextChunk ( iff ))
- {
- switch ( iff->ChunkID )
- {
- case CHUNK_INFO:
- IFF_READ ( iff, &txinfo, sizeof (txinfo), error );
- text->SetID ( txinfo.id );
- text->SetRevision ( txinfo.revision );
- break;
- case CHUNK_TEXT:
- readString ( iff, buffer );
- text->Set ( buffer );
- break;
- case CHUNK_WAVE:
- readString ( iff, buffer );
- text->SetWave ( buffer );
- break;
- case CHUNK_WAVE_INFO:
- {
- WVINFO wvinfo;
- IFF_READ ( iff, &wvinfo, sizeof (wvinfo), error );
- text->WaveInfo.SetValid ( wvinfo.valid );
- text->WaveInfo.SetLo ( wvinfo.lo );
- text->WaveInfo.SetHi ( wvinfo.hi );
- break;
- }
- }
- }
- break;
- }
- case FORM_TRANS:
- {
- TRINFO trinfo;
- if ( ! (trans = new Translation ()))
- {
- goto error;
- }
- while ( IFF_NextChunk ( iff ))
- {
- switch ( iff->ChunkID )
- {
- case CHUNK_INFO:
- IFF_READ ( iff, &trinfo, sizeof (trinfo), error );
- trans->SetLangID ( trinfo.lang );
- trans->SetRevision ( trinfo.revision );
- break;
- case CHUNK_TEXT:
- readString ( iff, buffer );
- trans->Set ( buffer );
- break;
- case CHUNK_COMMENT:
- readString ( iff, buffer );
- trans->SetComment ( buffer );
- break;
- case CHUNK_WAVE_INFO:
- {
- WVINFO wvinfo;
- IFF_READ ( iff, &wvinfo, sizeof (wvinfo), error );
- trans->WaveInfo.SetValid ( wvinfo.valid );
- trans->WaveInfo.SetLo ( wvinfo.lo );
- trans->WaveInfo.SetHi ( wvinfo.hi );
- }
- break;
- }
- }
- if ( text )
- {
- text->AddTranslation ( trans );
- }
- else
- {
- delete trans;
- }
- trans = NULL;
- break;
- }
- }
- }
- if ( text )
- {
- if ( label )
- {
- label->AddText ( text );
- }
- else
- {
- db->AddObsolete ( text );
- }
- text = NULL;
- }
- if ( label )
- {
- count++;
- db->AddLabel ( label );
- label = NULL;
- if ( cb )
- {
- cb ();
- }
- }
- ok = TRUE;
-
- error:
- if ( label )
- {
- delete label;
- }
- if ( text )
- {
- delete text;
- }
- if ( trans )
- {
- delete trans;
- }
- if ( iff )
- {
- IFF_Close ( iff );
- }
- db->ClearChanges ();
- if ( !ok )
- {
- db->Clear ();
- }
- return ok;
- }
- int GetLabelCountDB ( char *filename )
- {
- IFF_FILE *iff = NULL;
- DBINFO dbinfo;
- int count = 0;
- if ( !(iff = IFF_Open ( filename ) ) )
- {
- goto error;
- }
- if ( !IFF_NextForm ( iff ) || iff->FormID != FORM_NOXDB )
- {
- goto error;
- }
- dbinfo.next_id = -1;
- dbinfo.num_labels = 0;
- while ( IFF_NextChunk ( iff ))
- {
- switch (iff->ChunkID )
- {
- case CHUNK_INFO:
- IFF_READ ( iff, &dbinfo, sizeof ( dbinfo ), error );
- break;
- }
- }
- count = dbinfo.num_labels;
- error:
- if ( iff )
- {
- IFF_Close ( iff );
- }
- return count;
- }
|