Rev 298 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 298 | Rev 333 | ||
---|---|---|---|
1 | // Emacs style mode select -*- C++ -*- |
1 | // Emacs style mode select -*- C++ -*- |
2 | //----------------------------------------------------------------------------- |
2 | //----------------------------------------------------------------------------- |
3 | // |
3 | // |
4 | // $Id:$ |
4 | // $Id:$ |
5 | // |
5 | // |
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
7 | // |
7 | // |
8 | // This source is available for distribution and/or modification |
8 | // This source is available for distribution and/or modification |
9 | // only under the terms of the DOOM Source Code License as |
9 | // only under the terms of the DOOM Source Code License as |
10 | // published by id Software. All rights reserved. |
10 | // published by id Software. All rights reserved. |
11 | // |
11 | // |
12 | // The source is distributed in the hope that it will be useful, |
12 | // The source is distributed in the hope that it will be useful, |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License |
14 | // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License |
15 | // for more details. |
15 | // for more details. |
16 | // |
16 | // |
17 | // $Log:$ |
17 | // $Log:$ |
18 | // |
18 | // |
19 | // DESCRIPTION: none |
19 | // DESCRIPTION: none |
20 | // |
20 | // |
21 | //----------------------------------------------------------------------------- |
21 | //----------------------------------------------------------------------------- |
22 | 22 | ||
23 | 23 | ||
24 | static const char |
24 | static const char |
25 | rcsid[] = "$Id: s_sound.c,v 1.6 1997/02/03 22:45:12 b1 Exp $"; |
25 | rcsid[] = "$Id: s_sound.c,v 1.6 1997/02/03 22:45:12 b1 Exp $"; |
26 | 26 | ||
27 | 27 | ||
28 | #include |
28 | #include |
29 | #include |
29 | #include |
30 | 30 | ||
31 | #include "i_system.h" |
31 | #include "i_system.h" |
32 | #include "i_sound.h" |
32 | #include "i_sound.h" |
33 | #include "sounds.h" |
33 | #include "sounds.h" |
34 | #include "s_sound.h" |
34 | #include "s_sound.h" |
35 | 35 | ||
36 | #include "z_zone.h" |
36 | #include "z_zone.h" |
37 | #include "m_random.h" |
37 | #include "m_random.h" |
38 | #include "w_wad.h" |
38 | #include "w_wad.h" |
39 | 39 | ||
40 | #include "doomdef.h" |
40 | #include "doomdef.h" |
41 | #include "p_local.h" |
41 | #include "p_local.h" |
42 | //#include "m_music.h" |
42 | //#include "m_music.h" |
43 | 43 | ||
44 | #include "doomstat.h" |
44 | #include "doomstat.h" |
45 | 45 | ||
46 | //#include "qmus2mid.h" |
46 | //#include "qmus2mid.h" |
47 | 47 | ||
48 | void WriteDebug(char *); |
48 | void WriteDebug(char *); |
49 | 49 | ||
50 | // Purpose? |
50 | // Purpose? |
51 | const char snd_prefixen[] |
51 | const char snd_prefixen[] |
52 | = { 'P', 'P', 'A', 'S', 'S', 'S', 'M', 'M', 'M', 'S', 'S', 'S' }; |
52 | = { 'P', 'P', 'A', 'S', 'S', 'S', 'M', 'M', 'M', 'S', 'S', 'S' }; |
53 | 53 | ||
54 | #define S_MAX_VOLUME 127 |
54 | #define S_MAX_VOLUME 127 |
55 | 55 | ||
56 | // when to clip out sounds |
56 | // when to clip out sounds |
57 | // Does not fit the large outdoor areas. |
57 | // Does not fit the large outdoor areas. |
58 | #define S_CLIPPING_DIST (1200*0x10000) |
58 | #define S_CLIPPING_DIST (1200*0x10000) |
59 | 59 | ||
60 | // Distance tp origin when sounds should be maxed out. |
60 | // Distance tp origin when sounds should be maxed out. |
61 | // This should relate to movement clipping resolution |
61 | // This should relate to movement clipping resolution |
62 | // (see BLOCKMAP handling). |
62 | // (see BLOCKMAP handling). |
63 | // Originally: (200*0x10000). |
63 | // Originally: (200*0x10000). |
64 | #define S_CLOSE_DIST (160*0x10000) |
64 | #define S_CLOSE_DIST (160*0x10000) |
65 | 65 | ||
66 | 66 | ||
67 | #define S_ATTENUATOR ((S_CLIPPING_DIST-S_CLOSE_DIST)>>FRACBITS) |
67 | #define S_ATTENUATOR ((S_CLIPPING_DIST-S_CLOSE_DIST)>>FRACBITS) |
68 | 68 | ||
69 | // Adjustable by menu. |
69 | // Adjustable by menu. |
70 | #define NORM_VOLUME snd_MaxVolume |
70 | #define NORM_VOLUME snd_MaxVolume |
71 | 71 | ||
72 | #define NORM_PITCH 128 |
72 | #define NORM_PITCH 128 |
73 | #define NORM_PRIORITY 64 |
73 | #define NORM_PRIORITY 64 |
74 | #define NORM_SEP 128 |
74 | #define NORM_SEP 128 |
75 | 75 | ||
76 | #define S_PITCH_PERTURB 1 |
76 | #define S_PITCH_PERTURB 1 |
77 | #define S_STEREO_SWING (96*0x10000) |
77 | #define S_STEREO_SWING (96*0x10000) |
78 | 78 | ||
79 | // percent attenuation from front to back |
79 | // percent attenuation from front to back |
80 | #define S_IFRACVOL 30 |
80 | #define S_IFRACVOL 30 |
81 | 81 | ||
82 | #define NA 0 |
82 | #define NA 0 |
83 | //#define S_NUMCHANNELS 2 |
83 | //#define S_NUMCHANNELS 2 |
84 | #define NUM_CHANNELS 16 |
84 | #define NUM_CHANNELS 16 |
85 | 85 | ||
86 | // Current music/sfx card - index useless |
86 | // Current music/sfx card - index useless |
87 | // w/o a reference LUT in a sound module. |
87 | // w/o a reference LUT in a sound module. |
88 | extern int snd_MusicDevice; |
88 | extern int snd_MusicDevice; |
89 | extern int snd_SfxDevice; |
89 | extern int snd_SfxDevice; |
90 | // Config file? Same disclaimer as above. |
90 | // Config file? Same disclaimer as above. |
91 | extern int snd_DesiredMusicDevice; |
91 | extern int snd_DesiredMusicDevice; |
92 | extern int snd_DesiredSfxDevice; |
92 | extern int snd_DesiredSfxDevice; |
93 | 93 | ||
94 | 94 | ||
95 | typedef struct |
95 | typedef struct |
96 | { |
96 | { |
97 | // sound information (if null, channel avail.) |
97 | // sound information (if null, channel avail.) |
98 | sfxinfo_t* sfxinfo; |
98 | sfxinfo_t* sfxinfo; |
99 | 99 | ||
100 | // origin of sound |
100 | // origin of sound |
101 | void* origin; |
101 | void* origin; |
102 | 102 | ||
103 | // handle of the sound being played |
103 | // handle of the sound being played |
104 | int handle; |
104 | int handle; |
105 | 105 | ||
106 | } channel_t; |
106 | } channel_t; |
107 | 107 | ||
108 | 108 | ||
109 | // the set of channels available |
109 | // the set of channels available |
110 | static channel_t* channels; |
110 | static channel_t* channels; |
111 | 111 | ||
112 | // These are not used, but should be (menu). |
112 | // These are not used, but should be (menu). |
113 | // Maximum volume of a sound effect. |
113 | // Maximum volume of a sound effect. |
114 | // Internal default is max out of 0-15. |
114 | // Internal default is max out of 0-15. |
115 | int snd_SfxVolume = 80; |
115 | int snd_SfxVolume = 80; |
116 | 116 | ||
117 | // Maximum volume of music. Useless so far. |
117 | // Maximum volume of music. Useless so far. |
118 | int snd_MusicVolume = 80; |
118 | int snd_MusicVolume = 80; |
119 | 119 | ||
120 | 120 | ||
121 | 121 | ||
122 | // whether songs are mus_paused |
122 | // whether songs are mus_paused |
123 | static boolean mus_paused; |
123 | static boolean mus_paused; |
124 | 124 | ||
125 | // music currently being played |
125 | // music currently being played |
126 | static musicinfo_t* mus_playing=0; |
126 | static musicinfo_t* mus_playing=0; |
127 | 127 | ||
128 | // following is set |
128 | // following is set |
129 | // by the defaults code in M_misc: |
129 | // by the defaults code in M_misc: |
130 | // number of channels available |
130 | // number of channels available |
131 | int numChannels; |
131 | int numChannels; |
132 | 132 | ||
133 | static int nextcleanup; |
133 | static int nextcleanup; |
134 | 134 | ||
135 | 135 | ||
136 | 136 | ||
137 | // |
137 | // |
138 | // Internals. |
138 | // Internals. |
139 | // |
139 | // |
140 | int |
140 | int |
141 | S_getChannel |
141 | S_getChannel |
142 | ( void* origin, |
142 | ( void* origin, |
143 | sfxinfo_t* sfxinfo, |
143 | sfxinfo_t* sfxinfo, |
144 | int sfxid ); |
144 | int sfxid ); |
145 | 145 | ||
146 | 146 | ||
147 | int |
147 | int |
148 | S_AdjustSoundParams |
148 | S_AdjustSoundParams |
149 | ( mobj_t* listener, |
149 | ( mobj_t* listener, |
150 | mobj_t* source, |
150 | mobj_t* source, |
151 | int* vol, |
151 | int* vol, |
152 | int* sep, |
152 | int* sep, |
153 | int* pitch ); |
153 | int* pitch ); |
154 | 154 | ||
155 | void S_StopChannel(int cnum); |
155 | void S_StopChannel(int cnum); |
156 | 156 | ||
157 | 157 | ||
158 | 158 | ||
159 | // |
159 | // |
160 | // Initializes sound stuff, including volume |
160 | // Initializes sound stuff, including volume |
161 | // Sets channels, SFX and music volume, |
161 | // Sets channels, SFX and music volume, |
162 | // allocates channel buffer, sets S_sfx lookup. |
162 | // allocates channel buffer, sets S_sfx lookup. |
163 | // |
163 | // |
164 | void S_Init |
164 | void S_Init |
165 | ( int sfxVolume, |
165 | ( int sfxVolume, |
166 | int musicVolume ) |
166 | int musicVolume ) |
167 | { |
167 | { |
168 | int i; |
168 | int i; |
169 | 169 | ||
170 | printf("S_Init: default sfx volume %d\n", sfxVolume); |
170 | printf("S_Init: default sfx volume %d\n", sfxVolume); |
171 | 171 | ||
172 | I_CreateSound(); |
172 | //I_CreateSound(); |
173 | numChannels = NUM_CHANNELS; |
173 | numChannels = NUM_CHANNELS; |
174 | 174 | ||
175 | // Whatever these did with DMX, these are rather dummies now. |
175 | // Whatever these did with DMX, these are rather dummies now. |
176 | I_SetChannels(); |
176 | I_SetChannels(); |
177 | 177 | ||
178 | S_SetSfxVolume(sfxVolume); |
178 | S_SetSfxVolume(sfxVolume); |
179 | // No music with Linux - another dummy. |
179 | // No music with Linux - another dummy. |
180 | S_SetMusicVolume(musicVolume); |
180 | S_SetMusicVolume(musicVolume); |
181 | 181 | ||
182 | // Allocating the internal channels for mixing |
182 | // Allocating the internal channels for mixing |
183 | // (the maximum numer of sounds rendered |
183 | // (the maximum numer of sounds rendered |
184 | // simultaneously) within zone memory. |
184 | // simultaneously) within zone memory. |
185 | channels = |
185 | channels = |
186 | (channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0); |
186 | (channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0); |
187 | 187 | ||
188 | // Free all channels for use |
188 | // Free all channels for use |
189 | for (i=0 ; i |
189 | for (i=0 ; i |
190 | channels[i].sfxinfo = 0; |
190 | channels[i].sfxinfo = 0; |
191 | 191 | ||
192 | // no sounds are playing, and they are not mus_paused |
192 | // no sounds are playing, and they are not mus_paused |
193 | mus_paused = 0; |
193 | mus_paused = 0; |
194 | 194 | ||
195 | // Note that sounds have not been cached (yet). |
195 | // Note that sounds have not been cached (yet). |
196 | for (i=1 ; i |
196 | for (i=1 ; i |
197 | S_sfx[i].lumpnum = S_sfx[i].usefulness = -1; |
197 | S_sfx[i].lumpnum = S_sfx[i].usefulness = -1; |
198 | } |
198 | } |
199 | 199 | ||
200 | // |
200 | // |
201 | // Per level startup code. |
201 | // Per level startup code. |
202 | // Kills playing sounds at start of level, |
202 | // Kills playing sounds at start of level, |
203 | // determines music if any, changes music. |
203 | // determines music if any, changes music. |
204 | // |
204 | // |
205 | void S_Start(void) |
205 | void S_Start(void) |
206 | { |
206 | { |
207 | int cnum; |
207 | int cnum; |
208 | int mnum; |
208 | int mnum; |
209 | 209 | ||
210 | // kill all playing sounds at start of level |
210 | // kill all playing sounds at start of level |
211 | // (trust me - a good idea) |
211 | // (trust me - a good idea) |
212 | for (cnum=0 ; cnum |
212 | for (cnum=0 ; cnum |
213 | if (channels[cnum].sfxinfo) |
213 | if (channels[cnum].sfxinfo) |
214 | S_StopChannel(cnum); |
214 | S_StopChannel(cnum); |
215 | 215 | ||
216 | // start new music for the level |
216 | // start new music for the level |
217 | mus_paused = 0; |
217 | mus_paused = 0; |
218 | 218 | ||
219 | if (gamemode == commercial) |
219 | if (gamemode == commercial) |
220 | mnum = mus_runnin + gamemap - 1; |
220 | mnum = mus_runnin + gamemap - 1; |
221 | else |
221 | else |
222 | { |
222 | { |
223 | int spmus[]= |
223 | int spmus[]= |
224 | { |
224 | { |
225 | // Song - Who? - Where? |
225 | // Song - Who? - Where? |
226 | mus_e3m4, // American e4m1 |
226 | mus_e3m4, // American e4m1 |
227 | mus_e3m2, // Romero e4m2 |
227 | mus_e3m2, // Romero e4m2 |
228 | mus_e3m3, // Shawn e4m3 |
228 | mus_e3m3, // Shawn e4m3 |
229 | mus_e1m5, // American e4m4 |
229 | mus_e1m5, // American e4m4 |
230 | mus_e2m7, // Tim e4m5 |
230 | mus_e2m7, // Tim e4m5 |
231 | mus_e2m4, // Romero e4m6 |
231 | mus_e2m4, // Romero e4m6 |
232 | mus_e2m6, // J.Anderson e4m7 CHIRON.WAD |
232 | mus_e2m6, // J.Anderson e4m7 CHIRON.WAD |
233 | mus_e2m5, // Shawn e4m8 |
233 | mus_e2m5, // Shawn e4m8 |
234 | mus_e1m9 // Tim e4m9 |
234 | mus_e1m9 // Tim e4m9 |
235 | }; |
235 | }; |
236 | 236 | ||
237 | if (gameepisode < 4) |
237 | if (gameepisode < 4) |
238 | mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1; |
238 | mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1; |
239 | else |
239 | else |
240 | mnum = spmus[gamemap-1]; |
240 | mnum = spmus[gamemap-1]; |
241 | } |
241 | } |
242 | 242 | ||
243 | // HACK FOR COMMERCIAL |
243 | // HACK FOR COMMERCIAL |
244 | // if (commercial && mnum > mus_e3m9) |
244 | // if (commercial && mnum > mus_e3m9) |
245 | // mnum -= mus_e3m9; |
245 | // mnum -= mus_e3m9; |
246 | 246 | ||
247 | S_ChangeMusic(mnum, true); |
247 | S_ChangeMusic(mnum, true); |
248 | 248 | ||
249 | nextcleanup = 15; |
249 | nextcleanup = 15; |
250 | } |
250 | } |
251 | 251 | ||
252 | void S_StartSoundAtVolume( void *origin_p, int sfx_id, int volume ) |
252 | void S_StartSoundAtVolume( void *origin_p, int sfx_id, int volume ) |
253 | { |
253 | { |
254 | int rc; |
254 | int rc; |
255 | int sep; |
255 | int sep; |
256 | int pitch; |
256 | int pitch; |
257 | int priority; |
257 | int priority; |
258 | sfxinfo_t *sfx; |
258 | sfxinfo_t *sfx; |
259 | int cnum; |
259 | int cnum; |
260 | // int chnum; <-- 10.9.98 compiler warning |
260 | // int chnum; <-- 10.9.98 compiler warning |
261 | 261 | ||
262 | mobj_t* origin = (mobj_t *)origin_p; |
262 | mobj_t* origin = (mobj_t *)origin_p; |
263 | 263 | ||
264 | //WriteDebug("S_StartSoundAtVolume...\n"); |
264 | //WriteDebug("S_StartSoundAtVolume...\n"); |
265 | 265 | ||
266 | // Debug. |
266 | // Debug. |
267 | /*fprintf( stderr,"S_StartSoundAtVolume: playing sound %d (%s)\n",sfx_id, S_sfx[sfx_id].name );*/ |
267 | /*fprintf( stderr,"S_StartSoundAtVolume: playing sound %d (%s)\n",sfx_id, S_sfx[sfx_id].name );*/ |
268 | 268 | ||
269 | // check for bogus sound # |
269 | // check for bogus sound # |
270 | if (sfx_id < 1 || sfx_id > NUMSFX) |
270 | if (sfx_id < 1 || sfx_id > NUMSFX) |
271 | I_Error("Bad sfx #: %d", sfx_id); |
271 | I_Error("Bad sfx #: %d", sfx_id); |
272 | 272 | ||
273 | sfx = &S_sfx[sfx_id]; |
273 | sfx = &S_sfx[sfx_id]; |
274 | 274 | ||
275 | // Initialize sound parameters |
275 | // Initialize sound parameters |
276 | if (sfx->link) |
276 | if (sfx->link) |
277 | { |
277 | { |
278 | pitch = sfx->pitch; |
278 | pitch = sfx->pitch; |
279 | priority = sfx->priority; |
279 | priority = sfx->priority; |
280 | volume += sfx->volume; |
280 | volume += sfx->volume; |
281 | 281 | ||
282 | if (volume < 1) |
282 | if (volume < 1) |
283 | { |
283 | { |
284 | //WriteDebug("Volume off...\n"); |
284 | //WriteDebug("Volume off...\n"); |
285 | return; |
285 | return; |
286 | } |
286 | } |
287 | 287 | ||
288 | if (volume > snd_SfxVolume) |
288 | if (volume > snd_SfxVolume) |
289 | volume = snd_SfxVolume; |
289 | volume = snd_SfxVolume; |
290 | } |
290 | } |
291 | else |
291 | else |
292 | { |
292 | { |
293 | pitch = NORM_PITCH; |
293 | pitch = NORM_PITCH; |
294 | priority = NORM_PRIORITY; |
294 | priority = NORM_PRIORITY; |
295 | } |
295 | } |
296 | 296 | ||
297 | 297 | ||
298 | // Check to see if it is audible, |
298 | // Check to see if it is audible, |
299 | // and if not, modify the params |
299 | // and if not, modify the params |
300 | if (origin && origin != players[consoleplayer].mo) |
300 | if (origin && origin != players[consoleplayer].mo) |
301 | { |
301 | { |
302 | rc = S_AdjustSoundParams(players[consoleplayer].mo, origin, &volume, &sep, &pitch); |
302 | rc = S_AdjustSoundParams(players[consoleplayer].mo, origin, &volume, &sep, &pitch); |
303 | if ( origin->x == players[consoleplayer].mo->x && origin->y == players[consoleplayer].mo->y) |
303 | if ( origin->x == players[consoleplayer].mo->x && origin->y == players[consoleplayer].mo->y) |
304 | { |
304 | { |
305 | sep = NORM_SEP; |
305 | sep = NORM_SEP; |
306 | } |
306 | } |
307 | if (!rc) |
307 | if (!rc) |
308 | { |
308 | { |
309 | //WriteDebug("No rc from S_AdjustSoundParams...\n"); |
309 | //WriteDebug("No rc from S_AdjustSoundParams...\n"); |
310 | return; |
310 | return; |
311 | } |
311 | } |
312 | } |
312 | } |
313 | else |
313 | else |
314 | { |
314 | { |
315 | sep = NORM_SEP; |
315 | sep = NORM_SEP; |
316 | } |
316 | } |
317 | 317 | ||
318 | // hacks to vary the sfx pitches |
318 | // hacks to vary the sfx pitches |
319 | if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) |
319 | if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) |
320 | { |
320 | { |
321 | pitch += 8 - (M_Random()&15); |
321 | pitch += 8 - (M_Random()&15); |
322 | if (pitch < 0) |
322 | if (pitch < 0) |
323 | pitch = 0; |
323 | pitch = 0; |
324 | else |
324 | else |
325 | if (pitch>255) |
325 | if (pitch>255) |
326 | pitch = 255; |
326 | pitch = 255; |
327 | } |
327 | } |
328 | else |
328 | else |
329 | if (sfx_id != sfx_itemup && sfx_id != sfx_tink) |
329 | if (sfx_id != sfx_itemup && sfx_id != sfx_tink) |
330 | { |
330 | { |
331 | pitch += 16 - (M_Random()&31); |
331 | pitch += 16 - (M_Random()&31); |
332 | if (pitch<0) |
332 | if (pitch<0) |
333 | pitch = 0; |
333 | pitch = 0; |
334 | else |
334 | else |
335 | if (pitch > 255) |
335 | if (pitch > 255) |
336 | pitch = 255; |
336 | pitch = 255; |
337 | } |
337 | } |
338 | 338 | ||
339 | // kill old sound |
339 | // kill old sound |
340 | S_StopSound(origin); |
340 | S_StopSound(origin); |
341 | 341 | ||
342 | // try to find a channel |
342 | // try to find a channel |
343 | cnum = S_getChannel(origin, sfx, sfx_id); |
343 | cnum = S_getChannel(origin, sfx, sfx_id); |
344 | 344 | ||
345 | if (cnum<0) |
345 | if (cnum<0) |
346 | { |
346 | { |
347 | //WriteDebug("cnum < 0 -- no channel...\n"); |
347 | //WriteDebug("cnum < 0 -- no channel...\n"); |
348 | return; |
348 | return; |
349 | } |
349 | } |
350 | 350 | ||
351 | // |
351 | // |
352 | // This is supposed to handle the loading/caching. |
352 | // This is supposed to handle the loading/caching. |
353 | // For some odd reason, the caching is done nearly |
353 | // For some odd reason, the caching is done nearly |
354 | // each time the sound is needed? |
354 | // each time the sound is needed? |
355 | // |
355 | // |
356 | 356 | ||
357 | // get lumpnum if necessary |
357 | // get lumpnum if necessary |
358 | if (sfx->lumpnum < 0) |
358 | if (sfx->lumpnum < 0) |
359 | sfx->lumpnum = I_GetSfxLumpNum(sfx); |
359 | sfx->lumpnum = I_GetSfxLumpNum(sfx); |
360 | 360 | ||
361 | // cache data if necessary |
361 | // cache data if necessary |
362 | if (!sfx->data) |
362 | if (!sfx->data) |
363 | { |
363 | { |
364 | sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC); |
364 | sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC); |
365 | 365 | ||
366 | } |
366 | } |
367 | 367 | ||
368 | // increase the usefulness |
368 | // increase the usefulness |
369 | if (sfx->usefulness++ < 0) |
369 | if (sfx->usefulness++ < 0) |
370 | sfx->usefulness = 1; |
370 | sfx->usefulness = 1; |
371 | 371 | ||
372 | // Assigns the handle to one of the channels in the |
372 | // Assigns the handle to one of the channels in the |
373 | // mix/output buffer. |
373 | // mix/output buffer. |
374 | //WriteDebug("I_StartSound...\n"); |
374 | //WriteDebug("I_StartSound...\n"); |
375 | channels[cnum].handle = I_StartSound(sfx_id,/*sfx->data,*/volume,sep,pitch,priority,origin); |
375 | channels[cnum].handle = I_StartSound(sfx_id,volume,sep,pitch,priority); |
376 | //cnum = I_StartSound(sfx_id,/*sfx->data,*/volume,sep,pitch,priority,origin); |
- | |
377 | channels[cnum].handle = cnum; |
376 | channels[cnum].handle = cnum; |
378 | channels[cnum].sfxinfo = sfx; |
377 | channels[cnum].sfxinfo = sfx; |
379 | channels[cnum].origin = origin; |
378 | channels[cnum].origin = origin; |
380 | } |
379 | } |
381 | 380 | ||
382 | void S_StartSound( void *origin, int sfx_id ) |
381 | void S_StartSound( void *origin, int sfx_id ) |
383 | { |
382 | { |
384 | #ifdef SAWDEBUG |
383 | #ifdef SAWDEBUG |
385 | // if (sfx_id == sfx_sawful) |
384 | // if (sfx_id == sfx_sawful) |
386 | // sfx_id = sfx_itemup; |
385 | // sfx_id = sfx_itemup; |
387 | #endif |
386 | #endif |
388 | 387 | ||
389 | S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume); |
388 | S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume); |
390 | 389 | ||
391 | 390 | ||
392 | // UNUSED. We had problems, had we not? |
391 | // UNUSED. We had problems, had we not? |
393 | #ifdef SAWDEBUG |
392 | #ifdef SAWDEBUG |
394 | { |
393 | { |
395 | int i; |
394 | int i; |
396 | int n; |
395 | int n; |
397 | 396 | ||
398 | static mobj_t* last_saw_origins[10] = {1,1,1,1,1,1,1,1,1,1}; |
397 | static mobj_t* last_saw_origins[10] = {1,1,1,1,1,1,1,1,1,1}; |
399 | static int first_saw=0; |
398 | static int first_saw=0; |
400 | static int next_saw=0; |
399 | static int next_saw=0; |
401 | 400 | ||
402 | if (sfx_id == sfx_sawidl |
401 | if (sfx_id == sfx_sawidl |
403 | || sfx_id == sfx_sawful |
402 | || sfx_id == sfx_sawful |
404 | || sfx_id == sfx_sawhit) |
403 | || sfx_id == sfx_sawhit) |
405 | { |
404 | { |
406 | for (i=first_saw;i!=next_saw;i=(i+1)%10) |
405 | for (i=first_saw;i!=next_saw;i=(i+1)%10) |
407 | if (last_saw_origins[i] != origin) |
406 | if (last_saw_origins[i] != origin) |
408 | fprintf(stderr, "old origin 0x%lx != " |
407 | fprintf(stderr, "old origin 0x%lx != " |
409 | "origin 0x%lx for sfx %d\n", |
408 | "origin 0x%lx for sfx %d\n", |
410 | last_saw_origins[i], |
409 | last_saw_origins[i], |
411 | origin, |
410 | origin, |
412 | sfx_id); |
411 | sfx_id); |
413 | 412 | ||
414 | last_saw_origins[next_saw] = origin; |
413 | last_saw_origins[next_saw] = origin; |
415 | next_saw = (next_saw + 1) % 10; |
414 | next_saw = (next_saw + 1) % 10; |
416 | if (next_saw == first_saw) |
415 | if (next_saw == first_saw) |
417 | first_saw = (first_saw + 1) % 10; |
416 | first_saw = (first_saw + 1) % 10; |
418 | 417 | ||
419 | for (n=i=0; i |
418 | for (n=i=0; i |
420 | { |
419 | { |
421 | if (channels[i].sfxinfo == &S_sfx[sfx_sawidl] |
420 | if (channels[i].sfxinfo == &S_sfx[sfx_sawidl] |
422 | || channels[i].sfxinfo == &S_sfx[sfx_sawful] |
421 | || channels[i].sfxinfo == &S_sfx[sfx_sawful] |
423 | || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) n++; |
422 | || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) n++; |
424 | } |
423 | } |
425 | 424 | ||
426 | if (n>1) |
425 | if (n>1) |
427 | { |
426 | { |
428 | for (i=0; i |
427 | for (i=0; i |
429 | { |
428 | { |
430 | if (channels[i].sfxinfo == &S_sfx[sfx_sawidl] |
429 | if (channels[i].sfxinfo == &S_sfx[sfx_sawidl] |
431 | || channels[i].sfxinfo == &S_sfx[sfx_sawful] |
430 | || channels[i].sfxinfo == &S_sfx[sfx_sawful] |
432 | || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) |
431 | || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) |
433 | { |
432 | { |
434 | fprintf(stderr, |
433 | fprintf(stderr, |
435 | "chn: sfxinfo=0x%lx, origin=0x%lx, " |
434 | "chn: sfxinfo=0x%lx, origin=0x%lx, " |
436 | "handle=%d\n", |
435 | "handle=%d\n", |
437 | channels[i].sfxinfo, |
436 | channels[i].sfxinfo, |
438 | channels[i].origin, |
437 | channels[i].origin, |
439 | channels[i].handle); |
438 | channels[i].handle); |
440 | } |
439 | } |
441 | } |
440 | } |
442 | fprintf(stderr, "\n"); |
441 | fprintf(stderr, "\n"); |
443 | } |
442 | } |
444 | } |
443 | } |
445 | } |
444 | } |
446 | #endif |
445 | #endif |
447 | 446 | ||
448 | } |
447 | } |
449 | 448 | ||
450 | 449 | ||
451 | 450 | ||
452 | 451 | ||
453 | void S_StopSound(void *origin) |
452 | void S_StopSound(void *origin) |
454 | { |
453 | { |
455 | 454 | ||
456 | int cnum; |
455 | int cnum; |
457 | 456 | ||
458 | for (cnum=0 ; cnum |
457 | for (cnum=0 ; cnum |
459 | { |
458 | { |
460 | if (channels[cnum].sfxinfo && channels[cnum].origin == origin) |
459 | if (channels[cnum].sfxinfo && channels[cnum].origin == origin) |
461 | { |
460 | { |
462 | S_StopChannel(cnum); |
461 | S_StopChannel(cnum); |
463 | break; |
462 | break; |
464 | } |
463 | } |
465 | } |
464 | } |
466 | } |
465 | } |
467 | 466 | ||
468 | 467 | ||
469 | 468 | ||
470 | 469 | ||
471 | 470 | ||
472 | 471 | ||
473 | 472 | ||
474 | 473 | ||
475 | 474 | ||
476 | // |
475 | // |
477 | // Stop and resume music, during game PAUSE. |
476 | // Stop and resume music, during game PAUSE. |
478 | // |
477 | // |
479 | void S_PauseSound(void) |
478 | void S_PauseSound(void) |
480 | { |
479 | { |
481 | if (mus_playing && !mus_paused) |
480 | if (mus_playing && !mus_paused) |
482 | { |
481 | { |
483 | I_PauseSong(mus_playing->handle); |
482 | I_PauseSong(mus_playing->handle); |
484 | mus_paused = true; |
483 | mus_paused = true; |
485 | } |
484 | } |
486 | } |
485 | } |
487 | 486 | ||
488 | void S_ResumeSound(void) |
487 | void S_ResumeSound(void) |
489 | { |
488 | { |
490 | if (mus_playing && mus_paused) |
489 | if (mus_playing && mus_paused) |
491 | { |
490 | { |
492 | I_ResumeSong(mus_playing->handle); |
491 | I_ResumeSong(mus_playing->handle); |
493 | mus_paused = false; |
492 | mus_paused = false; |
494 | } |
493 | } |
495 | } |
494 | } |
496 | 495 | ||
497 | 496 | ||
498 | // |
497 | // |
499 | // Updates music & sounds |
498 | // Updates music & sounds |
500 | // |
499 | // |
501 | void S_UpdateSounds(void* listener_p) |
500 | void S_UpdateSounds(void* listener_p) |
502 | { |
501 | { |
503 | int audible; |
502 | int audible; |
504 | int cnum; |
503 | int cnum; |
505 | int volume; |
504 | int volume; |
506 | int sep; |
505 | int sep; |
507 | int pitch; |
506 | int pitch; |
508 | sfxinfo_t* sfx; |
507 | sfxinfo_t* sfx; |
509 | channel_t* c; |
508 | channel_t* c; |
510 | 509 | ||
511 | mobj_t* listener = (mobj_t*)listener_p; |
510 | mobj_t* listener = (mobj_t*)listener_p; |
512 | 511 | ||
513 | 512 | ||
514 | 513 | ||
515 | // Clean up unused data. |
514 | // Clean up unused data. |
516 | // This is currently not done for 16bit (sounds cached static). |
515 | // This is currently not done for 16bit (sounds cached static). |
517 | // DOS 8bit remains. |
516 | // DOS 8bit remains. |
518 | /*if (gametic > nextcleanup) |
517 | /*if (gametic > nextcleanup) |
519 | { |
518 | { |
520 | for (i=1 ; i |
519 | for (i=1 ; i |
521 | { |
520 | { |
522 | if (S_sfx[i].usefulness < 1 |
521 | if (S_sfx[i].usefulness < 1 |
523 | && S_sfx[i].usefulness > -1) |
522 | && S_sfx[i].usefulness > -1) |
524 | { |
523 | { |
525 | if (--S_sfx[i].usefulness == -1) |
524 | if (--S_sfx[i].usefulness == -1) |
526 | { |
525 | { |
527 | Z_ChangeTag(S_sfx[i].data, PU_CACHE); |
526 | Z_ChangeTag(S_sfx[i].data, PU_CACHE); |
528 | S_sfx[i].data = 0; |
527 | S_sfx[i].data = 0; |
529 | } |
528 | } |
530 | } |
529 | } |
531 | } |
530 | } |
532 | nextcleanup = gametic + 15; |
531 | nextcleanup = gametic + 15; |
533 | }*/ |
532 | }*/ |
534 | 533 | ||
535 | for (cnum=0 ; cnum |
534 | for (cnum=0 ; cnum |
536 | { |
535 | { |
537 | c = &channels[cnum]; |
536 | c = &channels[cnum]; |
538 | sfx = c->sfxinfo; |
537 | sfx = c->sfxinfo; |
539 | 538 | ||
540 | if (c->sfxinfo) |
539 | if (c->sfxinfo) |
541 | { |
540 | { |
542 | if (I_SoundIsPlaying(c->handle)) |
541 | if (I_SoundIsPlaying(c->handle)) |
543 | { |
542 | { |
544 | // initialize parameters |
543 | // initialize parameters |
545 | volume = snd_SfxVolume; |
544 | volume = snd_SfxVolume; |
546 | pitch = NORM_PITCH; |
545 | pitch = NORM_PITCH; |
547 | sep = NORM_SEP; |
546 | sep = NORM_SEP; |
548 | 547 | ||
549 | if (sfx->link) |
548 | if (sfx->link) |
550 | { |
549 | { |
551 | pitch = sfx->pitch; |
550 | pitch = sfx->pitch; |
552 | volume += sfx->volume; |
551 | volume += sfx->volume; |
553 | if (volume < 1) |
552 | if (volume < 1) |
554 | { |
553 | { |
555 | S_StopChannel(cnum); |
554 | S_StopChannel(cnum); |
556 | continue; |
555 | continue; |
557 | } |
556 | } |
558 | else if (volume > snd_SfxVolume) |
557 | else if (volume > snd_SfxVolume) |
559 | { |
558 | { |
560 | volume = snd_SfxVolume; |
559 | volume = snd_SfxVolume; |
561 | } |
560 | } |
562 | } |
561 | } |
563 | 562 | ||
564 | // check non-local sounds for distance clipping |
563 | // check non-local sounds for distance clipping |
565 | // or modify their params |
564 | // or modify their params |
566 | if (c->origin && listener_p != c->origin) |
565 | if (c->origin && listener_p != c->origin) |
567 | { |
566 | { |
568 | audible = S_AdjustSoundParams(listener, |
567 | audible = S_AdjustSoundParams(listener, |
569 | c->origin, |
568 | c->origin, |
570 | &volume, |
569 | &volume, |
571 | &sep, |
570 | &sep, |
572 | &pitch); |
571 | &pitch); |
573 | 572 | ||
574 | if (!audible) |
573 | if (!audible) |
575 | { |
574 | { |
576 | S_StopChannel(cnum); |
575 | S_StopChannel(cnum); |
577 | } |
576 | } |
578 | else |
577 | else |
579 | I_UpdateSoundParams(c->handle, volume, sep, pitch); |
578 | I_UpdateSoundParams(c->handle, volume, sep, pitch); |
580 | } |
579 | } |
581 | } |
580 | } |
582 | else |
581 | else |
583 | { |
582 | { |
584 | // if channel is allocated but sound has stopped, |
583 | // if channel is allocated but sound has stopped, |
585 | // free it |
584 | // free it |
586 | S_StopChannel(cnum); |
585 | S_StopChannel(cnum); |
587 | } |
586 | } |
588 | } |
587 | } |
589 | } |
588 | } |
590 | // kill music if it is a single-play && finished |
589 | // kill music if it is a single-play && finished |
591 | // if ( mus_playing |
590 | // if ( mus_playing |
592 | // && !I_QrySongPlaying(mus_playing->handle) |
591 | // && !I_QrySongPlaying(mus_playing->handle) |
593 | // && !mus_paused ) |
592 | // && !mus_paused ) |
594 | // S_StopMusic(); |
593 | // S_StopMusic(); |
595 | } |
594 | } |
596 | 595 | ||
597 | 596 | ||
598 | void S_SetMusicVolume(int volume) |
597 | void S_SetMusicVolume(int volume) |
599 | { |
598 | { |
600 | if (volume < 0 || volume > 127) |
599 | if (volume < 0 || volume > 127) |
601 | { |
600 | { |
602 | I_Error("Attempt to set music volume at %d", |
601 | I_Error("Attempt to set music volume at %d", |
603 | volume); |
602 | volume); |
604 | } |
603 | } |
605 | 604 | ||
606 | I_SetMusicVolume(127); |
605 | I_SetMusicVolume(127); |
607 | I_SetMusicVolume(volume); |
606 | I_SetMusicVolume(volume); |
608 | snd_MusicVolume = volume; |
607 | snd_MusicVolume = volume; |
609 | } |
608 | } |
610 | 609 | ||
611 | 610 | ||
612 | 611 | ||
613 | void S_SetSfxVolume(int volume) |
612 | void S_SetSfxVolume(int volume) |
614 | { |
613 | { |
615 | 614 | ||
616 | if (volume < 0 || volume > 127) |
615 | if (volume < 0 || volume > 127) |
617 | I_Error("Attempt to set sfx volume at %d", volume); |
616 | I_Error("Attempt to set sfx volume at %d", volume); |
618 | 617 | ||
619 | snd_SfxVolume = volume; |
618 | snd_SfxVolume = volume; |
620 | 619 | ||
621 | } |
620 | } |
622 | 621 | ||
623 | // |
622 | // |
624 | // Starts some music with the music id found in sounds.h. |
623 | // Starts some music with the music id found in sounds.h. |
625 | // |
624 | // |
626 | void S_StartMusic(int m_id) |
625 | void S_StartMusic(int m_id) |
627 | { |
626 | { |
628 | // S_ChangeMusic(m_id, false); |
627 | // S_ChangeMusic(m_id, false); |
629 | } |
628 | } |
630 | 629 | ||
631 | 630 | ||
632 | // clean-up&code for orig midi 10.9.98-dlw |
631 | // clean-up&code for orig midi 10.9.98-dlw |
633 | void S_ChangeMusic(int musicnum, int looping) |
632 | void S_ChangeMusic(int musicnum, int looping) |
634 | { |
633 | { |
635 | 634 | ||
636 | // I_PlaySong(music->handle, looping); |
635 | // I_PlaySong(music->handle, looping); |
637 | // mus_playing = music; |
636 | // mus_playing = music; |
638 | } |
637 | } |
639 | 638 | ||
640 | 639 | ||
641 | void S_StopMusic(void) |
640 | void S_StopMusic(void) |
642 | { |
641 | { |
643 | if (mus_playing) |
642 | if (mus_playing) |
644 | { |
643 | { |
645 | if (mus_paused) I_ResumeSong(mus_playing->handle); |
644 | if (mus_paused) I_ResumeSong(mus_playing->handle); |
646 | I_StopSong(mus_playing->handle); |
645 | I_StopSong(mus_playing->handle); |
647 | I_UnRegisterSong(mus_playing->handle); |
646 | I_UnRegisterSong(mus_playing->handle); |
648 | Z_ChangeTag(mus_playing->data, PU_CACHE); |
647 | Z_ChangeTag(mus_playing->data, PU_CACHE); |
649 | mus_playing->data = 0; |
648 | mus_playing->data = 0; |
650 | mus_playing = 0; |
649 | mus_playing = 0; |
651 | } |
650 | } |
652 | } |
651 | } |
653 | 652 | ||
654 | void S_StopChannel(int cnum) |
653 | void S_StopChannel(int cnum) |
655 | { |
654 | { |
656 | 655 | ||
657 | int i; |
656 | int i; |
658 | channel_t* c = &channels[cnum]; |
657 | channel_t* c = &channels[cnum]; |
659 | 658 | ||
660 | if (c->sfxinfo) |
659 | if (c->sfxinfo) |
661 | { |
660 | { |
662 | // stop the sound playing |
661 | // stop the sound playing |
663 | if (I_SoundIsPlaying(c->handle)) |
662 | if (I_SoundIsPlaying(c->handle)) |
664 | { |
663 | { |
665 | #ifdef SAWDEBUG |
664 | #ifdef SAWDEBUG |
666 | if (c->sfxinfo == &S_sfx[sfx_sawful]) |
665 | if (c->sfxinfo == &S_sfx[sfx_sawful]) |
667 | fprintf(stderr, "stopped\n"); |
666 | fprintf(stderr, "stopped\n"); |
668 | #endif |
667 | #endif |
669 | I_StopSound(c->handle); |
668 | I_StopSound(c->handle); |
670 | } |
669 | } |
671 | 670 | ||
672 | // check to see |
671 | // check to see |
673 | // if other channels are playing the sound |
672 | // if other channels are playing the sound |
674 | for (i=0 ; i |
673 | for (i=0 ; i |
675 | { |
674 | { |
676 | if (cnum != i |
675 | if (cnum != i |
677 | && c->sfxinfo == channels[i].sfxinfo) |
676 | && c->sfxinfo == channels[i].sfxinfo) |
678 | { |
677 | { |
679 | break; |
678 | break; |
680 | } |
679 | } |
681 | } |
680 | } |
682 | 681 | ||
683 | // degrade usefulness of sound data |
682 | // degrade usefulness of sound data |
684 | c->sfxinfo->usefulness--; |
683 | c->sfxinfo->usefulness--; |
685 | 684 | ||
686 | c->sfxinfo = 0; |
685 | c->sfxinfo = 0; |
687 | } |
686 | } |
688 | } |
687 | } |
689 | 688 | ||
690 | 689 | ||
691 | // |
690 | // |
692 | // Changes volume, stereo-separation, and pitch variables |
691 | // Changes volume, stereo-separation, and pitch variables |
693 | // from the norm of a sound effect to be played. |
692 | // from the norm of a sound effect to be played. |
694 | // If the sound is not audible, returns a 0. |
693 | // If the sound is not audible, returns a 0. |
695 | // Otherwise, modifies parameters and returns 1. |
694 | // Otherwise, modifies parameters and returns 1. |
696 | // |
695 | // |
697 | int |
696 | int |
698 | S_AdjustSoundParams (mobj_t* listener, mobj_t* source, |
697 | S_AdjustSoundParams (mobj_t* listener, mobj_t* source, |
699 | int* vol, int* sep, int* pitch) |
698 | int* vol, int* sep, int* pitch) |
700 | { |
699 | { |
701 | fixed_t approx_dist; |
700 | fixed_t approx_dist; |
702 | fixed_t adx; |
701 | fixed_t adx; |
703 | fixed_t ady; |
702 | fixed_t ady; |
704 | angle_t angle; |
703 | angle_t angle; |
705 | 704 | ||
706 | // calculate the distance to sound origin |
705 | // calculate the distance to sound origin |
707 | // and clip it if necessary |
706 | // and clip it if necessary |
708 | adx = abs(listener->x - source->x); |
707 | adx = abs(listener->x - source->x); |
709 | ady = abs(listener->y - source->y); |
708 | ady = abs(listener->y - source->y); |
710 | 709 | ||
711 | // From _GG1_ p.428. Appox. eucledian distance fast. |
710 | // From _GG1_ p.428. Appox. eucledian distance fast. |
712 | approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1); |
711 | approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1); |
713 | 712 | ||
714 | if (gamemap != 8 |
713 | if (gamemap != 8 |
715 | && approx_dist > S_CLIPPING_DIST) |
714 | && approx_dist > S_CLIPPING_DIST) |
716 | { |
715 | { |
717 | return 0; |
716 | return 0; |
718 | } |
717 | } |
719 | 718 | ||
720 | // angle of source to listener |
719 | // angle of source to listener |
721 | angle = R_PointToAngle2(listener->x, |
720 | angle = R_PointToAngle2(listener->x, |
722 | listener->y, |
721 | listener->y, |
723 | source->x, |
722 | source->x, |
724 | source->y); |
723 | source->y); |
725 | 724 | ||
726 | if (angle > listener->angle) |
725 | if (angle > listener->angle) |
727 | angle = angle - listener->angle; |
726 | angle = angle - listener->angle; |
728 | else |
727 | else |
729 | angle = angle + (0xffffffff - listener->angle); |
728 | angle = angle + (0xffffffff - listener->angle); |
730 | 729 | ||
731 | angle >>= ANGLETOFINESHIFT; |
730 | angle >>= ANGLETOFINESHIFT; |
732 | 731 | ||
733 | // stereo separation |
732 | // stereo separation |
734 | *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS); |
733 | *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS); |
735 | 734 | ||
736 | // volume calculation |
735 | // volume calculation |
737 | if (approx_dist < S_CLOSE_DIST) |
736 | if (approx_dist < S_CLOSE_DIST) |
738 | { |
737 | { |
739 | *vol = snd_SfxVolume; |
738 | *vol = snd_SfxVolume; |
740 | } |
739 | } |
741 | else if (gamemap == 8) |
740 | else if (gamemap == 8) |
742 | { |
741 | { |
743 | if (approx_dist > S_CLIPPING_DIST) |
742 | if (approx_dist > S_CLIPPING_DIST) |
744 | approx_dist = S_CLIPPING_DIST; |
743 | approx_dist = S_CLIPPING_DIST; |
745 | 744 | ||
746 | *vol = 15+ ((snd_SfxVolume-15) |
745 | *vol = 15+ ((snd_SfxVolume-15) |
747 | *((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) |
746 | *((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) |
748 | / S_ATTENUATOR; |
747 | / S_ATTENUATOR; |
749 | } |
748 | } |
750 | else |
749 | else |
751 | { |
750 | { |
752 | // distance effect |
751 | // distance effect |
753 | *vol = (snd_SfxVolume |
752 | *vol = (snd_SfxVolume |
754 | * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) |
753 | * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) |
755 | / S_ATTENUATOR; |
754 | / S_ATTENUATOR; |
756 | } |
755 | } |
757 | 756 | ||
758 | return (*vol > 0); |
757 | return (*vol > 0); |
759 | } |
758 | } |
760 | 759 | ||
761 | // |
760 | // |
762 | // S_getChannel : |
761 | // S_getChannel : |
763 | // If none available, return -1. Otherwise channel #. |
762 | // If none available, return -1. Otherwise channel #. |
764 | // |
763 | // |
765 | int S_getChannel( void *origin, sfxinfo_t *sfxinfo, int sfxid ) |
764 | int S_getChannel( void *origin, sfxinfo_t *sfxinfo, int sfxid ) |
766 | { |
765 | { |
767 | // channel number to use |
766 | // channel number to use |
768 | int cnum; |
767 | int cnum; |
769 | 768 | ||
770 | channel_t* c; |
769 | channel_t* c; |
771 | 770 | ||
772 | // Find an open channel |
771 | // Find an open channel |
773 | //for (cnum = 0; cnum < numChannels; cnum++) |
772 | //for (cnum = 0; cnum < numChannels; cnum++) |
774 | for (cnum = 0; cnum < NUM_CHANNELS; cnum++) |
773 | for (cnum = 0; cnum < NUM_CHANNELS; cnum++) |
775 | { |
774 | { |
776 | if (!channels[cnum].sfxinfo) |
775 | if (!channels[cnum].sfxinfo) |
777 | break; |
776 | break; |
778 | else |
777 | else |
779 | if (origin && channels[cnum].origin == origin) |
778 | if (origin && channels[cnum].origin == origin) |
780 | { |
779 | { |
781 | S_StopChannel(cnum); |
780 | S_StopChannel(cnum); |
782 | break; |
781 | break; |
783 | } |
782 | } |
784 | } |
783 | } |
785 | 784 | ||
786 | // None available |
785 | // None available |
787 | if (cnum == NUM_CHANNELS) |
786 | if (cnum == NUM_CHANNELS) |
788 | { |
787 | { |
789 | // Look for lower priority |
788 | // Look for lower priority |
790 | for (cnum = NUMSFX; cnum < NUM_CHANNELS; cnum++) |
789 | for (cnum = NUMSFX; cnum < NUM_CHANNELS; cnum++) |
791 | if (channels[cnum].sfxinfo->priority >= sfxinfo->priority) |
790 | if (channels[cnum].sfxinfo->priority >= sfxinfo->priority) |
792 | break; |
791 | break; |
793 | 792 | ||
794 | if (cnum == numChannels) |
793 | if (cnum == numChannels) |
795 | { |
794 | { |
796 | // FUCK! No lower priority. Sorry, Charlie. |
795 | // FUCK! No lower priority. Sorry, Charlie. |
797 | return -1; |
796 | return -1; |
798 | } |
797 | } |
799 | else |
798 | else |
800 | { |
799 | { |
801 | // Otherwise, kick out lower priority. |
800 | // Otherwise, kick out lower priority. |
802 | S_StopChannel(cnum); |
801 | S_StopChannel(cnum); |
803 | } |
802 | } |
804 | } |
803 | } |
805 | 804 | ||
806 | c = &channels[cnum]; |
805 | c = &channels[cnum]; |
807 | 806 | ||
808 | // channel is decided to be cnum. |
807 | // channel is decided to be cnum. |
809 | c->sfxinfo = sfxinfo; |
808 | c->sfxinfo = sfxinfo; |
810 | c->origin = origin; |
809 | c->origin = origin; |
811 | 810 | ||
812 | return cnum; |
811 | return cnum; |
813 | }>>>>>>>>>>>>0) |
812 | }>>>>>>>>>>>>0) |
814 | >0) |
813 | >0) |
815 | >>=>>>-->> |
814 | >>=>>>-->> |