1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "DLGImporter.h"
23 #include "FileStream.h"
24 #include "Interface.h"
35 if (str
&& autoFree
) {
40 bool DLGImp::Open(DataStream
* stream
, bool autoFree
)
45 if (str
&& this->autoFree
) {
49 this->autoFree
= autoFree
;
51 str
->Read( Signature
, 8 );
52 if (strnicmp( Signature
, "DLG V1.0", 8 ) != 0) {
53 printMessage( "DLGImporter", "Not a valid DLG File...", WHITE
);
54 printStatus( "ERROR", LIGHT_RED
);
58 str
->ReadDword( &StatesCount
);
59 str
->ReadDword( &StatesOffset
);
61 if (StatesOffset
== 0x34 ) {
67 str
->ReadDword( &TransitionsCount
);
68 str
->ReadDword( &TransitionsOffset
);
69 str
->ReadDword( &StateTriggersOffset
);
70 str
->ReadDword( &StateTriggersCount
);
71 str
->ReadDword( &TransitionTriggersOffset
);
72 str
->ReadDword( &TransitionTriggersCount
);
73 str
->ReadDword( &ActionsOffset
);
74 str
->ReadDword( &ActionsCount
);
76 str
->ReadDword( &Flags
);
84 Dialog
* DLGImp::GetDialog()
89 Dialog
* d
= new Dialog();
91 d
->TopLevelCount
= StatesCount
;
92 d
->Order
= (unsigned int *) calloc (StatesCount
, sizeof(unsigned int *) );
93 d
->initialStates
= (DialogState
**) calloc (StatesCount
, sizeof(DialogState
*) );
94 for (unsigned int i
= 0; i
< StatesCount
; i
++) {
95 DialogState
* ds
= GetDialogState( d
, i
);
96 d
->initialStates
[i
] = ds
;
101 DialogState
* DLGImp::GetDialogState(Dialog
*d
, unsigned int index
)
103 DialogState
* ds
= new DialogState();
105 str
->Seek( StatesOffset
+ ( index
* 16 ), GEM_STREAM_START
);
106 ieDword FirstTransitionIndex
;
107 ieDword TriggerIndex
;
108 str
->ReadDword( &ds
->StrRef
);
109 str
->ReadDword( &FirstTransitionIndex
);
110 str
->ReadDword( &ds
->transitionsCount
);
111 str
->ReadDword( &TriggerIndex
);
112 ds
->trigger
= GetStateTrigger( TriggerIndex
);
113 ds
->transitions
= GetTransitions( FirstTransitionIndex
, ds
->transitionsCount
);
114 if (TriggerIndex
<StatesCount
)
115 d
->Order
[TriggerIndex
] = index
;
119 DialogTransition
** DLGImp::GetTransitions(unsigned int firstIndex
, unsigned int count
)
121 DialogTransition
** trans
= ( DialogTransition
** )
122 malloc( count
*sizeof( DialogTransition
* ) );
123 for (unsigned int i
= 0; i
< count
; i
++) {
124 trans
[i
] = GetTransition( firstIndex
+ i
);
129 DialogTransition
* DLGImp::GetTransition(unsigned int index
)
131 if (index
>= TransitionsCount
) {
134 //32 = sizeof(Transition)
135 str
->Seek( TransitionsOffset
+ ( index
* 32 ), GEM_STREAM_START
);
136 DialogTransition
* dt
= new DialogTransition();
137 str
->ReadDword( &dt
->Flags
);
138 str
->ReadDword( &dt
->textStrRef
);
139 if (!(dt
->Flags
& IE_DLG_TR_TEXT
)) {
140 dt
->textStrRef
= 0xffffffff;
142 str
->ReadDword( &dt
->journalStrRef
);
143 if (!(dt
->Flags
& IE_DLG_TR_JOURNAL
)) {
144 dt
->journalStrRef
= 0xffffffff;
146 ieDword TriggerIndex
;
148 str
->ReadDword( &TriggerIndex
);
149 str
->ReadDword( &ActionIndex
);
150 str
->ReadResRef( dt
->Dialog
);
151 str
->ReadDword( &dt
->stateIndex
);
152 if (dt
->Flags
&IE_DLG_TR_TRIGGER
) {
153 dt
->trigger
= GetTransitionTrigger( TriggerIndex
);
158 if (dt
->Flags
& IE_DLG_TR_ACTION
) {
159 dt
->action
= GetAction( ActionIndex
);
167 DialogString
* DLGImp::GetStateTrigger(unsigned int index
)
169 if (index
>= StateTriggersCount
) {
172 //8 = sizeof(VarOffset)
173 str
->Seek( StateTriggersOffset
+ ( index
* 8 ), GEM_STREAM_START
);
174 ieDword Offset
, Length
;
175 str
->ReadDword( &Offset
);
176 str
->ReadDword( &Length
);
177 //a zero length trigger counts as no trigger
178 //a // comment counts as true(), so we simply ignore zero
179 //length trigger text like it isn't there
183 DialogString
* ds
= new DialogString();
184 str
->Seek( Offset
, GEM_STREAM_START
);
185 char* string
= ( char* ) malloc( Length
+ 1 );
186 str
->Read( string
, Length
);
188 ds
->strings
= GetStrings( string
, ds
->count
);
193 DialogString
* DLGImp::GetTransitionTrigger(unsigned int index
)
195 if (index
>= TransitionTriggersCount
) {
198 str
->Seek( TransitionTriggersOffset
+ ( index
* 8 ), GEM_STREAM_START
);
199 ieDword Offset
, Length
;
200 str
->ReadDword( &Offset
);
201 str
->ReadDword( &Length
);
202 DialogString
* ds
= new DialogString();
203 str
->Seek( Offset
, GEM_STREAM_START
);
204 char* string
= ( char* ) malloc( Length
+ 1 );
205 str
->Read( string
, Length
);
207 ds
->strings
= GetStrings( string
, ds
->count
);
212 DialogString
* DLGImp::GetAction(unsigned int index
)
214 if (index
>= ActionsCount
) {
217 str
->Seek( ActionsOffset
+ ( index
* 8 ), GEM_STREAM_START
);
218 ieDword Offset
, Length
;
219 str
->ReadDword( &Offset
);
220 str
->ReadDword( &Length
);
221 DialogString
* ds
= new DialogString();
222 str
->Seek( Offset
, GEM_STREAM_START
);
223 char* string
= ( char* ) malloc( Length
+ 1 );
224 str
->Read( string
, Length
);
226 ds
->strings
= GetStrings( string
, ds
->count
);
231 int GetActionLength(const char* string
)
236 const char* poi
= string
;
238 for (i
= 0; *poi
; i
++) {
249 if (quotes
&& level
) {
263 #define MyIsSpace(c) (((c) == ' ') || ((c) == '\n') || ((c) == '\r'))
265 /* this function will break up faulty script strings that lack the CRLF
266 between commands, common in PST dialog */
267 char** DLGImp::GetStrings(char* string
, unsigned int& count
)
295 if (quotes
&& level
) {
312 char** strings
= ( char** ) calloc( count
, sizeof( char* ) );
313 if (strings
== NULL
) {
318 for (int i
= 0; i
< (int)count
; i
++) {
319 while (MyIsSpace( *poi
))
321 int len
= GetActionLength( poi
);
322 if((*poi
=='/') && (*(poi
+1)=='/') ) {
327 strings
[i
] = ( char * ) malloc( len
+ 1 );
329 for (j
= 0; len
; poi
++,len
--) {
332 strings
[i
][j
++] = *poi
;
339 #include "plugindef.h"
341 GEMRB_PLUGIN(0x1970D894, "DLG File Importer")
342 PLUGIN_CLASS(IE_DLG_CLASS_ID
, DLGImp
)