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