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_OBSTRUCTS
29 #define ICB_OBSTRUCTS
30 
31 #include "engines/icb/common/px_common.h"
32 #include "engines/icb/common/px_game_object.h"
33 #include "engines/icb/common/px_route_barriers.h"
34 #include "engines/icb/common/px_array.h"
35 #include "engines/icb/common/px_string.h"
36 #include "engines/icb/animation_mega_set.h"
37 #include "engines/icb/p4_generic.h"
38 #include "engines/icb/string_vest.h"
39 #include "engines/icb/route_manager.h"
40 #include "engines/icb/breath.h"
41 #include "engines/icb/gfx/rlp_api.h"
42 #include "engines/icb/common/px_bones.h"
43 
44 // depth of script logic tree for game objects - 3 is same as Broken Sword games
45 #define TREE_SIZE 3
46 
47 namespace ICB {
48 
49 // high level walk or run mode for mega/player
50 // used by high level routing and interaction functionality
51 enum __motion { __MOTION_WALK, __MOTION_RUN };
52 
53 // high level armed state
54 // this will be used to construct the animation path name
55 enum __weapon {
56 	__NOT_ARMED,
57 	__GUN,
58 	__CROUCH_NOT_ARMED,
59 	__CROUCH_GUN,
60 	__TOTAL_WEAPONS, // used for searches
61 	__NOT_SET        // default - will cause error in fn-set-voxel-path
62 };
63 
64 // Added this enum for object type field.
65 enum __object_type { __NO_TYPE_SET = 0, __BUTTON_OPERATED_DOOR, __RECHARGE_POINT, __ORGANIC_MEGA, __NON_ORGANIC_MEGA, __REMORA_CARRIER, __RECHARGE_POINT_WITH_EMP, __AUTO_DOOR };
66 
67 #define MAX_WEAPON_NAME_LENGTH 16
68 
69 extern char weapon_text[__TOTAL_WEAPONS][MAX_WEAPON_NAME_LENGTH];
70 extern bool8 armed_state_table[__TOTAL_WEAPONS];
71 extern bool8 crouch_state_table[__TOTAL_WEAPONS];
72 
73 #define MAX_CHAR_NAME_LENGTH 32
74 #define MAX_OUTFIT_NAME_LENGTH 16
75 #define MAX_CUSTOM_NAME_LENGTH 16
76 
77 #define IMAGE_PATH_STR_LEN 144
78 #define BASE_PATH_STR_LEN 144
79 #define ANIM_NAME_STR_LEN 144
80 #define PALETTE_STR_LEN ENGINE_STRING_LEN
81 
82 // game objects with voxel images need one of these
83 // assigned at session start when objects are initialised
84 class _vox_image { // this is badly named - frame info or something
85 
86 private:
87 	int8 anim_table[__TOTAL_ANIMS];
88 
89 public:
90 	void ___init(const char *chr, const char *set, __weapon weapon);
91 
92 	// temprarily store these for swapping between voxel and polygons (so we can call ___init() again...
93 	// when the voxels go these things can go
94 	char palette[PALETTE_STR_LEN];
95 	char temp_chr[128];
96 	char temp_set[128];
97 	__weapon temp_weapon;
98 	char alternativeImagePath[128]; // this stores the pcp path for animations (for getting the raj files instead of rai files...
99 	char alternativeBasePath[128];  // this is same as base path but is pcp (on voxels) - isn't required for polys and can go when we
100 										// ditch
101 	// setting functions
102 	bool8 Init_custom_animation(const char *anim_name);
103 	bool8 Find_anim_type(__mega_set_names *anim, const char *name);
104 	bool8 Set_texture(const char *texture_name);
105 	bool8 Set_palette(const char *palette_name);
106 	bool8 Set_mesh(const char *mesh_name);
107 	void Promote_non_generic();
108 	int8 IsAnimTable(int32 i);
109 	void MakeAnimEntry(int32 i);
110 
111 	// those hashs in full
112 
113 	uint32 anim_name_hash[__TOTAL_ANIMS];
114 	uint32 info_name_hash[__TOTAL_ANIMS];
115 
116 	uint32 mesh_hash;        // the name of the base mesh
117 	uint32 shadow_mesh_hash; // the name of the base shadow mesh
118 	uint32 palette_hash;     // the name of the palette
119 	uint32 texture_hash;     // the name of the texture (which includes a default palette)
120 	uint32 pose_hash;        // the name of the ordinary pose/accessory mesh
121 	uint32 custom_pose_hash; // the name of the "custom" pose/accessory mesh
122 
123 	// base path
124 
125 	char base_path[BASE_PATH_STR_LEN];
126 	uint32 base_path_hash; // hash value of the base_path string
127 
128 	// init'ed by _vox_image::_vox_image which is created by fn-set-voxel-image-path
129 	// path primitives - require to build path+name to non generic custom specifics
130 	char image_path[IMAGE_PATH_STR_LEN]; // i.e. karl\, karl_in_coat\, etc. Initially set by objects init script and then by
131 	                                     // interaction/logic
132 
133 	bool8 has_custom_path_built; // says whether or not the current custom anim path has been built - done for preloader which builds
134 	                             // filename early
135 
136 	// bone deformations
137 
138 	BoneDeformation neckBone;
139 	BoneDeformation jawBone;
140 	BoneDeformation lookBone;
141 	SVECTOR
142 	scriptedLookBoneTarget; // this is the one the scripts set - if this is not <0,0,0> then these values override the look targets
143 
144 	uint8 padding2;
145 	uint8 padding3;
146 
147 	// on the pc we store these strings
148 	char anim_name[__TOTAL_ANIMS][ANIM_NAME_STR_LEN];
149 	char info_name[__TOTAL_ANIMS][ANIM_NAME_STR_LEN];
150 	char mesh_name[ANIM_NAME_STR_LEN];
151 	char shadow_mesh_name[ANIM_NAME_STR_LEN];
152 	char texture_name[PALETTE_STR_LEN];
153 	char palette_name[PALETTE_STR_LEN];
154 	char pose_name[ANIM_NAME_STR_LEN];
155 	char custom_pose_name[ANIM_NAME_STR_LEN];
156 
157 	// and so the access functions return the
158 	// actual thing
159 
get_anim_name(int32 i)160 	char *get_anim_name(int32 i) { return anim_name[i]; }
get_info_name(int32 i)161 	char *get_info_name(int32 i) { return info_name[i]; }
get_mesh_name()162 	char *get_mesh_name() { return mesh_name; }
get_shadow_mesh_name()163 	char *get_shadow_mesh_name() { return shadow_mesh_name; }
get_texture_name()164 	char *get_texture_name() { return texture_name; }
get_palette_name()165 	char *get_palette_name() { return palette_name; }
get_pose_name()166 	char *get_pose_name() { return pose_name; }
get_custom_pose_name()167 	char *get_custom_pose_name() { return custom_pose_name; }
168 
169 };
170 
IsAnimTable(int32 i)171 inline int8 _vox_image::IsAnimTable(int32 i) {
172 	// If the table has not been set yet : make the anim entry which will set anim_table entry to correct value
173 	if (anim_table[i] == (int8)-1)
174 		MakeAnimEntry(i);
175 	return anim_table[i];
176 }
177 
178 #define MAX_bars 96
179 
180 // Handy constants for accesing the viewState member variable
181 // <last_cycle_state>_<this_cycle_state>
182 // The <last_cycle_state> (1 or 0) is in bit 0
183 // The <this_cycle_state> (1 or 0) is in bit 1
184 enum CameraStateEnum { OFF_CAMERA = 0x0, ON_CAMERA = 0x1 };
185 
186 #define THIS_CYCLE_SHIFT 1
187 #define LAST_CYCLE_SHIFT 0
188 #define LAST_CYCLE_MASK ((1 << THIS_CYCLE_SHIFT) - 1)
189 
190 #define MAKE_VIEW_STATE(last, this) (last | (this << THIS_CYCLE_SHIFT))
191 
192 // off camera last cycle and this cycle : 0x0
193 #define OFF_OFF_CAMERA MAKE_VIEW_STATE(OFF_CAMERA, OFF_CAMERA)
194 
195 // on camera last cycle and off this cycle : 0x1
196 #define ON_OFF_CAMERA MAKE_VIEW_STATE(ON_CAMERA, OFF_CAMERA)
197 
198 // off camera last cycle and on this cycle : 0x2
199 #define OFF_ON_CAMERA MAKE_VIEW_STATE(OFF_CAMERA, ON_CAMERA)
200 
201 // on camera last cycle and on this cycle
202 #define ON_ON_CAMERA MAKE_VIEW_STATE(ON_CAMERA, ON_CAMERA)
203 
204 class _mega { // mega logic specific
205 public:
206 	_parent_box *cur_parent; // our owner parent box
207 	uint32 par_number;       // for players abar list update
208 	uint32 cur_slice;        // for speedups
209 
210 	uint32 barrier_list[MAX_bars]; // including animating ones
211 	uint32 nudge_list[MAX_bars];   // only player builds this - i cant be bothered with putting it in the player struct however
212 
213 	uint32 number_of_barriers;  // kept for safety
214 	uint32 number_of_nudge;     // kept for safety
215 	uint32 number_of_animating; // kept for safety
216 
217 	__mega_set_names next_anim_type; // queued anim to play after current link anim
218 
219 	// turn on spot pan stuff
220 	PXfloat target_pan;        // actual relative distance to turn
221 	PXfloat actual_target_pan; // actual target pan to clip to if necessary
222 
223 	PXfloat auto_target_pan; // target pan for auto engine pans - i.e. when routing\bumping
224 
225 	PXfloat looking_pan;
226 
227 	uint32 target_id;    // hurray! Its back again!! Id of target object
228 	PXvector target_xyz; // target coordinate - used for position correcting, etc
229 
230 	__weapon weapon; // what weapon the mega is carrying
231 	__motion motion; // walking, running, used by high level anim functions
232 
233 	// To maintain allignment, the sizes of these arrays must be a multiple of 4.
234 	char chr_name[MAX_CHAR_NAME_LENGTH];     // i.e. cord
235 	char anim_set[MAX_OUTFIT_NAME_LENGTH];   // i.e. casual_wear
236 	char custom_set[MAX_CUSTOM_NAME_LENGTH]; // i.e. mine
237 
238 	// this is the real game-world coordinate
239 	PXvector actor_xyz;
240 	PXvector pushed_actor_xyz;
241 
242 	uint32 m_phase;
243 	_route_description m_main_route;
244 
245 	Breath breath;
246 
247 	// the dynamic lamp (with one state only) and a switch as to whether it is on or off (if >0 then it is on for dynLightOn cycles, if
248 	// 0 then off, if -1 on until explicitly turned off)
249 	PSXLamp dynLight;                      // the lamp, filled in partly by logic and partly by stagedraw (rotating with character)
250 	int32 dynLightOn;                      // if 0-off, >0-on for n cycles (count down), -1 - constant until turned off
251 	int16 dynLightX, dynLightY, dynLightZ; // cm from centre of character (hip) (hip hurray!)
252 
253 	SVECTOR bulletPos;
254 	int16 bulletDX;
255 	int16 bulletDY;
256 	int16 bulletInitialHeight;
257 
258 	uint8 bulletBounced, bulletColour;
259 
260 	bool8 bulletOn;
261 
262 	// NOTE THAT THE FOLLOWING DATA MEMBERS HAVE BEEN ARRANGED TO MAKE 4-BYTE ALLIGNMENT CLEAR.
263 
264 	// A status flag containing info if the MEGA was in view last cycle,
265 	// and is in view this cycle, a change in view state causes an event
266 	// to be sent to the MEGA saying "oncamera" "offcamera"
267 	bool8 pushed;
268 	uint8 viewState;
269 	bool8 interacting; // yes or no to avoid problems interacting with id=0 !!!!
270 	bool8 turn_dir;    // 0 right       1 left
271 	bool8 custom;
272 	bool8 has_exclusive_coords; // if yes then this object will not have coordinates saved to micro-session - player and chi
273 
274 	bool8 is_evil;          // true if guard or robot, or some other horrible creature, false if lovely chi or some sort of scientist or whatever.
275 	bool8 make_remora_beep; // true for robots so the remora picks them up
276 
277 	uint8 inShadePercentage; // how much light to be in shadow
278 	bool8 in_shade;          // Set to TRUE8 when mega is in shade, FALSE8 otherwise.
279 	bool8 use_strike_script; // call a script instead of hitting object
280 	bool8 use_fire_script;   // call a script instead of shooting object
281 
282 	bool8 on_players_floor;
283 	uint8 speech_red;
284 	uint8 speech_green;
285 	uint8 speech_blue;
286 
287 	uint8 anim_speed;    // 1 is normal
288 	bool8 reverse_route; // routing backwards
289 	bool8 is_shooting;   // are we firing the gun ?
290 	bool8 drawShadow;    // sometimes turned off
291 
292 	// generic async
293 	bool8 asyncing;        // is loading a generic anim file
294 	uint8 async_list_pos;  // position in current file list/queue
295 	__weapon async_weapon; // current set used by asyncer
296 
297 	// footsteps
298 	int8 footstep_status;   // current foot left/right status...
299 	uint8 footstep_weight;  // weight of footstep (100 is Cord) 255 maximum...
300 	bool8 footstep_special; // whether special or not...
301 
302 	bool8 display_me; // high level character draw clip
303 
304 	// generic stair-----------------------------------------------------------
305 	// stuff for shadow correction on stairs
306 	bool8 on_stairs;
307 	PXreal bottom_x, bottom_z;
308 	PXreal top_x, top_z;
309 	PXfloat stair_pan;
310 
311 	uint8 extrap_size;           // route barrier extrapolation size
312 	bool8 dead;                  // dead or not?
313 	uint32 slice_hold_tolerance; // y distance to stray before slice hold kicks back in
314 	uint8 idle_count;            // how int32 just been stood
315 
316 	// camera control
317 	bool8 y_locked;
318 	PXreal y_lock;
319 
320 	void ___init();
321 
322 	void InitCartridgeCase(SVECTOR *initPos, int16 initialHeight);
323 
324 	bool8 Fetch_armed_status();
325 	bool8 Fetch_custom();
326 	__weapon Fetch_pose();
327 	bool8 Is_crouched();
328 
329 	// Move this cycle view state flag into last cycle view state
330 	void ShiftViewState();
331 	// Set the view state for this cycle
332 	void SetThisViewState(enum CameraStateEnum status);
333 
334 	void InitDynamicLight();
335 
336 	// SetDynamicLight(cycles,r,g,b,x,y,z,falloff);
337 	// where cycles is number of cycles to stay on (-1 for constant, 0 for off)
338 	// falloff is maximum extent of light, falloff starts 10% of the way from it...
339 	void SetDynamicLight(int32 in_cycles, int32 in_r, int32 in_g, int32 in_b, int32 in_x, int32 in_y, int32 in_z, int32 falloff);
340 
RemoveDynamicLight()341 	void RemoveDynamicLight() { dynLightOn = 0; }
342 };
343 
344 // Move this cycle view state flag into last cycle view state
ShiftViewState()345 inline void _mega::ShiftViewState() { viewState = (uint8)((viewState >> THIS_CYCLE_SHIFT) & (LAST_CYCLE_MASK)); }
346 
347 // Set the view state for this cycle
348 // status is ON_CAMERA or OFF_CAMERA
SetThisViewState(enum CameraStateEnum status)349 inline void _mega::SetThisViewState(enum CameraStateEnum status) { viewState = (uint8)((viewState & LAST_CYCLE_MASK) | ((int)status << THIS_CYCLE_SHIFT)); }
350 
351 enum _object_image_type { PROP, VOXEL };
352 
353 enum _hold_mode {
354 	prop_camera_hold = 1,
355 	mega_player_floor_hold,  // hold when not on player floor
356 	mega_initial_floor_hold, // hold until on player floor then release forever
357 	mega_slice_hold,         // hold if not on plyer y then release after a set y distance
358 	none
359 };
360 
361 enum _big_mode {
362 	__SCRIPT,
363 	__NO_LOGIC,
364 	__MEGA_SLICE_HELD,
365 	__MEGA_PLAYER_FLOOR_HELD,
366 	__MEGA_INITIAL_FLOOR_HELD,
367 	__CUSTOM_SIMPLE_ANIMATE,
368 	__CUSTOM_BUTTON_OPERATED_DOOR,
369 	__CUSTOM_AUTO_DOOR
370 };
371 
372 #define MAX_list 10
373 
374 #define THREE_SIXTY_INTERACT 2
375 #define PROP_CROUCH_INTERACT 1
376 
377 // game object logic structure
378 class _logic {
379 public:
380 	uint32 ms_timer; // timer for this object DEBUGGING
381 	uint32 looping;
382 	uint32 old_looping;       // logic controller for script functions - such as animators
383 	uint32 pause;             // logic pause value
384 	uint32 anim_direction;    // 0 forward, else backward
385 	_object_status ob_status; // low level internal stuff - see enum _object_status   //held/not held...
386 	_big_mode big_mode;
387 	uint32 owner_floor_rect;       // current floor rect number
388 	uint32 total_list;             // number of items in list
389 	uint32 list[MAX_list];         // a list available to script logic
390 	uint32 list_result;            // tempory holding place for the result of list checking functions - that must return true/false
391 	uint32 sfxVars[3];             // up to 3 different sound effect modifiers per type of object (gunshot,ricochet,tinkle) (door open,door close)
392 	uint32 logic_level;            // what level?                  0 is the context switch, 1 is the main logic, 2+ are gosubs from level 1
393 	char *logic[TREE_SIZE];        // pointers to the raw compiled script data
394 	char *logic_ref[TREE_SIZE];    // holds the initial pointers
395 	_object_image_type image_type; // object is PROP or VOXEL based
396 	__object_type object_type;
397 	uint32 conversation_uid;       // id of conversation we may be in
398 	// type of current animation - use to index into voxel_image->anim_name;
399 	__mega_set_names cur_anim_type;
400 	uint32 anim_pc;         // pc of current animation - i.e. position in track\voxel frame file
401 	_vox_image *voxel_info; // extra graphic info
402 	_mega *mega;            // extra mega info
403 	// prop xyz coord derived from nico
404 	PXvector prop_xyz;
405 	PXfloat prop_interact_pan;
406 	PXfloat pan;        // engine pan
407 	PXfloat pan_adjust; // pan neutraliser for frames that include a pan from the grab - i.e. turn on spot
408 	// this is a distance to look up when looking at the object, only useful:
409 	int32 look_height; // -1 means not used so don't do...
410 	// auto panning stuff
411 	PXfloat auto_display_pan;
412 	//  timers
413 	uint32 cycle_time;
414 	uint32 slowest_cycle_time;
415 	_hold_mode hold_mode;
416 
417 	int16 sparkleX;
418 	int16 sparkleY;
419 
420 	int16 sparkleZ;
421 	bool8 player_can_interact; // interactable true or false
422 	bool8 context_request;     // crude switch to force context script rerun
423 
424 	bool8 prop_coords_set;      // has a prop object been asigned coordinates - for development safety
425 	uint8 three_sixty_interact; // true then overides the normal tight pan approach to interaction - like a mega in-fact
426 	bool8 auto_panning;
427 	bool8 do_not_disturb; // If true, object will not rerun logic context.
428 
429 	bool8 camera_held;
430 	bool8 prop_on_this_screen; // actually on this camera - used by closed doors
431 	bool8 sparkleOn;           // whether or not sparkle is on
432 	bool8 padding;             // Pad the structure
433 
434 private:
435 	char ob_name[ENGINE_STRING_LEN];
436 
437 public:
438 	void ___init(const char *name);
439 	void ___destruct();
440 
GetName()441 	const char *GetName() const { return ob_name; }
442 
GetPosition(PXreal & x,PXreal & y,PXreal & z)443 	void GetPosition(PXreal &x, PXreal &y, PXreal &z) const {
444 		bool8 isActor = (bool8)(image_type == VOXEL);
445 
446 		if (isActor) {
447 			x = mega->actor_xyz.x;
448 			y = mega->actor_xyz.y;
449 			z = mega->actor_xyz.z;
450 		} else {
451 			x = prop_xyz.x;
452 			y = prop_xyz.y;
453 			z = prop_xyz.z;
454 		}
455 	}
456 };
457 
458 } // End of namespace ICB
459 
460 #endif
461