]> icculus.org git repositories - taylor/freespace2.git/blob - src/gamesnd/gamesnd.cpp
More stuff compiles
[taylor/freespace2.git] / src / gamesnd / gamesnd.cpp
1 /*
2  * $Logfile: /Freespace2/code/Gamesnd/GameSnd.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Routines to keep track of which sound files go where
8  *
9  * $Log$
10  * Revision 1.2  2002/05/03 13:34:33  theoddone33
11  * More stuff compiles
12  *
13  * Revision 1.1.1.1  2002/05/03 03:28:09  root
14  * Initial import.
15  *
16  * 
17  * 6     7/01/99 11:44a Dave
18  * Updated object sound system to allow multiple obj sounds per ship.
19  * Added hit-by-beam sound. Added killed by beam sound.
20  * 
21  * 5     6/25/99 3:08p Dave
22  * Multiple flyby sounds.
23  * 
24  * 4     5/23/99 8:11p Alanl
25  * Added support for EAX
26  * 
27  * 3     10/23/98 3:51p Dave
28  * Full support for tstrings.tbl and foreign languages. All that remains
29  * is to make it active in Fred.
30  * 
31  * 2     10/07/98 10:52a Dave
32  * Initial checkin.
33  * 
34  * 1     10/07/98 10:48a Dave
35  * 
36  * 39    5/05/98 4:49p Lawrance
37  * Put in code to authenticate A3D, improve A3D support
38  * 
39  * 38    4/25/98 1:25p Lawrance
40  * Make function for playing generic error beep
41  * 
42  * 37    4/18/98 9:12p Lawrance
43  * Added Aureal support.
44  * 
45  * 36    3/29/98 12:56a Lawrance
46  * preload the warp in and explosions sounds before a mission.
47  * 
48  * 35    3/25/98 6:10p Lawrance
49  * Work on DirectSound3D
50  * 
51  * 34    2/22/98 2:48p John
52  * More String Externalization Classification
53  * 
54  * 33    1/17/98 12:33p John
55  * Made the game_busy function be called a constant amount of times per
56  * level load, making the bar prediction easier.
57  * 
58  * 32    1/17/98 12:14p John
59  * Added loading... bar to freespace.
60  * 
61  * 31    1/11/98 11:14p Lawrance
62  * Preload sounds that we expect will get played.
63  * 
64  * 30    12/24/97 8:54p Lawrance
65  * Integrating new popup code
66  * 
67  * 29    12/19/97 3:44p Mike
68  * Fix parse code.  Would improperly read a number through a comma.  Lots
69  * of ships.tbl problems.
70  * 
71  * 28    12/01/97 5:25p Hoffoss
72  * Routed interface sound playing through a special function that will
73  * only allow one instance of the sound to play at a time, avoiding
74  * over-mixing problems.
75  * 
76  * 27    11/20/97 1:06a Lawrance
77  * Add Master_voice_volume, make voices play back at correctly scaled
78  * volumes
79  * 
80  * 26    10/17/97 1:36p Lawrance
81  * load/unload interface sounds
82  * 
83  * 25    10/14/97 11:35p Lawrance
84  * change snd_load parameters
85  * 
86  * 24    7/05/97 1:46p Lawrance
87  * improve robustness of gameplay and interface sound loading/unloading
88  * 
89  * 23    6/09/97 11:50p Lawrance
90  * integrating DirectSound3D
91  * 
92  * 22    6/08/97 5:59p Lawrance
93  * flag sounds as 3D
94  * 
95  * 21    6/05/97 11:25a Lawrance
96  * use sound signatures to ensure correct sound is loaded
97  * 
98  * 20    6/05/97 1:07a Lawrance
99  * changes to support sound interface
100  * 
101  * 19    6/04/97 1:18p Lawrance
102  * added hooks for shield impacts
103  * 
104  * 18    6/02/97 1:50p Lawrance
105  * supporting new format of sounds in table
106  * 
107  * 17    5/14/97 9:54a Lawrance
108  * supporting mission-specific briefing music
109  * 
110  * 16    5/08/97 1:56p Lawrance
111  * supporting ship-specific engine sounds
112  * 
113  * 15    5/06/97 9:36a Lawrance
114  * added support for min and max distances for 3d sounds
115  * 
116  * 14    4/23/97 5:19p Lawrance
117  * split up misc sounds into: gamewide, ingame, and interface
118  * 
119  * 13    4/20/97 11:48a Lawrance
120  * added array of filenames for misc sounds.  Will be useful if we want to
121  * unload then re-load sounds
122  * 
123  * 12    4/20/97 11:19a Lawrance
124  * sndman_ interface obsolete.  Using snd_ functions to load, play, and
125  * manage static sound fx
126  * 
127  * 11    4/18/97 4:31p Mike
128  * Add support for default volume levels.
129  * 
130  * 10    3/20/97 11:04a Lawrance
131  * using incorrect constant when loading music filenames
132  * 
133  * 9     3/19/97 5:53p Lawrance
134  * integrating new Misc_sounds[] array (replaces old Game_sounds
135  * structure)
136  * 
137  * 8     3/17/97 3:47p Mike
138  * Homing missile lock sound.
139  * More on AI ships firing missiles.
140  * 
141  * 7     3/10/97 8:54a Lawrance
142  * added gamesnd_init_looping_sounds()
143  * 
144  * 6     2/28/97 8:41a Lawrance
145  * added afterburner engage and burn sounds
146  * 
147  * 5     2/14/97 12:37a Lawrance
148  * added hooks to play docking/undocking sounds
149  * 
150  * 4     2/13/97 12:03p Lawrance
151  * hooked in throttle sounds
152  * 
153  * 3     2/05/97 10:35a Lawrance
154  * supporting spooled music at menus, briefings, credits etc.
155  * 
156  * 2     1/20/97 7:58p John
157  * Fixed some link errors with testcode.
158  * 
159  * 1     1/20/97 7:08p John
160  *
161  * $NoKeywords: $
162  */
163
164 #include "pstypes.h"
165 #include "gamesnd.h"
166 #include "sound.h"
167 #include "parselo.h"
168 #include "localize.h"
169
170 // Global array that holds data about the gameplay sound effects.
171 game_snd Snds[MAX_GAME_SOUNDS];
172
173 // Global array that holds data about the interface sound effects.
174 game_snd Snds_iface[MAX_INTERFACE_SOUNDS];
175 int Snds_iface_handle[MAX_INTERFACE_SOUNDS];
176
177 // flyby sounds - 2 for each species (fighter and bomber flybys)
178 game_snd Snds_flyby[MAX_SPECIES_NAMES][2];
179
180
181 void gamesnd_play_iface(int n)
182 {
183         if (Snds_iface_handle[n] >= 0)
184                 snd_stop(Snds_iface_handle[n]);
185
186         Snds_iface_handle[n] = snd_play(&Snds_iface[n]);
187 }
188
189 // load in sounds that we expect will get played
190 //
191 // The method currently used is to load all those sounds that have the hardware flag
192 // set.  This works well since we don't want to try and load hardware sounds in on the
193 // fly (too slow).
194 void gamesnd_preload_common_sounds()
195 {
196         int             i;
197         game_snd        *gs;
198
199         for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
200                 gs = &Snds[i];
201                 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
202                         if ( gs->preload ) {
203                                 gs->id = snd_load(gs);
204                         }
205                 }
206                 game_busy();            // Animate loading cursor... does nothing if loading screen not active.
207         }
208 }
209
210 // -------------------------------------------------------------------------------------------------
211 // gamesnd_load_gameplay_sounds()
212 //
213 // Load the ingame sounds into memory
214 //
215 void gamesnd_load_gameplay_sounds()
216 {
217         int             i;
218         game_snd        *gs;
219
220         for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
221                 gs = &Snds[i];
222                 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
223                         gs->id = snd_load(gs);
224                 }
225         }
226 }
227
228 // -------------------------------------------------------------------------------------------------
229 // gamesnd_unload_gameplay_sounds()
230 //
231 // Unload the ingame sounds from memory
232 //
233 void gamesnd_unload_gameplay_sounds()
234 {
235         int             i;
236         game_snd        *gs;
237
238         for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
239                 gs = &Snds[i];
240                 if ( gs->id != -1 ) {
241                         snd_unload( gs->id );
242                         gs->id = -1;
243                 }
244         }       
245 }
246
247 // -------------------------------------------------------------------------------------------------
248 // gamesnd_load_interface_sounds()
249 //
250 // Load the interface sounds into memory
251 //
252 void gamesnd_load_interface_sounds()
253 {
254         int             i;
255         game_snd        *gs;
256
257         for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
258                 gs = &Snds_iface[i];
259                 if ( gs->filename[0] != 0 && stricmp(gs->filename, NOX("none.wav")) ) {
260                         gs->id = snd_load(gs);
261                 }
262         }
263 }
264
265 // -------------------------------------------------------------------------------------------------
266 // gamesnd_unload_interface_sounds()
267 //
268 // Unload the interface sounds from memory
269 //
270 void gamesnd_unload_interface_sounds()
271 {
272         int             i;
273         game_snd        *gs;
274
275         for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
276                 gs = &Snds_iface[i];
277                 if ( gs->id != -1 ) {
278                         snd_unload( gs->id );
279                         gs->id = -1;
280                         gs->id_sig = -1;
281                 }
282         }
283 }
284
285 // -------------------------------------------------------------------------------------------------
286 // gamesnd_parse_line()
287 //
288 // Parse a sound effect line
289 //
290 void gamesnd_parse_line(game_snd *gs, char *tag)
291 {
292         int is_3d;
293
294         required_string(tag);
295         stuff_int(&gs->sig);
296         stuff_string(gs->filename, F_NAME, ",");
297         if ( !stricmp(gs->filename,NOX("empty")) ) {
298                 gs->filename[0] = 0;
299                 advance_to_eoln(NULL);
300                 return;
301         }
302         Mp++;
303         stuff_int(&gs->preload);
304         stuff_float(&gs->default_volume);
305         stuff_int(&is_3d);
306         if ( is_3d ) {
307                 gs->flags |= GAME_SND_USE_DS3D;
308                 stuff_int(&gs->min);
309                 stuff_int(&gs->max);
310         }
311         advance_to_eoln(NULL);
312 }
313
314 // -------------------------------------------------------------------------------------------------
315 // gamesnd_parse_soundstbl() will parse the sounds.tbl file, and load the specified sounds.
316 //
317 //
318 void gamesnd_parse_soundstbl()
319 {
320         int             rval;
321         int             num_game_sounds = 0;
322         int             num_iface_sounds = 0;
323
324         // open localization
325         lcl_ext_open();
326
327         gamesnd_init_sounds();
328
329         if ((rval = setjmp(parse_abort)) != 0) {
330                 Error(LOCATION, "Unable to parse sounds.tbl!  Code = %i.\n", rval);
331         }
332         else {
333                 read_file_text("sounds.tbl");
334                 reset_parse();          
335         }
336
337         // Parse the gameplay sounds section
338         required_string("#Game Sounds Start");
339         while (required_string_either("#Game Sounds End","$Name:")) {
340                 Assert( num_game_sounds < MAX_GAME_SOUNDS);
341                 gamesnd_parse_line( &Snds[num_game_sounds], "$Name:" );
342                 num_game_sounds++;
343         }
344         required_string("#Game Sounds End");
345
346         // Parse the interface sounds section
347         required_string("#Interface Sounds Start");
348         while (required_string_either("#Interface Sounds End","$Name:")) {
349                 Assert( num_iface_sounds < MAX_INTERFACE_SOUNDS);
350                 gamesnd_parse_line(&Snds_iface[num_iface_sounds], "$Name:");
351                 num_iface_sounds++;
352         }
353         required_string("#Interface Sounds End");
354
355         // parse flyby sound section    
356         required_string("#Flyby Sounds Start");
357
358         // read 2 terran sounds
359         gamesnd_parse_line(&Snds_flyby[SPECIES_TERRAN][0], "$Terran:");
360         gamesnd_parse_line(&Snds_flyby[SPECIES_TERRAN][1], "$Terran:");
361
362         // 2 vasudan sounds
363         gamesnd_parse_line(&Snds_flyby[SPECIES_VASUDAN][0], "$Vasudan:");
364         gamesnd_parse_line(&Snds_flyby[SPECIES_VASUDAN][1], "$Vasudan:");
365
366         gamesnd_parse_line(&Snds_flyby[SPECIES_SHIVAN][0], "$Shivan:");
367         gamesnd_parse_line(&Snds_flyby[SPECIES_SHIVAN][1], "$Shivan:");
368         
369         required_string("#Flyby Sounds End");
370
371         // close localization
372         lcl_ext_close();
373 }
374
375
376 // -------------------------------------------------------------------------------------------------
377 // gamesnd_init_struct()
378 //
379 void gamesnd_init_struct(game_snd *gs)
380 {
381         gs->filename[0] = 0;
382         gs->id = -1;
383         gs->id_sig = -1;
384 //      gs->is_3d = 0;
385 //      gs->use_ds3d = 0;
386         gs->flags = 0;
387 }
388
389 // -------------------------------------------------------------------------------------------------
390 // gamesnd_init_sounds() will initialize the Snds[] and Snds_iface[] arrays
391 //
392 void gamesnd_init_sounds()
393 {
394         int             i;
395
396         // init the gameplay sounds
397         for ( i = 0; i < MAX_GAME_SOUNDS; i++ ) {
398                 gamesnd_init_struct(&Snds[i]);
399         }
400
401         // init the interface sounds
402         for ( i = 0; i < MAX_INTERFACE_SOUNDS; i++ ) {
403                 gamesnd_init_struct(&Snds_iface[i]);
404                 Snds_iface_handle[i] = -1;
405         }
406 }
407
408 // callback function for the UI code to call when the mouse first goes over a button.
409 void common_play_highlight_sound()
410 {
411         gamesnd_play_iface(SND_USER_OVER);
412 }
413
414 void gamesnd_play_error_beep()
415 {
416         gamesnd_play_iface(SND_GENERAL_FAIL);
417 }
418