1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1999-2000 Revolution Software Ltd.
9 * This code is based on source code created by Revolution Software,
10 * used with permission.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 *
26 */
27
28 #ifndef ICB_GAME_OBJECT_H
29 #define ICB_GAME_OBJECT_H
30
31 #include "engines/icb/common/px_rcutypes.h"
32
33 namespace ICB {
34
35 // object run-time status values
36 enum _object_status { // possible values of object status field
37 OB_STATUS_NOT_HELD, // 0
38 OB_STATUS_HELD // 1 (when an object is held it does not get processed or drawn - it is excluded from the game)
39 };
40
41 #define OB_INIT_SCRIPT 0
42 #define OB_LOGIC_CONTEXT 1
43 #define OB_ACTION_CONTEXT 2
44
45 #define c_game_object c_compressed_game_object
46
47 class c_un_game_object {
48 // Only ob_status is made public. To access the other elements use
49 // the access functions. This is so that further changes to the structure
50 // can be catered for through the access functions, and not needed where
51 // any element is specifically referenced
52
53 public:
54 // Main access functions
55 const char *GetName() const; // Get a pointer to the object name
56 uint32 GetNoLvars() const; // Get the number of local variables
57 uint32 GetNoScripts() const; // Get the number of scripts
58 const char *GetScriptName(uint32) const; // Get the name of a script
GetSize()59 uint32 GetSize() { return (m_size); }
GetLvarInfoOffset()60 uint32 GetLvarInfoOffset() { return (m_var_table_offset); }
61
62 const char *GetScriptVariableName(uint32) const; // gets name
63 int32 GetVariable(const char *name) const; // get's number of named variable
64
65 int32 IsVariableString(uint32) const; // is variable a string (1=string, 0=int)
66
67 void SetIntegerVariable(uint32, int32); // Sets the value of an integer variable
68
69 int32 &GetIntegerVariable(uint32); // Get the value of an integer variable
70 const char *GetStringVariable(uint32) const; // Get the value of a string variable
71
GetStringValueOrDefault(const char * varName,const char * defaultStr)72 const char *GetStringValueOrDefault(const char *varName, const char *defaultStr) {
73 int32 var;
74 var = GetVariable(varName);
75 if (var == -1)
76 return defaultStr;
77 else
78 return GetStringVariable(var);
79 }
80
GetIntegerValueOrDefault(const char * varName,int32 defaultInt)81 int32 GetIntegerValueOrDefault(const char *varName, int32 defaultInt) {
82 int32 var;
83 var = GetVariable(varName);
84 if (var == -1)
85 return defaultInt;
86 else
87 return GetIntegerVariable(var);
88 }
89
90 // Let the new compressed object have full access to this one
91 friend class c_compressed_game_objectCreator;
92
93 protected: // The object data
94 uint32 m_size; // The size of the total data structure
95
96 uint32 m_var_table_offset;
97
98 public:
99 uint32 ob_status; // low level internal stuff - see enum _object_status
100
101 protected: // The rest of the data
102 // The offsets to the blocks of data. All offsets
103 // are from the start of the object
104 uint32 m_script_name_table_offset; // Offset to the script name table
105 uint32 m_lvars_offset; // Offset to the local variable data
106 uint32 m_name_offset; // Offset to the object name
107
108 // Variable and script count
109 uint32 m_noLvars; // How many lvars this object has
110 uint32 m_noScripts; // The number of scripts associated with this object
111 };
112
GetName()113 inline const char *c_un_game_object::GetName() const {
114 // Get a pointer to the object name
115 return ((const char *)(((const char *) this) + m_name_offset));
116 }
117
GetNoLvars()118 inline uint32 c_un_game_object::GetNoLvars() const {
119 // Get the number of local variables
120 return (m_noLvars);
121 }
122
GetNoScripts()123 inline uint32 c_un_game_object::GetNoScripts() const {
124 // Get the number of scripts
125 return (m_noScripts);
126 }
127
GetScriptName(uint32 scriptNo)128 inline const char *c_un_game_object::GetScriptName(uint32 scriptNo) const {
129 assert(scriptNo < m_noScripts);
130 return ((const char *)(((const char *) this) + ((const int32 *)(((const char *)this) + m_script_name_table_offset))[scriptNo]));
131 }
132
GetScriptVariableName(uint32 varNo)133 inline const char *c_un_game_object::GetScriptVariableName(uint32 varNo) const {
134 const char *currentPos;
135 const uint32 *table;
136
137 currentPos = (((const char *) this) + m_var_table_offset);
138 table = (const uint32 *)currentPos;
139 return currentPos + table[varNo * 2];
140 }
141
IsVariableString(uint32 varNo)142 inline int32 c_un_game_object::IsVariableString(uint32 varNo) const {
143 const char *currentPos;
144 const uint32 *table;
145
146 currentPos = (((const char *) this) + m_var_table_offset);
147 table = (const uint32 *)currentPos;
148 return table[varNo * 2 + 1];
149 }
150
GetVariable(const char * name)151 inline int32 c_un_game_object::GetVariable(const char *name) const {
152 const char *currentPos;
153 const uint32 *table;
154 int32 retValue;
155 int32 whichVar;
156
157 currentPos = (((const char *) this) + m_var_table_offset);
158 table = (const uint32 *)currentPos;
159
160 retValue = -1;
161
162 for (whichVar = 0; whichVar < (int32)m_noLvars; whichVar++) {
163 if (strcmp(name, currentPos + table[whichVar * 2]) == 0) {
164 retValue = whichVar;
165 whichVar = (int32)m_noLvars;
166 }
167 }
168
169 return retValue;
170 }
171
SetIntegerVariable(uint32 lvar,int32 val)172 inline void c_un_game_object::SetIntegerVariable(uint32 lvar, int32 val) {
173 assert(lvar < m_noLvars);
174 (((int32 *)(((char *)this) + m_lvars_offset))[lvar]) = val;
175 }
176
GetIntegerVariable(uint32 lvar)177 inline int32 &c_un_game_object::GetIntegerVariable(uint32 lvar) {
178 // Get an lvar value
179 assert(lvar < m_noLvars);
180 return (((int32 *)(((char *)this) + m_lvars_offset))[lvar]);
181 }
182
GetStringVariable(uint32 lvar)183 inline const char *c_un_game_object::GetStringVariable(uint32 lvar) const {
184 // Get an lvar value
185 assert(lvar < m_noLvars);
186 return (((const char *) this) + ((const int32 *)(((const char *)this) + m_lvars_offset))[lvar]);
187 }
188
189 class c_compressed_game_object {
190 // Only ob_status is made public. To access the other elements use
191 // the access functions. This is so that further changes to the structure
192 // can be catered for through the access functions, and not needed where
193 // any element is specifically referenced
194
195 public:
196 // Main access functions
197 const char *GetName() const; // Get a pointer to the object name
198 uint32 GetNoLvars() const; // Get the number of local variables
199 uint32 GetNoScripts() const; // Get the number of scripts
GetSize()200 uint32 GetSize() { return (m_size); }
201
202 // Using the hash system you cannot get names, only hashes
203 uint32 GetScriptNameFullHash(uint32) const;
204 uint32 GetScriptNamePartHash(uint32) const;
205
206 const char *GetScriptVariableName(uint32) const; // gets name
207 int32 GetVariable(const char *name) const; // get's number of named variable
208
209 int32 IsVariableString(uint32) const; // is variable a string (1=string, 0=int)
210
211 void SetIntegerVariable(uint32, int32); // Sets the value of an integer variable
212
213 int32 &GetIntegerVariable(uint32); // Get the value of an integer variable
214 const char *GetStringVariable(uint32) const; // Get the value of a string variable
215
GetStringValueOrDefault(const char * varName,const char * defaultStr)216 const char *GetStringValueOrDefault(const char *varName, const char *defaultStr) {
217 int32 var;
218 var = GetVariable(varName);
219 if (var == -1)
220 return defaultStr;
221 else
222 return GetStringVariable(var);
223 }
224
GetIntegerValueOrDefault(const char * varName,int32 defaultInt)225 int32 GetIntegerValueOrDefault(const char *varName, int32 defaultInt) {
226 int32 var;
227 var = GetVariable(varName);
228 if (var == -1)
229 return defaultInt;
230 else
231 return GetIntegerVariable(var);
232 }
233
234 friend class c_compressed_game_objectCreator;
235
236 protected: // The object data
237 uint32 m_size; // The size of the total data structure
238
239 uint32 m_var_table_offset;
240
241 public:
242 uint32 ob_status; // low level internal stuff - see enum _object_status
243
244 protected: // The rest of the data
245 // The offsets to the blocks of data. All offsets
246 // are from the start of the object
247
248 uint32 m_script_name_hash_table_offset; // Offset to the script name table
249
250 uint32 m_lvars_offset; // Offset to the local variable data
251 uint32 m_name_offset; // Offset to the object name
252
253 // Variable and script count
254 uint32 m_noLvars; // How many lvars this object has
255 uint32 m_noScripts; // The number of scripts associated with this object
256
257 /* This data is then followed by:
258
259 Null terminated object name
260 Object variable information block
261 Script names information block
262 */
263 };
264
GetName()265 inline const char *c_compressed_game_object::GetName() const {
266 // Get a pointer to the object name
267 return ((const char *)(((const char *) this) + m_name_offset));
268 }
269
GetNoLvars()270 inline uint32 c_compressed_game_object::GetNoLvars() const {
271 // Get the number of local variables
272 return (m_noLvars);
273 }
274
GetNoScripts()275 inline uint32 c_compressed_game_object::GetNoScripts() const {
276 // Get the number of scripts
277 return (m_noScripts);
278 }
279
GetScriptNameFullHash(uint32 scriptNo)280 inline uint32 c_compressed_game_object::GetScriptNameFullHash(uint32 scriptNo) const {
281 assert(scriptNo < m_noScripts);
282 return (((const int32 *)(((const char *)this) + m_script_name_hash_table_offset))[scriptNo * 2]);
283 }
284
GetScriptNamePartHash(uint32 scriptNo)285 inline uint32 c_compressed_game_object::GetScriptNamePartHash(uint32 scriptNo) const {
286 assert(scriptNo < m_noScripts);
287 return (((const int32 *)(((const char *)this) + m_script_name_hash_table_offset))[scriptNo * 2 + 1]);
288 }
289
GetScriptVariableName(uint32 varNo)290 inline const char *c_compressed_game_object::GetScriptVariableName(uint32 varNo) const {
291 const char *currentPos;
292 const uint32 *table;
293
294 currentPos = (((const char *) this) + m_var_table_offset);
295 table = (const uint32 *)currentPos;
296 return ((const char *)this) + table[varNo * 2];
297 }
298
IsVariableString(uint32 varNo)299 inline int32 c_compressed_game_object::IsVariableString(uint32 varNo) const {
300 const char *currentPos;
301 const uint32 *table;
302
303 currentPos = (((const char *) this) + m_var_table_offset);
304 table = (const uint32 *)currentPos;
305 return table[varNo * 2 + 1];
306 }
307
GetVariable(const char * name)308 inline int32 c_compressed_game_object::GetVariable(const char *name) const {
309 const char *currentPos;
310 const uint32 *table;
311 int32 retValue;
312 uint32 whichVar;
313
314 currentPos = (((const char *) this) + m_var_table_offset);
315 table = (const uint32 *)currentPos;
316
317 retValue = -1;
318
319 for (whichVar = 0; whichVar < m_noLvars; whichVar++) {
320 if (strcmp(name, ((const char *) this) + table[whichVar * 2]) == 0) {
321 retValue = whichVar;
322 whichVar = (int32)m_noLvars;
323 }
324 }
325
326 return retValue;
327 }
328
SetIntegerVariable(uint32 lvar,int32 val)329 inline void c_compressed_game_object::SetIntegerVariable(uint32 lvar, int32 val) {
330 assert(lvar < m_noLvars);
331 (((int32 *)(((char *)this) + m_lvars_offset))[lvar]) = val;
332 }
333
GetIntegerVariable(uint32 lvar)334 inline int32 &c_compressed_game_object::GetIntegerVariable(uint32 lvar) {
335 // Get an lvar value
336 assert(lvar < m_noLvars);
337 return (((int32 *)(((char *)this) + m_lvars_offset))[lvar]);
338 }
339
GetStringVariable(uint32 lvar)340 inline const char *c_compressed_game_object::GetStringVariable(uint32 lvar) const {
341 // Get an lvar value
342 assert(lvar < m_noLvars);
343 return (((const char *) this) + ((const int32 *)(((const char *)this) + m_lvars_offset))[lvar]);
344 }
345
346 class CSettableGameObject : public c_un_game_object {
347 public:
348 // Setfunctions
349 void SetSize(uint32); // Set the object size
350 void SetVarTable(uint32); // set var table offset
351 void Set_ob_status(uint32); // Set ob_status
352 void SetScriptNameTableOffset(uint32); // Set the name table offset
353 void SetLvarDataOffsetTable(uint32); // Set the lvars offset
354
355 void SetNoLvars(uint32); // Set the number of variables
356 void SetNoScripts(uint32); // Set the number of scripts
357 void SetNameOffset(uint32); // Set the name offset
358 };
359
SetSize(uint32 size)360 inline void CSettableGameObject::SetSize(uint32 size) {
361 // Set the object size
362 m_size = size;
363 m_var_table_offset = 0xdeadbeef;
364 }
365
SetVarTable(uint32 o)366 inline void CSettableGameObject::SetVarTable(uint32 o) {
367 // Set the object size
368 m_var_table_offset = o;
369 }
370
Set_ob_status(uint32 status)371 inline void CSettableGameObject::Set_ob_status(uint32 status) {
372 // Set ob_status
373 ob_status = status;
374 }
375
SetNoLvars(uint32 n)376 inline void CSettableGameObject::SetNoLvars(uint32 n) {
377 // Get the number of local variables
378 m_noLvars = n;
379 }
380
SetNoScripts(uint32 n)381 inline void CSettableGameObject::SetNoScripts(uint32 n) {
382 // Get the number of scripts
383 m_noScripts = n;
384 }
385
SetScriptNameTableOffset(uint32 o)386 inline void CSettableGameObject::SetScriptNameTableOffset(uint32 o) {
387 // Set the name table offset
388 m_script_name_table_offset = o;
389 }
390
SetLvarDataOffsetTable(uint32 o)391 inline void CSettableGameObject::SetLvarDataOffsetTable(uint32 o) {
392 // Set the lvars offset
393 m_lvars_offset = o;
394 }
395
SetNameOffset(uint32 o)396 inline void CSettableGameObject::SetNameOffset(uint32 o) {
397 // Set the name offset
398 m_name_offset = o;
399 }
400
401 } // End of namespace ICB
402
403 #endif
404