Subversion Repositories Kolibri OS

Rev

Rev 374 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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