s_sound.c.svn-base 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION: Platform-independent sound code
  30. *
  31. *-----------------------------------------------------------------------------*/
  32. // killough 3/7/98: modified to allow arbitrary listeners in spy mode
  33. // killough 5/2/98: reindented, removed useless code, beautified
  34. #ifdef HAVE_CONFIG_H
  35. #include "config.h"
  36. #endif
  37. #include "doomstat.h"
  38. #include "s_sound.h"
  39. #include "i_sound.h"
  40. #include "i_system.h"
  41. #include "d_main.h"
  42. #include "r_main.h"
  43. #include "m_random.h"
  44. #include "w_wad.h"
  45. #include "lprintf.h"
  46. // when to clip out sounds
  47. // Does not fit the large outdoor areas.
  48. #define S_CLIPPING_DIST (1200<<FRACBITS)
  49. // Distance tp origin when sounds should be maxed out.
  50. // This should relate to movement clipping resolution
  51. // (see BLOCKMAP handling).
  52. // Originally: (200*0x10000).
  53. #define S_CLOSE_DIST (160<<FRACBITS)
  54. #define S_ATTENUATOR ((S_CLIPPING_DIST-S_CLOSE_DIST)>>FRACBITS)
  55. // Adjustable by menu.
  56. #define NORM_PITCH 128
  57. #define NORM_PRIORITY 64
  58. #define NORM_SEP 128
  59. #define S_STEREO_SWING (96<<FRACBITS)
  60. const char* S_music_files[NUMMUSIC]; // cournia - stores music file names
  61. typedef struct
  62. {
  63. sfxinfo_t *sfxinfo; // sound information (if null, channel avail.)
  64. void *origin; // origin of sound
  65. int handle; // handle of the sound being played
  66. int is_pickup; // killough 4/25/98: whether sound is a player's weapon
  67. int volume; // JDC: perform overrides based on dynamic volume instead of static priority
  68. } channel_t;
  69. // the set of channels available
  70. static channel_t *channels;
  71. // These are not used, but should be (menu).
  72. // Maximum volume of a sound effect.
  73. // Internal default is max out of 0-15.
  74. int snd_SfxVolume = 15;
  75. // Maximum volume of music. Useless so far.
  76. int snd_MusicVolume = 15;
  77. // whether songs are mus_paused
  78. static boolean mus_paused;
  79. // music currently being played
  80. static musicinfo_t *mus_playing;
  81. // following is set
  82. // by the defaults code in M_misc:
  83. // number of channels available
  84. int default_numChannels;
  85. int numChannels;
  86. //jff 3/17/98 to keep track of last IDMUS specified music num
  87. int idmusnum;
  88. //
  89. // Internals.
  90. //
  91. void S_StopChannel(int cnum);
  92. int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
  93. int *vol, int *sep, int *pitch);
  94. static int S_getChannel(void *origin, sfxinfo_t *sfxinfo, int is_pickup);
  95. // Initializes sound stuff, including volume
  96. // Sets channels, SFX and music volume,
  97. // allocates channel buffer, sets S_sfx lookup.
  98. //
  99. void S_Init(int sfxVolume, int musicVolume)
  100. {
  101. //jff 1/22/98 skip sound init if sound not enabled
  102. numChannels = default_numChannels;
  103. if (snd_card && !nosfxparm)
  104. {
  105. int i;
  106. lprintf(LO_CONFIRM, "S_Init: default sfx volume %d\n", sfxVolume);
  107. // Whatever these did with DMX, these are rather dummies now.
  108. I_SetChannels();
  109. S_SetSfxVolume(sfxVolume);
  110. // Allocating the internal channels for mixing
  111. // (the maximum numer of sounds rendered
  112. // simultaneously) within zone memory.
  113. // CPhipps - calloc
  114. channels =
  115. (channel_t *) calloc(numChannels,sizeof(channel_t));
  116. // Note that sounds have not been cached (yet).
  117. for (i=1 ; i<NUMSFX ; i++)
  118. S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
  119. }
  120. // CPhipps - music init reformatted
  121. if (mus_card && !nomusicparm) {
  122. S_SetMusicVolume(musicVolume);
  123. // no sounds are playing, and they are not mus_paused
  124. mus_paused = 0;
  125. }
  126. }
  127. void S_Stop(void)
  128. {
  129. int cnum;
  130. //jff 1/22/98 skip sound init if sound not enabled
  131. if (snd_card && !nosfxparm)
  132. for (cnum=0 ; cnum<numChannels ; cnum++)
  133. if (channels[cnum].sfxinfo)
  134. S_StopChannel(cnum);
  135. }
  136. //
  137. // Per level startup code.
  138. // Kills playing sounds at start of level,
  139. // determines music if any, changes music.
  140. //
  141. void S_Start(void)
  142. {
  143. int mnum;
  144. // kill all playing sounds at start of level
  145. // (trust me - a good idea)
  146. S_Stop();
  147. //jff 1/22/98 return if music is not enabled
  148. if (!mus_card || nomusicparm)
  149. return;
  150. // start new music for the level
  151. mus_paused = 0;
  152. if (idmusnum!=-1)
  153. mnum = idmusnum; //jff 3/17/98 reload IDMUS music if not -1
  154. else
  155. if (gamemode == commercial)
  156. mnum = mus_runnin + gamemap - 1;
  157. else
  158. {
  159. static const int spmus[] = // Song - Who? - Where?
  160. {
  161. mus_e3m4, // American e4m1
  162. mus_e3m2, // Romero e4m2
  163. mus_e3m3, // Shawn e4m3
  164. mus_e1m5, // American e4m4
  165. mus_e2m7, // Tim e4m5
  166. mus_e2m4, // Romero e4m6
  167. mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
  168. mus_e2m5, // Shawn e4m8
  169. mus_e1m9 // Tim e4m9
  170. };
  171. if (gameepisode < 4)
  172. mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1;
  173. else
  174. mnum = spmus[gamemap-1];
  175. }
  176. S_ChangeMusic(mnum, true);
  177. }
  178. void S_StartSoundAtVolume(void *origin_p, int sfx_id, int volume)
  179. {
  180. int sep, pitch, priority, cnum, is_pickup;
  181. sfxinfo_t *sfx;
  182. mobj_t *origin = (mobj_t *) origin_p;
  183. //jff 1/22/98 return if sound is not enabled
  184. if (!snd_card || nosfxparm)
  185. return;
  186. is_pickup = sfx_id & PICKUP_SOUND || sfx_id == sfx_oof || (compatibility_level >= prboom_2_compatibility && sfx_id == sfx_noway); // killough 4/25/98
  187. sfx_id &= ~PICKUP_SOUND;
  188. // check for bogus sound #
  189. if (sfx_id < 1 || sfx_id > NUMSFX)
  190. I_Error("S_StartSoundAtVolume: Bad sfx #: %d", sfx_id);
  191. sfx = &S_sfx[sfx_id];
  192. // Initialize sound parameters
  193. if (sfx->link)
  194. {
  195. pitch = sfx->pitch;
  196. priority = sfx->priority;
  197. volume += sfx->volume;
  198. if (volume < 1)
  199. return;
  200. if (volume > snd_SfxVolume)
  201. volume = snd_SfxVolume;
  202. }
  203. else
  204. {
  205. pitch = NORM_PITCH;
  206. priority = NORM_PRIORITY;
  207. }
  208. // Check to see if it is audible, modify the params
  209. // killough 3/7/98, 4/25/98: code rearranged slightly
  210. if (!origin || origin == players[displayplayer].mo) {
  211. sep = NORM_SEP;
  212. volume *= 8;
  213. } else
  214. if (!S_AdjustSoundParams(players[displayplayer].mo, origin, &volume,
  215. &sep, &pitch)) {
  216. return;
  217. }
  218. else
  219. if ( origin->x == players[displayplayer].mo->x &&
  220. origin->y == players[displayplayer].mo->y)
  221. sep = NORM_SEP;
  222. // hacks to vary the sfx pitches
  223. if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
  224. pitch += 8 - (M_Random()&15);
  225. else
  226. if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
  227. pitch += 16 - (M_Random()&31);
  228. if (pitch<0)
  229. pitch = 0;
  230. if (pitch>255)
  231. pitch = 255;
  232. #if 0 //!@#
  233. // kill old sound
  234. for (cnum=0 ; cnum<numChannels ; cnum++)
  235. if (channels[cnum].sfxinfo && channels[cnum].origin == origin &&
  236. (comp[comp_sound] || channels[cnum].is_pickup == is_pickup))
  237. {
  238. S_StopChannel(cnum);
  239. break;
  240. }
  241. // try to find a channel
  242. cnum = S_getChannel(origin, sfx, is_pickup);
  243. #else
  244. // JDC: new sound channel logic
  245. // Find look for a channel that we should override
  246. // "pickup" acts like a one bit channel-on-emitter field,
  247. // so pickup sounds woon't override action sounds and vise-versa.
  248. // In later games we have explicit CHAN_VOICE, CHAN_FOOTSTEP, CHAN_WEAPON, etc
  249. cnum = numChannels;
  250. for (cnum=0; cnum<numChannels ; cnum++) {
  251. if ( channels[cnum].origin == origin &&
  252. channels[cnum].is_pickup == is_pickup) {
  253. break;
  254. }
  255. }
  256. if ( cnum == numChannels ) {
  257. // second, look for a completely free channel
  258. for (cnum=0; cnum<numChannels ; cnum++) {
  259. if ( !channels[cnum].sfxinfo ) {
  260. break;
  261. }
  262. }
  263. }
  264. if ( cnum == numChannels ) {
  265. // third, look for a lower volume sound to override
  266. // It is better to do this based on volume than on static
  267. // prioritites.
  268. int lowestVolume = volume+1; // override an older sound of same volume
  269. int test;
  270. for (test=0; test<numChannels ; test++) {
  271. if ( channels[test].volume < lowestVolume ) {
  272. lowestVolume = channels[test].volume;
  273. cnum = test;
  274. }
  275. }
  276. }
  277. if ( cnum == numChannels ) {
  278. // nothing available
  279. printf( "dropping sound for no channels available\n" );
  280. return;
  281. }
  282. // we are using this channel now
  283. channels[cnum].sfxinfo = sfx;
  284. channels[cnum].origin = origin;
  285. channels[cnum].volume = volume;
  286. channels[cnum].is_pickup = is_pickup;
  287. #endif
  288. if (cnum<0)
  289. return;
  290. // get lumpnum if necessary
  291. // killough 2/28/98: make missing sounds non-fatal
  292. if (sfx->lumpnum < 0 && (sfx->lumpnum = I_GetSfxLumpNum(sfx)) < 0)
  293. return;
  294. // increase the usefulness
  295. if (sfx->usefulness++ < 0)
  296. sfx->usefulness = 1;
  297. // Assigns the handle to one of the channels in the mix/output buffer.
  298. { // e6y: [Fix] Crash with zero-length sounds.
  299. int h = I_StartSound(sfx_id, cnum, volume, sep, pitch, priority);
  300. if (h != -1) channels[cnum].handle = h;
  301. }
  302. }
  303. void S_StartSound(void *origin, int sfx_id)
  304. {
  305. S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume);
  306. }
  307. void S_StopSound(void *origin)
  308. {
  309. int cnum;
  310. //jff 1/22/98 return if sound is not enabled
  311. if (!snd_card || nosfxparm)
  312. return;
  313. for (cnum=0 ; cnum<numChannels ; cnum++)
  314. if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
  315. {
  316. S_StopChannel(cnum);
  317. break;
  318. }
  319. }
  320. //
  321. // Stop and resume music, during game PAUSE.
  322. //
  323. void S_PauseSound(void)
  324. {
  325. //jff 1/22/98 return if music is not enabled
  326. if (!mus_card || nomusicparm)
  327. return;
  328. if (mus_playing && !mus_paused)
  329. {
  330. I_PauseSong(mus_playing->handle);
  331. mus_paused = true;
  332. }
  333. }
  334. void S_ResumeSound(void)
  335. {
  336. //jff 1/22/98 return if music is not enabled
  337. if (!mus_card || nomusicparm)
  338. return;
  339. if (mus_playing && mus_paused)
  340. {
  341. I_ResumeSong(mus_playing->handle);
  342. mus_paused = false;
  343. }
  344. }
  345. //
  346. // Updates music & sounds
  347. //
  348. void S_UpdateSounds(void* listener_p)
  349. {
  350. mobj_t *listener = (mobj_t*) listener_p;
  351. int cnum;
  352. //jff 1/22/98 return if sound is not enabled
  353. if (!snd_card || nosfxparm)
  354. return;
  355. #ifdef UPDATE_MUSIC
  356. I_UpdateMusic();
  357. #endif
  358. for (cnum=0 ; cnum<numChannels ; cnum++)
  359. {
  360. sfxinfo_t *sfx;
  361. channel_t *c = &channels[cnum];
  362. if ((sfx = c->sfxinfo))
  363. {
  364. if (I_SoundIsPlaying(c->handle))
  365. {
  366. // initialize parameters
  367. int volume = snd_SfxVolume;
  368. int pitch = NORM_PITCH;
  369. int sep = NORM_SEP;
  370. if (sfx->link)
  371. {
  372. pitch = sfx->pitch;
  373. volume += sfx->volume;
  374. if (volume < 1)
  375. {
  376. S_StopChannel(cnum);
  377. continue;
  378. }
  379. else
  380. if (volume > snd_SfxVolume)
  381. volume = snd_SfxVolume;
  382. }
  383. // check non-local sounds for distance clipping
  384. // or modify their params
  385. if (c->origin && listener_p != c->origin) { // killough 3/20/98
  386. if (!S_AdjustSoundParams(listener, c->origin,
  387. &volume, &sep, &pitch))
  388. S_StopChannel(cnum);
  389. else
  390. I_UpdateSoundParams(c->handle, volume, sep, pitch);
  391. }
  392. }
  393. else // if channel is allocated but sound has stopped, free it
  394. S_StopChannel(cnum);
  395. }
  396. }
  397. }
  398. void S_SetMusicVolume(int volume)
  399. {
  400. //jff 1/22/98 return if music is not enabled
  401. if (!mus_card || nomusicparm)
  402. return;
  403. if (volume < 0 || volume > 15)
  404. I_Error("S_SetMusicVolume: Attempt to set music volume at %d", volume);
  405. I_SetMusicVolume(volume);
  406. snd_MusicVolume = volume;
  407. }
  408. void S_SetSfxVolume(int volume)
  409. {
  410. //jff 1/22/98 return if sound is not enabled
  411. if (!snd_card || nosfxparm)
  412. return;
  413. if (volume < 0 || volume > 127)
  414. I_Error("S_SetSfxVolume: Attempt to set sfx volume at %d", volume);
  415. snd_SfxVolume = volume;
  416. }
  417. // Starts some music with the music id found in sounds.h.
  418. //
  419. void S_StartMusic(int m_id)
  420. {
  421. //jff 1/22/98 return if music is not enabled
  422. if (!mus_card || nomusicparm)
  423. return;
  424. S_ChangeMusic(m_id, false);
  425. }
  426. void S_ChangeMusic(int musicnum, int looping)
  427. {
  428. musicinfo_t *music;
  429. int music_file_failed; // cournia - if true load the default MIDI music
  430. char* music_filename; // cournia
  431. //jff 1/22/98 return if music is not enabled
  432. if (!mus_card || nomusicparm)
  433. return;
  434. if (musicnum <= mus_None || musicnum >= NUMMUSIC)
  435. I_Error("S_ChangeMusic: Bad music number %d", musicnum);
  436. music = &S_music[musicnum];
  437. if (mus_playing == music)
  438. return;
  439. #ifdef IPHONE
  440. extern void iphonePlayMusic( const char *name );
  441. iphonePlayMusic( music->name );
  442. #else
  443. // shutdown old music
  444. S_StopMusic();
  445. // get lumpnum if neccessary
  446. if (!music->lumpnum)
  447. {
  448. char namebuf[9];
  449. sprintf(namebuf, "d_%s", music->name);
  450. music->lumpnum = W_GetNumForName(namebuf);
  451. }
  452. music_file_failed = 1;
  453. // proff_fs - only load when from IWAD
  454. if (lumpinfo[music->lumpnum].source == source_iwad)
  455. {
  456. // cournia - check to see if we can play a higher quality music file
  457. // rather than the default MIDI
  458. music_filename = I_FindFile(S_music_files[musicnum], "");
  459. if (music_filename)
  460. {
  461. music_file_failed = I_RegisterMusic(music_filename, music);
  462. free(music_filename);
  463. }
  464. }
  465. if (music_file_failed)
  466. {
  467. //cournia - could not load music file, play default MIDI music
  468. // load & register it
  469. music->data = W_CacheLumpNum(music->lumpnum);
  470. music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum));
  471. }
  472. // play it
  473. I_PlaySong(music->handle, looping);
  474. #endif
  475. mus_playing = music;
  476. }
  477. void S_StopMusic(void)
  478. {
  479. //jff 1/22/98 return if music is not enabled
  480. if (!mus_card || nomusicparm)
  481. return;
  482. if (mus_playing)
  483. {
  484. if (mus_paused)
  485. I_ResumeSong(mus_playing->handle);
  486. I_StopSong(mus_playing->handle);
  487. I_UnRegisterSong(mus_playing->handle);
  488. if (mus_playing->lumpnum >= 0)
  489. W_UnlockLumpNum(mus_playing->lumpnum); // cph - release the music data
  490. mus_playing->data = 0;
  491. mus_playing = 0;
  492. }
  493. }
  494. void S_StopChannel(int cnum)
  495. {
  496. int i;
  497. channel_t *c = &channels[cnum];
  498. //jff 1/22/98 return if sound is not enabled
  499. if (!snd_card || nosfxparm)
  500. return;
  501. if (c->sfxinfo)
  502. {
  503. // stop the sound playing
  504. if (I_SoundIsPlaying(c->handle))
  505. I_StopSound(c->handle);
  506. // check to see
  507. // if other channels are playing the sound
  508. for (i=0 ; i<numChannels ; i++)
  509. if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
  510. break;
  511. // degrade usefulness of sound data
  512. c->sfxinfo->usefulness--;
  513. c->sfxinfo = 0;
  514. }
  515. }
  516. //
  517. // Changes volume, stereo-separation, and pitch variables
  518. // from the norm of a sound effect to be played.
  519. // If the sound is not audible, returns a 0.
  520. // Otherwise, modifies parameters and returns 1.
  521. //
  522. int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
  523. int *vol, int *sep, int *pitch)
  524. {
  525. fixed_t adx, ady,approx_dist;
  526. angle_t angle;
  527. //jff 1/22/98 return if sound is not enabled
  528. if (!snd_card || nosfxparm)
  529. return 0;
  530. // e6y
  531. // Fix crash when the program wants to S_AdjustSoundParams() for player
  532. // which is not displayplayer and displayplayer was not spawned at the moment.
  533. // It happens in multiplayer demos only.
  534. //
  535. // Stack trace is:
  536. // P_SetupLevel() \ P_LoadThings() \ P_SpawnMapThing() \ P_SpawnPlayer(players[0]) \
  537. // P_SetupPsprites() \ P_BringUpWeapon() \ S_StartSound(players[0]->mo, sfx_sawup) \
  538. // S_StartSoundAtVolume() \ S_AdjustSoundParams(players[displayplayer]->mo, ...);
  539. // players[displayplayer]->mo is NULL
  540. //
  541. // There is no more crash on e1cmnet3.lmp between e1m2 and e1m3
  542. // http://competn.doom2.net/pub/compet-n/doom/coop/movies/e1cmnet3.zip
  543. if (!listener)
  544. return 0;
  545. // calculate the distance to sound origin
  546. // and clip it if necessary
  547. adx = D_abs(listener->x - source->x);
  548. ady = D_abs(listener->y - source->y);
  549. // From _GG1_ p.428. Appox. eucledian distance fast.
  550. approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
  551. if (!approx_dist) // killough 11/98: handle zero-distance as special case
  552. {
  553. *sep = NORM_SEP;
  554. *vol = snd_SfxVolume * 8; // JDC: plasma fire sounds were 1/8 volume without this
  555. return *vol > 0;
  556. }
  557. if (approx_dist > S_CLIPPING_DIST)
  558. return 0;
  559. // angle of source to listener
  560. angle = R_PointToAngle2(listener->x, listener->y, source->x, source->y);
  561. if (angle <= listener->angle)
  562. angle += 0xffffffff;
  563. angle -= listener->angle;
  564. angle >>= ANGLETOFINESHIFT;
  565. // stereo separation
  566. *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS);
  567. // volume calculation
  568. if (approx_dist < S_CLOSE_DIST)
  569. *vol = snd_SfxVolume*8;
  570. else
  571. // distance effect
  572. *vol = (snd_SfxVolume * ((S_CLIPPING_DIST-approx_dist)>>FRACBITS) * 8)
  573. / S_ATTENUATOR;
  574. return (*vol > 0);
  575. }
  576. //
  577. // S_getChannel :
  578. // If none available, return -1. Otherwise channel #.
  579. //
  580. // killough 4/25/98: made static, added is_pickup argument
  581. static int S_getChannel(void *origin, sfxinfo_t *sfxinfo, int is_pickup)
  582. {
  583. // channel number to use
  584. int cnum;
  585. channel_t *c;
  586. //jff 1/22/98 return if sound is not enabled
  587. if (!snd_card || nosfxparm)
  588. return -1;
  589. // Find an open channel
  590. for (cnum=0; cnum<numChannels && channels[cnum].sfxinfo; cnum++)
  591. if (origin && channels[cnum].origin == origin &&
  592. channels[cnum].is_pickup == is_pickup)
  593. {
  594. S_StopChannel(cnum);
  595. break;
  596. }
  597. // None available
  598. if (cnum == numChannels)
  599. { // Look for lower priority
  600. for (cnum=0 ; cnum<numChannels ; cnum++)
  601. if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
  602. break;
  603. if (cnum == numChannels)
  604. return -1; // No lower priority. Sorry, Charlie.
  605. else
  606. S_StopChannel(cnum); // Otherwise, kick out lower priority.
  607. }
  608. c = &channels[cnum]; // channel is decided to be cnum.
  609. c->sfxinfo = sfxinfo;
  610. c->origin = origin;
  611. c->is_pickup = is_pickup; // killough 4/25/98
  612. return cnum;
  613. }