s_sound.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  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. // Initializes sound stuff, including volume
  95. // Sets channels, SFX and music volume,
  96. // allocates channel buffer, sets S_sfx lookup.
  97. //
  98. void S_Init(int sfxVolume, int musicVolume)
  99. {
  100. //jff 1/22/98 skip sound init if sound not enabled
  101. numChannels = default_numChannels;
  102. if (snd_card && !nosfxparm)
  103. {
  104. int i;
  105. lprintf(LO_CONFIRM, "S_Init: default sfx volume %d\n", sfxVolume);
  106. // Whatever these did with DMX, these are rather dummies now.
  107. I_SetChannels();
  108. S_SetSfxVolume(sfxVolume);
  109. // Allocating the internal channels for mixing
  110. // (the maximum numer of sounds rendered
  111. // simultaneously) within zone memory.
  112. // CPhipps - calloc
  113. channels =
  114. (channel_t *) calloc(numChannels,sizeof(channel_t));
  115. // Note that sounds have not been cached (yet).
  116. for (i=1 ; i<NUMSFX ; i++)
  117. S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
  118. }
  119. // CPhipps - music init reformatted
  120. if (mus_card && !nomusicparm) {
  121. S_SetMusicVolume(musicVolume);
  122. // no sounds are playing, and they are not mus_paused
  123. mus_paused = 0;
  124. }
  125. }
  126. void S_Stop(void)
  127. {
  128. int cnum;
  129. //jff 1/22/98 skip sound init if sound not enabled
  130. if (snd_card && !nosfxparm)
  131. for (cnum=0 ; cnum<numChannels ; cnum++)
  132. if (channels[cnum].sfxinfo)
  133. S_StopChannel(cnum);
  134. }
  135. //
  136. // Per level startup code.
  137. // Kills playing sounds at start of level,
  138. // determines music if any, changes music.
  139. //
  140. void S_Start(void)
  141. {
  142. int mnum;
  143. // kill all playing sounds at start of level
  144. // (trust me - a good idea)
  145. S_Stop();
  146. //jff 1/22/98 return if music is not enabled
  147. if (!mus_card || nomusicparm)
  148. return;
  149. // start new music for the level
  150. mus_paused = 0;
  151. if (idmusnum!=-1)
  152. mnum = idmusnum; //jff 3/17/98 reload IDMUS music if not -1
  153. else
  154. if (gamemode == commercial)
  155. mnum = mus_runnin + gamemap - 1;
  156. else
  157. {
  158. static const int spmus[] = // Song - Who? - Where?
  159. {
  160. mus_e3m4, // American e4m1
  161. mus_e3m2, // Romero e4m2
  162. mus_e3m3, // Shawn e4m3
  163. mus_e1m5, // American e4m4
  164. mus_e2m7, // Tim e4m5
  165. mus_e2m4, // Romero e4m6
  166. mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
  167. mus_e2m5, // Shawn e4m8
  168. mus_e1m9 // Tim e4m9
  169. };
  170. if (gameepisode < 4)
  171. mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1;
  172. else
  173. mnum = spmus[gamemap-1];
  174. }
  175. S_ChangeMusic(mnum, true);
  176. }
  177. void S_StartSoundAtVolume(void *origin_p, int sfx_id, int volume)
  178. {
  179. int sep, pitch, priority, cnum, is_pickup;
  180. sfxinfo_t *sfx;
  181. mobj_t *origin = (mobj_t *) origin_p;
  182. //jff 1/22/98 return if sound is not enabled
  183. if (!snd_card || nosfxparm)
  184. return;
  185. is_pickup = sfx_id & PICKUP_SOUND || sfx_id == sfx_oof || (compatibility_level >= prboom_2_compatibility && sfx_id == sfx_noway); // killough 4/25/98
  186. sfx_id &= ~PICKUP_SOUND;
  187. // check for bogus sound #
  188. if (sfx_id < 1 || sfx_id > NUMSFX)
  189. I_Error("S_StartSoundAtVolume: Bad sfx #: %d", sfx_id);
  190. sfx = &S_sfx[sfx_id];
  191. // Initialize sound parameters
  192. if (sfx->link)
  193. {
  194. pitch = sfx->pitch;
  195. priority = sfx->priority;
  196. volume += sfx->volume;
  197. if (volume < 1)
  198. return;
  199. if (volume > snd_SfxVolume)
  200. volume = snd_SfxVolume;
  201. }
  202. else
  203. {
  204. pitch = NORM_PITCH;
  205. priority = NORM_PRIORITY;
  206. }
  207. // Check to see if it is audible, modify the params
  208. // killough 3/7/98, 4/25/98: code rearranged slightly
  209. if (!origin || origin == players[displayplayer].mo) {
  210. sep = NORM_SEP;
  211. volume *= 8;
  212. } else
  213. if (!S_AdjustSoundParams(players[displayplayer].mo, origin, &volume,
  214. &sep, &pitch)) {
  215. return;
  216. }
  217. else
  218. if ( origin->x == players[displayplayer].mo->x &&
  219. origin->y == players[displayplayer].mo->y)
  220. sep = NORM_SEP;
  221. // hacks to vary the sfx pitches
  222. if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
  223. pitch += 8 - (M_Random()&15);
  224. else
  225. if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
  226. pitch += 16 - (M_Random()&31);
  227. if (pitch<0)
  228. pitch = 0;
  229. if (pitch>255)
  230. pitch = 255;
  231. #if 0
  232. // kill old sound
  233. for (cnum=0 ; cnum<numChannels ; cnum++)
  234. if (channels[cnum].sfxinfo && channels[cnum].origin == origin &&
  235. (comp[comp_sound] || channels[cnum].is_pickup == is_pickup))
  236. {
  237. S_StopChannel(cnum);
  238. break;
  239. }
  240. // try to find a channel
  241. cnum = S_getChannel(origin, sfx, is_pickup);
  242. #else
  243. // JDC: new sound channel logic
  244. // Find look for a channel that we should override
  245. // "pickup" acts like a one bit channel-on-emitter field,
  246. // so pickup sounds woon't override action sounds and vise-versa.
  247. // In later games we have explicit CHAN_VOICE, CHAN_FOOTSTEP, CHAN_WEAPON, etc
  248. cnum = numChannels;
  249. for (cnum=0; cnum<numChannels ; cnum++) {
  250. if ( channels[cnum].origin == origin &&
  251. channels[cnum].is_pickup == is_pickup) {
  252. break;
  253. }
  254. }
  255. if ( cnum == numChannels ) {
  256. // second, look for a completely free channel
  257. for (cnum=0; cnum<numChannels ; cnum++) {
  258. if ( !channels[cnum].sfxinfo ) {
  259. break;
  260. }
  261. }
  262. }
  263. if ( cnum == numChannels ) {
  264. // third, look for a lower volume sound to override
  265. // It is better to do this based on volume than on static
  266. // prioritites.
  267. int lowestVolume = volume+1; // override an older sound of same volume
  268. int test;
  269. for (test=0; test<numChannels ; test++) {
  270. if ( channels[test].volume < lowestVolume ) {
  271. lowestVolume = channels[test].volume;
  272. cnum = test;
  273. }
  274. }
  275. }
  276. if ( cnum == numChannels ) {
  277. // nothing available
  278. printf( "dropping sound for no channels available\n" );
  279. return;
  280. }
  281. // we are using this channel now
  282. channels[cnum].sfxinfo = sfx;
  283. channels[cnum].origin = origin;
  284. channels[cnum].volume = volume;
  285. channels[cnum].is_pickup = is_pickup;
  286. #endif
  287. if (cnum<0)
  288. return;
  289. // get lumpnum if necessary
  290. // killough 2/28/98: make missing sounds non-fatal
  291. if (sfx->lumpnum < 0 && (sfx->lumpnum = I_GetSfxLumpNum(sfx)) < 0)
  292. return;
  293. // increase the usefulness
  294. if (sfx->usefulness++ < 0)
  295. sfx->usefulness = 1;
  296. // Assigns the handle to one of the channels in the mix/output buffer.
  297. { // e6y: [Fix] Crash with zero-length sounds.
  298. int h = I_StartSound(sfx_id, cnum, volume, sep, pitch, priority);
  299. if (h != -1) channels[cnum].handle = h;
  300. }
  301. }
  302. void S_StartSound(void *origin, int sfx_id)
  303. {
  304. S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume);
  305. }
  306. void S_StopSound(void *origin)
  307. {
  308. int cnum;
  309. //jff 1/22/98 return if sound is not enabled
  310. if (!snd_card || nosfxparm)
  311. return;
  312. for (cnum=0 ; cnum<numChannels ; cnum++)
  313. if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
  314. {
  315. S_StopChannel(cnum);
  316. break;
  317. }
  318. }
  319. //
  320. // Stop and resume music, during game PAUSE.
  321. //
  322. void S_PauseSound(void)
  323. {
  324. //jff 1/22/98 return if music is not enabled
  325. if (!mus_card || nomusicparm)
  326. return;
  327. if (mus_playing && !mus_paused)
  328. {
  329. I_PauseSong(mus_playing->handle);
  330. mus_paused = true;
  331. }
  332. }
  333. void S_ResumeSound(void)
  334. {
  335. //jff 1/22/98 return if music is not enabled
  336. if (!mus_card || nomusicparm)
  337. return;
  338. if (mus_playing && mus_paused)
  339. {
  340. I_ResumeSong(mus_playing->handle);
  341. mus_paused = false;
  342. }
  343. }
  344. //
  345. // Updates music & sounds
  346. //
  347. void S_UpdateSounds(void* listener_p)
  348. {
  349. mobj_t *listener = (mobj_t*) listener_p;
  350. int cnum;
  351. //jff 1/22/98 return if sound is not enabled
  352. if (!snd_card || nosfxparm)
  353. return;
  354. #ifdef UPDATE_MUSIC
  355. I_UpdateMusic();
  356. #endif
  357. for (cnum=0 ; cnum<numChannels ; cnum++)
  358. {
  359. sfxinfo_t *sfx;
  360. channel_t *c = &channels[cnum];
  361. if ((sfx = c->sfxinfo))
  362. {
  363. if (I_SoundIsPlaying(c->handle))
  364. {
  365. // initialize parameters
  366. int volume = snd_SfxVolume;
  367. int pitch = NORM_PITCH;
  368. int sep = NORM_SEP;
  369. if (sfx->link)
  370. {
  371. pitch = sfx->pitch;
  372. volume += sfx->volume;
  373. if (volume < 1)
  374. {
  375. S_StopChannel(cnum);
  376. continue;
  377. }
  378. else
  379. if (volume > snd_SfxVolume)
  380. volume = snd_SfxVolume;
  381. }
  382. // check non-local sounds for distance clipping
  383. // or modify their params
  384. if (c->origin && listener_p != c->origin) { // killough 3/20/98
  385. if (!S_AdjustSoundParams(listener, c->origin,
  386. &volume, &sep, &pitch))
  387. S_StopChannel(cnum);
  388. else
  389. I_UpdateSoundParams(c->handle, volume, sep, pitch);
  390. }
  391. }
  392. else // if channel is allocated but sound has stopped, free it
  393. S_StopChannel(cnum);
  394. }
  395. }
  396. }
  397. void S_SetMusicVolume(int volume)
  398. {
  399. //jff 1/22/98 return if music is not enabled
  400. if (!mus_card || nomusicparm)
  401. return;
  402. if (volume < 0 || volume > 15)
  403. I_Error("S_SetMusicVolume: Attempt to set music volume at %d", volume);
  404. I_SetMusicVolume(volume);
  405. snd_MusicVolume = volume;
  406. }
  407. void S_SetSfxVolume(int volume)
  408. {
  409. //jff 1/22/98 return if sound is not enabled
  410. if (!snd_card || nosfxparm)
  411. return;
  412. if (volume < 0 || volume > 127)
  413. I_Error("S_SetSfxVolume: Attempt to set sfx volume at %d", volume);
  414. snd_SfxVolume = volume;
  415. }
  416. // Starts some music with the music id found in sounds.h.
  417. //
  418. void S_StartMusic(int m_id)
  419. {
  420. //jff 1/22/98 return if music is not enabled
  421. if (!mus_card || nomusicparm)
  422. return;
  423. S_ChangeMusic(m_id, false);
  424. }
  425. void S_ChangeMusic(int musicnum, int looping)
  426. {
  427. musicinfo_t *music;
  428. int music_file_failed; // cournia - if true load the default MIDI music
  429. char music_filename[ 1024 ]; // cournia
  430. (void)music_file_failed;
  431. (void)music_filename;
  432. //jff 1/22/98 return if music is not enabled
  433. if (!mus_card || nomusicparm)
  434. return;
  435. if (musicnum <= mus_None || musicnum >= NUMMUSIC)
  436. I_Error("S_ChangeMusic: Bad music number %d", musicnum);
  437. music = &S_music[musicnum];
  438. #ifndef IPHONE // music was paused in the menu, we want it to always restart even if starting the same level again
  439. if (mus_playing == music)
  440. return;
  441. #endif
  442. /*
  443. #ifdef IPHONE
  444. extern void iphonePlayMusic( const char *name );
  445. iphonePlayMusic( music->name );
  446. #else
  447. */
  448. // shutdown old music
  449. S_StopMusic();
  450. // get lumpnum if neccessary
  451. if (!music->lumpnum)
  452. {
  453. char namebuf[9];
  454. sprintf(namebuf, "d_%s", music->name);
  455. music->lumpnum = W_GetNumForName(namebuf);
  456. }
  457. music_file_failed = 1;
  458. // proff_fs - only load when from IWAD
  459. if (lumpinfo[music->lumpnum].source == source_iwad)
  460. {
  461. // cournia - check to see if we can play a higher quality music file
  462. // rather than the default MIDI
  463. I_FindFile(S_music_files[musicnum], "", music_filename);
  464. if ( music_filename[0] != '\0' )
  465. {
  466. music_file_failed = I_RegisterMusic(music_filename, music);
  467. free(music_filename);
  468. }
  469. }
  470. if (music_file_failed)
  471. {
  472. //cournia - could not load music file, play default MIDI music
  473. // load & register it
  474. music->data = W_CacheLumpNum(music->lumpnum);
  475. music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum));
  476. }
  477. // play it
  478. I_PlaySong(music->handle, looping);
  479. //#endif
  480. mus_playing = music;
  481. }
  482. void S_StopMusic(void)
  483. {
  484. //jff 1/22/98 return if music is not enabled
  485. if (!mus_card || nomusicparm)
  486. return;
  487. if (mus_playing)
  488. {
  489. if (mus_paused)
  490. I_ResumeSong(mus_playing->handle);
  491. I_StopSong(mus_playing->handle);
  492. I_UnRegisterSong(mus_playing->handle);
  493. if (mus_playing->lumpnum >= 0)
  494. W_UnlockLumpNum(mus_playing->lumpnum); // cph - release the music data
  495. mus_playing->data = 0;
  496. mus_playing = 0;
  497. }
  498. }
  499. void S_StopChannel(int cnum)
  500. {
  501. int i;
  502. channel_t *c = &channels[cnum];
  503. //jff 1/22/98 return if sound is not enabled
  504. if (!snd_card || nosfxparm)
  505. return;
  506. if (c->sfxinfo)
  507. {
  508. // stop the sound playing
  509. if (I_SoundIsPlaying(c->handle))
  510. I_StopSound(c->handle);
  511. // check to see
  512. // if other channels are playing the sound
  513. for (i=0 ; i<numChannels ; i++)
  514. if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
  515. break;
  516. // degrade usefulness of sound data
  517. c->sfxinfo->usefulness--;
  518. c->sfxinfo = 0;
  519. }
  520. }
  521. //
  522. // Changes volume, stereo-separation, and pitch variables
  523. // from the norm of a sound effect to be played.
  524. // If the sound is not audible, returns a 0.
  525. // Otherwise, modifies parameters and returns 1.
  526. //
  527. int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
  528. int *vol, int *sep, int *pitch)
  529. {
  530. fixed_t adx, ady,approx_dist;
  531. angle_t angle;
  532. //jff 1/22/98 return if sound is not enabled
  533. if (!snd_card || nosfxparm)
  534. return 0;
  535. // e6y
  536. // Fix crash when the program wants to S_AdjustSoundParams() for player
  537. // which is not displayplayer and displayplayer was not spawned at the moment.
  538. // It happens in multiplayer demos only.
  539. //
  540. // Stack trace is:
  541. // P_SetupLevel() \ P_LoadThings() \ P_SpawnMapThing() \ P_SpawnPlayer(players[0]) \
  542. // P_SetupPsprites() \ P_BringUpWeapon() \ S_StartSound(players[0]->mo, sfx_sawup) \
  543. // S_StartSoundAtVolume() \ S_AdjustSoundParams(players[displayplayer]->mo, ...);
  544. // players[displayplayer]->mo is NULL
  545. //
  546. // There is no more crash on e1cmnet3.lmp between e1m2 and e1m3
  547. // http://competn.doom2.net/pub/compet-n/doom/coop/movies/e1cmnet3.zip
  548. if (!listener)
  549. return 0;
  550. // calculate the distance to sound origin
  551. // and clip it if necessary
  552. adx = D_abs(listener->x - source->x);
  553. ady = D_abs(listener->y - source->y);
  554. // From _GG1_ p.428. Appox. eucledian distance fast.
  555. approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
  556. if (!approx_dist) // killough 11/98: handle zero-distance as special case
  557. {
  558. *sep = NORM_SEP;
  559. *vol = snd_SfxVolume * 8; // JDC: plasma fire sounds were 1/8 volume without this
  560. return *vol > 0;
  561. }
  562. if (approx_dist > S_CLIPPING_DIST)
  563. return 0;
  564. // angle of source to listener
  565. angle = R_PointToAngle2(listener->x, listener->y, source->x, source->y);
  566. if (angle <= listener->angle)
  567. angle += 0xffffffff;
  568. angle -= listener->angle;
  569. angle >>= ANGLETOFINESHIFT;
  570. // stereo separation
  571. *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS);
  572. // volume calculation
  573. if (approx_dist < S_CLOSE_DIST)
  574. *vol = snd_SfxVolume*8;
  575. else
  576. // distance effect
  577. *vol = (snd_SfxVolume * ((S_CLIPPING_DIST-approx_dist)>>FRACBITS) * 8)
  578. / S_ATTENUATOR;
  579. return (*vol > 0);
  580. }
  581. //
  582. // S_getChannel :
  583. // If none available, return -1. Otherwise channel #.
  584. //
  585. // killough 4/25/98: made static, added is_pickup argument
  586. #ifndef IPHONE
  587. static int S_getChannel(void *origin, sfxinfo_t *sfxinfo, int is_pickup)
  588. {
  589. // channel number to use
  590. int cnum;
  591. channel_t *c;
  592. //jff 1/22/98 return if sound is not enabled
  593. if (!snd_card || nosfxparm)
  594. return -1;
  595. // Find an open channel
  596. for (cnum=0; cnum<numChannels && channels[cnum].sfxinfo; cnum++)
  597. if (origin && channels[cnum].origin == origin &&
  598. channels[cnum].is_pickup == is_pickup)
  599. {
  600. S_StopChannel(cnum);
  601. break;
  602. }
  603. // None available
  604. if (cnum == numChannels)
  605. { // Look for lower priority
  606. for (cnum=0 ; cnum<numChannels ; cnum++)
  607. if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
  608. break;
  609. if (cnum == numChannels)
  610. return -1; // No lower priority. Sorry, Charlie.
  611. else
  612. S_StopChannel(cnum); // Otherwise, kick out lower priority.
  613. }
  614. c = &channels[cnum]; // channel is decided to be cnum.
  615. c->sfxinfo = sfxinfo;
  616. c->origin = origin;
  617. c->is_pickup = is_pickup; // killough 4/25/98
  618. return cnum;
  619. }
  620. #endif