FS2_Open
Open source remastering of the Freespace 2 engine
gamesnd.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 #include <sstream>
11 #include <limits.h>
12 
13 #include "gamesnd/gamesnd.h"
14 #include "localization/localize.h"
15 #include "parse/parselo.h"
16 #include "sound/ds.h"
18 
22 
23 // jg18 - default priorities and limits for retail gameplay sounds
24 static const int NUM_RETAIL_GAMEPLAY_SOUNDS = 192; // indices 0-191, from retail sounds.tbl
25 static EnhancedSoundData Default_sound_priorities[NUM_RETAIL_GAMEPLAY_SOUNDS] =
26 {
27  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_MISSILE_TRACKING = 0, //!< Missle tracking to acquire a lock (looped)
28  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_MISSILE_LOCK = 1, //!< Missle lock (non-looping)
29  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_PRIMARY_CYCLE = 2, //!< cycle primary weapon
30  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SECONDARY_CYCLE = 3, //!< cycle secondary weapon
31  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ENGINE = 4, //!< engine sound (as heard in cockpit)
32  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_CARGO_REVEAL = 5, //!< cargo revealed
33  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_DEATH_ROLL = 6, //!< ship death roll
34  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_SHIP_EXPLODE_1 = 7, //!< ship explosion 1
35  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_TARGET_ACQUIRE = 8, //!< target acquried
36  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ENERGY_ADJUST = 9, //!< energy level change success
37  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ENERGY_ADJUST_FAIL = 10, //!< energy level change fail
38  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ENERGY_TRANS = 11, //!< energy transfer success
39  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ENERGY_TRANS_FAIL = 12, //!< energy transfer fail
40  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_FULL_THROTTLE = 13, //!< set full throttle
41  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_ZERO_THROTTLE = 14, //!< set zero throttle
42  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_THROTTLE_UP = 15, //!< set 1/3 or 2/3 throttle (up)
43  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_THROTTLE_DOWN = 16, //!< set 1/3 or 2/3 throttle (down)
44  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_DOCK_APPROACH = 17, //!< dock approach retros
45  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_DOCK_ATTACH = 18, //!< dock attach
46  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_DOCK_DETACH = 19, //!< dock detach
47  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_DOCK_DEPART = 20, //!< dock depart retros
48  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_ABURN_ENGAGE = 21, //!< afterburner engage
49  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_ABURN_LOOP = 22, //!< afterburner burn sound (looped)
50  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_VAPORIZED = 23, //!< Destroyed by a beam (vaporized)
51  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 2), // SND_ABURN_FAIL = 24, //!< afterburner fail (no fuel when aburn pressed)
52  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_HEATLOCK_WARN = 25, //!< heat-seeker launch warning
53  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_OUT_OF_MISSLES = 26, //!< tried to fire a missle when none are left
54  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_OUT_OF_WEAPON_ENERGY = 27, //!< tried to fire lasers when not enough energy left
55  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_TARGET_FAIL = 28, //!< target fail sound (i.e. press targeting key, but nothing happens)
56  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SQUADMSGING_ON = 29, //!< squadmate message menu appears
57  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SQUADMSGING_OFF = 30, //!< squadmate message menu disappears
58  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 5), // SND_DEBRIS = 31, //!< debris sound (persistant, looping)
59  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_SUBSYS_DIE_1 = 32, //!< subsystem gets destroyed on player ship
60  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_MISSILE_START_LOAD = 33, //!< missle start load (during rearm/repair)
61  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_MISSILE_LOAD = 34, //!< missle load (during rearm/repair)
62  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_SHIP_REPAIR = 35, //!< ship is being repaired (during rearm/repair)
63  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_PLAYER_HIT_LASER = 36, //!< player ship is hit by laser fire
64  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_PLAYER_HIT_MISSILE = 37, //!< player ship is hit by missile
65  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_CMEASURE_CYCLE = 38, //!< countermeasure cycle
66  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_SHIELD_HIT = 39, //!< shield hit
67  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_SHIELD_HIT_YOU = 40, //!< player shield is hit
68  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_GAME_MOUSE_CLICK = 41, //!< mouse click
69  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_ASPECTLOCK_WARN = 42, //!< aspect launch warning
70  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SHIELD_XFER_OK = 43, //!< shield quadrant transfer successful
71  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 5), // SND_ENGINE_WASH = 44, //!< Engine wash (looped)
72  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_WARP_IN = 45, //!< warp hole opening up for arriving
73  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_WARP_OUT = 46, //!< warp hole opening up for departing (Same as warp in for now)
74  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_PLAYER_WARP_FAIL = 47, //!< player warp has failed
75  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_STATIC = 48, //!< hud gauge static
76  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_SHIP_EXPLODE_2 = 49, //!< ship explosion 2
77  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_PLAYER_WARP_OUT = 50, //!< ship is warping out in 3rd person
78  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_SHIP_SHIP_HEAVY = 51, //!< heavy ship-ship collide sound
79  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_SHIP_SHIP_LIGHT = 52, //!< light ship-ship collide sound
80  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_SHIP_SHIP_SHIELD = 53, //!< shield ship-ship collide overlay sound
81  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_THREAT_FLASH = 54, //!< missile threat indicator flashes
82  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_PROXIMITY_WARNING = 55, //!< proximity warning (heat seeker)
83  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 3), // SND_PROXIMITY_ASPECT_WARNING = 56, //!< proximity warning (aspect)
84  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_DIRECTIVE_COMPLETE = 57, //!< directive complete
85  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_SUBSYS_EXPLODE = 58, //!< other ship subsystem destroyed
86  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_CAPSHIP_EXPLODE = 59, //!< captial ship explosion
87  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_CAPSHIP_SUBSYS_EXPLODE = 60, //!< captial ship subsystem destroyed
88  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_LARGESHIP_WARPOUT = 61, //!< large ship warps out
89  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 5), // SND_ASTEROID_EXPLODE_LARGE = 62, //!< large asteroid blows up
90  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 5), // SND_ASTEROID_EXPLODE_SMALL = 63, //!< small asteroid blows up
91  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_CUE_VOICE = 64, //!< sound to indicate voice is about to start
92  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_END_VOICE = 65, //!< sound to indicate voice has ended
93  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 2), // SND_CARGO_SCAN = 66, //!< cargo scanning (looped)
94  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_WEAPON_FLYBY = 67, //!< weapon flyby sound
95  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 5), // SND_ASTEROID = 68, //!< asteroid sound (persistant, looped)
96  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_CAPITAL_WARP_IN = 69, //!< capital warp hole opening
97  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_CAPITAL_WARP_OUT = 70, //!< capital warp hole closing
98  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 5), // SND_ENGINE_LOOP_LARGE = 71, //!< LARGE engine ambient
99  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SUBSPACE_LEFT_CHANNEL = 72, //!< subspace ambient sound (left channel) (looped)
100  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SUBSPACE_RIGHT_CHANNEL = 73, //!< subspace ambient sound (right channel) (looped)
101  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 4), // SND_MISSILE_EVADED_POPUP = 74, //!< "evaded" HUD popup
102  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_ENGINE_LOOP_HUGE = 75, //!< HUGE engine ambient
103  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_LIGHT_LASER_FIRE = 76, //!< SD-4 Sidearm laser fired
104  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_LIGHT_LASER_IMPACT = 77, //!< DR-2 Scalpel fired
105  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_HVY_LASER_FIRE = 78, //!< Flail II fired
106  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_HVY_LASER_IMPACT = 79, //!< Prometheus R laser fired
107  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_MASSDRV_FIRED = 80, //!< Prometheus S laser fired
108  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_MASSDRV_IMPACT = 81, //!< GTW-66 Newton Cannon fired
109  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_FLAIL_FIRED = 82, //!< UD-8 Kayser Laser fired
110  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_FLAIL_IMPACT = 83, //!< GTW-19 Circe laser fired
111  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_NEUTRON_FLUX_FIRED = 84, //!< GTW-83 Lich laser fired
112  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_NEUTRON_FLUX_IMPACT = 85, //!< Laser impact
113  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_DEBUG_LASER_FIRED = 86, //!< Subach-HLV Vasudan laser
114  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_ROCKEYE_FIRED = 87, //!< rockeye missile launch
115  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_MISSILE_IMPACT1 = 88, //!< missile impact 1
116  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_MAG_MISSILE_LAUNCH = 89, //!< mag pulse missile launch
117  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_FURY_MISSILE_LAUNCH = 90, //!< fury missile launch
118  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_SHRIKE_MISSILE_LAUNCH = 91, //!< shrike missile launch
119  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_ANGEL_MISSILE_LAUNCH = 92, //!< angel fire missile launch
120  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_CLUSTER_MISSILE_LAUNCH = 93, //!< cluster bomb launch
121  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_CLUSTERB_MISSILE_LAUNCH = 94, //!< cluster baby bomb launch
122  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_STILETTO_MISSILE_LAUNCH = 95, //!< stiletto bomb launch
123  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_TSUNAMI_MISSILE_LAUNCH = 96, //!< tsunami bomb launch
124  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_HARBINGER_MISSILE_LAUNCH = 97, //!< harbinger bomb launch
125  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_MEGAWOKKA_MISSILE_LAUNCH = 98, //!< mega wokka launch
126  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_CMEASURE1_LAUNCH = 99, //!< countermeasure 1 launch
127  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_SHIVAN_LIGHT_LASER_FIRE = 100,//!< Shivan light laser
128  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_SHOCKWAVE_EXPLODE = 101,//!< shockwave ignition
129  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_SWARM_MISSILE_LAUNCH = 102,//!< swarm missile sound
130  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_103 = 103,//!< Shivan heavy laser
131  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_UNDEFINED_104 = 104,//!< Vasudan SuperCap engine
132  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_UNDEFINED_105 = 105,//!< Shivan SuperCap engine
133  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_UNDEFINED_106 = 106,//!< Terran SuperCap engine
134  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_107 = 107,//!< Vasudan light laser fired
135  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_108 = 108,//!< Shivan heavy laser
136  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 2), // SND_SHOCKWAVE_IMPACT = 109,//!< shockwave impact
137  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_110 = 110,//!< TERRAN TURRET 1
138  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_111 = 111,//!< TERRAN TURRET 2
139  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_112 = 112,//!< VASUDAN TURRET 1
140  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_113 = 113,//!< VASUDAN TURRET 2
141  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_UNDEFINED_114 = 114,//!< SHIVAN TURRET 1
142  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_TARG_LASER_LOOP = 115,//!< targeting laser loop sound
143  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 8), // SND_FLAK_FIRE = 116,//!< Flak Gun Launch
144  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_SHIELD_BREAKER = 117,//!< Flak Gun Impact
145  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM_LOW, 8), // SND_EMP_MISSILE = 118,//!< EMP Missle
146  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 5), // SND_AUTOCANNON_LOOP = 119,//!< Escape Pod Drone
147  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 5), // SND_AUTOCANNON_SHOT = 120,//!< Beam Hit 1
148  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_BEAM_LOOP = 121,//!< beam loop
149  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_BEAM_UP = 122,//!< beam power up
150  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_BEAM_DOWN = 123,//!< beam power down
151  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_BEAM_SHOT = 124,//!< Beam shot 1
152  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_BEAM_VAPORIZE = 125,//!< Beam shot 2
153  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_TERRAN_FIGHTER_ENG = 126,//!< Terran fighter engine
154  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_TERRAN_BOMBER_ENG = 127,//!< Terran bomber engine
155  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_TERRAN_CAPITAL_ENG = 128,//!< Terran cruiser engine
156  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SPECIESB_FIGHTER_ENG = 129,//!< Vasudan fighter engine
157  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SPECIESB_BOMBER_ENG = 130,//!< Vasudan bomber engine
158  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SPECIESB_CAPITAL_ENG = 131,//!< Vasudan cruiser engine
159  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SHIVAN_FIGHTER_ENG = 132,//!< Shivan fighter engine
160  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SHIVAN_BOMBER_ENG = 133,//!< Shivan bomber engine
161  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_SHIVAN_CAPITAL_ENG = 134,//!< Shivan cruiser engine
162  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_REPAIR_SHIP_ENG = 135,//!< Repair ship beacon/engine sound
163  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_UNDEFINED_136 = 136,//!< Terran capital engine
164  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_UNDEFINED_137 = 137,//!< Vasudan capital engine
165  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 4), // SND_UNDEFINED_138 = 138,//!< Shivan capital engine
166  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_DEBRIS_ARC_01 = 139,//!< 0.10 second spark sound effect
167  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_DEBRIS_ARC_02 = 140,//!< 0.25 second spark sound effect
168  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_DEBRIS_ARC_03 = 141,//!< 0.50 second spark sound effect
169  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_DEBRIS_ARC_04 = 142,//!< 0.75 second spark sound effect
170  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_DEBRIS_ARC_05 = 143,//!< 1.00 second spark sound effect
171  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_144 = 144,//!< LTerSlash beam loop
172  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_145 = 145,//!< TerSlash beam loop
173  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_146 = 146,//!< SGreen beam loop
174  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_147 = 147,//!< BGreen beem loop
175  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_148 = 148,//!< BFGreen been loop
176  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_149 = 149,//!< Antifighter beam loop
177  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_150 = 150,//!< 1 sec warm up
178  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_151 = 151,//!< 1.5 sec warm up
179  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_152 = 152,//!< 2.5 sec warm up
180  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_153 = 153,//!< 3 sec warm up
181  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_154 = 154,//!< 3.5 sec warm up
182  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_155 = 155,//!< 5 sec warm up
183  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_156 = 156,//!< LTerSlash warm down
184  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_157 = 157,//!< TerSlash warm down
185  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_158 = 158,//!< SGreen warm down
186  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_159 = 159,//!< BGreen warm down
187  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_160 = 160,//!< BFGreen warm down
188  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_161 = 161,//!< T_AntiFtr warm down
189  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_COPILOT = 162,//!< copilot (SCP)
190  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_163 = 163,//!< (Empty in Retail)
191  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_164 = 164,//!< (Empty in Retail)
192  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_165 = 165,//!< (Empty in Retail)
193  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_166 = 166,//!< (Empty in Retail)
194  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_167 = 167,//!< (Empty in Retail)
195  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_168 = 168,//!< (Empty in Retail)
196  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_169 = 169,//!< (Empty in Retail)
197  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_170 = 170,//!< (Empty in Retail)
198  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_171 = 171,//!< (Empty in Retail)
199  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_172 = 172,//!< (Empty in Retail)
200  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SUPERNOVA_1 = 173,//!< SuperNova (distant)
201  EnhancedSoundData( SND_ENHANCED_PRIORITY_MUST_PLAY, 1), // SND_SUPERNOVA_2 = 174,//!< SuperNova (shockwave)
202  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_UNDEFINED_175 = 175,//!< Shivan large engine
203  EnhancedSoundData( SND_ENHANCED_PRIORITY_MEDIUM, 3), // SND_UNDEFINED_176 = 176,//!< Shivan large engine
204  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_177 = 177,//!< SRed beam loop
205  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_178 = 178,//!< LRed beam loop
206  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 3), // SND_UNDEFINED_179 = 179,//!< Antifighter beam loop
207  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_LIGHTNING_1 = 180,//!< Thunder 1 sound in neblua
208  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 4), // SND_LIGHTNING_2 = 181,//!< Thunder 2 sound in neblua
209  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_182 = 182,//!< 1 sec warm up
210  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_183 = 183,//!< 1.5 sec warm up
211  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_184 = 184,//!< 3 sec warm up
212  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 2), // SND_UNDEFINED_185 = 185,//!< Shivan Commnode
213  EnhancedSoundData( SND_ENHANCED_PRIORITY_HIGH, 1), // SND_UNDEFINED_186 = 186,//!< Volition PirateShip
214  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_187 = 187,//!< SRed warm down
215  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_188 = 188,//!< LRed warm down
216  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 3), // SND_UNDEFINED_189 = 189,//!< AntiFtr warm down
217  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 2), // SND_UNDEFINED_190 = 190,//!< Instellation 1
218  EnhancedSoundData(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 2) // SND_UNDEFINED_191 = 191,//!< Instellation 2
219 };
220 
221 static const EnhancedSoundData default_enhanced_sound_data(SND_ENHANCED_PRIORITY_MEDIUM_HIGH, 1);
222 
223 
224 /*
225  * Update any uninitialized EnhancedSoundData in Snds
226  * with hardcoded defaults for retail.
227  */
229 {
230  int i = 0;
231 
232  for (SCP_vector<game_snd>::iterator it = Snds.begin(), end = Snds.end(); it != end; ++it, ++i)
233  {
234  if (it->enhanced_sound_data.priority== SND_ENHANCED_PRIORITY_INVALID)
235  {
236  if (i < NUM_RETAIL_GAMEPLAY_SOUNDS)
237  {
238  it->enhanced_sound_data.priority= Default_sound_priorities[i].priority;
239  }
240  else
241  {
242  it->enhanced_sound_data.priority= default_enhanced_sound_data.priority;
243  }
244  }
245 
246  if (it->enhanced_sound_data.limit < 1)
247  {
248  if (i < NUM_RETAIL_GAMEPLAY_SOUNDS)
249  {
250  it->enhanced_sound_data.limit = Default_sound_priorities[i].limit;
251  }
252  else
253  {
254  it->enhanced_sound_data.limit= default_enhanced_sound_data.limit;
255  }
256  }
257  }
258 }
259 
261 {
262  if (Snds_iface_handle[n] >= 0)
263  snd_stop(Snds_iface_handle[n]);
264 
265  Snds_iface_handle[n] = snd_play(&Snds_iface[n]);
266 }
267 
276 int gamesnd_lookup_name(const char* name, const SCP_vector<game_snd>& sounds)
277 {
278  // if we get passed -1, don't bother trying to look it up.
279  if (name == NULL || *name == 0 || !strcmp(name, "-1"))
280  {
281  return -1;
282  }
283 
284  Assert( sounds.size() <= INT_MAX );
285 
286  int i = 0;
287 
288  for(SCP_vector<game_snd>::const_iterator snd = sounds.begin(); snd != sounds.end(); ++snd)
289  {
290  if (!snd->name.compare(name))
291  {
292  return i;
293  }
294  i++;
295  }
296 
297  return -1;
298 }
299 
300 // WMC - now ignores file extension.
301 int gamesnd_get_by_name(const char* name)
302 {
303  Assert( Snds.size() <= INT_MAX );
304 
305  int index = gamesnd_lookup_name(name, Snds);
306 
307  if (index < 0)
308  {
309  int i = 0;
310  for(SCP_vector<game_snd>::iterator snd = Snds.begin(); snd != Snds.end(); ++snd)
311  {
312  char *p = strrchr( snd->filename, '.' );
313  if(p == NULL)
314  {
315  if(!stricmp(snd->filename, name))
316  {
317  index = i;
318  break;
319  }
320  }
321  else if(!strnicmp(snd->filename, name, p-snd->filename))
322  {
323  index = i;
324  break;
325  }
326 
327  i++;
328  }
329  }
330 
331  return index;
332 }
333 
335 {
336  Assert( Snds_iface.size() <= INT_MAX );
337  Assert( Snds_iface.size() == Snds_iface_handle.size() );
338 
339  int index = gamesnd_lookup_name(name, Snds_iface);
340 
341  if (index < 0)
342  {
343  int i = 0;
344  for(SCP_vector<game_snd>::iterator snd = Snds_iface.begin(); snd != Snds_iface.end(); ++snd)
345  {
346  char *p = strrchr( snd->filename, '.' );
347  if(p == NULL)
348  {
349  if(!stricmp(snd->filename, name))
350  {
351  index = i;
352  break;
353  }
354  }
355  else if(!strnicmp(snd->filename, name, p-snd->filename))
356  {
357  index = i;
358  break;
359  }
360 
361  i++;
362  }
363  }
364 
365  return index;
366 }
367 
369 {
370  char temp[11];
371  sprintf(temp, "%i", index);
372 
373  return gamesnd_lookup_name(temp, Snds);
374 }
375 
377 {
378  Assert( Snds_iface.size() == Snds_iface_handle.size() );
379 
380  char temp[11];
381  sprintf(temp, "%i", index);
382 
383  return gamesnd_lookup_name(temp, Snds_iface);
384 }
385 
396 void parse_sound_core(const char* tag, int *idx_dest, const char* object_name, const char* buf, parse_sound_flags flags)
397 {
398  int idx;
399 
400  if(flags & PARSE_SOUND_INTERFACE_SOUND)
401  idx = gamesnd_get_by_iface_name(buf);
402  else
403  idx = gamesnd_get_by_name(buf);
404 
405  if(idx != -1)
406  {
407  (*idx_dest) = idx;
408  }
409 
410  size_t size_to_check = 0;
411 
412  if(flags & PARSE_SOUND_INTERFACE_SOUND)
413  {
414  size_to_check = Snds_iface.size();
415  Assert( Snds_iface.size() == Snds_iface_handle.size() );
416  }
417  else
418  {
419  size_to_check = Snds.size();
420  }
421 
422  Assert( size_to_check <= INT_MAX );
423 
424  //Ensure sound is in range
425  if((*idx_dest) < -1 || (*idx_dest) >= (int)size_to_check)
426  {
427  (*idx_dest) = -1;
428  Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and " SIZE_T_ARG ". Forcing to -1 (Nonexistent sound).\n",
429  tag, object_name, size_to_check);
430  }
431 }
432 
445 void parse_sound(const char* tag, int *idx_dest, const char* object_name, parse_sound_flags flags)
446 {
447  if(optional_string(tag))
448  {
449  char buf[MAX_FILENAME_LEN];
451 
452  parse_sound_core(tag, idx_dest, object_name, buf, flags);
453  }
454 }
455 
468 void parse_sound_list(const char* tag, SCP_vector<int>& destination, const char* object_name, parse_sound_flags flags)
469 {
470  if(optional_string(tag))
471  {
472  int check=0;
473 
474  //if we're using the old format, parse the first entry separately
475  if(!(flags & PARSE_SOUND_SCP_SOUND_LIST))
476  {
477  stuff_int(&check);
478  }
479 
480  //now read the rest of the entries on the line
481  for(size_t i=0; !check_for_eoln(); i++)
482  {
483  char buf[MAX_FILENAME_LEN];
485 
486  //we do this conditionally to avoid adding needless entries when reparsing
487  if(destination.size() <= i)
488  {
489  destination.push_back(-1);
490  }
491 
492  parse_sound_core(tag, &destination.at(i), object_name, buf, flags);
493  }
494 
495  //if we're using the old format, double check the size)
496  if(!(flags & PARSE_SOUND_SCP_SOUND_LIST) && (destination.size() != (unsigned)check))
497  {
498  mprintf(("%s in '%s' has " SIZE_T_ARG " entries. This does not match entered size of %i.", tag, object_name, destination.size(), check));
499  }
500  }
501 }
502 
511 {
512  if ( !Sound_enabled )
513  return;
514 
515  Assert( Snds.size() <= INT_MAX );
516  for (SCP_vector<game_snd>::iterator gs = Snds.begin(); gs != Snds.end(); ++gs) {
517  if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
518  if ( gs->preload ) {
519  game_busy( NOX("** preloading common game sounds **") ); // Animate loading cursor... does nothing if loading screen not active.
520  gs->id = snd_load(&(*gs));
521  }
522  }
523  }
524 }
525 
530 {
531  if ( !Sound_enabled )
532  return;
533 
534  Assert( Snds.size() <= INT_MAX );
535  for (SCP_vector<game_snd>::iterator gs = Snds.begin(); gs != Snds.end(); ++gs) {
536  if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
537  if ( !gs->preload ) { // don't try to load anything that's already preloaded
538  game_busy( NOX("** preloading gameplay sounds **") ); // Animate loading cursor... does nothing if loading screen not active.
539  gs->id = snd_load(&(*gs));
540  }
541  }
542  }
543 }
544 
549 {
550  Assert( Snds.size() <= INT_MAX );
551  for (SCP_vector<game_snd>::iterator gs = Snds.begin(); gs != Snds.end(); ++gs) {
552  if ( gs->id != -1 ) {
553  snd_unload( gs->id );
554  gs->id = -1;
555  }
556  }
557 }
558 
563 {
564  if ( !Sound_enabled )
565  return;
566 
567  Assert( Snds_iface.size() < INT_MAX );
568  for (SCP_vector<game_snd>::iterator si = Snds_iface.begin(); si != Snds_iface.end(); ++si) {
569  if ( si->filename[0] != 0 && strnicmp(si->filename, NOX("none.wav"), 4) ) {
570  si->id = snd_load(&(*si));
571  }
572  }
573 }
574 
579 {
580  Assert( Snds_iface.size() < INT_MAX );
581  for (SCP_vector<game_snd>::iterator si = Snds_iface.begin(); si != Snds_iface.end(); ++si) {
582  if ( si->id != -1 ) {
583  snd_unload( si->id );
584  si->id = -1;
585  si->id_sig = -1;
586  }
587  }
588 }
589 
591 {
592  int is_3d;
593  int temp;
594 
596 
597  if (!stricmp(gs->filename, NOX("empty")))
598  {
599  gs->filename[0] = 0;
600  advance_to_eoln(NULL);
601  return;
602  }
603  Mp++;
604 
605  stuff_int(&temp);
606 
607  if (temp > 0)
608  {
609  gs->preload = true;
610  }
611 
613 
614  stuff_int(&is_3d);
615 
616  if (is_3d)
617  {
618  gs->flags |= GAME_SND_USE_DS3D;
619  stuff_int(&gs->min);
620  stuff_int(&gs->max);
621  }
622  else
623  {
624  gs->min = 0;
625  gs->max = 0;
626 
627  // silly retail, not abiding by its own format...
628  if (!stricmp(gs->filename, "l_hit.wav") || !stricmp(gs->filename, "m_hit.wav"))
629  {
630  int temp_min, temp_max;
631 
633  if (stuff_int_optional(&temp_min, true) == 2)
634  {
636  if (stuff_int_optional(&temp_max, true) == 2)
637  {
638  mprintf(("Dutifully converting retail sound %s, '%s' to a 3D sound...\n", gs->name.c_str(), gs->filename));
639  is_3d = 1;
640 
641  gs->flags |= GAME_SND_USE_DS3D;
642  gs->min = temp_min;
643  gs->max = temp_max;
644  }
645  }
646  }
647  }
648 
649  // check for extra values per Mantis #2408
651  if (stuff_int_optional(&temp, true) == 2)
652  {
653  Warning(LOCATION, "Unexpected extra value %d found for sound '%s' (filename '%s')! Check the format of the sounds.tbl (or .tbm) entry.", temp, gs->name.c_str(), gs->filename);
654  }
655 
656  advance_to_eoln(NULL);
657 }
658 
660 {
661  Assertion(priority_str != NULL, "convert_to_enhanced_priority given null priority_str!");
662 
663  if (!stricmp(priority_str, "Must Play"))
664  {
666  }
667  else if (!stricmp(priority_str, "High"))
668  {
670  }
671  else if (!stricmp(priority_str, "Medium-High"))
672  {
674  }
675  else if (!stricmp(priority_str, "Medium"))
676  {
678  }
679  else if (!stricmp(priority_str, "Medium-Low"))
680  {
682  }
683  else if (!stricmp(priority_str, "Low"))
684  {
686  }
687  else
688  {
689  error_display(1, "Unknown enhanced sound priority: %s\n", priority_str);
691  }
692 }
693 
694 bool required_string_no_create(const char* token, bool no_create)
695 {
696  if (no_create)
697  {
698  return optional_string(token) == 1;
699  }
700 
701  required_string(token);
702  return true;
703 }
704 
705 void parse_gamesnd_new(game_snd* gs, bool no_create)
706 {
707  char name[MAX_FILENAME_LEN];
708  // New extended format found
710 
711  if (!stricmp(name, NOX("empty")))
712  {
713  gs->filename[0] = 0;
714  return;
715  }
716 
717  // If the name _doesn't_ match <same> put it into gs->filename;
718  if (stricmp(name, "<same>"))
719  {
720  strcpy_s(gs->filename, name);
721  }
722  else if (!no_create)
723  {
724  // Throw an error if <same> was specified but we are creating a new entry
725  error_display(1, "'<same>' is only allowed if +nocreate was specified!");
726  return;
727  }
728 
729  if (required_string_no_create("+Preload:", no_create))
730  {
731  stuff_boolean(&gs->preload);
732  }
733 
734  if (required_string_no_create("+Volume:", no_create))
735  {
737  }
738 
739  if (optional_string("+3D Sound:"))
740  {
741  gs->flags |= GAME_SND_USE_DS3D;
742  required_string("+Attenuation start:");
743 
744  stuff_int(&gs->min);
745 
746  required_string("+Attenuation end:");
747 
748  stuff_int(&gs->max);
749  }
750  else
751  {
752  gs->min = 0;
753  gs->max = 0;
754  }
755 
756  // jg18 - enhanced sound parameters
757  if (optional_string("+Priority:"))
758  {
759  SCP_string priority_string;
760  stuff_string(priority_string, F_NAME);
761  EnhancedSoundPriority priority = convert_to_enhanced_priority(priority_string.c_str());
762  if (priority != SND_ENHANCED_PRIORITY_INVALID)
763  {
764  gs->enhanced_sound_data.priority= priority;
765  }
766  // else case not needed since conversion function displays message on error
767  }
768 
769  if (optional_string("+Limit:"))
770  {
771  int temp_limit;
772  stuff_int(&temp_limit);
773 
774  if ((temp_limit > 0) && (static_cast<uint>(temp_limit) <= SND_ENHANCED_MAX_LIMIT))
775  {
776  gs->enhanced_sound_data.limit = (unsigned int)temp_limit;
777  }
778  else
779  {
780  error_display(1, "Invalid enhanced sound limit: %d\n", temp_limit);
781  }
782  }
783 }
784 
785 void gamesnd_parse_entry(game_snd *gs, bool no_create, SCP_vector<game_snd> *lookupVector)
786 {
788 
789  stuff_string(name, F_NAME, "\t \n");
790 
791  if (!no_create)
792  {
793  if (lookupVector != NULL)
794  {
795  if (gamesnd_lookup_name(name.c_str(), *lookupVector) >= 0)
796  {
797  Warning(LOCATION, "Duplicate sound name \"%s\" found!", name.c_str());
798  }
799  }
800 
801  gs->name = name;
802  }
803  else
804  {
805  int vectorIndex = gamesnd_lookup_name(name.c_str(), *lookupVector);
806 
807  if (vectorIndex < 0)
808  {
809  Warning(LOCATION, "No existing sound entry with name \"%s\" found!", name.c_str());
810  no_create = false;
811  gs->name = name;
812  }
813  else
814  {
815  gs = &lookupVector->at(vectorIndex);
816  }
817  }
818 
819  if (optional_string("+Filename:"))
820  {
821  parse_gamesnd_new(gs, no_create);
822  }
823  else
824  {
825  parse_gamesnd_old(gs);
826  }
827 }
828 
839 bool gamesnd_parse_line(game_snd *gs, const char *tag, SCP_vector<game_snd> *lookupVector = NULL)
840 {
841  Assertion(gs != NULL, "Invalid game_snd pointer passed to gamesnd_parse_line!");
842 
843  required_string(tag);
844 
845  bool no_create = false;
846 
847  if (lookupVector != NULL)
848  {
849  if(optional_string("+nocreate"))
850  {
851  no_create = true;
852  }
853  }
854 
855  gamesnd_parse_entry(gs, no_create, lookupVector);
856 
857  return !no_create;
858 }
859 
861 {
862  char name[65] = { '\0' };
863  char template_name[65] = { '\0' };
864  EFXREVERBPROPERTIES *props;
865 
866  while (required_string_either("#Sound Environments End", "$Name:"))
867  {
868  required_string("$Name:");
869  stuff_string(name, F_NAME, sizeof(name)-1);
870 
871  if (optional_string("$Template:"))
872  {
873  stuff_string(template_name, F_NAME, sizeof(template_name)-1);
874  }
875  else
876  {
877  template_name[0] = '\0';
878  }
879 
880  ds_eax_get_prop(&props, name, template_name);
881 
882  if (optional_string("+Density:"))
883  {
884  stuff_float(&props->flDensity);
885  CLAMP(props->flDensity, 0.0f, 1.0f);
886  }
887 
888  if (optional_string("+Diffusion:"))
889  {
890  stuff_float(&props->flDiffusion);
891  CLAMP(props->flDiffusion, 0.0f, 1.0f);
892  }
893 
894  if (optional_string("+Gain:"))
895  {
896  stuff_float(&props->flGain);
897  CLAMP(props->flGain, 0.0f, 1.0f);
898  }
899 
900  if (optional_string("+Gain HF:"))
901  {
902  stuff_float(&props->flGainHF);
903  CLAMP(props->flGainHF, 0.0f, 1.0f);
904  }
905 
906  if (optional_string("+Gain LF:"))
907  {
908  stuff_float(&props->flGainLF);
909  CLAMP(props->flGainLF, 0.0f, 1.0f);
910  }
911 
912  if (optional_string("+Decay Time:"))
913  {
914  stuff_float(&props->flDecayTime);
915  CLAMP(props->flDecayTime, 0.01f, 20.0f);
916  }
917 
918  if (optional_string("+Decay HF Ratio:"))
919  {
920  stuff_float(&props->flDecayHFRatio);
921  CLAMP(props->flDecayHFRatio, 0.1f, 20.0f);
922  }
923 
924  if (optional_string("+Decay LF Ratio:"))
925  {
926  stuff_float(&props->flDecayLFRatio);
927  CLAMP(props->flDecayLFRatio, 0.1f, 20.0f);
928  }
929 
930  if (optional_string("+Reflections Gain:"))
931  {
933  CLAMP(props->flReflectionsGain, 0.0f, 3.16f);
934  }
935 
936  if (optional_string("+Reflections Delay:"))
937  {
939  CLAMP(props->flReflectionsDelay, 0.0f, 0.3f);
940  }
941 
942  if (optional_string("+Reflections Pan:"))
943  {
945  CLAMP(props->flReflectionsPan[0], 0.0f, 1.0f);
946  CLAMP(props->flReflectionsPan[1], 0.0f, 1.0f);
947  CLAMP(props->flReflectionsPan[2], 0.0f, 1.0f);
948  }
949 
950  if (optional_string("+Late Reverb Gain:"))
951  {
952  stuff_float(&props->flLateReverbGain);
953  CLAMP(props->flLateReverbGain, 0.0f, 10.0f);
954  }
955 
956  if (optional_string("+Late Reverb Delay:"))
957  {
959  CLAMP(props->flLateReverbDelay, 0.0f, 0.1f);
960  }
961 
962  if (optional_string("+Late Reverb Pan:"))
963  {
965  CLAMP(props->flLateReverbPan[0], 0.0f, 1.0f);
966  CLAMP(props->flLateReverbPan[1], 0.0f, 1.0f);
967  CLAMP(props->flLateReverbPan[2], 0.0f, 1.0f);
968  }
969 
970  if (optional_string("+Echo Time:"))
971  {
972  stuff_float(&props->flEchoTime);
973  CLAMP(props->flEchoTime, 0.075f, 0.25f);
974  }
975 
976  if (optional_string("+Echo Depth:"))
977  {
978  stuff_float(&props->flEchoDepth);
979  CLAMP(props->flEchoDepth, 0.0f, 1.0f);
980  }
981 
982  if (optional_string("+Modulation Time:"))
983  {
984  stuff_float(&props->flModulationTime);
985  CLAMP(props->flModulationTime, 0.004f, 4.0f);
986  }
987 
988  if (optional_string("+Modulation Depth:"))
989  {
991  CLAMP(props->flModulationDepth, 0.0f, 1.0f);
992  }
993 
994  if (optional_string("+HF Reference:"))
995  {
996  stuff_float(&props->flHFReference);
997  CLAMP(props->flHFReference, 1000.0f, 20000.0f);
998  }
999 
1000  if (optional_string("+LF Reference:"))
1001  {
1002  stuff_float(&props->flLFReference);
1003  CLAMP(props->flLFReference, 20.0f, 1000.0f);
1004  }
1005 
1006  if (optional_string("+Room Rolloff Factor:"))
1007  {
1009  CLAMP(props->flRoomRolloffFactor, 0.0f, 10.0f);
1010  }
1011 
1012  if (optional_string("+Air Absorption Gain HF:"))
1013  {
1015  CLAMP(props->flAirAbsorptionGainHF, 0.892f, 1.0f);
1016  }
1017 
1018  if (optional_string("+Decay HF Limit:"))
1019  {
1020  stuff_int(&props->iDecayHFLimit);
1021  CLAMP(props->iDecayHFLimit, 0, 1);
1022  }
1023  }
1024 
1025  required_string("#Sound Environments End");
1026 }
1027 
1028 static SCP_vector<species_info> missingFlybySounds;
1029 
1030 void parse_sound_table(const char* filename)
1031 {
1032  try
1033  {
1034  read_file_text(filename, CF_TYPE_TABLES);
1035  reset_parse();
1036 
1037  // Parse the gameplay sounds section
1038  if (optional_string("#Game Sounds Start"))
1039  {
1040  while (!check_for_string("#Game Sounds End"))
1041  {
1042  game_snd tempSound;
1043  if (gamesnd_parse_line(&tempSound, "$Name:", &Snds))
1044  {
1045  Snds.push_back(game_snd(tempSound));
1046  }
1047  }
1048 
1049  required_string("#Game Sounds End");
1050  }
1051 
1052  // Parse the interface sounds section
1053  if (optional_string("#Interface Sounds Start"))
1054  {
1055  while (!check_for_string("#Interface Sounds End"))
1056  {
1057  game_snd tempSound;
1058  if (gamesnd_parse_line(&tempSound, "$Name:", &Snds_iface))
1059  {
1060  Snds_iface.push_back(game_snd(tempSound));
1061  Snds_iface_handle.push_back(-1);
1062  }
1063  }
1064 
1065  required_string("#Interface Sounds End");
1066  }
1067 
1068  // parse flyby sound section
1069  if (optional_string("#Flyby Sounds Start"))
1070  {
1071  char species_name_tag[NAME_LENGTH + 2];
1072  int sanity_check = 0;
1073  size_t i;
1074 
1075  while (!check_for_string("#Flyby Sounds End") && (sanity_check <= (int)Species_info.size()))
1076  {
1077  for (i = 0; i < Species_info.size(); i++)
1078  {
1079  species_info *species = &Species_info[i];
1080 
1081  sprintf(species_name_tag, "$%s:", species->species_name);
1082 
1083  if (check_for_string(species_name_tag))
1084  {
1085  gamesnd_parse_line(&species->snd_flyby_fighter, species_name_tag);
1086  gamesnd_parse_line(&species->snd_flyby_bomber, species_name_tag);
1087  sanity_check--;
1088  }
1089  else
1090  {
1091  sanity_check++;
1092  }
1093  }
1094  }
1095 
1096  required_string("#Flyby Sounds End");
1097  }
1098 
1099  if (optional_string("#Sound Environments Start"))
1100  {
1102  }
1103  }
1104  catch (const parse::ParseException& e)
1105  {
1106  mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
1107  return;
1108  }
1109 
1111 }
1112 
1117 {
1118  parse_sound_table("sounds.tbl");
1119 
1120  parse_modular_table("*-snd.tbm", parse_sound_table);
1121 
1122  // if we are missing any species then report
1123  if (missingFlybySounds.size() > 0)
1124  {
1125  SCP_string errorString;
1126  for (size_t i = 0; i < missingFlybySounds.size(); i++)
1127  {
1128  errorString.append(missingFlybySounds[i].species_name);
1129  errorString.append("\n");
1130  }
1131 
1132  Error(LOCATION, "The following species are missing flyby sounds in sounds.tbl:\n%s", errorString.c_str());
1133  }
1134 
1135  missingFlybySounds.clear();
1136 }
1137 
1142 {
1143  Snds.clear();
1144  Snds_iface.clear();
1145  Snds_iface_handle.clear();
1146 }
1147 
1152 {
1154 }
1155 
1160 {
1162 }
float flDiffusion
Definition: ds.h:142
void advance_to_eoln(char *more_terminators)
Definition: parselo.cpp:335
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
int i
Definition: multi_pxo.cpp:466
float flDecayLFRatio
Definition: ds.h:148
float flGainLF
Definition: ds.h:145
int check_for_string(const char *pstr)
Definition: parselo.cpp:517
EnhancedSoundPriority convert_to_enhanced_priority(const char *priority_str)
Definition: gamesnd.cpp:659
float flReflectionsPan[3]
Definition: ds.h:151
LOCAL state_stack gs[GS_STACK_SIZE]
void gamesnd_parse_soundstbl()
Definition: gamesnd.cpp:1116
int stuff_int_optional(int *i, bool raw)
Definition: parselo.cpp:2387
SCP_vector< game_snd > Snds
Definition: gamesnd.cpp:19
int gamesnd_get_by_tbl_index(int index)
Definition: gamesnd.cpp:368
void gamesnd_unload_gameplay_sounds()
Definition: gamesnd.cpp:548
int snd_load(game_snd *gs, int allow_hardware_load)
Definition: sound.cpp:281
GLuint index
Definition: Glext.h:5608
user_over (mouse over a control)
Definition: gamesnd.h:304
bool preload
preload sound (ie read from disk before mission starts)
Definition: sound.h:81
char * object_name(int obj)
void parse_sound_core(const char *tag, int *idx_dest, const char *object_name, const char *buf, parse_sound_flags flags)
Definition: gamesnd.cpp:396
int min
distance at which sound will stop getting louder
Definition: sound.h:79
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
#define mprintf(args)
Definition: pstypes.h:238
general failure sound for any event
Definition: gamesnd.h:297
float flDecayTime
Definition: ds.h:146
#define SIZE_T_ARG
Definition: clang.h:61
int gamesnd_get_by_name(const char *name)
Definition: gamesnd.cpp:301
void parse_gamesnd_new(game_snd *gs, bool no_create)
Definition: gamesnd.cpp:705
#define Assertion(expr, msg,...)
Definition: clang.h:41
game_snd snd_flyby_bomber
Definition: species_defs.h:70
game_snd snd_flyby_fighter
Definition: species_defs.h:69
float flDecayHFRatio
Definition: ds.h:147
float flLateReverbDelay
Definition: ds.h:153
float flEchoDepth
Definition: ds.h:156
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
int flags
Definition: sound.h:84
parse_sound_flags
Definition: gamesnd.h:36
int required_string_either(char *str1, char *str2)
Checks for one of two required strings.
Definition: parselo.cpp:673
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
void gamesnd_parse_entry(game_snd *gs, bool no_create, SCP_vector< game_snd > *lookupVector)
Definition: gamesnd.cpp:785
void stuff_float(float *f)
Definition: parselo.cpp:2328
char filename[MAX_FILENAME_LEN]
Definition: sound.h:76
#define CLAMP(x, min, max)
Definition: pstypes.h:488
void game_busy(const char *filename=NULL)
Definition: systemvars.cpp:173
float flLFReference
Definition: ds.h:161
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
void parse_sound(const char *tag, int *idx_dest, const char *object_name, parse_sound_flags flags)
Definition: gamesnd.cpp:445
void gamesnd_unload_interface_sounds()
Definition: gamesnd.cpp:578
void ignore_gray_space()
Definition: parselo.cpp:83
void gamesnd_load_interface_sounds()
Definition: gamesnd.cpp:562
char * filename
#define strnicmp(s1, s2, n)
Definition: config.h:272
EnhancedSoundPriority
Definition: sound.h:32
void stuff_string(char *outstr, int type, int len, char *terminators)
Definition: parselo.cpp:1189
#define CF_TYPE_TABLES
Definition: cfile.h:50
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
float flEchoTime
Definition: ds.h:155
float flRoomRolloffFactor
Definition: ds.h:162
int required_string(const char *pstr)
Definition: parselo.cpp:468
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
Definition: sound.cpp:517
int optional_string(const char *pstr)
Definition: parselo.cpp:539
bool required_string_no_create(const char *token, bool no_create)
Definition: gamesnd.cpp:694
EnhancedSoundData enhanced_sound_data
Definition: sound.h:85
unsigned int limit
Definition: sound.h:46
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
Definition: parselo.cpp:1995
int idx
Definition: multiui.cpp:761
void gamesnd_load_gameplay_sounds()
Definition: gamesnd.cpp:529
float flModulationDepth
Definition: ds.h:158
int Sound_enabled
Definition: sound.cpp:51
void parse_sound_table(const char *filename)
Definition: gamesnd.cpp:1030
bool gamesnd_parse_line(game_snd *gs, const char *tag, SCP_vector< game_snd > *lookupVector=NULL)
Definition: gamesnd.cpp:839
float flReflectionsDelay
Definition: ds.h:150
GLclampd n
Definition: Glext.h:7286
SCP_vector< game_snd > Snds_iface
Definition: gamesnd.cpp:20
int iDecayHFLimit
Definition: ds.h:163
void stuff_boolean(int *i, bool a_to_eol)
Definition: parselo.cpp:2519
#define NOX(s)
Definition: pstypes.h:473
int max
distance at which sound is inaudible
Definition: sound.h:80
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Parse the list of sounds SCP style (just indexes and/or files names, no count first) ...
Definition: gamesnd.h:40
void gamesnd_preload_common_sounds()
Definition: gamesnd.cpp:510
SCP_string name
The name of the sound.
Definition: sound.h:75
GLbitfield flags
Definition: Glext.h:6722
void reset_parse(char *text)
Definition: parselo.cpp:3305
GLuint const GLchar * name
Definition: Glext.h:5608
int gamesnd_get_by_iface_name(const char *name)
Definition: gamesnd.cpp:334
void stuff_int(int *i)
Definition: parselo.cpp:2372
void parse_gamesnd_old(game_snd *gs)
Definition: gamesnd.cpp:590
float flHFReference
Definition: ds.h:160
#define NAME_LENGTH
Definition: globals.h:15
int ds_eax_get_prop(EFXREVERBPROPERTIES **props, const char *name, const char *template_name)
Definition: ds.cpp:2393
float flDensity
Definition: ds.h:141
const unsigned int SND_ENHANCED_MAX_LIMIT
Definition: sound.cpp:35
#define GAME_SND_USE_DS3D
Definition: sound.h:21
int check_for_eoln()
Definition: parselo.cpp:505
void parse_sound_environments()
Definition: gamesnd.cpp:860
Search for sound in the interface part of sounds.tbl.
Definition: gamesnd.h:39
GLfloat GLfloat p
Definition: Glext.h:8373
#define F_NAME
Definition: parselo.h:34
#define LOCATION
Definition: pstypes.h:245
void common_play_highlight_sound()
Definition: gamesnd.cpp:1151
char species_name[NAME_LENGTH]
Definition: species_defs.h:47
void gamesnd_play_error_beep()
Definition: gamesnd.cpp:1159
SCP_vector< species_info > Species_info
float flReflectionsGain
Definition: ds.h:149
float flGain
Definition: ds.h:143
void error_display(int error_level, char *format,...)
Definition: parselo.cpp:308
int snd_unload(int n)
Definition: sound.cpp:415
int parse_modular_table(const char *name_check, void(*parse_callback)(const char *filename), int path_type, int sort_type)
Definition: parselo.cpp:4205
float flLateReverbPan[3]
Definition: ds.h:154
int temp
Definition: lua.cpp:4996
float flAirAbsorptionGainHF
Definition: ds.h:159
SCP_vector< int > Snds_iface_handle
Definition: gamesnd.cpp:21
float flGainHF
Definition: ds.h:144
void stuff_string_white(char *outstr, int len)
Definition: parselo.cpp:969
void snd_stop(int sig)
Definition: sound.cpp:875
void gamesnd_play_iface(int n)
Definition: gamesnd.cpp:260
float flLateReverbGain
Definition: ds.h:152
int stuff_float_list(float *flp, int max_floats)
Definition: parselo.cpp:2988
void parse_sound_list(const char *tag, SCP_vector< int > &destination, const char *object_name, parse_sound_flags flags)
Definition: gamesnd.cpp:468
float default_volume
range: 0.0 -> 1.0
Definition: sound.h:78
void gamesnd_add_retail_default_enhanced_sound_data()
Definition: gamesnd.cpp:228
void gamesnd_close()
Definition: gamesnd.cpp:1141
#define stricmp(s1, s2)
Definition: config.h:271
char * Mp
Definition: parselo.cpp:48
int gamesnd_lookup_name(const char *name, const SCP_vector< game_snd > &sounds)
Definition: gamesnd.cpp:276
float flModulationTime
Definition: ds.h:157
GLuint GLuint end
Definition: Gl.h:1502
#define strcpy_s(...)
Definition: safe_strings.h:67
Definition: sound.h:72
int gamesnd_get_by_iface_tbl_index(int index)
Definition: gamesnd.cpp:376