1 /***** HModel.h *****/
2 
3 #ifndef _hmodel_h
4 #define _hmodel_h 1
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 #include "decal.h"
10 #include "psnd.h"
11 
12 /* CDF 15/9/97 New Damage System */
13 typedef struct sb_health_bitfield
14 {
15 	unsigned int AcidResistant:1;
16 	unsigned int FireResistant:1;
17 	unsigned int ElectricResistant:1;
18 	unsigned int PerfectArmour:1; /* For true aliens! */
19 	unsigned int ElectricSensitive:1; /* For Xenoborgs */
20 	unsigned int Combustability:2;
21 	unsigned int Indestructable:1;
22 }SBHEALTHFLAGS;
23 /*
24 Combustability:
25 0=Non: Will not burn.
26 1=Combustable: Normal rules.
27 2=Sensitive: Normal rules?, + double damage.
28 3=Flammable: Always ignites + double damage.
29 */
30 
31 typedef struct damageblock {
32 	/* CDF 15/9/97 New Damage System */
33 	int Health;
34 	int Armour;
35 	unsigned int IsOnFire:1;
36 
37 	SBHEALTHFLAGS SB_H_flags;
38 	/* CDF 15/9/97 New Damage System */
39 } DAMAGEBLOCK;
40 
41 /* CDF 15/9/97 New Damage System */
42 /* Moved to this file 12/11/97 */
43 
44 typedef struct Hierarchy_Sound
45 {
46 	SOUND3DDATA s3d;
47 	struct loaded_sound const * sound_loaded;
48 	SOUNDINDEX sound_index;
49 	int pitch;
50 	int volume;
51 }HIERARCHY_SOUND;
52 
53 
54 /*
55 I'm going to try storing the quaternions as shorts within the keyframes ,
56 because there are loads of them.
57 -Richard.
58 */
59 typedef struct quat_short
60 {
61 	short quatx;
62 	short quaty;
63 	short quatz;
64 	short quatw;
65 } QUAT_SHORT;
66 
67 /*A couple of conversion functions */
68 extern void CopyShortQuatToInt(QUAT_SHORT* qs_from,QUAT* q_to);
69 extern void CopyIntQuatToShort(QUAT* q_from,QUAT_SHORT* qs_to);
70 
71 
72 #define KEYFRAME_VECTOR_SHIFT 4
73 
74 //make sure the keyframe structure packs as much as possible
75 // packing pragmas removed to fix alignment issues.
76 
77 typedef struct keyframe_data {
78 	short Offset_x; /*Offset values may need to be scaled*/
79 	short Offset_y;	/*In practice scaling should only be needed for 'placed' hierarchies*/
80 	short Offset_z;
81 
82 	/* Quats */
83 	QUAT_SHORT QOrient;
84 
85 	/*
86 	  These have been moved from the end to here
87 	  to reduce padding.
88 	 */
89 	unsigned short Sequence_Length; /* Time between these values and the next ones. */
90 	struct keyframe_data *Next_Frame; /*This is no longer Null for the last frame - look at the last_frame setting instead*/
91 
92 	/*
93 	int oneoversinomega;
94 	Removed oneoversinomega , since I can save a far amount of memory by doing so ,
95 	and the value is just calculated using a lookup table anyway. -Richard
96 	*/
97 	int oneoversequencelength;
98 
99 	unsigned short omega:12;
100 	/* Quats */
101 	unsigned short slerp_to_negative_quat:1; /*Should the slerping use the negative version of the next quaternion*/
102 	unsigned short frame_has_extended_data:1; /*frame can be cast to a KEYFRAME_DATA_EXTENDED in order to access flag and sound info*/
103 	unsigned short shift_offset:1; /*does offset need to be scaled*/
104 
105 	unsigned short last_frame:1; /*Is this the last frame?*/
106 } KEYFRAME_DATA;
107 
108 /*Two functions for extracting and setting the key frame offset */
109 extern void GetKeyFrameOffset(KEYFRAME_DATA* frame,VECTORCH* output_vector);
110 extern void SetKeyFrameOffset(KEYFRAME_DATA* frame,VECTORCH* input_vector);
111 
112 /*
113 If a keyframe has frame_has_extended_data set , then it can be cast to a
114 KEYFRAME_DATA_EXTENDED in order to access  the flags and sound.
115 */
116 typedef struct keyframe_data_extended {
117 	KEYFRAME_DATA frame_data;
118 	/* Keyframe flagging! */
119 	int flags;
120 	/*sound to be played this frame*/
121 	HIERARCHY_SOUND* sound;
122 } KEYFRAME_DATA_EXTENDED;
123 
124 typedef struct sequence {
125 	int sequence_id;
126 	KEYFRAME_DATA *first_frame;
127 	KEYFRAME_DATA *last_frame;
128 	int Time;
129 } SEQUENCE;
130 
131 typedef struct Hierarchy_Shape_Replacement
132 {
133 	char* replaced_section_name;
134 	int replacement_shape_index;
135 	SHAPEHEADER* replacement_shape;
136 	int replacement_id;
137 }HIERARCHY_SHAPE_REPLACEMENT;
138 
139 typedef struct section {
140 	int ShapeNum; /* Just in case */
141 	SHAPEHEADER *Shape;
142 	char *ShapeName;
143 	char *Section_Name;
144 	char *Hierarchy_Name;
145 	char *Rif_Name;
146 	struct section **Children;
147 	int num_sequences;
148 	SEQUENCE *sequence_array;
149 	struct damageblock StartingStats;
150 	VECTORCH gore_spray_direction;
151 	int flags;
152 	int IDnumber;
153 } SECTION;
154 
155 typedef struct section_attachment {
156 	char *Riffname;
157 	char *Section_Name;
158 	char **Hierarchy_Name;
159 	struct damageblock StartingStats;
160 	int flags;
161 } SECTION_ATTACHMENT;
162 
163 /* Nature flags */
164 #define section_has_shape_animation		0x00000001
165 #define section_has_sparkoflife			0x00000002
166 #define section_is_master_root			0x00000004
167 
168 /* Section behaviour flags */
169 #define section_sprays_blood			0x00000008
170 #define section_sprays_acid				0x00000010
171 #define section_sprays_predoblood		0x00000020
172 #define section_sprays_sparks			0x00000040
173 #define section_flag_nofurthergibbing	0x00000080
174 #define section_flag_doesnthurtsb		0x00000100
175 #define section_flag_heatsource			0x00000200
176 #define section_flag_affectedbyheat		0x00000400
177 #define section_flag_never_frag			0x00000800
178 #define section_flag_fragonlyfordisks	0x00001000
179 #define section_flag_gibbwhenfragged	0x00002000
180 #define section_flag_passdamagetoparent	0x00004000
181 
182 #define NORMAL_GORE_RATE	10000
183 
184 /* Wounding flags */
185 #define section_flag_left_arm			0x00010000
186 #define section_flag_right_arm			0x00020000
187 #define section_flag_left_leg			0x00040000
188 #define section_flag_right_leg			0x00080000
189 #define section_flag_left_foot			0x00100000
190 #define section_flag_right_foot			0x00200000
191 #define section_flag_left_hand			0x00400000
192 #define section_flag_right_hand			0x00800000
193 #define section_flag_head				0x01000000
194 #define section_flag_tail				0x02000000
195 
196 /* Multipart flags */
197 #define section_flags_wounding	(section_flag_left_arm|section_flag_right_arm|section_flag_left_leg|section_flag_right_leg\
198 	|section_flag_left_foot|section_flag_right_foot|section_flag_left_hand|section_flag_right_hand|section_flag_head\
199 	|section_flag_tail|section_has_sparkoflife)
200 #define section_sprays_anything (section_sprays_blood|section_sprays_acid|section_sprays_predoblood|section_sprays_sparks)
201 
202 typedef struct section_data {
203 	int ShapeNum; /* Just in case */
204 	SHAPEHEADER *Shape;
205 
206 	VECTORCH Offset;
207 	VECTORCH World_Offset;
208 	VECTORCH Last_World_Offset;
209 	VECTORCH View_Offset;
210 	MATRIXCH RelSecMat;
211 	MATRIXCH SecMat;
212 
213 	struct damageblock current_damage;
214 	struct hmodelcontroller *my_controller;
215 	SHAPEANIMATIONCONTROLLER *sac_ptr;
216 	TXACTRLBLK *tac_ptr;
217 	SECTION *sempai;
218 
219 	SEQUENCE *current_sequence;
220 	KEYFRAME_DATA *current_keyframe;
221 	int accumulated_timer;
222 	int freezeframe_timer;
223 	int lastframe_timer;
224 	int gore_timer;
225 
226 	int flags;
227 
228 	struct section_data *First_Child;
229 	struct section_data *Prev_Sibling;
230 	struct section_data *My_Parent;
231 	struct section_data *Next_Sibling;
232 
233 	/* KJL 16:56:51 31/07/98 - decal support */
234 	OBJECT_DECAL Decals[MAX_NO_OF_DECALS_PER_HIERARCHICAL_SECTION];
235 	int	NumberOfDecals;
236 	int NextDecalToUse;
237 
238 	/*For remembering the alternate shape sets*/
239 	int replacement_id;
240 
241 	/* Tweening */
242 	VECTORCH stored_offset;
243 	VECTORCH target_offset;
244 	VECTORCH delta_offset;
245 	QUAT stored_quat;
246 	QUAT target_quat;
247 	int omega;
248 	int oneoversinomega;
249 	int oneovertweeninglength;
250 	unsigned int Tweening:1;
251 
252 } SECTION_DATA;
253 
254 
255 #define section_data_master_root	0x00000001
256 #define section_data_false_root		0x00000002
257 #define section_data_notreal		0x00000004
258 #define section_data_terminate_here	0x00000008
259 #define section_data_view_init		0x40000000
260 #define section_data_initialised	0x80000000
261 
262 typedef struct delta_controller {
263 	char *id;
264 	int timer;
265 	int lastframe_timer;
266 	int sequence_type;
267 	int sub_sequence;
268 	int seconds_for_sequence;
269 	int timer_increment;
270 	int Looped:1;
271 	int Playing:1;
272 	int Active:1;
273 	struct delta_controller *next_controller;
274 	struct hmodelcontroller *my_hmodel_controller;
275 } DELTA_CONTROLLER;
276 
277 typedef struct hmodelcontroller {
278 
279 	int Seconds_For_Sequence;
280 	int timer_increment;
281 	int Sequence_Type;
282 	int	Sub_Sequence;
283 	int sequence_timer;
284 	int FrameStamp;
285 	int View_FrameStamp;
286 	VECTORCH Computed_Position;
287 	/* For keeping track of the state of the viewspace coords. */
288 	int keyframe_flags;
289 
290 	DELTA_CONTROLLER *Deltas;
291 
292 	SECTION *Root_Section;
293 	SECTION_DATA *section_data;
294 
295 	int After_Tweening_Sequence_Type;
296 	int After_Tweening_Sub_Sequence;
297 	int AT_seconds_for_sequence;
298 	int AT_sequence_timer;
299 
300 	unsigned int Playing:1;
301 	unsigned int Reversed:1;
302 	unsigned int Looped:1;
303 	unsigned int Tweening:2;
304 	unsigned int LoopAfterTweening:1;
305 	unsigned int StopAfterTweening:1;
306 	unsigned int ElevationTweening:1;
307 	unsigned int DisableBleeding:1;
308 	unsigned int LockTopSection:1;
309 	unsigned int ZeroRootDisplacement:1;
310 	unsigned int ZeroRootRotation:1;
311 	unsigned int DisableSounds:1;
312 	/* Bear in mind that 'Reversed' carries A LOT
313 	of overhead.  In fact, it does it the old way,
314 	looking down the entire frame list each frame. */
315 
316 } HMODELCONTROLLER;
317 
318 #define Controller_NoTweening	0
319 #define Controller_Tweening		1
320 #define Controller_EndTweening	2
321 
322 typedef struct hitlocationtableentry {
323 	char *section_name;
324 	int aspect;
325 	int cprob;
326 } HITLOCATIONTABLEENTRY;
327 
328 #define centre_aspect	0
329 #define front_aspect	1
330 #define back_aspect		2
331 
332 typedef struct hitlocationtable {
333 
334 	char *id;
335 	int index; //for loading and saving
336 	HITLOCATIONTABLEENTRY *CentreLocs;
337 	HITLOCATIONTABLEENTRY *TopLocs;
338 	HITLOCATIONTABLEENTRY *BaseLocs;
339 	HITLOCATIONTABLEENTRY *LeftLocs;
340 	HITLOCATIONTABLEENTRY *RightLocs;
341 	HITLOCATIONTABLEENTRY *TopLeftLocs;
342 	HITLOCATIONTABLEENTRY *TopRightLocs;
343 	HITLOCATIONTABLEENTRY *BaseLeftLocs;
344 	HITLOCATIONTABLEENTRY *BaseRightLocs;
345 
346 } HITLOCATIONTABLE;
347 
348 extern SECTION_ATTACHMENT Global_Section_Attachments[];
349 extern SECTION_ATTACHMENT Default_Stats;
350 
351 struct strategyblock;
352 
353 extern void Preprocess_HModel(SECTION *root,char *riffname);
354 extern void Create_HModel(HMODELCONTROLLER *controller,SECTION *root);
355 extern void InitHModelSequence(HMODELCONTROLLER *controller, int sequence_type, int subsequence, int seconds_for_sequence);
356 extern void DoHModel(HMODELCONTROLLER *controller, struct displayblock *dptr);
357 extern void DoHModelTimer(HMODELCONTROLLER *controller);
358 extern void ProveHModel(HMODELCONTROLLER *controller, struct displayblock *dptr);
359 extern void ProveHModel_Far(HMODELCONTROLLER *controller, struct strategyblock *sbPtr);
360 extern void Dispel_HModel(HMODELCONTROLLER *controller);
361 extern int Prune_HModel_Virtual(SECTION_DATA *top_section);
362 extern void Correlate_HModel_Instances(SECTION_DATA *victim,SECTION_DATA *templat);
363 extern int GetSequenceID(int sequence_type,int sub_sequence);
364 extern SEQUENCE *GetSequencePointer(int sequence_type,int sub_sequence,SECTION *this_section);
365 extern SECTION_ATTACHMENT *GetThisSectionAttachment(char *riffname,char *section_name,char *hierarchy_name);
366 extern void Extreme_Gibbing(struct strategyblock *sbPtr,SECTION_DATA *this_section_data, int probability);
367 extern int Splice_HModels(HMODELCONTROLLER *new_controller,SECTION_DATA *top_section_data);
368 extern void HModel_ChangeSpeed(HMODELCONTROLLER *controller, int seconds_for_sequence);
369 extern SECTION_DATA *GetThisSectionData(SECTION_DATA *root,char *name);
370 extern SECTION *GetThisSection(SECTION *root,char *name);
371 extern void InitHModelTweening(HMODELCONTROLLER *controller, int seconds_for_tweening, int target_sequence_type, int target_subsequence, int target_seconds_for_sequence, int loop);
372 extern void InitHModelTweening_Backwards(HMODELCONTROLLER *controller, int seconds_for_tweening, int target_sequence_type, int target_subsequence, int target_seconds_for_sequence, int loop);
373 extern void InitHModelTweening_ToTheMiddle(HMODELCONTROLLER *controller, int seconds_for_tweening,int target_sequence_type, int target_subsequence, int target_seconds_for_sequence, int target_sequence_timer, int loop);
374 extern DELTA_CONTROLLER *Add_Delta_Sequence(HMODELCONTROLLER *controller,char *id,int sequence_type,int sub_sequence, int seconds_for_sequence);
375 extern DELTA_CONTROLLER *Get_Delta_Sequence(HMODELCONTROLLER *controller,char *id);
376 extern void Remove_Delta_Sequence(HMODELCONTROLLER *controller,char *id);
377 extern void Transmogrify_HModels(struct strategyblock *sbPtr,HMODELCONTROLLER *controller,SECTION *new_template, int frag, int newsections, int regrowsections);
378 extern void TrimToTemplate(struct strategyblock *sbPtr,HMODELCONTROLLER *controller,SECTION *new_template, int frag);
379 extern void Start_Delta_Sequence(DELTA_CONTROLLER *delta_controller,int sequence_type,int sub_sequence,int seconds_for_sequence);
380 extern void Delta_Sequence_ChangeSpeed(DELTA_CONTROLLER *delta_controller,int seconds_for_sequence);
381 extern int HModelSequence_Exists(HMODELCONTROLLER *controller,int sequence_type,int sub_sequence);
382 extern int HModelSequence_Exists_FromRoot(SECTION *root,int sequence_type,int sub_sequence);
383 extern void RemoveAllDeltas(HMODELCONTROLLER *controller);
384 extern void KillRandomSections(SECTION_DATA *this_section_data, int probability);
385 extern void HModel_Regen(HMODELCONTROLLER *controller,int time);
386 extern int HModelAnimation_IsFinished(HMODELCONTROLLER *controller);
387 extern int DeltaAnimation_IsFinished(DELTA_CONTROLLER *controller);
388 extern SECTION_DATA *PointInHModel(HMODELCONTROLLER *controller,VECTORCH *point);
389 extern SECTION *Get_Corresponding_Section_Recursive(SECTION *this_section,char *Name);
390 extern SECTION_DATA *GetThisSectionData_FromID(SECTION_DATA *root,int IDnumber);
391 extern void PlayHierarchySound(HIERARCHY_SOUND* sound,VECTORCH* location);
392 extern void HModel_SetToolsRelativeSpeed(HMODELCONTROLLER *controller, int factor);
393 extern void Setup_Texture_Animation_For_Section(SECTION_DATA *this_section_data);
394 extern void Verify_Positions_In_HModel(struct strategyblock *sbPtr,HMODELCONTROLLER *controller,char *callCode);
395 extern int HModel_DepthTest(HMODELCONTROLLER *controller,SECTION_DATA *test_section_data,int depth);
396 extern void DeInitialise_HModel(HMODELCONTROLLER *controller);
397 
398 
399 struct save_block_header; // savegame.h
400 extern void LoadHierarchy(struct save_block_header* header,HMODELCONTROLLER* controller);
401 extern void SaveHierarchy(HMODELCONTROLLER* controller);
402 
403 #ifdef __cplusplus
404 }
405 #endif
406 
407 #endif
408