1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 
6 #ifdef __MSW__
7 # include <windows.h>
8 #endif
9 
10 #include "obj.h"
11 #include "objsound.h"
12 #include "objutils.h"
13 #include "sound.h"
14 #include "sar.h"
15 #include "scenesound.h"
16 #include "config.h"
17 
18 
19 void SARSceneSoundUpdate(
20 	sar_core_struct *core_ptr,
21 	Boolean engine_sounds,
22 	Boolean event_sounds,
23 	Boolean voice_sounds,
24 	Boolean music
25 );
26 
27 
28 #define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
29 #define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
30 #define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
31 #define STRDUP(s)       (((s) != NULL) ? strdup(s) : NULL)
32 
33 #define MAX(a,b)        (((a) > (b)) ? (a) : (b))
34 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
35 #define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
36 #define STRLEN(s)       (((s) != NULL) ? ((int)strlen(s)) : 0)
37 
38 
39 /*
40  *	Updates all sound resources on the core's scene structure and
41  *	its objects with respect to the given sound conditions. Purpose
42  *	for this function is to start or stop sounds at startup or as the
43  *	sound options change in the middle of a game.
44  *
45  *	The core structure's scene must be valid (not NULL).
46  *	If the core structure's recorder is NULL and any given inputs
47  *	suggest sound is to be enabled then the recorder will be
48  *	initialized.
49  *
50  *	The core structure's recorder will never be shut down by this
51  *	function.
52  */
SARSceneSoundUpdate(sar_core_struct * core_ptr,Boolean engine_sounds,Boolean event_sounds,Boolean voice_sounds,Boolean music)53 void SARSceneSoundUpdate(
54 	sar_core_struct *core_ptr,
55 	Boolean engine_sounds,
56 	Boolean event_sounds,
57 	Boolean voice_sounds,
58 	Boolean music
59 )
60 {
61 	int obj_num;
62 	const char *name;
63 	int sndsrc_num;
64 	sar_object_struct *obj_ptr;
65 	sar_object_aircraft_struct *aircraft;
66 	void **snd_play_rtn;
67 	const char *sound_server_connect_arg = "127.0.0.1:9433";
68 	gw_display_struct *display = core_ptr->display;
69 	sar_scene_struct *scene = core_ptr->scene;
70 	snd_recorder_struct *recorder = core_ptr->recorder;
71 
72 	/* Is recorder NULL? */
73 	if(recorder == NULL)
74 	{
75 	    /* Turn sound on? */
76 	    if(engine_sounds || event_sounds || voice_sounds ||
77 	       music
78 	    )
79 	    {
80 		/* Need to initialize recorder. */
81 		void *window;
82                 int type;
83 
84                 #ifdef Y_H
85                 type = SNDSERV_TYPE_Y;
86                 #else
87                 type = SNDSERV_TYPE_SDL;
88                 #endif
89 		GWContextGet(
90 		    display, GWContextCurrent(display),
91 		    &window, NULL,
92 		    NULL, NULL, NULL, NULL
93 		);
94 
95 		GWSetInputBusy(core_ptr->display);
96 		recorder = SoundInit(
97 		    core_ptr, type,
98 		    sound_server_connect_arg,
99 		    NULL,          /* Do not start sound server. */
100 		    window
101 		);
102 		if(recorder == NULL)
103 		{
104 		    const char *con_arg = sound_server_connect_arg;
105 		    char *buf = (char *)malloc(
106 			(256 + STRLEN(con_arg)) * sizeof(char)
107 		    );
108 		    sprintf(
109 			buf,
110 "Unable to connect to sound server at:\n\n    %s",
111 			con_arg
112 		    );
113 		    GWOutputMessage(
114 			core_ptr->display,
115 			GWOutputMessageTypeError,
116 			"Sound initialization failed!",
117 			buf,
118 "Please check to make sure that your sound server\n\
119 is running and available at the specified address.\n\
120 Also make sure that you have sufficient permission\n\
121 to connect to it."
122 		    );
123 		    free(buf);
124 		}
125 		else
126 		{
127 		    core_ptr->recorder = recorder;
128 
129 		    SoundChangeMode(
130 			core_ptr->recorder, core_ptr->audio_mode_name
131 		    );
132 		}
133 		GWSetInputReady(core_ptr->display);
134 	    }
135 	    else
136 	    {
137 		/* Recorder not initialized and sound is turned off,
138 		 * there is nothing further to do.
139 		 */
140 		return;
141 	    }
142 	}
143 
144 	/* Scene structure must be valid. */
145 	if(scene == NULL)
146 	    return;
147 
148 
149 	/* Update sounds on the scene structure. */
150 
151 
152 
153 
154 	/* Update sounds on each object. */
155 	for(obj_num = 0; obj_num < core_ptr->total_objects; obj_num++)
156 	{
157 	    obj_ptr = core_ptr->object[obj_num];
158 	    if(obj_ptr == NULL)
159 		continue;
160 
161 	    switch(obj_ptr->type)
162 	    {
163 	      case SAR_OBJ_TYPE_GARBAGE:
164 	      case SAR_OBJ_TYPE_STATIC:
165 	      case SAR_OBJ_TYPE_AUTOMOBILE:
166 	      case SAR_OBJ_TYPE_WATERCRAFT:
167 		break;
168 	      case SAR_OBJ_TYPE_AIRCRAFT:
169 		aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr);
170 		if(aircraft != NULL)
171 		{
172 #define DO_LOAD_ENGINE_SOUND				\
173 { if(*snd_play_rtn == NULL)				\
174   *snd_play_rtn = SARSoundSourcePlayFromListRepeating(	\
175    recorder, obj_ptr->sndsrc, obj_ptr->total_sndsrcs,	\
176    name, &sndsrc_num					\
177   );							\
178 }
179 #define DO_UNLOAD_ENGINE_SOUND				\
180 { if(*snd_play_rtn != NULL)				\
181  {							\
182   SoundStopPlay(recorder, *snd_play_rtn);		\
183   *snd_play_rtn = NULL;					\
184  }							\
185 }
186 		    /* Load/unload engine sounds. */
187 		    if(engine_sounds)
188 		    {
189 			/* Turn engine sounds on as needed. */
190 
191 			name = "engine_inside";
192 			snd_play_rtn = &aircraft->engine_inside_sndplay;
193 			DO_LOAD_ENGINE_SOUND
194 			aircraft->engine_inside_sndsrc = sndsrc_num;
195 
196 			name = "engine_outside";
197 			snd_play_rtn = &aircraft->engine_outside_sndplay;
198 			DO_LOAD_ENGINE_SOUND
199 			aircraft->engine_outside_sndsrc = sndsrc_num;
200 		    }
201 		    else
202 		    {
203 			/* Turn engine sounds off as needed. */
204 
205 			snd_play_rtn = &aircraft->engine_inside_sndplay;
206 			DO_UNLOAD_ENGINE_SOUND
207 
208 			snd_play_rtn = &aircraft->engine_outside_sndplay;
209 			DO_UNLOAD_ENGINE_SOUND
210 		    }
211 #undef DO_UNLOAD_ENGINE_SOUND
212 #undef DO_LOAD_ENGINE_SOUND
213 
214 #define DO_GET_SNDSRC_INDEX	{			\
215  sndsrc_num = SARSoundSourceMatchFromList(		\
216   obj_ptr->sndsrc, obj_ptr->total_sndsrcs,		\
217   name							\
218  );							\
219 }
220 		    /* Get sound source index of warning sounds. */
221 		    if(event_sounds)
222 		    {
223 			name = "stall";
224 			DO_GET_SNDSRC_INDEX
225 			aircraft->stall_sndsrc = sndsrc_num;
226 
227 			name = "overspeed";
228 			DO_GET_SNDSRC_INDEX
229 			aircraft->overspeed_sndsrc = sndsrc_num;
230 
231 		    }
232 #undef DO_GET_SNDSRC_INDEX
233 		}
234 		break;
235 	      case SAR_OBJ_TYPE_GROUND:
236 	      case SAR_OBJ_TYPE_RUNWAY:
237 	      case SAR_OBJ_TYPE_HELIPAD:
238 	      case SAR_OBJ_TYPE_HUMAN:
239 	      case SAR_OBJ_TYPE_SMOKE:
240 	      case SAR_OBJ_TYPE_FIRE:
241 	      case SAR_OBJ_TYPE_EXPLOSION:
242 	      case SAR_OBJ_TYPE_CHEMICAL_SPRAY:
243 	      case SAR_OBJ_TYPE_FUELTANK:
244 	      case SAR_OBJ_TYPE_PREMODELED:
245 		break;
246 	    }
247 	}
248 
249 
250 }
251