1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5
6 #ifdef __MSW__
7 # include <windows.h>
8 #endif
9
10 #include <GL/gl.h>
11
12 #include "../include/string.h"
13
14 #include "matrixmath.h"
15 #include "sfm.h"
16
17 #include "sound.h"
18 #include "sarreality.h"
19 #include "obj.h"
20 #include "objsound.h"
21 #include "objutils.h"
22 #include "sar.h"
23 #include "config.h"
24
25
26 #ifdef __MSW__
27 static double rint(double x);
28 #endif /* __MSW__ */
29
30 int SARObjIsAllocated(
31 sar_object_struct **ptr, int total,
32 int n
33 );
34 sar_object_struct *SARObjGetPtr(
35 sar_object_struct **ptr, int total,
36 int n
37 );
38 int SARGetObjectNumberFromPointer(
39 sar_scene_struct *scene,
40 sar_object_struct **ptr, int total,
41 sar_object_struct *obj_ptr
42 );
43 int SARIsTextureAllocated(sar_scene_struct *scene, int n);
44 sar_object_struct *SARObjMatchPointerByName(
45 sar_scene_struct *scene,
46 sar_object_struct **ptr, int total,
47 const char *name, int *obj_num
48 );
49
50 v3d_texture_ref_struct *SARGetTextureRefByName(
51 sar_scene_struct *scene, const char *name
52 );
53 int SARGetTextureRefNumberByName(
54 sar_scene_struct *scene, const char *name
55 );
56
57 int SARObjLandingGearState(sar_object_struct *obj_ptr);
58
59 sar_obj_part_struct *SARObjGetPartPtr(
60 sar_object_struct *obj_ptr, sar_obj_part_type type, int skip
61 );
62 sar_obj_rotor_struct *SARObjGetRotorPtr(
63 sar_object_struct *obj_ptr, int n, int *total
64 );
65 sar_obj_hoist_struct *SARObjGetHoistPtr(
66 sar_object_struct *obj_ptr, int n, int *total
67 );
68 int SARObjGetOnBoardPtr(
69 sar_object_struct *obj_ptr,
70 int **crew, int **passengers, int **passengers_max,
71 float **passengers_mass,
72 int **passengers_leave_pending, int **passengers_drop_pending
73 );
74 sar_external_fueltank_struct *SARObjGetFuelTankPtr(
75 sar_object_struct *obj_ptr, int n, int *total
76 );
77
78 sar_visual_model_struct *SARVisualModelNew(
79 sar_scene_struct *scene,
80 const char *filename, const char *name
81 );
82 void *SARVisualModelNewList(sar_visual_model_struct *vmodel);
83 int SARVisualModelGetRefCount(sar_visual_model_struct *vmodel);
84 void SARVisualModelRef(sar_visual_model_struct *vmodel);
85 void SARVisualModelUnref(
86 sar_scene_struct *scene, sar_visual_model_struct *vmodel
87 );
88 void SARVisualModelCallList(sar_visual_model_struct *vmodel);
89 static void SARVisualModelDelete(sar_visual_model_struct *vmodel);
90 void SARVisualModelDeleteAll(sar_scene_struct *scene);
91
92 sar_cloud_layer_struct *SARCloudLayerNew(
93 sar_scene_struct *scene,
94 int tile_width, int tile_height,
95 float range, float altitude,
96 const char *tex_name
97 );
98 void SARCloudLayerDelete(
99 sar_scene_struct *scene,
100 sar_cloud_layer_struct *cloud_layer_ptr
101 );
102
103 sar_cloud_bb_struct *SARCloudBBNew(
104 sar_scene_struct *scene,
105 int tile_width, int tile_height,
106 const sar_position_struct *pos,
107 float width, float height, /* In meters */
108 const char *tex_name,
109 time_t lightening_min_int, /* In ms */
110 time_t lightening_max_int /* In ms */
111 );
112 void SARCloudBBDelete(sar_cloud_bb_struct *cloud_bb_ptr);
113
114 int SARObjAddToGroundList(
115 sar_scene_struct *scene, sar_object_struct *obj_ptr
116 );
117 void SARObjRemoveFromGroundList(
118 sar_scene_struct *scene, sar_object_struct *obj_ptr
119 );
120
121 int SARObjAddToHumanRescueList(
122 sar_scene_struct *scene, sar_object_struct *obj_ptr
123 );
124 void SARObjRemoveFromHumanRescueList(
125 sar_scene_struct *scene, sar_object_struct *obj_ptr
126 );
127
128 int SARObjAddContactBoundsSpherical(
129 sar_object_struct *obj_ptr,
130 sar_obj_flags_t crash_flags, int crash_type,
131 float contact_radius
132 );
133 int SARObjAddContactBoundsCylendrical(
134 sar_object_struct *obj_ptr,
135 sar_obj_flags_t crash_flags, int crash_type,
136 float contact_radius,
137 float contact_h_min, float contact_h_max
138 );
139 int SARObjAddContactBoundsRectangular(
140 sar_object_struct *obj_ptr,
141 sar_obj_flags_t crash_flags, int crash_type,
142 float contact_x_min, float contact_x_max,
143 float contact_y_min, float contact_y_max,
144 float contact_z_min, float contact_z_max
145 );
146
147 int SARObjInterceptNew(
148 sar_scene_struct *scene,
149 sar_intercept_struct ***ptr, int *total,
150 sar_obj_flags_t flags,
151 float x, float y, float z,
152 float radius,
153 float urgency,
154 const char *name
155 );
156 static sar_obj_part_struct *SARObjPartNewNexus(
157 sar_scene_struct *scene,
158 sar_obj_part_struct ***ptr, int *total,
159 sar_obj_part_type type
160 );
161 sar_obj_part_struct *SARObjPartNew(
162 sar_scene_struct *scene,
163 sar_obj_part_struct ***ptr, int *total,
164 sar_obj_part_type type
165 );
166 sar_obj_part_struct *SARObjAirBrakeNew(
167 sar_scene_struct *scene,
168 sar_obj_part_struct ***ptr, int *total
169 );
170 sar_obj_part_struct *SARObjDoorRescueNew(
171 sar_scene_struct *scene,
172 sar_obj_part_struct ***ptr, int *total
173 );
174 sar_obj_part_struct *SARObjLandingGearNew(
175 sar_scene_struct *scene,
176 sar_obj_part_struct ***ptr, int *total
177 );
178 int SARObjExternalFuelTankNew(
179 sar_scene_struct *scene,
180 sar_external_fueltank_struct ***ptr, int *total
181 );
182 int SARObjRotorNew(
183 sar_scene_struct *scene,
184 sar_obj_rotor_struct ***ptr, int *total
185 );
186 sar_light_struct *SARObjLightNew(
187 sar_scene_struct *scene,
188 sar_light_struct ***ptr, int *total
189 );
190 int SARObjNew(
191 sar_scene_struct *scene,
192 sar_object_struct ***ptr, int *total,
193 int type
194 );
195
196 void SARObjDeleteIntercepts(
197 sar_scene_struct *scene,
198 sar_intercept_struct ***ptr, int *total
199 );
200 void SARObjDeleteLights(
201 sar_scene_struct *scene,
202 sar_light_struct ***ptr, int *total
203 );
204 void SARObjDeleteParts(
205 sar_scene_struct *scene,
206 sar_obj_part_struct ***ptr, int *total
207 );
208 void SARObjDeleteExternalFuelTanks(
209 sar_scene_struct *scene,
210 sar_external_fueltank_struct ***ptr, int *total
211 );
212 void SARObjDeleteRotors(
213 sar_scene_struct *scene,
214 sar_obj_rotor_struct ***ptr, int *total
215 );
216 void SARObjDelete(
217 void *core_ptr,
218 sar_object_struct ***ptr, int *total, int n
219 );
220
221 void SARObjGenerateTilePlane(
222 float min, float max,
223 float tile_width, float tile_height
224 );
225
226
227 #define ATOI(s) (((s) != NULL) ? atoi(s) : 0)
228 #define ATOL(s) (((s) != NULL) ? atol(s) : 0)
229 #define ATOF(s) (((s) != NULL) ? atof(s) : 0.0f)
230 #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL)
231
232 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
233 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
234 #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h)))
235
236 #define ISSTREMPTY(s) (((s) != NULL) ? (*(s) == '\0') : True)
237 #define STRLEN(s) (((s) != NULL) ? ((int)strlen(s)) : 0)
238
239
240 #ifdef __MSW__
rint(double x)241 static double rint(double x)
242 {
243 if((double)((double)x - (int)x) > (double)0.5)
244 return((double)((int)x + (int)1));
245 else
246 return((double)((int)x));
247 }
248 #endif /* __MSW__ */
249
250
251 /*
252 * Returns true if object n is allocated in the given array.
253 */
SARObjIsAllocated(sar_object_struct ** ptr,int total,int n)254 int SARObjIsAllocated(
255 sar_object_struct **ptr, int total,
256 int n
257 )
258 {
259 if((ptr == NULL) || (n < 0) || (n >= total))
260 return(0);
261 else if(ptr[n] == NULL)
262 return(0);
263 else
264 return(1);
265 }
266
267 /*
268 * Returns pointer to object n if it is valid and not NULL.
269 *
270 * Returns NULL on error.
271 */
SARObjGetPtr(sar_object_struct ** ptr,int total,int n)272 sar_object_struct *SARObjGetPtr(
273 sar_object_struct **ptr, int total,
274 int n
275 )
276 {
277 if((ptr == NULL) || (n < 0) || (n >= total))
278 return(NULL);
279 else
280 return(ptr[n]);
281 }
282
283
284 /*
285 * Returns the number of the object pointer in the given pointer
286 * array or -1 if no match.
287 */
SARGetObjectNumberFromPointer(sar_scene_struct * scene,sar_object_struct ** ptr,int total,sar_object_struct * obj_ptr)288 int SARGetObjectNumberFromPointer(
289 sar_scene_struct *scene,
290 sar_object_struct **ptr, int total,
291 sar_object_struct *obj_ptr
292 )
293 {
294 int i;
295
296 if(obj_ptr == NULL)
297 return(-1);
298
299 for(i = 0; i < total; i++)
300 {
301 if(ptr[i] == obj_ptr)
302 return(i);
303 }
304
305 return(-1);
306 }
307
308 /*
309 * Checks if the texture is allocated on the scene.
310 */
SARIsTextureAllocated(sar_scene_struct * scene,int n)311 int SARIsTextureAllocated(sar_scene_struct *scene, int n)
312 {
313 if((scene == NULL) || (n < 0) || (n >= scene->total_texture_refs))
314 return(0);
315 else if(scene->texture_ref[n] == NULL)
316 return(0);
317 else
318 return(1);
319 }
320
321 /*
322 * Returns the pointer to the object matching the given name or
323 * NULL if no match was made.
324 */
SARObjMatchPointerByName(sar_scene_struct * scene,sar_object_struct ** ptr,int total,const char * name,int * obj_num)325 sar_object_struct *SARObjMatchPointerByName(
326 sar_scene_struct *scene,
327 sar_object_struct **ptr, int total,
328 const char *name, int *obj_num
329 )
330 {
331 int i;
332 sar_object_struct *obj_ptr;
333
334
335 if(obj_num != NULL)
336 *obj_num = -1;
337
338 /* Go through each object */
339 for(i = 0; i < total; i++)
340 {
341 obj_ptr = ptr[i];
342 if((obj_ptr != NULL) ? (obj_ptr->name == NULL) : 1)
343 continue;
344
345 /* Names match? */
346 if(!strcasecmp(obj_ptr->name, name))
347 {
348 if(obj_num != NULL)
349 *obj_num = i;
350
351 return(obj_ptr);
352 }
353 }
354
355 return(NULL);
356 }
357
358 /*
359 * Returns a pointer to the texture reference structure matching
360 * the given name. Can return NULL for failed match.
361 */
SARGetTextureRefByName(sar_scene_struct * scene,const char * name)362 v3d_texture_ref_struct *SARGetTextureRefByName(
363 sar_scene_struct *scene, const char *name
364 )
365 {
366 int i, total;
367 v3d_texture_ref_struct *t, **ptr;
368
369
370 if((scene == NULL) || (name == NULL))
371 return(NULL);
372
373 ptr = scene->texture_ref;
374 total = scene->total_texture_refs;
375
376 for(i = 0; i < total; i++)
377 {
378 t = ptr[i];
379 if((t != NULL) ? (t->name == NULL) : 1)
380 continue;
381
382 if((t->name == name) ? 1 : !strcasecmp(t->name, name))
383 return(t);
384 }
385
386 return(NULL);
387 }
388
389 /*
390 * Same as SARGetTextureRefByName() except that it returns the
391 * texture index number of -1 on error.
392 */
SARGetTextureRefNumberByName(sar_scene_struct * scene,const char * name)393 int SARGetTextureRefNumberByName(
394 sar_scene_struct *scene, const char *name
395 )
396 {
397 int i, total;
398 v3d_texture_ref_struct *t, **ptr;
399
400 if((scene == NULL) || ISSTREMPTY(name))
401 return(-1);
402
403 ptr = scene->texture_ref;
404 total = scene->total_texture_refs;
405
406 for(i = 0; i < total; i++)
407 {
408 t = ptr[i];
409 if((t != NULL) ? (t->name == NULL) : 1)
410 continue;
411
412 if((t->name == name) ? 1 : !strcasecmp(t->name, name))
413 return(i);
414 }
415
416 return(-1);
417 }
418
419
420 /*
421 * Returns -1 if the object does not have landing gears, 0 if the
422 * landing gears exist but are up, or 1 if the landing gears are
423 * down.
424 */
SARObjLandingGearState(sar_object_struct * obj_ptr)425 int SARObjLandingGearState(sar_object_struct *obj_ptr)
426 {
427 sar_object_aircraft_struct *aircraft;
428
429 if(obj_ptr == NULL)
430 return(-1);
431
432 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
433 return((aircraft != NULL) ?
434 aircraft->landing_gear_state : -1
435 );
436 }
437
438 /*
439 * Returns the pointer to the part structure on the object that
440 * matches the given part type. The skip indicates the number
441 * of part structures of the specified type to be skipped.
442 */
SARObjGetPartPtr(sar_object_struct * obj_ptr,sar_obj_part_type type,int skip)443 sar_obj_part_struct *SARObjGetPartPtr(
444 sar_object_struct *obj_ptr, sar_obj_part_type type, int skip
445 )
446 {
447 int i, j, m = 0;
448 sar_object_aircraft_struct *aircraft;
449 sar_obj_part_struct *part, **list = NULL;
450
451
452 if(obj_ptr == NULL)
453 return(NULL);
454
455
456 /* Begin checking object type and get the object parts list */
457
458 /* Aircraft */
459 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
460 if(aircraft != NULL)
461 {
462 list = aircraft->part;
463 m = aircraft->total_parts;
464 }
465
466
467 /* Got list of object parts? */
468 if(list != NULL)
469 {
470 for(i = 0, j = 0; i < m; i++)
471 {
472 part = list[i];
473 if(part == NULL)
474 continue;
475 if(part->type != type)
476 continue;
477
478 /* Increment j, the skip count. If the skip count is still
479 * at or below the requested number of times to skip n,
480 * then skip this part.
481 */
482 j++;
483 if(j <= skip)
484 continue;
485
486 return(part);
487 }
488 }
489
490 return(NULL);
491 }
492
493 /*
494 * Returns pointer to the n th index rotor and optional total
495 * on the given object. Can return NULL if none exist.
496 *
497 * If object only has one, then pass n as 0.
498 */
SARObjGetRotorPtr(sar_object_struct * obj_ptr,int n,int * total)499 sar_obj_rotor_struct *SARObjGetRotorPtr(
500 sar_object_struct *obj_ptr, int n, int *total
501 )
502 {
503 sar_object_aircraft_struct *aircraft;
504
505
506 if(total != NULL)
507 *total = 0;
508
509 if(obj_ptr == NULL)
510 return(NULL);
511
512 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
513 if(aircraft != NULL)
514 {
515 if(total != NULL)
516 *total = aircraft->total_rotors;
517 if((aircraft->rotor != NULL) &&
518 (n >= 0) && (n < aircraft->total_rotors)
519 )
520 return(aircraft->rotor[n]);
521 }
522
523 return(NULL);
524 }
525
526 /*
527 * Returns pointer to the n th index door and optional total
528 * on the given object. Can return NULL if none exist.
529 *
530 * If object only has one, then pass n as 0.
531 */
SARObjGetHoistPtr(sar_object_struct * obj_ptr,int n,int * total)532 sar_obj_hoist_struct *SARObjGetHoistPtr(
533 sar_object_struct *obj_ptr, int n, int *total
534 )
535 {
536 sar_object_aircraft_struct *aircraft;
537
538
539 if(total != NULL)
540 *total = 0;
541
542 if(obj_ptr == NULL)
543 return(NULL);
544
545 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
546 if(aircraft != NULL)
547 {
548 if(total != NULL)
549 *total = 1;
550 if(n == 0)
551 return(aircraft->hoist);
552 }
553
554 return(NULL);
555 }
556
557 /*
558 * Returns pointers to the object's value for crew and passengers
559 * (and related information).
560 *
561 * Returns -1 on error, -2 if the object's type does not have
562 * passengers, and 0 on success.
563 */
SARObjGetOnBoardPtr(sar_object_struct * obj_ptr,int ** crew,int ** passengers,int ** passengers_max,float ** passengers_mass,int ** passengers_leave_pending,int ** passengers_drop_pending)564 int SARObjGetOnBoardPtr(
565 sar_object_struct *obj_ptr,
566 int **crew, int **passengers, int **passengers_max,
567 float **passengers_mass,
568 int **passengers_leave_pending, int **passengers_drop_pending
569 )
570 {
571 sar_object_aircraft_struct *aircraft;
572
573
574 if(crew != NULL)
575 *crew = NULL;
576 if(passengers != NULL)
577 *passengers = NULL;
578 if(passengers_max != NULL)
579 *passengers_max = NULL;
580 if(passengers_mass != NULL)
581 *passengers_mass = NULL;
582 if(passengers_leave_pending != NULL)
583 *passengers_leave_pending = NULL;
584 if(passengers_drop_pending != NULL)
585 *passengers_drop_pending = NULL;
586
587 if(obj_ptr == NULL)
588 return(-1);
589
590 switch(obj_ptr->type)
591 {
592 case SAR_OBJ_TYPE_GARBAGE:
593 case SAR_OBJ_TYPE_STATIC:
594 case SAR_OBJ_TYPE_AUTOMOBILE:
595 case SAR_OBJ_TYPE_WATERCRAFT:
596 return(-2);
597 break;
598 case SAR_OBJ_TYPE_AIRCRAFT:
599 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
600 if(aircraft != NULL)
601 {
602 if(crew != NULL)
603 *crew = &aircraft->crew;
604 if(passengers != NULL)
605 *passengers = &aircraft->passengers;
606 if(passengers_max != NULL)
607 *passengers_max = &aircraft->passengers_max;
608 if(passengers_mass != NULL)
609 *passengers_mass = &aircraft->passengers_mass;
610 if(passengers_leave_pending != NULL)
611 *passengers_leave_pending = &aircraft->passengers_leave_pending;
612 if(passengers_drop_pending != NULL)
613 *passengers_drop_pending = &aircraft->passengers_drop_pending;
614 return(0);
615 }
616 break;
617 case SAR_OBJ_TYPE_GROUND:
618 case SAR_OBJ_TYPE_RUNWAY:
619 case SAR_OBJ_TYPE_HELIPAD:
620 case SAR_OBJ_TYPE_HUMAN:
621 case SAR_OBJ_TYPE_SMOKE:
622 case SAR_OBJ_TYPE_FIRE:
623 case SAR_OBJ_TYPE_EXPLOSION:
624 case SAR_OBJ_TYPE_CHEMICAL_SPRAY:
625 case SAR_OBJ_TYPE_FUELTANK:
626 case SAR_OBJ_TYPE_PREMODELED:
627 return(-2);
628 break;
629 }
630
631 return(-1);
632 }
633
634 /*
635 * Returns pointer to the n th external reserved fuel tank and
636 * optional total on the given object. Can return NULL if none exist.
637 *
638 * If object only has one, then pass n as 0.
639 */
SARObjGetFuelTankPtr(sar_object_struct * obj_ptr,int n,int * total)640 sar_external_fueltank_struct *SARObjGetFuelTankPtr(
641 sar_object_struct *obj_ptr, int n, int *total
642 )
643 {
644 sar_object_aircraft_struct *aircraft;
645
646 if(total != NULL)
647 *total = 0;
648
649 if(obj_ptr == NULL)
650 return(NULL);
651
652 switch(obj_ptr->type)
653 {
654 case SAR_OBJ_TYPE_GARBAGE:
655 case SAR_OBJ_TYPE_STATIC:
656 case SAR_OBJ_TYPE_AUTOMOBILE:
657 case SAR_OBJ_TYPE_WATERCRAFT:
658 break;
659 case SAR_OBJ_TYPE_AIRCRAFT:
660 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
661 if(aircraft != NULL)
662 {
663 if(total != NULL)
664 *total = aircraft->total_external_fueltanks;
665
666 if((aircraft->external_fueltank != NULL) &&
667 (n >= 0) && (n < aircraft->total_external_fueltanks)
668 )
669 return(aircraft->external_fueltank[n]);
670 }
671 break;
672 case SAR_OBJ_TYPE_GROUND:
673 case SAR_OBJ_TYPE_RUNWAY:
674 case SAR_OBJ_TYPE_HELIPAD:
675 case SAR_OBJ_TYPE_HUMAN:
676 case SAR_OBJ_TYPE_SMOKE:
677 case SAR_OBJ_TYPE_FIRE:
678 case SAR_OBJ_TYPE_EXPLOSION:
679 case SAR_OBJ_TYPE_CHEMICAL_SPRAY:
680 case SAR_OBJ_TYPE_FUELTANK:
681 case SAR_OBJ_TYPE_PREMODELED:
682 break;
683 }
684 return(NULL);
685 }
686
687
688 /*
689 * Creates a new or returns an existing Visual Model on the
690 * specified Scene.
691 *
692 * If the specified Visual Model filename and name both match an
693 * existing Visual Model on the Scene then that Visual Model is
694 * returned.
695 *
696 * If filename or name is NULL then a new visual model will be
697 * created and will be treated as `unique' meaning that it will not
698 * be returned for match with any other call to SARVisualModelNew()
699 * (since the filename and name are unmatchable).
700 *
701 * A new visual model will be given one ref count, while an existing
702 * visual model will have its ref count incremented by one. There
703 * will never be a case where a returned visual model will have only
704 * 0 or negative ref counts. Ref counts on returned visual models
705 * will always be 1 or greater.
706 *
707 * Can return NULL on error.
708 */
SARVisualModelNew(sar_scene_struct * scene,const char * filename,const char * name)709 sar_visual_model_struct *SARVisualModelNew(
710 sar_scene_struct *scene,
711 const char *filename, const char *name
712 )
713 {
714 int i;
715 sar_visual_model_struct *vmodel;
716
717 if(scene == NULL)
718 return(NULL);
719
720 /* Both filename and name given? */
721 if((filename != NULL) && (name != NULL))
722 {
723 /* Check for an existing visual model with the same
724 * filename and name
725 */
726 for(i = 0; i < scene->total_visual_models; i++)
727 {
728 vmodel = scene->visual_model[i];
729 if(vmodel == NULL)
730 continue;
731
732 /* Both filename and name match (case sensitive)? */
733 if((vmodel->filename != NULL) && (vmodel->name != NULL))
734 {
735 if(!strcmp(vmodel->filename, filename) &&
736 !strcmp(vmodel->name, name)
737 )
738 {
739 /* Increment the ref count for matched visual
740 * model and return its pointer
741 */
742 vmodel->ref_count++;
743 return(vmodel);
744 }
745 }
746 }
747 }
748
749
750 /* Create new visual model */
751
752 /* Sanitize total */
753 if(scene->total_visual_models < 0)
754 scene->total_visual_models = 0;
755
756 /* Look for available pointer */
757 for(i = 0; i < scene->total_visual_models; i++)
758 {
759 if(scene->visual_model[i] == NULL)
760 break;
761 }
762 if(i < scene->total_visual_models)
763 {
764 /* Got available pointer at index i */
765 }
766 else
767 {
768 /* Need to allocate a new pointer */
769 i = scene->total_visual_models;
770 scene->total_visual_models = i + 1;
771 scene->visual_model = (sar_visual_model_struct **)realloc(
772 scene->visual_model,
773 scene->total_visual_models * sizeof(sar_visual_model_struct *)
774 );
775 if(scene->visual_model == NULL)
776 {
777 scene->total_visual_models = 0;
778 return(NULL);
779 }
780 else
781 {
782 scene->visual_model[i] = NULL;
783 }
784 }
785
786 /* Allocate new structure */
787 scene->visual_model[i] = vmodel = SAR_VISUAL_MODEL(calloc(
788 1, sizeof(sar_visual_model_struct)
789 ));
790 if(vmodel != NULL)
791 {
792 vmodel->load_state = SAR_VISUAL_MODEL_NOT_LOADED;
793
794 /* Set initial ref count to 1 for all new visual models
795 * this is how calling functions can tell that this is a
796 * new visual model
797 */
798 vmodel->ref_count = 1;
799
800 vmodel->filename = STRDUP(filename);
801 vmodel->name = STRDUP(name);
802
803 vmodel->data = NULL;
804
805 vmodel->mem_size = 0;
806 vmodel->statements = 0;
807 vmodel->primitives = 0;
808 }
809
810 return(vmodel);
811 }
812
813 /*
814 * (Re)generates a GL display list on the given visual model.
815 *
816 * The return value is really a GLuint (not a void *), can return
817 * NULL on failure.
818 */
SARVisualModelNewList(sar_visual_model_struct * vmodel)819 void *SARVisualModelNewList(sar_visual_model_struct *vmodel)
820 {
821 GLuint list;
822
823 if(vmodel == NULL)
824 return(NULL);
825
826 /* Get existing GL display list if any */
827 list = (GLuint)vmodel->data;
828 if(list > 0)
829 {
830 /* Already has an allocated GL display list so delete it
831 * and create a new one
832 */
833 glDeleteLists(list, 1);
834 list = 0;
835 vmodel->data = NULL;
836 }
837
838 /* Create new GL display list */
839 list = glGenLists(1);
840
841 /* Set new GL display list as the data pointer on the visual
842 * model structure
843 */
844 vmodel->data = (void *)list;
845
846 return((void *)list);
847 }
848
849 /*
850 * Returns number of ref counts on visual model.
851 *
852 * Can return -1 if visual model is NULL.
853 */
SARVisualModelGetRefCount(sar_visual_model_struct * vmodel)854 int SARVisualModelGetRefCount(sar_visual_model_struct *vmodel)
855 {
856 if(vmodel != NULL)
857 return(vmodel->ref_count);
858 else
859 return(-1);
860 }
861
862 /*
863 * Increases the ref count on the given visual model by one.
864 */
SARVisualModelRef(sar_visual_model_struct * vmodel)865 void SARVisualModelRef(sar_visual_model_struct *vmodel)
866 {
867 if(vmodel != NULL)
868 vmodel->ref_count++;
869 }
870
871 /*
872 * Decrease the ref count on the given visual model by one.
873 *
874 * If (after decrement) the ref count drops to 0 then the given
875 * visual model will be destroyed and its pointer should not
876 * be referenced again.
877 *
878 * It's a general sense to not reference any pointer value again from
879 * any one variable after it's passed to this function. The scene
880 * structure's visual_model list is ultimatly to hold the pointer
881 * the visual model all the way to when it is down to its last
882 * ref count of 0.
883 *
884 * If scene is not NULL then any visual model pointers on the
885 * scene's visual models list matching the given vmodel pointer
886 * will be set to NULL.
887 */
SARVisualModelUnref(sar_scene_struct * scene,sar_visual_model_struct * vmodel)888 void SARVisualModelUnref(
889 sar_scene_struct *scene, sar_visual_model_struct *vmodel
890 )
891 {
892 if(vmodel == NULL)
893 return;
894
895 /* Reference counts have already reached 0? */
896 if(vmodel->ref_count < 1)
897 fprintf(
898 stderr,
899 "SARVisualModelUnref(): Warning: \
900 Visual model \"%s\" has less than 1 reference count.\n",
901 vmodel->name
902 );
903
904 /* Reduce reference count */
905 vmodel->ref_count--;
906 if(vmodel->ref_count < 0)
907 vmodel->ref_count = 0;
908
909 /* No reference counts left? */
910 if(vmodel->ref_count == 0)
911 {
912 /* Reference counts have reached 0 on this visual model,
913 * so once that happens the visual model needs
914 * to be deleted and removed from the Scene
915 */
916
917 /* Delete this visual model, deleting its GL
918 * display list and the visual model structure itself
919 */
920 SARVisualModelDelete(vmodel);
921
922 /* Pointer vmodel is now invalid, but do not set it to
923 * NULL just yet as it needs to be used to check for
924 * references to it on the scene structure
925 */
926 if(scene != NULL)
927 {
928 int i;
929
930 for(i = 0; i < scene->total_visual_models; i++)
931 {
932 if(scene->visual_model[i] == vmodel)
933 scene->visual_model[i] = NULL;
934 }
935 }
936 }
937 }
938
939 /*
940 * Calls the GL list on the visual model if it is not 0.
941 */
SARVisualModelCallList(sar_visual_model_struct * vmodel)942 void SARVisualModelCallList(sar_visual_model_struct *vmodel)
943 {
944 GLuint list = (vmodel != NULL) ? (GLuint)vmodel->data : 0;
945 if(list > 0)
946 glCallList(list);
947 }
948
949 /*
950 * Deletes the Visual Model.
951 *
952 * This function is intended to be called from SARVisualModelUnref().
953 */
SARVisualModelDelete(sar_visual_model_struct * vmodel)954 static void SARVisualModelDelete(sar_visual_model_struct *vmodel)
955 {
956 GLuint list;
957
958 if(vmodel == NULL)
959 return;
960
961 if(vmodel->ref_count > 0)
962 fprintf(
963 stderr,
964 "SARVisualModelDelete(): Warning: \
965 Visual model `%s' still has %i reference counts.\n",
966 vmodel->name, vmodel->ref_count
967 );
968
969 free(vmodel->filename);
970 free(vmodel->name);
971
972 list = (GLuint)vmodel->data;
973 if(list > 0)
974 glDeleteLists(list, 1);
975
976 free(vmodel);
977 }
978
979 /*
980 * Deletes all the Visual Models on the specified Scene.
981 */
SARVisualModelDeleteAll(sar_scene_struct * scene)982 void SARVisualModelDeleteAll(sar_scene_struct *scene)
983 {
984 int i;
985
986 if(scene == NULL)
987 return;
988
989 for(i = 0; i < scene->total_visual_models; i++)
990 {
991 /* Delete the visual model, note that its ref counts
992 * should be 0 at this point
993 */
994 SARVisualModelDelete(scene->visual_model[i]);
995 }
996 free(scene->visual_model);
997 scene->visual_model = NULL;
998 scene->total_visual_models = 0;
999 }
1000
1001
1002 /*
1003 * Creates a new Cloud Layer.
1004 */
SARCloudLayerNew(sar_scene_struct * scene,int tile_width,int tile_height,float range,float altitude,const char * tex_name)1005 sar_cloud_layer_struct *SARCloudLayerNew(
1006 sar_scene_struct *scene,
1007 int tile_width, int tile_height,
1008 float range, /* Tiling range in meters */
1009 float altitude, /* Altitude in meters */
1010 const char *tex_name
1011 )
1012 {
1013 GLuint list;
1014 float min, max;
1015 v3d_texture_ref_struct *t;
1016 sar_visual_model_struct **vmodel;
1017 sar_cloud_layer_struct *cloud_layer_ptr = (sar_cloud_layer_struct *)
1018 calloc(1, sizeof(sar_cloud_layer_struct));
1019
1020
1021 if(cloud_layer_ptr == NULL)
1022 return(NULL);
1023
1024 cloud_layer_ptr->tile_width = tile_width;
1025 cloud_layer_ptr->tile_height = tile_height;
1026 cloud_layer_ptr->range = MAX(range, MAX(tile_width, tile_height));
1027 cloud_layer_ptr->z = altitude;
1028
1029 /* Match texture by name */
1030 t = SARGetTextureRefByName(scene, tex_name);
1031
1032 /* Calculate entire size limits */
1033 min = -cloud_layer_ptr->range;
1034 max = cloud_layer_ptr->range;
1035
1036 /* Get pointer to visual model */
1037 vmodel = &cloud_layer_ptr->visual_model;
1038
1039 /* Unref visual model if its pointer to reference is not NULL */
1040 if((*vmodel) != NULL)
1041 {
1042 SARVisualModelUnref(scene, *vmodel);
1043 (*vmodel) = NULL;
1044 }
1045
1046 /* Create new visual model */
1047 (*vmodel) = SARVisualModelNew(
1048 scene, NULL, NULL
1049 );
1050
1051 /* (Re)generate GL list on visual model structure */
1052 list = (GLuint)SARVisualModelNewList(*vmodel);
1053 if(list != 0)
1054 {
1055 /* Mark as loading */
1056 (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADING;
1057
1058 /* Begin recording GL list */
1059 glNewList(list, GL_COMPILE);
1060 {
1061 /* Select texture if defined */
1062 V3DTextureSelect(t);
1063
1064 /* Do not set color */
1065
1066 /* Close range textured tiles */
1067 SARObjGenerateTilePlane(
1068 min, max, /* Min and max */
1069 (float)tile_width, (float)tile_height /* Tiling size */
1070 );
1071 }
1072 glEndList();
1073
1074 /* Mark as done loading */
1075 (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADED;
1076 }
1077
1078 return(cloud_layer_ptr);
1079 }
1080
1081 /*
1082 * Deletes the Cloud Layer.
1083 *
1084 * If scene is NULL then the visual model will not be unref'ed.
1085 */
SARCloudLayerDelete(sar_scene_struct * scene,sar_cloud_layer_struct * cloud_layer_ptr)1086 void SARCloudLayerDelete(
1087 sar_scene_struct *scene,
1088 sar_cloud_layer_struct *cloud_layer_ptr
1089 )
1090 {
1091 if(cloud_layer_ptr == NULL)
1092 return;
1093
1094 SARVisualModelUnref(scene, cloud_layer_ptr->visual_model);
1095 free(cloud_layer_ptr->tex_name);
1096 free(cloud_layer_ptr);
1097 }
1098
1099 /*
1100 * Creates a new Cloud BillBoard.
1101 */
SARCloudBBNew(sar_scene_struct * scene,int tile_width,int tile_height,const sar_position_struct * pos,float width,float height,const char * tex_name,time_t lightening_min_int,time_t lightening_max_int)1102 sar_cloud_bb_struct *SARCloudBBNew(
1103 sar_scene_struct *scene,
1104 int tile_width, int tile_height,
1105 const sar_position_struct *pos,
1106 float width, float height, /* In meters */
1107 const char *tex_name,
1108 time_t lightening_min_int, /* In ms */
1109 time_t lightening_max_int /* In ms */
1110 )
1111 {
1112 sar_cloud_bb_struct *cloud = SAR_CLOUD_BB(
1113 calloc(1, sizeof(sar_cloud_bb_struct))
1114 );
1115 if(cloud == NULL)
1116 return(NULL);
1117
1118 cloud->tile_width = tile_width;
1119 cloud->tile_height = tile_height;
1120
1121 cloud->tex_name = STRDUP(tex_name);
1122
1123 /* Match texture number on scene */
1124 cloud->tex_num = SARGetTextureRefNumberByName(
1125 scene, tex_name
1126 );
1127
1128 if(pos != NULL)
1129 memcpy(&cloud->pos, pos, sizeof(sar_position_struct));
1130
1131 cloud->width = width;
1132 cloud->height = height;
1133
1134 cloud->lightening_min_int = lightening_min_int;
1135 cloud->lightening_max_int = lightening_max_int;
1136 cloud->lightening_next_on = 0;
1137 cloud->lightening_next_off = 0;
1138 cloud->lightening_started_on = 0;
1139
1140 memset(
1141 &cloud->lightening_point[0], 0x00,
1142 SAR_LIGHTENING_POINTS_MAX * sizeof(sar_position_struct)
1143 );
1144
1145 return(cloud);
1146 }
1147
1148 /*
1149 * Deletes the Cloud BillBoard.
1150 */
SARCloudBBDelete(sar_cloud_bb_struct * cloud_bb_ptr)1151 void SARCloudBBDelete(sar_cloud_bb_struct *cloud_bb_ptr)
1152 {
1153 if(cloud_bb_ptr == NULL)
1154 return;
1155
1156 free(cloud_bb_ptr->tex_name);
1157 free(cloud_bb_ptr);
1158 }
1159
1160
1161 /*
1162 * Checks if the object is in the scene's ground list.
1163 * If not, then it will add it to the list. Returns 0 on success
1164 * or negative on error/already in list.
1165 */
SARObjAddToGroundList(sar_scene_struct * scene,sar_object_struct * obj_ptr)1166 int SARObjAddToGroundList(
1167 sar_scene_struct *scene,
1168 sar_object_struct *obj_ptr
1169 )
1170 {
1171 int i;
1172
1173
1174 if((scene == NULL) ||
1175 (obj_ptr == NULL)
1176 )
1177 return(-1);
1178
1179 if(scene->total_ground_objects < 0)
1180 scene->total_ground_objects = 0;
1181
1182 /* Check if already in list */
1183 for(i = 0; i < scene->total_ground_objects; i++)
1184 {
1185 if(obj_ptr == scene->ground_object[i])
1186 return(-2);
1187 }
1188
1189 /* Not in list, so add to list */
1190 for(i = 0; i < scene->total_ground_objects; i++)
1191 {
1192 if(scene->ground_object[i] == NULL)
1193 {
1194 /* Found an empty entry */
1195 scene->ground_object[i] = obj_ptr;
1196 return(0);
1197 }
1198 }
1199
1200 /* Need to allocate more entries */
1201 i = scene->total_ground_objects;
1202 scene->total_ground_objects++;
1203
1204 scene->ground_object = (sar_object_struct **)realloc(
1205 scene->ground_object,
1206 scene->total_ground_objects * sizeof(sar_object_struct *)
1207 );
1208 if(scene->ground_object == NULL)
1209 {
1210 scene->total_ground_objects = 0;
1211 return(-1);
1212 }
1213
1214 scene->ground_object[i] = obj_ptr;
1215
1216 return(0);
1217 }
1218
1219 /*
1220 * Removes the object from the ground list if it is in there.
1221 */
SARObjRemoveFromGroundList(sar_scene_struct * scene,sar_object_struct * obj_ptr)1222 void SARObjRemoveFromGroundList(
1223 sar_scene_struct *scene,
1224 sar_object_struct *obj_ptr
1225 )
1226 {
1227 int i;
1228
1229
1230 if((scene == NULL) || (obj_ptr == NULL))
1231 return;
1232
1233 for(i = 0; i < scene->total_ground_objects; i++)
1234 {
1235 if(obj_ptr == scene->ground_object[i])
1236 scene->ground_object[i] = NULL;
1237 }
1238 }
1239
1240 /*
1241 * Adds object pointer to the humans need rescue list on the scene:
1242 */
SARObjAddToHumanRescueList(sar_scene_struct * scene,sar_object_struct * obj_ptr)1243 int SARObjAddToHumanRescueList(
1244 sar_scene_struct *scene,
1245 sar_object_struct *obj_ptr
1246 )
1247 {
1248 int i;
1249
1250
1251 if((scene == NULL) ||
1252 (obj_ptr == NULL)
1253 )
1254 return(-1);
1255
1256 if(scene->total_human_need_rescue_objects < 0)
1257 scene->total_human_need_rescue_objects = 0;
1258
1259 /* Check if already in list */
1260 for(i = 0; i < scene->total_human_need_rescue_objects; i++)
1261 {
1262 if(obj_ptr == scene->human_need_rescue_object[i])
1263 return(-2);
1264 }
1265
1266 /* Not in list, so add to list */
1267 for(i = 0; i < scene->total_human_need_rescue_objects; i++)
1268 {
1269 if(scene->human_need_rescue_object[i] == NULL)
1270 {
1271 /* Found an empty entry */
1272 scene->human_need_rescue_object[i] = obj_ptr;
1273 return(0);
1274 }
1275 }
1276
1277 /* Need to allocate more entries */
1278 i = scene->total_human_need_rescue_objects;
1279 scene->total_human_need_rescue_objects++;
1280
1281 scene->human_need_rescue_object = (sar_object_struct **)realloc(
1282 scene->human_need_rescue_object,
1283 scene->total_human_need_rescue_objects * sizeof(sar_object_struct *)
1284 );
1285 if(scene->human_need_rescue_object == NULL)
1286 {
1287 scene->total_human_need_rescue_objects = 0;
1288 return(-1);
1289 }
1290
1291 scene->human_need_rescue_object[i] = obj_ptr;
1292
1293 return(0);
1294 }
1295
1296 /*
1297 * Removes object from humans that need rescue list if it is in
1298 * there.
1299 */
SARObjRemoveFromHumanRescueList(sar_scene_struct * scene,sar_object_struct * obj_ptr)1300 void SARObjRemoveFromHumanRescueList(
1301 sar_scene_struct *scene,
1302 sar_object_struct *obj_ptr
1303 )
1304 {
1305 int i;
1306
1307 if((scene == NULL) || (obj_ptr == NULL))
1308 return;
1309
1310 for(i = 0; i < scene->total_human_need_rescue_objects; i++)
1311 {
1312 if(obj_ptr == scene->human_need_rescue_object[i])
1313 scene->human_need_rescue_object[i] = NULL;
1314 }
1315 }
1316
1317
1318 /*
1319 * Allocate (as needed) contact bounds structure to object
1320 * for shape SAR_CONTACT_SHAPE_SPHERICAL.
1321 *
1322 * Returns non-zero on error.
1323 */
SARObjAddContactBoundsSpherical(sar_object_struct * obj_ptr,sar_obj_flags_t crash_flags,int crash_type,float contact_radius)1324 int SARObjAddContactBoundsSpherical(
1325 sar_object_struct *obj_ptr,
1326 sar_obj_flags_t crash_flags, int crash_type,
1327 float contact_radius
1328 )
1329 {
1330 sar_contact_bounds_struct *cb;
1331
1332
1333 if(obj_ptr == NULL)
1334 return(-1);
1335
1336 /* Allocate as needed */
1337 if(obj_ptr->contact_bounds == NULL)
1338 obj_ptr->contact_bounds = SAR_CONTACT_BOUNDS(
1339 calloc(1, sizeof(sar_contact_bounds_struct))
1340 );
1341
1342 cb = obj_ptr->contact_bounds;
1343 if(cb == NULL)
1344 return(-1);
1345
1346 cb->crash_flags = crash_flags;
1347 cb->crash_type = crash_type;
1348 cb->contact_shape = SAR_CONTACT_SHAPE_SPHERICAL;
1349
1350 cb->contact_radius = (float)MAX(contact_radius, 0.0);
1351
1352 return(0);
1353 }
1354
1355 /*
1356 * Allocate (as needed) contact bounds structure to object
1357 * for shape SAR_CONTACT_SHAPE_CYLENDRICAL.
1358 *
1359 * Returns non-zero on error.
1360 */
SARObjAddContactBoundsCylendrical(sar_object_struct * obj_ptr,sar_obj_flags_t crash_flags,int crash_type,float contact_radius,float contact_h_min,float contact_h_max)1361 int SARObjAddContactBoundsCylendrical(
1362 sar_object_struct *obj_ptr,
1363 sar_obj_flags_t crash_flags, int crash_type,
1364 float contact_radius,
1365 float contact_h_min, float contact_h_max
1366 )
1367 {
1368 sar_contact_bounds_struct *cb;
1369
1370
1371 if(obj_ptr == NULL)
1372 return(-1);
1373
1374 /* Allocate as needed */
1375 if(obj_ptr->contact_bounds == NULL)
1376 obj_ptr->contact_bounds = SAR_CONTACT_BOUNDS(
1377 calloc(1, sizeof(sar_contact_bounds_struct))
1378 );
1379
1380 cb = obj_ptr->contact_bounds;
1381 if(cb == NULL)
1382 return(-1);
1383
1384 cb->crash_flags = crash_flags;
1385 cb->crash_type = crash_type;
1386 cb->contact_shape = SAR_CONTACT_SHAPE_CYLENDRICAL;
1387
1388 cb->contact_radius = (float)MAX(contact_radius, 0.0);
1389 cb->contact_h_min = contact_h_min;
1390 cb->contact_h_max = contact_h_max;
1391
1392 /* Flip height as needed */
1393 if(cb->contact_h_min > cb->contact_h_max)
1394 {
1395 float h = cb->contact_h_min;
1396
1397 cb->contact_h_min = cb->contact_h_max;
1398 cb->contact_h_max = h;
1399 }
1400
1401 return(0);
1402 }
1403
1404 /*
1405 * Allocate (as needed) contact bounds structure to object
1406 * for shape SAR_CONTACT_SHAPE_RECTANGULAR.
1407 *
1408 * Returns non-zero on error.
1409 */
SARObjAddContactBoundsRectangular(sar_object_struct * obj_ptr,sar_obj_flags_t crash_flags,int crash_type,float contact_x_min,float contact_x_max,float contact_y_min,float contact_y_max,float contact_z_min,float contact_z_max)1410 int SARObjAddContactBoundsRectangular(
1411 sar_object_struct *obj_ptr,
1412 sar_obj_flags_t crash_flags, int crash_type,
1413 float contact_x_min, float contact_x_max,
1414 float contact_y_min, float contact_y_max,
1415 float contact_z_min, float contact_z_max
1416 )
1417 {
1418 sar_contact_bounds_struct *cb;
1419
1420
1421 if(obj_ptr == NULL)
1422 return(-1);
1423
1424 /* Allocate as needed */
1425 if(obj_ptr->contact_bounds == NULL)
1426 obj_ptr->contact_bounds = SAR_CONTACT_BOUNDS(
1427 calloc(1, sizeof(sar_contact_bounds_struct))
1428 );
1429
1430 cb = obj_ptr->contact_bounds;
1431 if(cb == NULL)
1432 return(-1);
1433
1434 cb->crash_flags = crash_flags;
1435 cb->crash_type = crash_type;
1436 cb->contact_shape = SAR_CONTACT_SHAPE_RECTANGULAR;
1437
1438 cb->contact_x_min = contact_x_min;
1439 cb->contact_x_max = contact_x_max;
1440 if(cb->contact_x_min > cb->contact_x_max)
1441 {
1442 float d = cb->contact_x_min;
1443
1444 cb->contact_x_min = cb->contact_x_max;
1445 cb->contact_x_max = d;
1446 }
1447
1448 cb->contact_y_min = contact_y_min;
1449 cb->contact_y_max = contact_y_max;
1450 if(cb->contact_y_min > cb->contact_y_max)
1451 {
1452 float d = cb->contact_y_min;
1453
1454 cb->contact_y_min = cb->contact_y_max;
1455 cb->contact_y_max = d;
1456 }
1457
1458 cb->contact_z_min = contact_z_min;
1459 cb->contact_z_max = contact_z_max;
1460 if(cb->contact_z_min > cb->contact_z_max)
1461 {
1462 float d = cb->contact_z_min;
1463
1464 cb->contact_z_min = cb->contact_z_max;
1465 cb->contact_z_max = d;
1466 }
1467
1468 /* Calculate trig values based on object's current heading */
1469 cb->cos_heading = (float)cos(-obj_ptr->dir.heading);
1470 cb->sin_heading = (float)sin(-obj_ptr->dir.heading);
1471
1472 return(0);
1473 }
1474
1475
1476 /*
1477 * Adds an intercept to the object. Returns the allocated intercept
1478 * index number or -1 on error.
1479 */
SARObjInterceptNew(sar_scene_struct * scene,sar_intercept_struct *** ptr,int * total,sar_obj_flags_t flags,float x,float y,float z,float radius,float urgency,const char * name)1480 int SARObjInterceptNew(
1481 sar_scene_struct *scene,
1482 sar_intercept_struct ***ptr, int *total,
1483 sar_obj_flags_t flags,
1484 float x, float y, float z,
1485 float radius,
1486 float urgency,
1487 const char *name
1488 )
1489 {
1490 int n;
1491 sar_intercept_struct *intercept_ptr;
1492
1493
1494 if((ptr == NULL) || (total == NULL))
1495 return(-1);
1496
1497 /* Append intercept */
1498 n = MAX(*total, 0);
1499 *total = n + 1;
1500 *ptr = (sar_intercept_struct **)realloc(
1501 *ptr,
1502 (*total) * sizeof(sar_intercept_struct *)
1503 );
1504 if(*ptr == NULL)
1505 {
1506 *total = 0;
1507 return(-1);
1508 }
1509
1510 /* Allocate structure */
1511 (*ptr)[n] = intercept_ptr = (sar_intercept_struct *)calloc(
1512 1, sizeof(sar_intercept_struct)
1513 );
1514 if(intercept_ptr == NULL)
1515 return(-1);
1516
1517 /* Set values */
1518 intercept_ptr->flags = flags;
1519 intercept_ptr->x = x;
1520 intercept_ptr->y = y;
1521 intercept_ptr->z = z;
1522 intercept_ptr->radius = (float)MAX(radius, 0.0);
1523 intercept_ptr->urgency = (float)CLIP(urgency, 0.0, 1.0);
1524 intercept_ptr->name = STRDUP(name);
1525
1526 return(n);
1527 }
1528
1529
1530 /*
1531 * Nexus for creating a new Part in the Object Parts List.
1532 */
SARObjPartNewNexus(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total,sar_obj_part_type type)1533 static sar_obj_part_struct *SARObjPartNewNexus(
1534 sar_scene_struct *scene,
1535 sar_obj_part_struct ***ptr, int *total,
1536 sar_obj_part_type type
1537 )
1538 {
1539 int i, n;
1540 sar_obj_part_struct *part;
1541
1542 if((ptr == NULL) || (total == NULL))
1543 return(NULL);
1544
1545 for(i = 0; i < *total; i++)
1546 {
1547 if((*ptr)[i] == NULL)
1548 break;
1549 }
1550 if(i < *total)
1551 {
1552 n = i;
1553 }
1554 else
1555 {
1556 n = MAX(*total, 0);
1557 *total = n + 1;
1558
1559 *ptr = (sar_obj_part_struct **)realloc(
1560 *ptr,
1561 (*total) * sizeof(sar_obj_part_struct *)
1562 );
1563 if(*ptr == NULL)
1564 {
1565 *total = 0;
1566 return(NULL);
1567 }
1568 }
1569
1570 (*ptr)[n] = part = (sar_obj_part_struct *)calloc(
1571 1, sizeof(sar_obj_part_struct)
1572 );
1573 if(part == NULL)
1574 return(NULL);
1575
1576 part->type = type;
1577 part->flags = 0;
1578 part->temperature = SAR_DEF_TEMPERATURE;
1579
1580 return(part);
1581 }
1582
1583 /*
1584 * Creates a new Part on the Object Parts List.
1585 */
SARObjPartNew(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total,sar_obj_part_type type)1586 sar_obj_part_struct *SARObjPartNew(
1587 sar_scene_struct *scene,
1588 sar_obj_part_struct ***ptr, int *total,
1589 sar_obj_part_type type
1590 )
1591 {
1592 return(SARObjPartNewNexus(
1593 scene, ptr, total, type
1594 ));
1595 }
1596
1597 /*
1598 * Creates a new Air Brake on the Object Parts List.
1599 */
SARObjAirBrakeNew(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total)1600 sar_obj_part_struct *SARObjAirBrakeNew(
1601 sar_scene_struct *scene,
1602 sar_obj_part_struct ***ptr, int *total
1603 )
1604 {
1605 return(SARObjPartNewNexus(
1606 scene, ptr, total, SAR_OBJ_PART_TYPE_AIR_BRAKE
1607 ));
1608 }
1609
1610 /*
1611 * Creates a new Rescue Door on the Object Parts List.
1612 */
SARObjDoorRescueNew(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total)1613 sar_obj_part_struct *SARObjDoorRescueNew(
1614 sar_scene_struct *scene,
1615 sar_obj_part_struct ***ptr, int *total
1616 )
1617 {
1618 return(SARObjPartNewNexus(
1619 scene, ptr, total, SAR_OBJ_PART_TYPE_DOOR_RESCUE
1620 ));
1621 }
1622
1623 /*
1624 * Creates a new Landing Gear on the Object Parts List.
1625 */
SARObjLandingGearNew(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total)1626 sar_obj_part_struct *SARObjLandingGearNew(
1627 sar_scene_struct *scene,
1628 sar_obj_part_struct ***ptr, int *total
1629 )
1630 {
1631 return(SARObjPartNewNexus(
1632 scene, ptr, total, SAR_OBJ_PART_TYPE_LANDING_GEAR
1633 ));
1634 }
1635
1636 /*
1637 * Creates a new External Fuel Tank Object.
1638 */
SARObjExternalFuelTankNew(sar_scene_struct * scene,sar_external_fueltank_struct *** ptr,int * total)1639 int SARObjExternalFuelTankNew(
1640 sar_scene_struct *scene,
1641 sar_external_fueltank_struct ***ptr, int *total
1642 )
1643 {
1644 int i, n;
1645 sar_external_fueltank_struct *eft;
1646
1647 if((ptr == NULL) || (total == NULL))
1648 return(-1);
1649
1650 for(i = 0; i < (*total); i++)
1651 {
1652 if((*ptr)[i] == NULL)
1653 break;
1654 }
1655 if(i < *total)
1656 {
1657 n = i;
1658 }
1659 else
1660 {
1661 n = MAX(*total, 0);
1662 *total = (*total) + 1;
1663
1664 *ptr = (sar_external_fueltank_struct **)realloc(
1665 *ptr,
1666 (*total) * sizeof(sar_external_fueltank_struct *)
1667 );
1668 if(*ptr == NULL)
1669 {
1670 *total = 0;
1671 return(-1);
1672 }
1673 }
1674
1675 (*ptr)[n] = (sar_external_fueltank_struct *)calloc(
1676 1, sizeof(sar_external_fueltank_struct)
1677 );
1678 eft = (*ptr)[n];
1679 if(eft == NULL)
1680 return(-1);
1681
1682 /* Reset values */
1683 eft->flags = 0;
1684
1685 return(n);
1686 }
1687
1688 /*
1689 * Creates a new Rotor on the specified Object Rotors List.
1690 */
SARObjRotorNew(sar_scene_struct * scene,sar_obj_rotor_struct *** ptr,int * total)1691 int SARObjRotorNew(
1692 sar_scene_struct *scene,
1693 sar_obj_rotor_struct ***ptr, int *total
1694 )
1695 {
1696 int i, n;
1697 sar_obj_rotor_struct *rotor;
1698
1699 if((ptr == NULL) || (total == NULL))
1700 return(-1);
1701
1702 for(i = 0; i < *total; i++)
1703 {
1704 if((*ptr)[i] == NULL)
1705 break;
1706 }
1707 if(i < *total)
1708 {
1709 n = i;
1710 }
1711 else
1712 {
1713 n = MAX(*total, 0);
1714 *total = n + 1;
1715
1716 *ptr = (sar_obj_rotor_struct **)realloc(
1717 *ptr,
1718 (*total) * sizeof(sar_obj_rotor_struct *)
1719 );
1720 if(*ptr == NULL)
1721 {
1722 *total = 0;
1723 return(-1);
1724 }
1725 }
1726
1727 (*ptr)[n] = rotor = (sar_obj_rotor_struct *)calloc(
1728 1, sizeof(sar_obj_rotor_struct)
1729 );
1730 if(rotor == NULL)
1731 return(-1);
1732
1733 rotor->flags = 0;
1734 rotor->dir.heading = (float)(0.0 * PI);
1735 rotor->dir.pitch = (float)(0.5 * PI);
1736 rotor->dir.bank = (float)(0.0 * PI);
1737 rotor->blade_blur_tex_num = -1;
1738 rotor->wash_tex_num = -1;
1739
1740 return(n);
1741 }
1742
1743 /*
1744 * Creates a new Light on the specified Object Light List.
1745 */
SARObjLightNew(sar_scene_struct * scene,sar_light_struct *** ptr,int * total)1746 sar_light_struct *SARObjLightNew(
1747 sar_scene_struct *scene,
1748 sar_light_struct ***ptr, int *total
1749 )
1750 {
1751 int i, n;
1752 sar_light_struct *light;
1753
1754 if((ptr == NULL) || (total == NULL))
1755 return(NULL);
1756
1757 for(i = 0; i < *total; i++)
1758 {
1759 if((*ptr)[i] == NULL)
1760 break;
1761 }
1762 if(i < *total)
1763 {
1764 n = i;
1765 }
1766 else
1767 {
1768 n = MAX(*total, 0);
1769 *total = n + 1;
1770 *ptr = (sar_light_struct **)realloc(
1771 *ptr,
1772 (*total) * sizeof(sar_light_struct *)
1773 );
1774 if(*ptr == NULL)
1775 {
1776 *total = 0;
1777 return(NULL);
1778 }
1779 }
1780
1781 (*ptr)[n] = light = (sar_light_struct *)calloc(
1782 1, sizeof(sar_light_struct)
1783 );
1784 if(light == NULL)
1785 return(NULL);
1786
1787 light->flags = 0;
1788
1789 return(light);
1790 }
1791
1792
1793 /*
1794 * Creates a new Object on the specified Scene.
1795 */
SARObjNew(sar_scene_struct * scene,sar_object_struct *** ptr,int * total,int type)1796 int SARObjNew(
1797 sar_scene_struct *scene,
1798 sar_object_struct ***ptr, int *total,
1799 int type
1800 )
1801 {
1802 int i, n, len;
1803 sar_object_struct *obj_ptr;
1804
1805 if((scene == NULL) || (ptr == NULL) || (total == NULL) ||
1806 (type <= SAR_OBJ_TYPE_GARBAGE)
1807 )
1808 return(-1);
1809
1810 for(i = 0; i < *total; i++)
1811 {
1812 if((*ptr)[i] == NULL)
1813 break;
1814
1815 if((*ptr)[i]->type <= SAR_OBJ_TYPE_GARBAGE)
1816 break;
1817 }
1818 if(i < *total)
1819 {
1820 n = i;
1821 }
1822 else
1823 {
1824 n = MAX(*total, 0);
1825 (*total) = n + 1;
1826
1827 *ptr = (sar_object_struct **)realloc(
1828 *ptr,
1829 (*total) * sizeof(sar_object_struct *)
1830 );
1831 if(*ptr == NULL)
1832 {
1833 *total = 0;
1834 return(-1);
1835 }
1836
1837 (*ptr)[n] = NULL;
1838 }
1839
1840 /* Allocate object structure as needed */
1841 if((*ptr)[n] == NULL)
1842 {
1843 (*ptr)[n] = (sar_object_struct *)calloc(
1844 1, sizeof(sar_object_struct)
1845 );
1846 if((*ptr)[n] == NULL)
1847 return(-1);
1848 }
1849
1850 obj_ptr = (*ptr)[n];
1851
1852
1853 /* Set object type */
1854 obj_ptr->type = type;
1855
1856 obj_ptr->temperature = SAR_DEF_TEMPERATURE;
1857
1858 /* Mark birth time */
1859 obj_ptr->birth_time_ms = cur_millitime;
1860 obj_ptr->birth_time_sec = cur_systime;
1861
1862 /* Allocate substructure by the Object's type */
1863 switch(type)
1864 {
1865 case SAR_OBJ_TYPE_GARBAGE:
1866 len = 0;
1867 break;
1868 case SAR_OBJ_TYPE_STATIC:
1869 len = 0;
1870 break;
1871 case SAR_OBJ_TYPE_AUTOMOBILE:
1872 len = 0;
1873 break;
1874 case SAR_OBJ_TYPE_WATERCRAFT:
1875 len = 0;
1876 break;
1877 case SAR_OBJ_TYPE_AIRCRAFT:
1878 len = sizeof(sar_object_aircraft_struct);
1879 break;
1880 case SAR_OBJ_TYPE_GROUND:
1881 len = sizeof(sar_object_ground_struct);
1882 break;
1883 case SAR_OBJ_TYPE_RUNWAY:
1884 len = sizeof(sar_object_runway_struct);
1885 break;
1886 case SAR_OBJ_TYPE_HELIPAD:
1887 len = sizeof(sar_object_helipad_struct);
1888 break;
1889 case SAR_OBJ_TYPE_HUMAN:
1890 len = sizeof(sar_object_human_struct);
1891 break;
1892 case SAR_OBJ_TYPE_SMOKE:
1893 len = sizeof(sar_object_smoke_struct);
1894 break;
1895 case SAR_OBJ_TYPE_FIRE:
1896 len = sizeof(sar_object_fire_struct);;
1897 break;
1898 case SAR_OBJ_TYPE_EXPLOSION:
1899 len = sizeof(sar_object_explosion_struct);
1900 break;
1901 case SAR_OBJ_TYPE_FUELTANK:
1902 len = sizeof(sar_object_fueltank_struct);
1903 break;
1904 case SAR_OBJ_TYPE_PREMODELED:
1905 len = sizeof(sar_object_premodeled_struct);
1906 break;
1907 default:
1908 len = 0;
1909 break;
1910 }
1911
1912 /* If size of substructure is positive then allocate it */
1913 if(len > 0)
1914 obj_ptr->data = calloc(1, len);
1915 else
1916 obj_ptr->data = NULL;
1917
1918
1919 /* If object type is SAR_OBJ_TYPE_GROUND, then add it to the
1920 * scene's list of ground objects
1921 */
1922 if((scene != NULL) &&
1923 (obj_ptr->type == SAR_OBJ_TYPE_GROUND)
1924 )
1925 SARObjAddToGroundList(scene, obj_ptr);
1926
1927
1928 return(n);
1929 }
1930
1931
1932 /*
1933 * Deletes all intercept structures in the given array.
1934 */
SARObjDeleteIntercepts(sar_scene_struct * scene,sar_intercept_struct *** ptr,int * total)1935 void SARObjDeleteIntercepts(
1936 sar_scene_struct *scene,
1937 sar_intercept_struct ***ptr, int *total
1938 )
1939 {
1940 int i;
1941 sar_intercept_struct *intercept_ptr;
1942
1943
1944 if((ptr == NULL) || (total == NULL))
1945 return;
1946
1947 for(i = 0; i < (*total); i++)
1948 {
1949 intercept_ptr = (*ptr)[i];
1950 if(intercept_ptr == NULL)
1951 continue;
1952
1953 free(intercept_ptr->name);
1954 free(intercept_ptr);
1955 }
1956
1957 free(*ptr);
1958 (*ptr) = NULL;
1959 (*total) = 0;
1960 }
1961
1962 /*
1963 * Deletes all structures and resources in the array of light
1964 * structures.
1965 */
SARObjDeleteLights(sar_scene_struct * scene,sar_light_struct *** ptr,int * total)1966 void SARObjDeleteLights(
1967 sar_scene_struct *scene,
1968 sar_light_struct ***ptr, int *total
1969 )
1970 {
1971 int i;
1972 sar_light_struct *light;
1973
1974
1975 if((ptr == NULL) || (total == NULL))
1976 return;
1977
1978 for(i = 0; i < *total; i++)
1979 {
1980 light = (*ptr)[i];
1981 if(light == NULL)
1982 continue;
1983
1984 free(light);
1985 }
1986
1987 free(*ptr);
1988 *ptr = NULL;
1989 *total = 0;
1990 }
1991
1992
1993 /*
1994 * Delete the list of object parts.
1995 */
SARObjDeleteParts(sar_scene_struct * scene,sar_obj_part_struct *** ptr,int * total)1996 void SARObjDeleteParts(
1997 sar_scene_struct *scene,
1998 sar_obj_part_struct ***ptr, int *total
1999 )
2000 {
2001 int i;
2002 sar_obj_part_struct *part;
2003
2004 if((ptr == NULL) || (total == NULL))
2005 return;
2006
2007 for(i = 0; i < *total; i++)
2008 {
2009 part = (*ptr)[i];
2010 if(part == NULL)
2011 continue;
2012
2013 SARVisualModelUnref(scene, part->visual_model);
2014 SARVisualModelUnref(scene, part->visual_model_ir);
2015 free(part);
2016 }
2017
2018 free(*ptr);
2019 (*ptr) = NULL;
2020 (*total) = 0;
2021 }
2022
2023
2024 /*
2025 * Deletes the list of external fuel tanks.
2026 */
SARObjDeleteExternalFuelTanks(sar_scene_struct * scene,sar_external_fueltank_struct *** ptr,int * total)2027 void SARObjDeleteExternalFuelTanks(
2028 sar_scene_struct *scene,
2029 sar_external_fueltank_struct ***ptr, int *total
2030 )
2031 {
2032 int i;
2033 sar_external_fueltank_struct *eft;
2034
2035 for(i = 0; i < (*total); i++)
2036 {
2037 eft = (*ptr)[i];
2038 if(eft == NULL)
2039 continue;
2040
2041 SARVisualModelUnref(scene, eft->visual_model);
2042 SARVisualModelUnref(scene, eft->visual_model_ir);
2043 free(eft);
2044 }
2045
2046 free(*ptr);
2047 (*ptr) = NULL;
2048
2049 (*total) = 0;
2050 }
2051
2052 /*
2053 * Deletes all structures and resources in the array of landing
2054 * gear structures.
2055 */
SARObjDeleteRotors(sar_scene_struct * scene,sar_obj_rotor_struct *** ptr,int * total)2056 void SARObjDeleteRotors(
2057 sar_scene_struct *scene,
2058 sar_obj_rotor_struct ***ptr, int *total
2059 )
2060 {
2061 int i;
2062 sar_obj_rotor_struct *rotor;
2063
2064 if((ptr == NULL) || (total == NULL))
2065 return;
2066
2067 for(i = 0; i < *total; i++)
2068 {
2069 rotor = (*ptr)[i];
2070 if(rotor == NULL)
2071 continue;
2072
2073 SARVisualModelUnref(scene, rotor->visual_model);
2074 SARVisualModelUnref(scene, rotor->visual_model_ir);
2075 free(rotor);
2076 }
2077
2078 free(*ptr);
2079 *ptr = NULL;
2080 *total = 0;
2081 }
2082
2083 /*
2084 * Deletes object n from the array, setting it to NULL.
2085 */
SARObjDelete(void * core_ptr,sar_object_struct *** ptr,int * total,int n)2086 void SARObjDelete(
2087 void *core_ptr,
2088 sar_object_struct ***ptr, int *total, int n
2089 )
2090 {
2091 sar_core_struct *cp = core_ptr;
2092 sar_scene_struct *scene;
2093 snd_recorder_struct *recorder;
2094
2095 if(cp == NULL)
2096 return;
2097
2098 scene = cp->scene;
2099 if(scene == NULL)
2100 {
2101 fprintf(
2102 stderr,
2103 "SARObjDelete(): Error: Scene is NULL.\n"
2104 );
2105 return;
2106 }
2107
2108 recorder = cp->recorder;
2109
2110 if(SARObjIsAllocated(*ptr, *total, n))
2111 {
2112 int i;
2113 sar_object_struct *obj_ptr, *obj_ptr2;
2114 sar_object_aircraft_struct *aircraft;
2115 sar_object_runway_struct *runway;
2116 sar_object_helipad_struct *helipad;
2117 sar_object_ground_struct *ground;
2118 sar_object_smoke_struct *smoke;
2119 sar_object_explosion_struct *explosion;
2120 sar_object_fire_struct *fire;
2121 sar_object_chemical_spray_struct *chemical_spray;
2122 sar_object_fueltank_struct *fueltank;
2123 sar_object_human_struct *human;
2124 sar_object_premodeled_struct *premodeled;
2125
2126
2127 obj_ptr = (*ptr)[n];
2128
2129 #define VISUAL_MODEL_UNREF(_vm_) \
2130 SARVisualModelUnref(scene, (_vm_))
2131
2132 #define SOUND_STOP_PLAY(_sp_) \
2133 SoundStopPlay(recorder, (_sp_))
2134
2135 /* Delete substructure */
2136 if(obj_ptr->data != NULL)
2137 {
2138 switch(obj_ptr->type)
2139 {
2140 case SAR_OBJ_TYPE_GARBAGE:
2141 case SAR_OBJ_TYPE_STATIC:
2142 case SAR_OBJ_TYPE_AUTOMOBILE:
2143 case SAR_OBJ_TYPE_WATERCRAFT:
2144 break;
2145 case SAR_OBJ_TYPE_AIRCRAFT:
2146 aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
2147 if(aircraft != NULL)
2148 {
2149 sar_obj_hoist_struct *hoist;
2150
2151 /* Engine sound play object and source index */
2152 SOUND_STOP_PLAY(aircraft->engine_inside_sndplay);
2153 aircraft->engine_inside_sndsrc = -1;
2154
2155 SOUND_STOP_PLAY(aircraft->engine_outside_sndplay);
2156 aircraft->engine_outside_sndsrc = -1;
2157
2158 /* Repeating warning sound play object and source index */
2159 SOUND_STOP_PLAY(aircraft->stall_sndplay);
2160 aircraft->stall_sndsrc = -1;
2161
2162 SOUND_STOP_PLAY(aircraft->overspeed_sndplay);
2163 aircraft->overspeed_sndsrc = -1;
2164
2165 /* Cockpit visual model */
2166 VISUAL_MODEL_UNREF(aircraft->visual_model_cockpit);
2167
2168 /* Delete all parts and their visual models */
2169 SARObjDeleteParts(
2170 scene, &aircraft->part, &aircraft->total_parts
2171 );
2172
2173 /* Delete all rotors and their visual models */
2174 SARObjDeleteRotors(
2175 scene, &aircraft->rotor, &aircraft->total_rotors
2176 );
2177
2178 /* Delete all external fuel tanks and their visual models */
2179 SARObjDeleteExternalFuelTanks(
2180 scene,
2181 &aircraft->external_fueltank,
2182 &aircraft->total_external_fueltanks
2183 );
2184
2185 /* Delete hoist */
2186 hoist = aircraft->hoist;
2187 if(hoist != NULL)
2188 {
2189 free(hoist->occupant);
2190 free(hoist);
2191 aircraft->hoist = NULL;
2192 }
2193
2194 /* Delete all way pointer intercepts */
2195 SARObjDeleteIntercepts(
2196 scene,
2197 &aircraft->intercept,
2198 &aircraft->total_intercepts
2199 );
2200
2201 /* Flight dynamics model */
2202 if((scene->realm != NULL) &&
2203 (aircraft->fdm != NULL)
2204 )
2205 {
2206 SFMModelDelete(scene->realm, aircraft->fdm);
2207 #if 0
2208 /* SFM fdm destroy callback will call our
2209 * callback function to set this pointer to
2210 * NULL
2211 */
2212 aircraft->fdm = NULL;
2213 #endif
2214 }
2215 }
2216 break;
2217 case SAR_OBJ_TYPE_GROUND:
2218 ground = SAR_OBJ_GET_GROUND(obj_ptr);
2219 if(ground != NULL)
2220 {
2221 /* Heightfield z points map */
2222 free(ground->z_point_value);
2223 ground->z_point_value = NULL;
2224
2225 ground->grid_points_x = 0;
2226 ground->grid_points_y = 0;
2227 ground->grid_points_total = 0;
2228 }
2229 break;
2230 case SAR_OBJ_TYPE_RUNWAY:
2231 runway = SAR_OBJ_GET_RUNWAY(obj_ptr);
2232 if(runway != NULL)
2233 {
2234 free(runway->north_label);
2235 free(runway->south_label);
2236 VISUAL_MODEL_UNREF(runway->north_label_vmodel);
2237 VISUAL_MODEL_UNREF(runway->south_label_vmodel);
2238 VISUAL_MODEL_UNREF(runway->threshold_vmodel);
2239 VISUAL_MODEL_UNREF(runway->td_marker_vmodel);
2240 VISUAL_MODEL_UNREF(runway->midway_marker_vmodel);
2241 VISUAL_MODEL_UNREF(
2242 runway->north_displaced_threshold_vmodel
2243 );
2244 VISUAL_MODEL_UNREF(
2245 runway->south_displaced_threshold_vmodel
2246 );
2247 }
2248 break;
2249 case SAR_OBJ_TYPE_HELIPAD:
2250 helipad = SAR_OBJ_GET_HELIPAD(obj_ptr);
2251 if(helipad != NULL)
2252 {
2253 free(helipad->label);
2254 VISUAL_MODEL_UNREF(helipad->label_vmodel);
2255 }
2256 break;
2257 case SAR_OBJ_TYPE_HUMAN:
2258 human = SAR_OBJ_GET_HUMAN(obj_ptr);
2259 if(human != NULL)
2260 {
2261 free(human->mesg_enter);
2262 }
2263 break;
2264 case SAR_OBJ_TYPE_SMOKE:
2265 smoke = SAR_OBJ_GET_SMOKE(obj_ptr);
2266 if(smoke != NULL)
2267 {
2268 free(smoke->unit);
2269 smoke->unit = NULL;
2270 smoke->total_units = 0;
2271 }
2272 break;
2273 case SAR_OBJ_TYPE_FIRE:
2274 fire = SAR_OBJ_GET_FIRE(obj_ptr);
2275 if(fire != NULL)
2276 {
2277
2278 }
2279 break;
2280 case SAR_OBJ_TYPE_EXPLOSION:
2281 explosion = SAR_OBJ_GET_EXPLOSION(obj_ptr);
2282 if(explosion != NULL)
2283 {
2284
2285 }
2286 break;
2287 case SAR_OBJ_TYPE_CHEMICAL_SPRAY:
2288 chemical_spray = SAR_OBJ_GET_CHEMICAL_SPRAY(obj_ptr);
2289 if(chemical_spray != NULL)
2290 {
2291 chemical_spray->owner = -1;
2292 chemical_spray->tex_num = -1;
2293 }
2294 break;
2295 case SAR_OBJ_TYPE_FUELTANK:
2296 fueltank = SAR_OBJ_GET_FUELTANK(obj_ptr);
2297 if(fueltank != NULL)
2298 {
2299
2300 }
2301 break;
2302 case SAR_OBJ_TYPE_PREMODELED:
2303 premodeled = SAR_OBJ_GET_PREMODELED(obj_ptr);
2304 if(premodeled != NULL)
2305 {
2306
2307 }
2308 break;
2309 }
2310
2311 free(obj_ptr->data);
2312 obj_ptr->data = NULL;
2313 }
2314
2315 /* Delete standard visual models */
2316 VISUAL_MODEL_UNREF(obj_ptr->visual_model_shadow);
2317 VISUAL_MODEL_UNREF(obj_ptr->visual_model_night);
2318 VISUAL_MODEL_UNREF(obj_ptr->visual_model_dusk);
2319 VISUAL_MODEL_UNREF(obj_ptr->visual_model_dawn);
2320 VISUAL_MODEL_UNREF(obj_ptr->visual_model_far);
2321 VISUAL_MODEL_UNREF(obj_ptr->visual_model_ir);
2322 VISUAL_MODEL_UNREF(obj_ptr->visual_model);
2323
2324 /* Delete contact bounds */
2325 if(obj_ptr->contact_bounds != NULL)
2326 {
2327 free(obj_ptr->contact_bounds);
2328 obj_ptr->contact_bounds = NULL;
2329 }
2330
2331 /* Delete lights */
2332 SARObjDeleteLights(
2333 scene,
2334 &obj_ptr->light, &obj_ptr->total_lights
2335 );
2336
2337 /* Delete sound sources */
2338 for(i = 0; i < obj_ptr->total_sndsrcs; i++)
2339 SARSoundSourceDelete(obj_ptr->sndsrc[i]);
2340 free(obj_ptr->sndsrc);
2341 obj_ptr->sndsrc = NULL;
2342 obj_ptr->total_sndsrcs = 0;
2343
2344
2345 /* Delete name */
2346 free(obj_ptr->name);
2347 obj_ptr->name = NULL;
2348
2349 /* Delete the Object itself */
2350 free(obj_ptr);
2351 (*ptr)[n] = NULL;
2352
2353
2354 /* Object has now been deleted, now we need to check if
2355 * any other objects are referencing this object
2356 *
2357 * If so, then we need to reset those references
2358 */
2359 for(i = 0; i < *total; i++)
2360 {
2361 obj_ptr2 = (*ptr)[i];
2362 if(obj_ptr2 == NULL)
2363 continue;
2364
2365 /* Skip this object */
2366 if(i == n)
2367 continue;
2368
2369 switch(obj_ptr2->type)
2370 {
2371 case SAR_OBJ_TYPE_GARBAGE:
2372 case SAR_OBJ_TYPE_STATIC:
2373 case SAR_OBJ_TYPE_AUTOMOBILE:
2374 case SAR_OBJ_TYPE_WATERCRAFT:
2375 case SAR_OBJ_TYPE_AIRCRAFT:
2376 case SAR_OBJ_TYPE_GROUND:
2377 case SAR_OBJ_TYPE_RUNWAY:
2378 break;
2379 case SAR_OBJ_TYPE_HELIPAD:
2380 helipad = SAR_OBJ_GET_HELIPAD(obj_ptr2);
2381 if(helipad != NULL)
2382 {
2383 if(helipad->ref_object == n)
2384 helipad->ref_object = -1;
2385 }
2386 break;
2387 case SAR_OBJ_TYPE_HUMAN:
2388 human = SAR_OBJ_GET_HUMAN(obj_ptr2);
2389 if(human != NULL)
2390 {
2391 if(human->intercepting_object == n)
2392 human->intercepting_object = -1;
2393 }
2394 break;
2395 case SAR_OBJ_TYPE_SMOKE:
2396 smoke = SAR_OBJ_GET_SMOKE(obj_ptr2);
2397 if(smoke != NULL)
2398 {
2399 if(smoke->ref_object == n)
2400 smoke->ref_object = -1;
2401 }
2402 break;
2403 case SAR_OBJ_TYPE_FIRE:
2404 fire = SAR_OBJ_GET_FIRE(obj_ptr2);
2405 if(fire != NULL)
2406 {
2407 if(fire->ref_object == n)
2408 fire->ref_object = -1;
2409 }
2410 break;
2411 case SAR_OBJ_TYPE_EXPLOSION:
2412 explosion = SAR_OBJ_GET_EXPLOSION(obj_ptr2);
2413 if(explosion != NULL)
2414 {
2415 if(explosion->ref_object == n)
2416 explosion->ref_object = -1;
2417 }
2418 break;
2419 case SAR_OBJ_TYPE_CHEMICAL_SPRAY:
2420 chemical_spray = SAR_OBJ_GET_CHEMICAL_SPRAY(obj_ptr2);
2421 if(chemical_spray != NULL)
2422 {
2423 if(chemical_spray->owner == n)
2424 chemical_spray->owner = -1;
2425 }
2426 break;
2427 case SAR_OBJ_TYPE_FUELTANK:
2428 fueltank = SAR_OBJ_GET_FUELTANK(obj_ptr2);
2429 if(fueltank != NULL)
2430 {
2431 if(fueltank->ref_object == n)
2432 fueltank->ref_object = -1;
2433 }
2434 break;
2435 case SAR_OBJ_TYPE_PREMODELED:
2436 break;
2437 }
2438 }
2439
2440 /* Unreference this object from the scene structure so that
2441 * no other resources check the scene structure and mistake
2442 * the object as still being allocated
2443 */
2444 if(scene != NULL)
2445 {
2446 /* Was this referenced as the player object? */
2447 if(obj_ptr == scene->player_obj_ptr)
2448 scene->player_obj_ptr = NULL;
2449
2450 if(n == scene->player_obj_num)
2451 scene->player_obj_num = -1;
2452
2453 /* Was this referenced as the camera target? */
2454 if(n == scene->camera_target)
2455 scene->camera_target = -1;
2456
2457 /* Remove this object from ground list as needed */
2458 SARObjRemoveFromGroundList(scene, obj_ptr);
2459
2460 /* Remove this object from human need rescue list as needed */
2461 SARObjRemoveFromHumanRescueList(scene, obj_ptr);
2462 }
2463
2464 #undef VISUAL_MODEL_UNREF
2465 #undef SOUND_STOP_PLAY
2466 }
2467 }
2468
2469 /*
2470 * Generates an array of tiles. The call to begin a list and
2471 * set up color and texture should already have been made before
2472 * calling this function.
2473 */
SARObjGenerateTilePlane(float min,float max,float tile_width,float tile_height)2474 void SARObjGenerateTilePlane(
2475 float min, float max, /* In meters */
2476 float tile_width, float tile_height
2477 )
2478 {
2479 float x, y, x2, y2;
2480
2481
2482 /* Begin gl instructions */
2483 glBegin(GL_QUADS);
2484
2485 /* Quadrant 1 is `upper right' and quadrants are numbed
2486 * clockwise.
2487 */
2488
2489 /* Quads in quadrant 1 */
2490 for(y = 0; y < max; y += tile_height)
2491 {
2492 for(x = 0; x < max; x += tile_width)
2493 {
2494 x2 = x + tile_width;
2495 y2 = y + tile_height;
2496 {
2497 glNormal3f(0.0f, 1.0f, 0.0f);
2498 glTexCoord2f(0.0f, 1.0f - 0.0f);
2499 glVertex3f((GLfloat)x, (GLfloat)0.0f, (GLfloat)-y);
2500 glTexCoord2f(1.0f, 1.0f - 0.0f);
2501 glVertex3f((GLfloat)x2, (GLfloat)0.0f, (GLfloat)-y);
2502 glTexCoord2f(1.0f, 1.0f - 1.0f);
2503 glVertex3f((GLfloat)x2, (GLfloat)0.0f, (GLfloat)-y2);
2504 glTexCoord2f(0.0f, 1.0f - 1.0f);
2505 glVertex3f((GLfloat)x, (GLfloat)0.0f, (GLfloat)-y2);
2506 }
2507 }
2508 }
2509 /* Quads in quadrant 2 */
2510 for(y = 0; y > min; y -= tile_height)
2511 {
2512 for(x = 0; x < max; x += tile_width)
2513 {
2514 x2 = x + tile_width;
2515 y2 = y - tile_height;
2516 {
2517 glNormal3f(0.0f, 1.0f, 0.0f);
2518 glTexCoord2f(0.0f, 1.0f - 0.0f);
2519 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y2);
2520 glTexCoord2f(1.0f, 1.0f - 0.0f);
2521 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y2);
2522 glTexCoord2f(1.0f, 1.0f - 1.0f);
2523 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y);
2524 glTexCoord2f(0.0f, 1.0f - 1.0f);
2525 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y);
2526 }
2527 }
2528 }
2529 /* Quads in quadrant 3 */
2530 for(y = 0; y > min; y -= tile_height)
2531 {
2532 for(x = 0; x > min; x -= tile_width)
2533 {
2534 x2 = x - tile_width;
2535 y2 = y - tile_height;
2536 {
2537 glNormal3f(0.0f, 1.0f, 0.0f);
2538 glTexCoord2f(1.0f, 1.0f - 1.0f);
2539 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y);
2540 glTexCoord2f(0.0f, 1.0f - 1.0f);
2541 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y);
2542 glTexCoord2f(0.0f, 1.0f - 0.0f);
2543 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y2);
2544 glTexCoord2f(1.0f, 1.0f - 0.0f);
2545 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y2);
2546 }
2547 }
2548 }
2549 /* Quads in quadrant 4 */
2550 for(y = 0; y < max; y += tile_height)
2551 {
2552 for(x = 0; x > min; x -= tile_width)
2553 {
2554 x2 = x - tile_width;
2555 y2 = y + tile_height;
2556 {
2557 glNormal3f(0.0f, 1.0f, 0.0f);
2558 glTexCoord2f(1.0f, 1.0f - 1.0f);
2559 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y2);
2560 glTexCoord2f(0.0f, 1.0f - 1.0f);
2561 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y2);
2562 glTexCoord2f(0.0f, 1.0f - 0.0f);
2563 glVertex3f((GLfloat)x2, 0.0f, (GLfloat)-y);
2564 glTexCoord2f(1.0f, 1.0f - 0.0f);
2565 glVertex3f((GLfloat)x, 0.0f, (GLfloat)-y);
2566 }
2567 }
2568 }
2569 glEnd();
2570 }
2571