1 // MODULE FOR SOUND SYSTEM
2 
3 #include "Directories.h"
4 #include "Sound_Control.h"
5 #include "SoundMan.h"
6 #include "Overhead.h"
7 #include "Isometric_Utils.h"
8 #include "RenderWorld.h"
9 #include <math.h>
10 
11 
12 #define SOUND_FAR_VOLUME_MOD 25
13 
14 static UINT32 guiSpeechVolume       = MIDVOLUME;
15 static UINT32 guiSoundEffectsVolume = MIDVOLUME;
16 
17 static char const* const szSoundEffects[NUM_SAMPLES] =
18 {
19 	SOUNDSDIR "/ricochet 01.wav",                               // 0
20 	SOUNDSDIR "/ricochet 02.wav",                               // 1
21 	SOUNDSDIR "/ricochet 01.wav",                               // 2
22 	SOUNDSDIR "/ricochet 02.wav",                               // 3
23 	SOUNDSDIR "/ricochet 01.wav",                               // 4
24 	SOUNDSDIR "/ricochet 02.wav",                               // 5
25 	SOUNDSDIR "/ricochet 01.wav",                               // 6
26 	SOUNDSDIR "/ricochet 02.wav",                               // 7
27 	SOUNDSDIR "/dirt impact 01.wav",                            // 8
28 	SOUNDSDIR "/dirt impact 01.wav",                            // 9
29 	SOUNDSDIR "/knife hit ground.wav",                          // 10
30 	SOUNDSDIR "/fall to knees 01.wav",                          // 11
31 	SOUNDSDIR "/fall to knees 02.wav",                          // 12
32 	SOUNDSDIR "/knees to dirt 01.wav",                          // 13
33 	SOUNDSDIR "/knees to dirt 02.wav",                          // 14
34 	SOUNDSDIR "/knees to dirt 03.wav",                          // 15
35 	SOUNDSDIR "/heavy fall 01.wav",                             // 16
36 	SOUNDSDIR "/body_splat.wav",                                // 17
37 	SOUNDSDIR "/glass_break1.wav",                              // 18
38 	SOUNDSDIR "/glass_break2.wav",                              // 19
39 	SOUNDSDIR "/door open 01.wav",                              // 20
40 	SOUNDSDIR "/door open 02.wav",                              // 21
41 	SOUNDSDIR "/door open 03.wav",                              // 22
42 	SOUNDSDIR "/door close 01.wav",                             // 23
43 	SOUNDSDIR "/door close 02.wav",                             // 24
44 	SOUNDSDIR "/unlock lock.wav",                               // 25
45 	SOUNDSDIR "/kickin lock.wav",                               // 26
46 	SOUNDSDIR "/break lock.wav",                                // 27
47 	SOUNDSDIR "/picking lock.wav",                              // 28
48 	SOUNDSDIR "/garage door open.wav",                          // 29
49 	SOUNDSDIR "/garage door close.wav",                         // 30
50 	NULL,                                                       // 31
51 	NULL,                                                       // 32
52 	NULL,                                                       // 33
53 	NULL,                                                       // 34
54 	SOUNDSDIR "/curtains door open.wav",                        // 35
55 	SOUNDSDIR "/curtains door close.wav",                       // 36
56 	SOUNDSDIR "/metal door open.wav",                           // 37
57 	SOUNDSDIR "/metal door close.wav",                          // 38
58 	SOUNDSDIR "/ftp gravel 01.wav",                             // 39
59 	SOUNDSDIR "/ftp gravel 02.wav",                             // 40
60 	SOUNDSDIR "/ftp gravel 03.wav",                             // 41
61 	SOUNDSDIR "/ftp gravel 04.wav",                             // 42
62 	SOUNDSDIR "/ftp gritty 01.wav",                             // 43
63 	SOUNDSDIR "/ftp gritty 02.wav",                             // 44
64 	SOUNDSDIR "/ftp gritty 03.wav",                             // 45
65 	SOUNDSDIR "/ftp gritty 04.wav",                             // 46
66 	SOUNDSDIR "/ftp leaves 01.wav",                             // 47
67 	SOUNDSDIR "/ftp leaves 02.wav",                             // 48
68 	SOUNDSDIR "/ftp leaves 03.wav",                             // 49
69 	SOUNDSDIR "/ftp leaves 04.wav",                             // 50
70 	SOUNDSDIR "/crawling 01.wav",                               // 51
71 	SOUNDSDIR "/crawling 02.wav",                               // 52
72 	SOUNDSDIR "/crawling 03.wav",                               // 53
73 	SOUNDSDIR "/crawling 04.wav",                               // 54
74 	SOUNDSDIR "/beep2.wav",                                     // 55
75 	SOUNDSDIR "/endturn.wav",                                   // 56
76 	SOUNDSDIR "/ja2 death hit.wav",                             // 57
77 	SOUNDSDIR "/doorcr.wav",                                    // 58
78 	SOUNDSDIR "/head exploding 01.wav",                         // 59
79 	SOUNDSDIR "/body exploding.wav",                            // 60
80 	SOUNDSDIR "/explode1.wav",                                  // 61
81 	SOUNDSDIR "/crow exploding.wav",                            // 62
82 	SOUNDSDIR "/small explosion 01.wav",                        // 63
83 	SOUNDSDIR "/heli1.wav",                                     // 64
84 	SOUNDSDIR "/bullet impact 01.wav",                          // 65
85 	SOUNDSDIR "/bullet impact 02.wav",                          // 66
86 	SOUNDSDIR "/bullet impact 02.wav",                          // 67
87 	STSOUNDSDIR "/blah.wav",                                    // 68  URE ATTACK
88 	SOUNDSDIR "/step into water.wav",                           // 69
89 	SOUNDSDIR "/splash from shallow to deep.wav",               // 70
90 	SOUNDSDIR "/cow hit.wav",                                   // 71  COW HIT
91 	SOUNDSDIR "/cow die.wav",                                   // 72  COW DIE
92 	SOUNDSDIR "/line 02 fx.wav",                                // 73
93 	SOUNDSDIR "/line 01 fx.wav",                                // 74
94 	SOUNDSDIR "/line 03 fx.wav",                                // 75
95 	SOUNDSDIR "/cave collapsing.wav",                           // 76  CAVE_COLLAPSE
96 	SOUNDSDIR "/raid whistle.wav",                              // 77  RAID
97 	SOUNDSDIR "/raid ambient.wav",                              // 78
98 	SOUNDSDIR "/raid dive.wav",                                 // 79
99 	SOUNDSDIR "/raid dive.wav",                                 // 80
100 	SOUNDSDIR "/raid whistle.wav",                              // 81  RAID
101 	SOUNDSDIR "/driving 01.wav",                                // 82  DRIVING
102 	SOUNDSDIR "/engine start.wav",                              // 83  ON
103 	SOUNDSDIR "/engine off.wav",                                // 84  OFF
104 	SOUNDSDIR "/into vehicle.wav",                              // 85  INTO
105 	SOUNDSDIR "/weapons/dry fire 1.wav",                        // 86  Dry fire sound ( for gun jam )
106 	SOUNDSDIR "/wood impact 01a.wav",                           // 87  S_WOOD_IMPACT1
107 	SOUNDSDIR "/wood impact 01b.wav",                           // 88
108 	SOUNDSDIR "/wood impact 01a.wav",                           // 89
109 	SOUNDSDIR "/porcelain impact.wav",                          // 90
110 	SOUNDSDIR "/tire impact 01.wav",                            // 91
111 	SOUNDSDIR "/stone impact 01.wav",                           // 92
112 	SOUNDSDIR "/water impact 01.wav",                           // 93
113 	SOUNDSDIR "/veg impact 01.wav",                             // 94
114 	SOUNDSDIR "/metal hit 01.wav",                              // 95  S_METAL_HIT1
115 	SOUNDSDIR "/metal hit 01.wav",                              // 96
116 	SOUNDSDIR "/metal hit 01.wav",                              // 97
117 	SOUNDSDIR "/slap_impact.wav",                               // 98
118 	SOUNDSDIR "/weapons/revolver reload.wav",                   // 99  REVOLVER
119 	SOUNDSDIR "/weapons/pistol reload.wav",                     // 100  PISTOL
120 	SOUNDSDIR "/weapons/smg reload.wav",                        // 101  SMG
121 	SOUNDSDIR "/weapons/rifle reload.wav",                      // 102  RIFLE
122 	SOUNDSDIR "/weapons/shotgun reload.wav",                    // 103  SHOTGUN
123 	SOUNDSDIR "/weapons/lmg reload.wav",                        // 104  LMG
124 	SOUNDSDIR "/weapons/revolver lnl.wav",                      // 105  REVOLVER
125 	SOUNDSDIR "/weapons/pistol lnl.wav",                        // 106  PISTOL
126 	SOUNDSDIR "/weapons/smg lnl.wav",                           // 107  SMG
127 	SOUNDSDIR "/weapons/rifle lnl.wav",                         // 108  RIFLE
128 	SOUNDSDIR "/weapons/shotgun lnl.wav",                       // 109  SHOTGUN
129 	SOUNDSDIR "/weapons/lmg lnl.wav",                           // 110  LMG
130 	NULL,                                                       // 111
131 	NULL,                                                       // 112
132 	NULL,                                                       // 113
133 	NULL,                                                       // 114
134 	NULL,                                                       // 115
135 	NULL,                                                       // 116
136 	NULL,                                                       // 117
137 	NULL,                                                       // 118
138 	NULL,                                                       // 119
139 	NULL,                                                       // 120
140 	NULL,                                                       // 121
141 	NULL,                                                       // 122
142 	NULL,                                                       // 123
143 	NULL,                                                       // 124
144 	NULL,                                                       // 125
145 	NULL,                                                       // 126
146 	NULL,                                                       // 127
147 	NULL,                                                       // 128
148 	NULL,                                                       // 129
149 	NULL,                                                       // 130
150 	NULL,                                                       // 131
151 	NULL,                                                       // 132
152 	NULL,                                                       // 133
153 	NULL,                                                       // 134
154 	NULL,                                                       // 135
155 	NULL,                                                       // 136
156 	NULL,                                                       // 137
157 	NULL,                                                       // 138
158 	NULL,                                                       // 139
159 	NULL,                                                       // 140
160 	NULL,                                                       // 141
161 	NULL,                                                       // 142
162 	NULL,                                                       // 143
163 	NULL,                                                       // 144
164 	NULL,                                                       // 145
165 	NULL,                                                       // 146
166 	NULL,                                                       // 147
167 	NULL,                                                       // 148
168 	NULL,                                                       // 149
169 	NULL,                                                       // 150
170 	NULL,                                                       // 151
171 	NULL,                                                       // 152
172 	NULL,                                                       // 153
173 	NULL,                                                       // 154
174 	NULL,                                                       // 155
175 	SOUNDSDIR "/weapons/silencer 02.wav",                       // 156
176 	SOUNDSDIR "/weapons/silencer 03.wav",                       // 157
177 	SOUNDSDIR "/swoosh 01.wav",                                 // 158
178 	SOUNDSDIR "/swoosh 03.wav",                                 // 159
179 	SOUNDSDIR "/swoosh 05.wav",                                 // 160
180 	SOUNDSDIR "/swoosh 06.wav",                                 // 161
181 	SOUNDSDIR "/swoosh 11.wav",                                 // 162
182 	SOUNDSDIR "/swoosh 14.wav",                                 // 163
183 	SOUNDSDIR "/adult fall 01.wav",                             // 164
184 	SOUNDSDIR "/adult step 01.wav",                             // 165
185 	SOUNDSDIR "/adult step 02.wav",                             // 166
186 	SOUNDSDIR "/adult swipe 01.wav",                            // 167
187 	SOUNDSDIR "/eating_flesh 01.wav",                           // 168
188 	SOUNDSDIR "/adult crippled.wav",                            // 169
189 	SOUNDSDIR "/adult dying part 1.wav",                        // 170
190 	SOUNDSDIR "/adult dying part 2.wav",                        // 171
191 	SOUNDSDIR "/adult lunge 01.wav",                            // 172
192 	SOUNDSDIR "/adult smells threat.wav",                       // 173
193 	SOUNDSDIR "/adult smells prey.wav",                         // 174
194 	SOUNDSDIR "/adult spit.wav",                                // 175
195 	SOUNDSDIR "/baby dying 01.wav",                             // 176
196 	SOUNDSDIR "/baby dragging 01.wav",                          // 177
197 	SOUNDSDIR "/baby shriek 01.wav",                            // 178
198 	NULL,                                                       // 179
199 	SOUNDSDIR "/larvae movement 01.wav",                        // 180
200 	SOUNDSDIR "/larvae rupture 01.wav",                         // 181
201 	SOUNDSDIR "/queen shriek 01.wav",                           // 182
202 	SOUNDSDIR "/queen dying 01.wav",                            // 183
203 	SOUNDSDIR "/queen enraged attack.wav",                      // 184
204 	SOUNDSDIR "/queen rupturing.wav",                           // 185
205 	SOUNDSDIR "/queen crippled.wav",                            // 186
206 	SOUNDSDIR "/queen smells threat.wav",                       // 187
207 	SOUNDSDIR "/queen whip attack.wav",                         // 188
208 	SOUNDSDIR "/rock hit 01.wav",                               // 189
209 	SOUNDSDIR "/rock hit 02.wav",                               // 190
210 	SOUNDSDIR "/scratch.wav",                                   // 191
211 	SOUNDSDIR "/armpit.wav",                                    // 192
212 	SOUNDSDIR "/cracking back.wav",                             // 193
213 	SOUNDSDIR "/weapons/auto resolve composite 02 (8-22).wav",  // 194  The FF sound in autoresolve interface
214 	SOUNDSDIR "/email alert 01.wav",                            // 195
215 	SOUNDSDIR "/entering text 02.wav",                          // 196
216 	SOUNDSDIR "/removing text 02.wav",                          // 197
217 	SOUNDSDIR "/computer beep 01 in.wav",                       // 198
218 	SOUNDSDIR "/computer beep 01 out.wav",                      // 199
219 	SOUNDSDIR "/computer switch 01 in.wav",                     // 200
220 	SOUNDSDIR "/computer switch 01 out.wav",                    // 201
221 	SOUNDSDIR "/very small switch 01 in.wav",                   // 202
222 	SOUNDSDIR "/very small switch 01 out.wav",                  // 203
223 	SOUNDSDIR "/very small switch 02 in.wav",                   // 204
224 	SOUNDSDIR "/very small switch 02 out.wav",                  // 205
225 	SOUNDSDIR "/small switch 01 in.wav",                        // 206
226 	SOUNDSDIR "/small switch 01 out.wav",                       // 207
227 	SOUNDSDIR "/small switch 02 in.wav",                        // 208
228 	SOUNDSDIR "/small switch 02 out.wav",                       // 209
229 	SOUNDSDIR "/small switch 03 in.wav",                        // 210
230 	SOUNDSDIR "/small switch 03 out.wav",                       // 211
231 	SOUNDSDIR "/big switch 03 in.wav",                          // 212
232 	SOUNDSDIR "/big switch 03 out.wav",                         // 213
233 	SOUNDSDIR "/alarm.wav",                                     // 214
234 	SOUNDSDIR "/fight bell.wav",                                // 215
235 	NULL,                                                       // 216
236 	SOUNDSDIR "/attachment.wav",                                // 217
237 	SOUNDSDIR "/ceramic armor insert.wav",                      // 218
238 	SOUNDSDIR "/detonator beep.wav",                            // 219
239 	SOUNDSDIR "/grab roof.wav",                                 // 220
240 	SOUNDSDIR "/land on roof.wav",                              // 221
241 	NULL,                                                       // 222
242 	NULL,                                                       // 223
243 	NULL,                                                       // 224
244 	SOUNDSDIR "/fridge door open.wav",                          // 225
245 	SOUNDSDIR "/fridge door close.wav",                         // 226
246 	SOUNDSDIR "/fire 03 loop.wav",                              // 227
247 	SOUNDSDIR "/glass_crack.wav",                               // 228
248 	SOUNDSDIR "/spit ricochet.wav",                             // 229
249 	SOUNDSDIR "/tiger hit.wav",                                 // 230
250 	SOUNDSDIR "/bloodcat dying 02.wav",                         // 231
251 	SOUNDSDIR "/slap.wav",                                      // 232
252 	SOUNDSDIR "/robot beep.wav",                                // 233
253 	SOUNDSDIR "/electricity.wav",                               // 234
254 	SOUNDSDIR "/swimming 01.wav",                               // 235
255 	SOUNDSDIR "/swimming 02.wav",                               // 236
256 	SOUNDSDIR "/key failure.wav",                               // 237
257 	SOUNDSDIR "/target cursor.wav",                             // 238
258 	SOUNDSDIR "/statue open.wav",                               // 239
259 	SOUNDSDIR "/remote activate.wav",                           // 240
260 	SOUNDSDIR "/wirecutters.wav",                               // 241
261 	SOUNDSDIR "/drink from canteen.wav",                        // 242
262 	SOUNDSDIR "/bloodcat attack.wav",                           // 243
263 	SOUNDSDIR "/bloodcat loud roar.wav",                        // 244
264 	SOUNDSDIR "/robot greeting.wav",                            // 245
265 	SOUNDSDIR "/robot death.wav",                               // 246
266 	SOUNDSDIR "/gas grenade explode.wav",                       // 247
267 	SOUNDSDIR "/air escaping.wav",                              // 248
268 	SOUNDSDIR "/drawer open.wav",                               // 249
269 	SOUNDSDIR "/drawer close.wav",                              // 250
270 	SOUNDSDIR "/locker door open.wav",                          // 251
271 	SOUNDSDIR "/locker door close.wav",                         // 252
272 	SOUNDSDIR "/wooden box open.wav",                           // 253
273 	SOUNDSDIR "/wooden box close.wav",                          // 254
274 	SOUNDSDIR "/robot stop moving.wav",                         // 255
275 	SOUNDSDIR "/water movement 01.wav",                         // 256
276 	SOUNDSDIR "/water movement 02.wav",                         // 257
277 	SOUNDSDIR "/water movement 03.wav",                         // 258
278 	SOUNDSDIR "/water movement 04.wav",                         // 259
279 	SOUNDSDIR "/prone to crouch.wav",                           // 260
280 	SOUNDSDIR "/crouch to prone.wav",                           // 261
281 	SOUNDSDIR "/crouch to stand.wav",                           // 262
282 	SOUNDSDIR "/stand to crouch.wav",                           // 263
283 	SOUNDSDIR "/picking something up.wav",                      // 264
284 	SOUNDSDIR "/cow falling.wav",                               // 265
285 	SOUNDSDIR "/bloodcat_growl_01.wav",                         // 266
286 	SOUNDSDIR "/bloodcat_growl_02.wav",                         // 267
287 	SOUNDSDIR "/bloodcat_growl_03.wav",                         // 268
288 	SOUNDSDIR "/bloodcat_growl_04.wav",                         // 269
289 	SOUNDSDIR "/spit ricochet.wav",                             // 270
290 	SOUNDSDIR "/adult crippled.wav",                            // 271
291 	SOUNDSDIR "/death disintegration.wav",                      // 272
292 	SOUNDSDIR "/queen ambience.wav",                            // 273
293 	SOUNDSDIR "/alien impact.wav",                              // 274
294 	SOUNDSDIR "/crow pecking flesh 01.wav",                     // 275
295 	SOUNDSDIR "/crow fly.wav",                                  // 276
296 	SOUNDSDIR "/slap 02.wav",                                   // 277
297 	SOUNDSDIR "/setting up mortar.wav",                         // 278
298 	SOUNDSDIR "/mortar whistle.wav",                            // 279
299 	SOUNDSDIR "/load mortar.wav",                               // 280
300 	SOUNDSDIR "/tank turret a.wav",                             // 281
301 	SOUNDSDIR "/tank turret b.wav",                             // 282
302 	SOUNDSDIR "/cow falling b.wav",                             // 283
303 	SOUNDSDIR "/stab into flesh.wav",                           // 284
304 	SOUNDSDIR "/explosion 10.wav",                              // 285
305 	SOUNDSDIR "/explosion 12.wav",                              // 286
306 	SOUNDSDIR "/drink from canteen male.wav",                   // 287
307 	SOUNDSDIR "/x ray activated.wav",                           // 288
308 	SOUNDSDIR "/catch object.wav",                              // 289
309 	SOUNDSDIR "/fence open.wav",                                // 290
310 };
311 
312 static char const* const szAmbientEffects[NUM_AMBIENTS] =
313 {
314 	SOUNDSDIR "/storm1.wav",
315 	SOUNDSDIR "/storm2.wav",
316 	SOUNDSDIR "/rain_loop_22k.wav",
317 	SOUNDSDIR "/bird1-22k.wav",
318 	SOUNDSDIR "/bird3-22k.wav",
319 	SOUNDSDIR "/crickety_loop.wav",
320 	SOUNDSDIR "/crickety_loop2.wav",
321 	SOUNDSDIR "/cricket1.wav",
322 	SOUNDSDIR "/cricket2.wav",
323 	SOUNDSDIR "/owl1.wav",
324 	SOUNDSDIR "/owl2.wav",
325 	SOUNDSDIR "/owl3.wav",
326 	SOUNDSDIR "/night_bird1.wav",
327 	SOUNDSDIR "/night_bird3.wav"
328 };
329 
ShutdownJA2Sound(void)330 void ShutdownJA2Sound(void)
331 {
332 	SoundStopAll();
333 }
334 
335 
getSoundSample(SoundID soundId)336 const char * getSoundSample(SoundID soundId)
337 {
338 	if(soundId == -1) {
339 		return "";
340 	}
341 	else
342 	{
343 		return szSoundEffects[soundId];
344 	}
345 }
346 
PlayJA2Sample(SoundID const usNum,UINT32 const ubVolume,UINT32 const ubLoops,UINT32 const uiPan)347 UINT32 PlayJA2Sample(SoundID const usNum, UINT32 const ubVolume, UINT32 const ubLoops, UINT32 const uiPan)
348 {
349 	UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
350 	return SoundPlay(szSoundEffects[usNum], vol, uiPan, ubLoops, NULL, NULL);
351 }
352 
353 
PlayJA2Sample(const char * sample,UINT32 const ubVolume,UINT32 const ubLoops,UINT32 const uiPan)354 UINT32 PlayJA2Sample(const char *sample, UINT32 const ubVolume, UINT32 const ubLoops, UINT32 const uiPan)
355 {
356 	if((sample != NULL) && strcmp(sample, ""))
357 	{
358 		UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
359 		return SoundPlay(sample, vol, uiPan, ubLoops, NULL, NULL);
360 	}
361 	return SOUND_ERROR;
362 }
363 
364 
PlayJA2StreamingSample(SoundID const usNum,UINT32 const ubVolume,UINT32 const ubLoops,UINT32 const uiPan)365 UINT32 PlayJA2StreamingSample(SoundID const usNum, UINT32 const ubVolume, UINT32 const ubLoops, UINT32 const uiPan)
366 {
367 	UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
368 	return SoundPlay(szSoundEffects[usNum], vol, uiPan, ubLoops, NULL, NULL);
369 }
370 
371 
PlayJA2SampleFromFile(char const * const szFileName,UINT32 const ubVolume,UINT32 const ubLoops,UINT32 const uiPan)372 UINT32 PlayJA2SampleFromFile(char const* const szFileName, UINT32 const ubVolume, UINT32 const ubLoops, UINT32 const uiPan)
373 {
374 	// does the same thing as PlayJA2Sound, but one only has to pass the filename, not the index of the sound array
375 	UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
376 	return SoundPlay(szFileName, vol, uiPan, ubLoops, NULL, NULL);
377 }
378 
379 
PlayJA2StreamingSampleFromFile(char const * const szFileName,UINT32 const ubVolume,UINT32 const ubLoops,UINT32 const uiPan,SOUND_STOP_CALLBACK const EndsCallback)380 UINT32 PlayJA2StreamingSampleFromFile(char const* const szFileName, UINT32 const ubVolume, UINT32 const ubLoops, UINT32 const uiPan, SOUND_STOP_CALLBACK const EndsCallback)
381 {
382 	// does the same thing as PlayJA2Sound, but one only has to pass the filename, not the index of the sound array
383 	UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
384 	return SoundPlay(szFileName, vol, uiPan, ubLoops, EndsCallback, NULL);
385 }
386 
387 
PlayJA2Ambient(AmbientSoundID const usNum,UINT32 const ubVolume,UINT32 const ubLoops)388 UINT32 PlayJA2Ambient(AmbientSoundID const usNum, UINT32 const ubVolume, UINT32 const ubLoops)
389 {
390 	UINT32 const vol = CalculateSoundEffectsVolume(ubVolume);
391 	return SoundPlay(szAmbientEffects[usNum], vol, MIDDLEPAN, ubLoops, NULL, NULL);
392 }
393 
PlayLocationJA2SampleFromFile(UINT16 const grid_no,char const * const filename,UINT32 const base_vol,UINT32 const loops)394 UINT32 PlayLocationJA2SampleFromFile(UINT16 const grid_no, char const* const filename, UINT32 const base_vol, UINT32 const loops)
395 {
396 	UINT32 const vol = SoundVolume(base_vol, grid_no);
397 	UINT32 const pan = SoundDir(grid_no);
398 	return PlayJA2SampleFromFile(filename, vol, loops, pan);
399 }
400 
401 
PlayLocationJA2Sample(UINT16 const grid_no,SoundID const idx,UINT32 const base_vol,UINT32 const loops)402 UINT32 PlayLocationJA2Sample(UINT16 const grid_no, SoundID const idx, UINT32 const base_vol, UINT32 const loops)
403 {
404 	UINT32 const vol = SoundVolume(base_vol, grid_no);
405 	UINT32 const pan = SoundDir(grid_no);
406 	return PlayJA2Sample(idx, vol, loops, pan);
407 }
408 
409 
PlayLocationJA2Sample(UINT16 const grid_no,const ST::string & sample,UINT32 const base_vol,UINT32 const loops)410 UINT32 PlayLocationJA2Sample(UINT16 const grid_no, const ST::string &sample, UINT32 const base_vol, UINT32 const loops)
411 {
412 	UINT32 const vol = SoundVolume(base_vol, grid_no);
413 	UINT32 const pan = SoundDir(grid_no);
414 	return PlayJA2Sample(sample.c_str(), vol, loops, pan);
415 }
416 
417 
PlayLocationJA2StreamingSample(UINT16 const grid_no,SoundID const idx,UINT32 const base_vol,UINT32 const loops)418 UINT32 PlayLocationJA2StreamingSample(UINT16 const grid_no, SoundID const idx, UINT32 const base_vol, UINT32 const loops)
419 {
420 	UINT32 const vol = SoundVolume(base_vol, grid_no);
421 	UINT32 const pan = SoundDir(grid_no);
422 	return PlayJA2StreamingSample(idx, vol, loops, pan);
423 }
424 
425 
PlaySoldierJA2Sample(SOLDIERTYPE const * const s,SoundID const usNum,UINT32 const base_vol,UINT32 const ubLoops,BOOLEAN const fCheck)426 UINT32 PlaySoldierJA2Sample(SOLDIERTYPE const* const s, SoundID const usNum, UINT32 const base_vol, UINT32 const ubLoops, BOOLEAN const fCheck)
427 {
428 	if( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
429 	{
430 		// CHECK IF GUY IS ON SCREEN BEFORE PLAYING!
431 		if (s->bVisible != -1 || !fCheck)
432 		{
433 			UINT32 const vol = SoundVolume(base_vol, s->sGridNo);
434 			UINT32 const pan = SoundDir(s->sGridNo);
435 			return PlayJA2Sample(usNum, CalculateSoundEffectsVolume(vol), ubLoops, pan);
436 		}
437 	}
438 
439 	return( 0 );
440 }
441 
442 
SetSpeechVolume(UINT32 uiNewVolume)443 void SetSpeechVolume(UINT32 uiNewVolume)
444 {
445 	guiSpeechVolume = __min(uiNewVolume, MAXVOLUME);
446 }
447 
448 
GetSpeechVolume(void)449 UINT32 GetSpeechVolume(void)
450 {
451 	return( guiSpeechVolume );
452 }
453 
454 
SetSoundEffectsVolume(UINT32 uiNewVolume)455 void SetSoundEffectsVolume(UINT32 uiNewVolume)
456 {
457 	guiSoundEffectsVolume = __min(uiNewVolume, MAXVOLUME);
458 }
459 
460 
GetSoundEffectsVolume(void)461 UINT32 GetSoundEffectsVolume(void)
462 {
463 	return( guiSoundEffectsVolume );
464 }
465 
466 
CalculateSpeechVolume(UINT32 uiVolume)467 UINT32 CalculateSpeechVolume(UINT32 uiVolume)
468 {
469 	return (uiVolume * guiSpeechVolume + HIGHVOLUME / 2) / HIGHVOLUME;
470 }
471 
472 
CalculateSoundEffectsVolume(UINT32 uiVolume)473 UINT32 CalculateSoundEffectsVolume(UINT32 uiVolume)
474 {
475 	return (uiVolume * guiSoundEffectsVolume + HIGHVOLUME / 2) / HIGHVOLUME;
476 }
477 
478 
479 #if 0
480 	int x,dif,absDif;
481 
482 	// This function calculates the general LEFT / RIGHT direction of a gridno
483 	// based on the middle of your screen.
484 
485 	x = Gridx(gridno);
486 
487 	dif = ScreenMiddleX - x;
488 
489 	if ( (absDif=abs(dif)) > 32)
490 	{
491 		// OK, NOT the middle.
492 
493 		// Is it outside the screen?
494 		if (absDif > HalfWindowWidth)
495 		{
496 			// yes, outside...
497 			if (dif > 0)
498 				return(25);
499 			else
500 				return(102);
501 		}
502 	}
503 	else // inside screen
504 	{
505 		if (dif > 0)
506 			return(LEFTSIDE);
507 		else
508 			return(RIGHTSIDE);
509 	}
510 	else // hardly any difference, so sound should be played from middle
511 		return(MIDDLE);
512 
513 }
514 #endif
515 
SoundDir(INT16 sGridNo)516 INT8 SoundDir( INT16 sGridNo )
517 {
518 	INT16 sScreenX, sScreenY;
519 	INT16	sMiddleX;
520 	INT16	sDif, sAbsDif;
521 
522 	if ( sGridNo == NOWHERE )
523 	{
524 		return( MIDDLEPAN );
525 	}
526 
527 	GetAbsoluteScreenXYFromMapPos(sGridNo, &sScreenX, &sScreenY);
528 
529 	// Get middle of where we are now....
530 	sMiddleX = gsTopLeftWorldX + ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2;
531 
532 	sDif = sMiddleX - sScreenX;
533 
534 	if ( ( sAbsDif = ABS( sDif ) ) > 64 )
535 	{
536 		// OK, NOT the middle.
537 
538 		// Is it outside the screen?
539 		if ( sAbsDif > ( ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2 ) )
540 		{
541 			// yes, outside...
542 			if ( sDif > 0 )
543 			{
544 				//return( FARLEFT );
545 				return( 1 );
546 			}
547 			else
548 			{
549 				//return( FARRIGHT );
550 				return( 126 );
551 			}
552 		}
553 		else // inside screen
554 		{
555 			if ( sDif > 0)
556 			{
557 				return( LEFTSIDE );
558 			}
559 			else
560 			{
561 				return( RIGHTSIDE );
562 			}
563 		}
564 	}
565 	else // hardly any difference, so sound should be played from middle
566 	{
567 		return(MIDDLE);
568 	}
569 }
570 
571 
SoundVolume(INT8 bInitialVolume,INT16 sGridNo)572 INT8 SoundVolume( INT8 bInitialVolume, INT16 sGridNo )
573 {
574 	INT16 sScreenX, sScreenY;
575 	INT16	sMiddleX, sMiddleY;
576 	INT16	sDifX, sAbsDifX;
577 	INT16	sDifY, sAbsDifY;
578 
579 	if ( sGridNo == NOWHERE )
580 	{
581 		return( bInitialVolume );
582 	}
583 
584 	GetAbsoluteScreenXYFromMapPos(sGridNo, &sScreenX, &sScreenY);
585 
586 	// Get middle of where we are now....
587 	sMiddleX = gsTopLeftWorldX + ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2;
588 	sMiddleY = gsTopLeftWorldY + ( gsBottomRightWorldY - gsTopLeftWorldY ) / 2;
589 
590 	sDifX = sMiddleX - sScreenX;
591 	sDifY = sMiddleY - sScreenY;
592 
593 	sAbsDifX = ABS( sDifX );
594 	sAbsDifY = ABS( sDifY );
595 
596 	if ( sAbsDifX  > 64 || sAbsDifY > 64 )
597 	{
598 		// OK, NOT the middle.
599 
600 		// Is it outside the screen?
601 		if ( sAbsDifX > ( ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2 ) ||
602 			sAbsDifY > ( ( gsBottomRightWorldY - gsTopLeftWorldY ) / 2 ) )
603 		{
604 			return( __max( LOWVOLUME, ( bInitialVolume - SOUND_FAR_VOLUME_MOD ) ) );
605 		}
606 	}
607 
608 	return( bInitialVolume );
609 }
610 
611 
612 /////////////////////////////////////////////////////////
613 /////////
614 /////////
615 /////////////////////////////////////////////////////////
616 // Positional Ambients
617 /////////////////////////////////////////////////////////
618 #define NUM_POSITION_SOUND_EFFECT_SLOTS 10
619 
620 struct POSITIONSND
621 {
622 	INT16         sGridNo;
623 	UINT32        uiSoundSampleID;
624 	SoundID       iSoundToPlay;
625 	const SOLDIERTYPE* SoundSource;
626 	BOOLEAN       fAllocated;
627 	BOOLEAN       fInActive;
628 };
629 
630 
631 // GLOBAL FOR SMOKE LISTING
632 static POSITIONSND gPositionSndData[NUM_POSITION_SOUND_EFFECT_SLOTS];
633 static UINT32      guiNumPositionSnds     = 0;
634 static BOOLEAN     gfPositionSoundsActive = FALSE;
635 
636 
GetFreePositionSnd(void)637 static INT32 GetFreePositionSnd(void)
638 {
639 	for (UINT32 i = 0; i != guiNumPositionSnds; ++i)
640 	{
641 		if (!gPositionSndData[i].fAllocated) return (INT32)i;
642 	}
643 
644 	if (guiNumPositionSnds < NUM_POSITION_SOUND_EFFECT_SLOTS)
645 		return (INT32)guiNumPositionSnds++;
646 
647 	return -1;
648 }
649 
650 
RecountPositionSnds(void)651 static void RecountPositionSnds(void)
652 {
653 	INT32 uiCount;
654 
655 	for(uiCount=guiNumPositionSnds-1; (uiCount >=0) ; uiCount--)
656 	{
657 		if( ( gPositionSndData[uiCount].fAllocated ) )
658 		{
659 			guiNumPositionSnds=(UINT32)(uiCount+1);
660 			break;
661 		}
662 	}
663 }
664 
665 
NewPositionSnd(INT16 const sGridNo,SOLDIERTYPE const * const SoundSource,SoundID const iSoundToPlay)666 INT32 NewPositionSnd(INT16 const sGridNo, SOLDIERTYPE const* const SoundSource, SoundID const iSoundToPlay)
667 {
668 	INT32 const idx = GetFreePositionSnd();
669 	if (idx == -1) return -1;
670 
671 	POSITIONSND& p = gPositionSndData[idx];
672 	p = POSITIONSND{};
673 	p.fInActive      = !gfPositionSoundsActive;
674 	p.sGridNo        = sGridNo;
675 	p.SoundSource    = SoundSource;
676 	p.fAllocated     = TRUE;
677 	p.iSoundToPlay   = iSoundToPlay;
678 	p.uiSoundSampleID = NO_SAMPLE;
679 
680 	return idx;
681 }
682 
DeletePositionSnd(INT32 iPositionSndIndex)683 void DeletePositionSnd( INT32 iPositionSndIndex )
684 {
685 	POSITIONSND *pPositionSnd;
686 
687 	pPositionSnd = &gPositionSndData[ iPositionSndIndex ];
688 
689 	if ( pPositionSnd->fAllocated )
690 	{
691 		// Turn inactive first...
692 		pPositionSnd->fInActive = TRUE;
693 
694 		// End sound...
695 		if ( pPositionSnd->uiSoundSampleID != NO_SAMPLE )
696 		{
697 			SoundStop( pPositionSnd->uiSoundSampleID );
698 		}
699 
700 		pPositionSnd->fAllocated = FALSE;
701 
702 		RecountPositionSnds( );
703 	}
704 }
705 
SetPositionSndGridNo(INT32 iPositionSndIndex,INT16 sGridNo)706 void SetPositionSndGridNo( INT32 iPositionSndIndex, INT16 sGridNo )
707 {
708 	POSITIONSND *pPositionSnd;
709 
710 	pPositionSnd = &gPositionSndData[ iPositionSndIndex ];
711 
712 	if ( pPositionSnd->fAllocated )
713 	{
714 		pPositionSnd->sGridNo = sGridNo;
715 
716 		SetPositionSndsVolumeAndPanning( );
717 	}
718 }
719 
720 
SetPositionSndsActive(void)721 void SetPositionSndsActive(void)
722 {
723 	gfPositionSoundsActive = TRUE;
724 	for (UINT32 i = 0; i != guiNumPositionSnds; ++i)
725 	{
726 		POSITIONSND& p = gPositionSndData[i];
727 		if (!p.fAllocated) continue;
728 		if (!p.fInActive)  continue;
729 
730 		p.fInActive      = FALSE;
731 		// Begin sound effect, Volume 0
732 		p.uiSoundSampleID = PlayJA2Sample(p.iSoundToPlay, 0, 0, MIDDLEPAN);
733 	}
734 }
735 
736 
SetPositionSndsInActive(void)737 void SetPositionSndsInActive(void)
738 {
739 	gfPositionSoundsActive = FALSE;
740 	for (UINT32 i = 0; i != guiNumPositionSnds; ++i)
741 	{
742 		POSITIONSND& p = gPositionSndData[i];
743 		if (!p.fAllocated) continue;
744 
745 		p.fInActive = TRUE;
746 
747 		if (p.uiSoundSampleID == NO_SAMPLE) continue;
748 
749 		// End sound
750 		SoundStop(p.uiSoundSampleID);
751 		p.uiSoundSampleID = NO_SAMPLE;
752 	}
753 }
754 
755 
PositionSoundDir(INT16 sGridNo)756 static INT8 PositionSoundDir(INT16 sGridNo)
757 {
758 	INT16 sScreenX, sScreenY;
759 	INT16	sMiddleX;
760 	INT16	sDif, sAbsDif;
761 
762 	if ( sGridNo == NOWHERE )
763 	{
764 		return( MIDDLEPAN );
765 	}
766 
767 	GetAbsoluteScreenXYFromMapPos(sGridNo, &sScreenX, &sScreenY);
768 
769 	// Get middle of where we are now....
770 	sMiddleX = gsTopLeftWorldX + ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2;
771 
772 	sDif = sMiddleX - sScreenX;
773 
774 	if ( ( sAbsDif = ABS( sDif ) ) > 64 )
775 	{
776 		// OK, NOT the middle.
777 
778 		// Is it outside the screen?
779 		if ( sAbsDif > ( ( gsBottomRightWorldX - gsTopLeftWorldX ) / 2 ) )
780 		{
781 			// yes, outside...
782 			if ( sDif > 0 )
783 			{
784 				//return( FARLEFT );
785 				return( 1 );
786 			}
787 			else
788 			{
789 				//return( FARRIGHT );
790 				return( 126 );
791 			}
792 		}
793 		else // inside screen
794 		{
795 			if (sDif > 0)
796 			{
797 				return( LEFTSIDE );
798 			}
799 			else
800 			{
801 				return( RIGHTSIDE );
802 			}
803 		}
804 	}
805 	else // hardly any difference, so sound should be played from middle
806 	{
807 		return(MIDDLE);
808 	}
809 }
810 
811 
PositionSoundVolume(INT8 const initial_volume,GridNo const grid_no)812 static INT8 PositionSoundVolume(INT8 const initial_volume, GridNo const grid_no)
813 {
814 	if (grid_no == NOWHERE) return initial_volume;
815 
816 	INT16 sScreenX;
817 	INT16 sScreenY;
818 	GetAbsoluteScreenXYFromMapPos(grid_no, &sScreenX, &sScreenY);
819 
820 	// Get middle of where we are now
821 	INT16 const sMiddleX = gsTopLeftWorldX + (gsBottomRightWorldX - gsTopLeftWorldX) / 2;
822 	INT16 const sMiddleY = gsTopLeftWorldY + (gsBottomRightWorldY - gsTopLeftWorldY) / 2;
823 
824 	INT16 const sDifX = sMiddleX - sScreenX;
825 	INT16 const sDifY = sMiddleY - sScreenY;
826 
827 	INT16 const sMaxDistX = (gsBottomRightWorldX - gsTopLeftWorldX) * 3 / 2;
828 	INT16 const sMaxDistY = (gsBottomRightWorldY - gsTopLeftWorldY) * 3 / 2;
829 
830 	double const sMaxSoundDist = sqrt((double)(sMaxDistX * sMaxDistX) + (sMaxDistY * sMaxDistY));
831 	double       sSoundDist    = sqrt((double)(sDifX * sDifX)  + (sDifY * sDifY));
832 
833 	if (sSoundDist == 0) return initial_volume;
834 
835 	if (sSoundDist > sMaxSoundDist) sSoundDist = sMaxSoundDist;
836 
837 	// Scale
838 	return  (INT8)(initial_volume * ((sMaxSoundDist - sSoundDist) / sMaxSoundDist));
839 }
840 
841 
SetPositionSndsVolumeAndPanning(void)842 void SetPositionSndsVolumeAndPanning(void)
843 {
844 	for (UINT32 i = 0; i != guiNumPositionSnds; ++i)
845 	{
846 		POSITIONSND const& p = gPositionSndData[i];
847 		if (!p.fAllocated)                 continue;
848 		if (p.fInActive)                   continue;
849 		if (p.uiSoundSampleID == NO_SAMPLE) continue;
850 
851 		INT8 volume = PositionSoundVolume(15, p.sGridNo);
852 		if (p.SoundSource && p.SoundSource->bVisible == -1)
853 		{ // Limit volume
854 			if (volume > 10) volume = 10;
855 		}
856 		SoundSetVolume(p.uiSoundSampleID, volume);
857 
858 		INT8 const pan = PositionSoundDir(p.sGridNo);
859 		SoundSetPan(p.uiSoundSampleID, pan);
860 	}
861 }
862