2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Gamesnd/GameSnd.cpp $
15 * Routines to keep track of which sound files go where
18 * Revision 1.3 2002/06/09 04:41:17 relnev
19 * added copyright header
21 * Revision 1.2 2002/05/03 13:34:33 theoddone33
24 * Revision 1.1.1.1 2002/05/03 03:28:09 root
28 * 6 7/01/99 11:44a Dave
29 * Updated object sound system to allow multiple obj sounds per ship.
30 * Added hit-by-beam sound. Added killed by beam sound.
32 * 5 6/25/99 3:08p Dave
33 * Multiple flyby sounds.
35 * 4 5/23/99 8:11p Alanl
36 * Added support for EAX
38 * 3 10/23/98 3:51p Dave
39 * Full support for tstrings.tbl and foreign languages. All that remains
40 * is to make it active in Fred.
42 * 2 10/07/98 10:52a Dave
45 * 1 10/07/98 10:48a Dave
47 * 39 5/05/98 4:49p Lawrance
48 * Put in code to authenticate A3D, improve A3D support
50 * 38 4/25/98 1:25p Lawrance
51 * Make function for playing generic error beep
53 * 37 4/18/98 9:12p Lawrance
54 * Added Aureal support.
56 * 36 3/29/98 12:56a Lawrance
57 * preload the warp in and explosions sounds before a mission.
59 * 35 3/25/98 6:10p Lawrance
60 * Work on DirectSound3D
62 * 34 2/22/98 2:48p John
63 * More String Externalization Classification
65 * 33 1/17/98 12:33p John
66 * Made the game_busy function be called a constant amount of times per
67 * level load, making the bar prediction easier.
69 * 32 1/17/98 12:14p John
70 * Added loading... bar to freespace.
72 * 31 1/11/98 11:14p Lawrance
73 * Preload sounds that we expect will get played.
75 * 30 12/24/97 8:54p Lawrance
76 * Integrating new popup code
78 * 29 12/19/97 3:44p Mike
79 * Fix parse code. Would improperly read a number through a comma. Lots
80 * of ships.tbl problems.
82 * 28 12/01/97 5:25p Hoffoss
83 * Routed interface sound playing through a special function that will
84 * only allow one instance of the sound to play at a time, avoiding
85 * over-mixing problems.
87 * 27 11/20/97 1:06a Lawrance
88 * Add Master_voice_volume, make voices play back at correctly scaled
91 * 26 10/17/97 1:36p Lawrance
92 * load/unload interface sounds
94 * 25 10/14/97 11:35p Lawrance
95 * change snd_load parameters
97 * 24 7/05/97 1:46p Lawrance
98 * improve robustness of gameplay and interface sound loading/unloading
100 * 23 6/09/97 11:50p Lawrance
101 * integrating DirectSound3D
103 * 22 6/08/97 5:59p Lawrance
106 * 21 6/05/97 11:25a Lawrance
107 * use sound signatures to ensure correct sound is loaded
109 * 20 6/05/97 1:07a Lawrance
110 * changes to support sound interface
112 * 19 6/04/97 1:18p Lawrance
113 * added hooks for shield impacts
115 * 18 6/02/97 1:50p Lawrance
116 * supporting new format of sounds in table
118 * 17 5/14/97 9:54a Lawrance
119 * supporting mission-specific briefing music
121 * 16 5/08/97 1:56p Lawrance
122 * supporting ship-specific engine sounds
124 * 15 5/06/97 9:36a Lawrance
125 * added support for min and max distances for 3d sounds
127 * 14 4/23/97 5:19p Lawrance
128 * split up misc sounds into: gamewide, ingame, and interface
130 * 13 4/20/97 11:48a Lawrance
131 * added array of filenames for misc sounds. Will be useful if we want to
132 * unload then re-load sounds
134 * 12 4/20/97 11:19a Lawrance
135 * sndman_ interface obsolete. Using snd_ functions to load, play, and
136 * manage static sound fx
138 * 11 4/18/97 4:31p Mike
139 * Add support for default volume levels.
141 * 10 3/20/97 11:04a Lawrance
142 * using incorrect constant when loading music filenames
144 * 9 3/19/97 5:53p Lawrance
145 * integrating new Misc_sounds[] array (replaces old Game_sounds
148 * 8 3/17/97 3:47p Mike
149 * Homing missile lock sound.
150 * More on AI ships firing missiles.
152 * 7 3/10/97 8:54a Lawrance
153 * added gamesnd_init_looping_sounds()
155 * 6 2/28/97 8:41a Lawrance
156 * added afterburner engage and burn sounds
158 * 5 2/14/97 12:37a Lawrance
159 * added hooks to play docking/undocking sounds
161 * 4 2/13/97 12:03p Lawrance
162 * hooked in throttle sounds
164 * 3 2/05/97 10:35a Lawrance
165 * supporting spooled music at menus, briefings, credits etc.
167 * 2 1/20/97 7:58p John
168 * Fixed some link errors with testcode.
170 * 1 1/20/97 7:08p John
179 #include "localize.h"
181 // Global array that holds data about the gameplay sound effects.
182 game_snd Snds[MAX_GAME_SOUNDS];
184 // Global array that holds data about the interface sound effects.
185 game_snd Snds_iface[MAX_INTERFACE_SOUNDS];
186 int Snds_iface_handle[MAX_INTERFACE_SOUNDS];
188 // flyby sounds - 2 for each species (fighter and bomber flybys)
189 game_snd Snds_flyby[MAX_SPECIES_NAMES][2];
192 void gamesnd_play_iface(int n)
194 if (Snds_iface_handle[n] >= 0)
195 snd_stop(Snds_iface_handle[n]);
197 Snds_iface_handle[n] = snd_play(&Snds_iface[n]);
200 // load in sounds that we expect will get played
202 // The method currently used is to load all those sounds that have the hardware flag
203 // set. This works well since we don't want to try and load hardware sounds in on the
205 void gamesnd_preload_common_sounds()
210 for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
212 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
214 gs->id = snd_load(gs);
217 game_busy(); // Animate loading cursor... does nothing if loading screen not active.
221 // -------------------------------------------------------------------------------------------------
222 // gamesnd_load_gameplay_sounds()
224 // Load the ingame sounds into memory
226 void gamesnd_load_gameplay_sounds()
231 for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
233 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
234 gs->id = snd_load(gs);
239 // -------------------------------------------------------------------------------------------------
240 // gamesnd_unload_gameplay_sounds()
242 // Unload the ingame sounds from memory
244 void gamesnd_unload_gameplay_sounds()
249 for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
251 if ( gs->id != -1 ) {
252 snd_unload( gs->id );
258 // -------------------------------------------------------------------------------------------------
259 // gamesnd_load_interface_sounds()
261 // Load the interface sounds into memory
263 void gamesnd_load_interface_sounds()
268 for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
270 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
271 gs->id = snd_load(gs);
276 // -------------------------------------------------------------------------------------------------
277 // gamesnd_unload_interface_sounds()
279 // Unload the interface sounds from memory
281 void gamesnd_unload_interface_sounds()
286 for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
288 if ( gs->id != -1 ) {
289 snd_unload( gs->id );
296 // -------------------------------------------------------------------------------------------------
297 // gamesnd_parse_line()
299 // Parse a sound effect line
301 void gamesnd_parse_line(game_snd *gs, char *tag)
305 required_string(tag);
307 stuff_string(gs->filename, F_NAME, ",");
308 if ( !stricmp(gs->filename,NOX("empty")) ) {
310 advance_to_eoln(NULL);
314 stuff_int(&gs->preload);
315 stuff_float(&gs->default_volume);
318 gs->flags |= GAME_SND_USE_DS3D;
322 advance_to_eoln(NULL);
325 // -------------------------------------------------------------------------------------------------
326 // gamesnd_parse_soundstbl() will parse the sounds.tbl file, and load the specified sounds.
329 void gamesnd_parse_soundstbl()
332 int num_game_sounds = 0;
333 int num_iface_sounds = 0;
338 gamesnd_init_sounds();
340 if ((rval = setjmp(parse_abort)) != 0) {
341 Error(LOCATION, "Unable to parse sounds.tbl! Code = %i.\n", rval);
344 read_file_text("sounds.tbl");
348 // Parse the gameplay sounds section
349 required_string("#Game Sounds Start");
350 while (required_string_either("#Game Sounds End","$Name:")) {
351 Assert( num_game_sounds < MAX_GAME_SOUNDS);
352 gamesnd_parse_line( &Snds[num_game_sounds], "$Name:" );
355 required_string("#Game Sounds End");
357 // Parse the interface sounds section
358 required_string("#Interface Sounds Start");
359 while (required_string_either("#Interface Sounds End","$Name:")) {
360 Assert( num_iface_sounds < MAX_INTERFACE_SOUNDS);
361 gamesnd_parse_line(&Snds_iface[num_iface_sounds], "$Name:");
364 required_string("#Interface Sounds End");
366 // parse flyby sound section
367 required_string("#Flyby Sounds Start");
369 // read 2 terran sounds
370 gamesnd_parse_line(&Snds_flyby[SPECIES_TERRAN][0], "$Terran:");
371 gamesnd_parse_line(&Snds_flyby[SPECIES_TERRAN][1], "$Terran:");
374 gamesnd_parse_line(&Snds_flyby[SPECIES_VASUDAN][0], "$Vasudan:");
375 gamesnd_parse_line(&Snds_flyby[SPECIES_VASUDAN][1], "$Vasudan:");
377 gamesnd_parse_line(&Snds_flyby[SPECIES_SHIVAN][0], "$Shivan:");
378 gamesnd_parse_line(&Snds_flyby[SPECIES_SHIVAN][1], "$Shivan:");
380 required_string("#Flyby Sounds End");
382 // close localization
387 // -------------------------------------------------------------------------------------------------
388 // gamesnd_init_struct()
390 void gamesnd_init_struct(game_snd *gs)
400 // -------------------------------------------------------------------------------------------------
401 // gamesnd_init_sounds() will initialize the Snds[] and Snds_iface[] arrays
403 void gamesnd_init_sounds()
407 // init the gameplay sounds
408 for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
409 gamesnd_init_struct(&Snds[i]);
412 // init the interface sounds
413 for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
414 gamesnd_init_struct(&Snds_iface[i]);
415 Snds_iface_handle[i] = -1;
419 // callback function for the UI code to call when the mouse first goes over a button.
420 void common_play_highlight_sound()
422 gamesnd_play_iface(SND_USER_OVER);
425 void gamesnd_play_error_beep()
427 gamesnd_play_iface(SND_GENERAL_FAIL);