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