1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: snd_reverbs.cpp 4297 2010-06-03 22:49:00Z firebrand_kh $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "gamedefs.h"
29 #include "snd_local.h"
30
31 // MACROS ------------------------------------------------------------------
32
33 // TYPES -------------------------------------------------------------------
34
35 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
36
37 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38
39 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40
41 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
42
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
44
45 // PRIVATE DATA DEFINITIONS ------------------------------------------------
46
47 static VReverbInfo Psychotic =
48 {
49 NULL,
50 "Psychotic",
51 0x1900,
52 true,
53 { 25, 1.0f, 0.50f, -1000, -151, 0, 7.56f, 0.91f, 1.0f, -626, 0.020f, 0.0f,0.0f,0.0f, 774, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 4.00f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x1f }
54 };
55
56 static VReverbInfo Dizzy =
57 {
58 &Psychotic,
59 "Dizzy",
60 0x1800,
61 true,
62 { 24, 1.8f, 0.60f, -1000, -400, 0, 17.23f, 0.56f, 1.0f, -1713, 0.020f, 0.0f,0.0f,0.0f, -613, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 1.00f, 0.81f, 0.310f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x1f }
63 };
64
65 static VReverbInfo Drugged =
66 {
67 &Dizzy,
68 "Drugged",
69 0x1700,
70 true,
71 { 23, 1.9f, 0.50f, -1000, 0, 0, 8.39f, 1.39f, 1.0f, -115, 0.002f, 0.0f,0.0f,0.0f, 985, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x1f }
72 };
73
74 static VReverbInfo Underwater =
75 {
76 &Drugged,
77 "Underwater",
78 0x1600,
79 true,
80 { 22, 1.8f, 1.00f, -1000, -4000, 0, 1.49f, 0.10f, 1.0f, -449, 0.007f, 0.0f,0.0f,0.0f, 1700, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 1.18f, 0.348f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
81 };
82
83 static VReverbInfo SewerPipe =
84 {
85 &Underwater,
86 "Sewer Pipe",
87 0x1500,
88 true,
89 { 21, 1.7f, 0.80f, -1000, -1000, 0, 2.81f, 0.14f, 1.0f, 429, 0.014f, 0.0f,0.0f,0.0f, 1023, 0.021f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 80.0f, 60.0f, 0x3f }
90 };
91
92 static VReverbInfo ParkingLot =
93 {
94 &SewerPipe,
95 "Parking Lot",
96 0x1400,
97 true,
98 { 20, 8.3f, 1.00f, -1000, 0, 0, 1.65f, 1.50f, 1.0f, -1363, 0.008f, 0.0f,0.0f,0.0f, -1153, 0.012f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x1f }
99 };
100
101 static VReverbInfo Plain =
102 {
103 &ParkingLot,
104 "Plain",
105 0x1300,
106 true,
107 { 19, 42.5f, 0.21f, -1000, -2000, 0, 1.49f, 0.50f, 1.0f, -2466, 0.179f, 0.0f,0.0f,0.0f, -1926, 0.100f, 0.0f,0.0f,0.0f, 0.250f, 1.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 21.0f, 100.0f, 0x3f }
108 };
109
110 static VReverbInfo Quarry =
111 {
112 &Plain,
113 "Quarry",
114 0x1200,
115 true,
116 { 18, 17.5f, 1.00f, -1000, -1000, 0, 1.49f, 0.83f, 1.0f, -10000, 0.061f, 0.0f,0.0f,0.0f, 500, 0.025f, 0.0f,0.0f,0.0f, 0.125f, 0.70f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
117 };
118
119 static VReverbInfo Mountains =
120 {
121 &Quarry,
122 "Mountains",
123 0x1100,
124 true,
125 { 17, 100.0f, 0.27f, -1000, -2500, 0, 1.49f, 0.21f, 1.0f, -2780, 0.300f, 0.0f,0.0f,0.0f, -1434, 0.100f, 0.0f,0.0f,0.0f, 0.250f, 1.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 27.0f, 100.0f, 0x1f }
126 };
127
128 static VReverbInfo City =
129 {
130 &Mountains,
131 "City",
132 0x1000,
133 true,
134 { 16, 7.5f, 0.50f, -1000, -800, 0, 1.49f, 0.67f, 1.0f, -2273, 0.007f, 0.0f,0.0f,0.0f, -1691, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 50.0f, 100.0f, 0x3f }
135 };
136
137 static VReverbInfo Forest =
138 {
139 &City,
140 "Forest",
141 0x0F00,
142 true,
143 { 15, 38.0f, 0.30f, -1000, -3300, 0, 1.49f, 0.54f, 1.0f, -2560, 0.162f, 0.0f,0.0f,0.0f, -229, 0.088f, 0.0f,0.0f,0.0f, 0.125f, 1.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 79.0f, 100.0f, 0x3f }
144 };
145
146 static VReverbInfo Alley =
147 {
148 &Forest,
149 "Alley",
150 0x0E00,
151 true,
152 { 14, 7.5f, 0.30f, -1000, -270, 0, 1.49f, 0.86f, 1.0f, -1204, 0.007f, 0.0f,0.0f,0.0f, -4, 0.011f, 0.0f,0.0f,0.0f, 0.125f, 0.95f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
153 };
154
155 static VReverbInfo StoneCorridor =
156 {
157 &Alley,
158 "Stone Corridor",
159 0x0D00,
160 true,
161 { 13, 13.5f, 1.00f, -1000, -237, 0, 2.70f, 0.79f, 1.0f, -1214, 0.013f, 0.0f,0.0f,0.0f, 395, 0.020f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
162 };
163
164 static VReverbInfo Hallway =
165 {
166 &StoneCorridor,
167 "Hallway",
168 0x0C00,
169 true,
170 { 12, 1.8f, 1.00f, -1000, -300, 0, 1.49f, 0.59f, 1.0f, -1219, 0.007f, 0.0f,0.0f,0.0f, 441, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
171 };
172
173 static VReverbInfo CarpettedHallway =
174 {
175 &Hallway,
176 "Carpetted Hallway",
177 0x0B00,
178 true,
179 { 11, 1.9f, 1.00f, -1000, -4000, 0, 0.30f, 0.10f, 1.0f, -1831, 0.002f, 0.0f,0.0f,0.0f, -1630, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
180 };
181
182 static VReverbInfo Hangar =
183 {
184 &CarpettedHallway,
185 "Hangar",
186 0x0A00,
187 true,
188 { 10, 50.3f, 1.00f, -1000, -1000, 0, 10.05f, 0.23f, 1.0f, -602, 0.020f, 0.0f,0.0f,0.0f, 198, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
189 };
190
191 static VReverbInfo Arena =
192 {
193 &Hangar,
194 "Arena",
195 0x0900,
196 true,
197 { 9, 36.2f, 1.00f, -1000, -698, 0, 7.24f, 0.33f, 1.0f, -1166, 0.020f, 0.0f,0.0f,0.0f, 16, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
198 };
199
200 static VReverbInfo Cave =
201 {
202 &Arena,
203 "Cave",
204 0x0800,
205 true,
206 { 8, 14.6f, 1.00f, -1000, 0, 0, 2.91f, 1.30f, 1.0f, -602, 0.015f, 0.0f,0.0f,0.0f, -302, 0.022f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x1f }
207 };
208
209 static VReverbInfo ConcertHall =
210 {
211 &Cave,
212 "Concert Hall",
213 0x0700,
214 true,
215 { 7, 19.6f, 1.00f, -1000, -500, 0, 3.92f, 0.70f, 1.0f, -1230, 0.020f, 0.0f,0.0f,0.0f, -2, 0.029f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
216 };
217
218 static VReverbInfo Auditorium =
219 {
220 &ConcertHall,
221 "Auditorium",
222 0x0600,
223 true,
224 { 6, 21.6f, 1.00f, -1000, -476, 0, 4.32f, 0.59f, 1.0f, -789, 0.020f, 0.0f,0.0f,0.0f, -289, 0.030f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
225 };
226
227 static VReverbInfo StoneRoom =
228 {
229 &Auditorium,
230 "Stone Room",
231 0x0500,
232 true,
233 { 5, 11.6f, 1.00f, -1000, -300, 0, 2.31f, 0.64f, 1.0f, -711, 0.012f, 0.0f,0.0f,0.0f, 83, 0.017f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
234 };
235
236 static VReverbInfo LivingRoom =
237 {
238 &StoneRoom,
239 "Living Room",
240 0x0400,
241 true,
242 { 4, 2.5f, 1.00f, -1000, -6000, 0, 0.50f, 0.10f, 1.0f, -1376, 0.003f, 0.0f,0.0f,0.0f, -1104, 0.004f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
243 };
244
245 static VReverbInfo Bathroom =
246 {
247 &LivingRoom,
248 "Bathroom",
249 0x0300,
250 true,
251 { 3, 1.4f, 1.00f, -1000, -1200, 0, 1.49f, 0.54f, 1.0f, -370, 0.007f, 0.0f,0.0f,0.0f, 1030, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 60.0f, 0x3f }
252 };
253
254 static VReverbInfo Room =
255 {
256 &Bathroom,
257 "Room",
258 0x0200,
259 true,
260 { 2, 1.9f, 1.00f, -1000, -454, 0, 0.40f, 0.83f, 1.0f, -1646, 0.002f, 0.0f,0.0f,0.0f, 53, 0.003f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
261 };
262
263 static VReverbInfo PaddedCell =
264 {
265 &Room,
266 "Padded Cell",
267 0x0100,
268 true,
269 { 1, 1.4f, 1.00f, -1000, -6000, 0, 0.17f, 0.10f, 1.0f, -1204, 0.001f, 0.0f,0.0f,0.0f, 207, 0.002f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
270 };
271
272 static VReverbInfo Generic =
273 {
274 &PaddedCell,
275 "Generic",
276 0x0001,
277 true,
278 { 0, 7.5f, 1.00f, -1000, -100, 0, 1.49f, 0.83f, 1.0f, -2602, 0.007f, 0.0f,0.0f,0.0f, 200, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 100.0f, 100.0f, 0x3f }
279 };
280
281 static VReverbInfo Off =
282 {
283 &Generic,
284 "Off",
285 0x0000,
286 true,
287 { 0, 7.5f, 1.00f, -10000, -10000, 0, 1.00f, 1.00f, 1.0f, -2602, 0.007f, 0.0f,0.0f,0.0f, 200, 0.011f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 0.0f, 0.0f, 0x33f }
288 };
289
290 static const VReverbInfo* const DefaultEnvironments[26] =
291 {
292 &Off, &PaddedCell, &Room, &Bathroom, &LivingRoom, &StoneRoom, &Auditorium,
293 &ConcertHall, &Cave, &Arena, &Hangar, &CarpettedHallway, &Hallway,
294 &StoneCorridor, &Alley, &Forest, &City, &Mountains, &Quarry, &Plain,
295 &ParkingLot, &SewerPipe, &Underwater, &Drugged, &Dizzy, &Psychotic
296 };
297
298 // CODE --------------------------------------------------------------------
299
300 //==========================================================================
301 //
302 // DoInt
303 //
304 //==========================================================================
305
DoInt(VScriptParser * sc,int & Val,int Min,int Max)306 static void DoInt(VScriptParser* sc, int& Val, int Min, int Max)
307 {
308 sc->ExpectNumber();
309 Val = MID(Min, sc->Number, Max);
310 }
311
312 //==========================================================================
313 //
314 // DoFloat
315 //
316 //==========================================================================
317
DoFloat(VScriptParser * sc,float & Val,float Min,float Max)318 static void DoFloat(VScriptParser* sc, float& Val, float Min, float Max)
319 {
320 sc->ExpectFloat();
321 Val = MID(Min, sc->Float, Max);
322 }
323
324 //==========================================================================
325 //
326 // DoBool
327 //
328 //==========================================================================
329
DoBool(VScriptParser * sc,int & Flags,int Mask)330 static void DoBool(VScriptParser* sc, int& Flags, int Mask)
331 {
332 if (sc->Check("true"))
333 {
334 Flags |= Mask;
335 }
336 else if (sc->Check("false"))
337 {
338 Flags &= ~Mask;
339 }
340 else
341 {
342 sc->Error("Bad syntax");
343 }
344 }
345
346 //==========================================================================
347 //
348 // VSoundManager::ParseReverbs
349 //
350 //==========================================================================
351
ParseReverbs(VScriptParser * sc)352 void VSoundManager::ParseReverbs(VScriptParser* sc)
353 {
354 guard(VSoundManager::ParseReverbs);
355 if (!Environments)
356 {
357 Environments = &Off;
358 }
359
360 while (!sc->AtEnd())
361 {
362 // Name and ID.
363 sc->ExpectString();
364 VStr Name = sc->String;
365 sc->ExpectNumber();
366 int Id1 = sc->Number;
367 sc->ExpectNumber();
368 int Id2 = sc->Number;
369
370 VReverbProperties Prop;
371 Prop.Flags = 0;
372
373 bool HaveEnvironment = false;
374 bool HaveEnvironmentSize = false;
375 bool HaveEnvironmentDiffusion = false;
376 bool HaveRoom = false;
377 bool HaveRoomHF = false;
378 bool HaveRoomLF = false;
379 bool HaveDecayTime = false;
380 bool HaveDecayHFRatio = false;
381 bool HaveDecayLFRatio = false;
382 bool HaveReflections = false;
383 bool HaveReflectionsDelay = false;
384 bool HaveReflectionsPanX = false;
385 bool HaveReflectionsPanY = false;
386 bool HaveReflectionsPanZ = false;
387 bool HaveReverb = false;
388 bool HaveReverbDelay = false;
389 bool HaveReverbPanX = false;
390 bool HaveReverbPanY = false;
391 bool HaveReverbPanZ = false;
392 bool HaveEchoTime = false;
393 bool HaveEchoDepth = false;
394 bool HaveModulationTime = false;
395 bool HaveModulationDepth = false;
396 bool HaveAirAbsorptionHF = false;
397 bool HaveHFReference = false;
398 bool HaveLFReference = false;
399 bool HaveRoomRolloffFactor = false;
400 bool HaveDiffusion = false;
401 bool HaveDensity = false;
402 int HaveFlags = 0;
403
404 sc->Expect("{");
405 while (!sc->Check("}"))
406 {
407 if (sc->Check("Environment"))
408 {
409 sc->ExpectNumber();
410 if (sc->Number < 0 || sc->Number > 25)
411 {
412 sc->Error("Environment number out of range");
413 }
414 Prop.Environment = sc->Number;
415 HaveEnvironment = true;
416 }
417 else if (sc->Check("EnvironmentSize"))
418 {
419 DoFloat(sc, Prop.EnvironmentSize, 1.0, 100.0);
420 HaveEnvironmentSize = true;
421 }
422 else if (sc->Check("EnvironmentDiffusion"))
423 {
424 DoFloat(sc, Prop.EnvironmentDiffusion, 0.0, 1.0);
425 HaveEnvironmentDiffusion = true;
426 }
427 else if (sc->Check("Room"))
428 {
429 DoInt(sc, Prop.Room, -10000, 0);
430 HaveRoom = true;
431 }
432 else if (sc->Check("RoomHF"))
433 {
434 DoInt(sc, Prop.RoomHF, -10000, 0);
435 HaveRoomHF = true;
436 }
437 else if (sc->Check("RoomLF"))
438 {
439 DoInt(sc, Prop.RoomLF, -10000, 0);
440 HaveRoomLF = true;
441 }
442 else if (sc->Check("DecayTime"))
443 {
444 DoFloat(sc, Prop.DecayTime, 0.1, 20.0);
445 HaveDecayTime = true;
446 }
447 else if (sc->Check("DecayHFRatio"))
448 {
449 DoFloat(sc, Prop.DecayHFRatio, 0.1, 2.0);
450 HaveDecayHFRatio = true;
451 }
452 else if (sc->Check("DecayLFRatio"))
453 {
454 DoFloat(sc, Prop.DecayLFRatio, 0.1, 2.0);
455 HaveDecayLFRatio = true;
456 }
457 else if (sc->Check("Reflections"))
458 {
459 DoInt(sc, Prop.Reflections, -10000, 1000);
460 HaveReflections = true;
461 }
462 else if (sc->Check("ReflectionsDelay"))
463 {
464 DoFloat(sc, Prop.ReflectionsDelay, 0.0, 0.3);
465 HaveReflectionsDelay = true;
466 }
467 else if (sc->Check("ReflectionsPanX"))
468 {
469 DoFloat(sc, Prop.ReflectionsPanX, -2000.0, 2000.0);
470 HaveReflectionsPanX = true;
471 }
472 else if (sc->Check("ReflectionsPanY"))
473 {
474 DoFloat(sc, Prop.ReflectionsPanY, -2000.0, 2000.0);
475 HaveReflectionsPanY = true;
476 }
477 else if (sc->Check("ReflectionsPanZ"))
478 {
479 DoFloat(sc, Prop.ReflectionsPanZ, -2000.0, 2000.0);
480 HaveReflectionsPanZ = true;
481 }
482 else if (sc->Check("Reverb"))
483 {
484 DoInt(sc, Prop.Reverb, -10000, 2000);
485 HaveReverb = true;
486 }
487 else if (sc->Check("ReverbDelay"))
488 {
489 DoFloat(sc, Prop.ReverbDelay, 0.0, 0.1);
490 HaveReverbDelay = true;
491 }
492 else if (sc->Check("ReverbPanX"))
493 {
494 DoFloat(sc, Prop.ReverbPanX, -2000.0, 2000.0);
495 HaveReverbPanX = true;
496 }
497 else if (sc->Check("ReverbPanY"))
498 {
499 DoFloat(sc, Prop.ReverbPanY, -2000.0, 2000.0);
500 HaveReverbPanY = true;
501 }
502 else if (sc->Check("ReverbPanZ"))
503 {
504 DoFloat(sc, Prop.ReverbPanZ, -2000.0, 2000.0);
505 HaveReverbPanZ = true;
506 }
507 else if (sc->Check("EchoTime"))
508 {
509 DoFloat(sc, Prop.EchoTime, 0.075, 0.25);
510 HaveEchoTime = true;
511 }
512 else if (sc->Check("EchoDepth"))
513 {
514 DoFloat(sc, Prop.EchoDepth, 0.0, 1.0);
515 HaveEchoDepth = true;
516 }
517 else if (sc->Check("ModulationTime"))
518 {
519 DoFloat(sc, Prop.ModulationTime, 0.04, 4.0);
520 HaveModulationTime = true;
521 }
522 else if (sc->Check("ModulationDepth"))
523 {
524 DoFloat(sc, Prop.ModulationDepth, 0.0, 1.0);
525 HaveModulationDepth = true;
526 }
527 else if (sc->Check("AirAbsorptionHF"))
528 {
529 DoFloat(sc, Prop.AirAbsorptionHF, -100.0, 0.0);
530 HaveAirAbsorptionHF = true;
531 }
532 else if (sc->Check("HFReference"))
533 {
534 DoFloat(sc, Prop.HFReference, 1000.0, 20000.0);
535 HaveHFReference = true;
536 }
537 else if (sc->Check("LFReference"))
538 {
539 DoFloat(sc, Prop.LFReference, 20.0, 1000.0);
540 HaveLFReference = true;
541 }
542 else if (sc->Check("RoomRolloffFactor"))
543 {
544 DoFloat(sc, Prop.RoomRolloffFactor, 0.0, 10.0);
545 HaveRoomRolloffFactor = true;
546 }
547 else if (sc->Check("Diffusion"))
548 {
549 DoFloat(sc, Prop.Diffusion, 0.0, 100.0);
550 HaveDiffusion = true;
551 }
552 else if (sc->Check("Density"))
553 {
554 DoFloat(sc, Prop.Density, 0.0, 100.0);
555 HaveDensity = true;
556 }
557 else if (sc->Check("bReflectionsScale"))
558 {
559 DoBool(sc, Prop.Flags, REVERBF_ReflectionsScale);
560 HaveFlags |= REVERBF_ReflectionsScale;
561 }
562 else if (sc->Check("bReflectionsDelayScale"))
563 {
564 DoBool(sc, Prop.Flags, REVERBF_ReflectionsDelayScale);
565 HaveFlags |= REVERBF_ReflectionsDelayScale;
566 }
567 else if (sc->Check("bDecayTimeScale"))
568 {
569 DoBool(sc, Prop.Flags, REVERBF_DecayTimeScale);
570 HaveFlags |= REVERBF_DecayTimeScale;
571 }
572 else if (sc->Check("bDecayHFLimit"))
573 {
574 DoBool(sc, Prop.Flags, REVERBF_DecayHFLimit);
575 HaveFlags |= REVERBF_DecayHFLimit;
576 }
577 else if (sc->Check("bReverbScale"))
578 {
579 DoBool(sc, Prop.Flags, REVERBF_ReverbScale);
580 HaveFlags |= REVERBF_ReverbScale;
581 }
582 else if (sc->Check("bReverbDelayScale"))
583 {
584 DoBool(sc, Prop.Flags, REVERBF_ReverbDelayScale);
585 HaveFlags |= REVERBF_ReverbDelayScale;
586 }
587 else if (sc->Check("bEchoTimeScale"))
588 {
589 DoBool(sc, Prop.Flags, REVERBF_EchoTimeScale);
590 HaveFlags |= REVERBF_EchoTimeScale;
591 }
592 else if (sc->Check("bModulationTimeScale"))
593 {
594 DoBool(sc, Prop.Flags, REVERBF_ModulationTimeScale);
595 HaveFlags |= REVERBF_ModulationTimeScale;
596 }
597 else
598 {
599 sc->Error("Bad syntax");
600 }
601 }
602
603 if (!HaveEnvironment)
604 {
605 sc->Error(va("Environment %s is mising an Environment field", *Name));
606 }
607
608 const VReverbProperties& Def = DefaultEnvironments[Prop.Environment]->Props;
609 if (!HaveEnvironmentSize)
610 {
611 Prop.EnvironmentSize = Def.EnvironmentSize;
612 }
613 if (!HaveEnvironmentDiffusion)
614 {
615 Prop.EnvironmentDiffusion = Def.EnvironmentDiffusion;
616 }
617 if (!HaveRoom)
618 {
619 Prop.Room = Def.Room;
620 }
621 if (!HaveRoomHF)
622 {
623 Prop.RoomHF = Def.RoomHF;
624 }
625 if (!HaveRoomLF)
626 {
627 Prop.RoomLF = Def.RoomLF;
628 }
629 if (!HaveDecayTime)
630 {
631 Prop.DecayTime = Def.DecayTime;
632 }
633 if (!HaveDecayHFRatio)
634 {
635 Prop.DecayHFRatio = Def.DecayHFRatio;
636 }
637 if (!HaveDecayLFRatio)
638 {
639 Prop.DecayLFRatio = Def.DecayLFRatio;
640 }
641 if (!HaveReflections)
642 {
643 Prop.Reflections = Def.Reflections;
644 }
645 if (!HaveReflectionsDelay)
646 {
647 Prop.ReflectionsDelay = Def.ReflectionsDelay;
648 }
649 if (!HaveReflectionsPanX)
650 {
651 Prop.ReflectionsPanX = Def.ReflectionsPanX;
652 }
653 if (!HaveReflectionsPanY)
654 {
655 Prop.ReflectionsPanY = Def.ReflectionsPanY;
656 }
657 if (!HaveReflectionsPanZ)
658 {
659 Prop.ReflectionsPanZ = Def.ReflectionsPanZ;
660 }
661 if (!HaveReverb)
662 {
663 Prop.Reverb = Def.Reverb;
664 }
665 if (!HaveReverbDelay)
666 {
667 Prop.ReverbDelay = Def.ReverbDelay;
668 }
669 if (!HaveReverbPanX)
670 {
671 Prop.ReverbPanX = Def.ReverbPanX;
672 }
673 if (!HaveReverbPanY)
674 {
675 Prop.ReverbPanY = Def.ReverbPanY;
676 }
677 if (!HaveReverbPanZ)
678 {
679 Prop.ReverbPanZ = Def.ReverbPanZ;
680 }
681 if (!HaveEchoTime)
682 {
683 Prop.EchoTime = Def.EchoTime;
684 }
685 if (!HaveEchoDepth)
686 {
687 Prop.EchoDepth = Def.EchoDepth;
688 }
689 if (!HaveModulationTime)
690 {
691 Prop.ModulationTime = Def.ModulationTime;
692 }
693 if (!HaveModulationDepth)
694 {
695 Prop.ModulationDepth = Def.ModulationDepth;
696 }
697 if (!HaveAirAbsorptionHF)
698 {
699 Prop.AirAbsorptionHF = Def.AirAbsorptionHF;
700 }
701 if (!HaveHFReference)
702 {
703 Prop.HFReference = Def.HFReference;
704 }
705 if (!HaveLFReference)
706 {
707 Prop.LFReference = Def.LFReference;
708 }
709 if (!HaveRoomRolloffFactor)
710 {
711 Prop.RoomRolloffFactor = Def.RoomRolloffFactor;
712 }
713 if (!HaveDiffusion)
714 {
715 Prop.Diffusion = Def.Diffusion;
716 }
717 if (!HaveDensity)
718 {
719 Prop.Density = Def.Density;
720 }
721 Prop.Flags |= Def.Flags & ~HaveFlags;
722
723 VReverbInfo* NewEnv = new VReverbInfo;
724 char* NewName = new char[Name.Length() + 1];
725 strcpy(NewName, *Name);
726 NewEnv->Next = NULL;
727 NewEnv->Name = NewName;
728 NewEnv->Id = (Id1 << 8) | Id2;
729 NewEnv->Builtin = false;
730 NewEnv->Props = Prop;
731
732 // Find a slot for the new environment.
733 VReverbInfo* Check = Environments;
734 VReverbInfo** Ptr = &Environments;
735 while (Check && Check->Id < NewEnv->Id)
736 {
737 Ptr = &Check->Next;
738 Check = Check->Next;
739 }
740
741 // Check for redeclared environment.
742 if (Check && Check->Id == NewEnv->Id)
743 {
744 // Don't allow replacements of builtin environments.
745 if (!Check->Builtin)
746 {
747 NewEnv->Next = Check->Next;
748 *Ptr = NewEnv;
749 delete[] const_cast<char*>(Check->Name);
750 Check->Name = NULL;
751 delete Check;
752 Check = NULL;
753 }
754 else
755 {
756 delete[] NewName;
757 delete NewEnv;
758 NewEnv = NULL;
759 }
760 }
761 else
762 {
763 NewEnv->Next = Check;
764 *Ptr = NewEnv;
765 }
766 }
767 delete sc;
768 sc = NULL;
769 unguard;
770 }
771
772 //==========================================================================
773 //
774 // VSoundManager::FindEnvironment
775 //
776 //==========================================================================
777
FindEnvironment(int Id)778 VReverbInfo* VSoundManager::FindEnvironment(int Id)
779 {
780 guard(VSoundManager::FindEnvironment);
781 VReverbInfo* Check = Environments;
782 while (Check->Next && Check->Next->Id <= Id)
783 {
784 Check = Check->Next;
785 }
786 return Check;
787 unguard;
788 }
789