Subversion Repositories Kolibri OS

Rev

Rev 376 | Blame | Compare with Previous | 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( SOUND_VERSION>(ver&0xFFFF))
  261.   {
  262.      printf("Sound version mismatch\n\r");
  263.      printf("Current version: %d, required version %d\n\r",
  264.              ver&0xFFFF, SOUND_VERSION);
  265.      _asm
  266.      {
  267.        mov eax, -1
  268.        int 0x40
  269.      };      
  270.   };
  271.      
  272.   if(SOUND_VERSION<(ver >> 16))
  273.   {  
  274.      printf("Sound version obsolete\n\r");
  275.      printf("Compatible version: %d, required version %d\n\r",
  276.              ver, SOUND_VERSION);
  277.      _asm
  278.      {
  279.        mov eax, -1
  280.        int 0x40
  281.      };      
  282.   };
  283.  
  284.   if (err = CreateBuffer(PCM_2_16_11|PCM_RING,0, &hMixBuff))
  285.   {
  286.     printf("Error %x sound not available\n\r", err);
  287.     printf("handle = %x\n\r", hMixBuff);
  288.     _asm
  289.     {
  290.       mov eax, -1
  291.       int 0x40
  292.     };      
  293.   }
  294.  
  295.   if(err = GetBufferSize(hMixBuff, &mix_size))
  296.   {
  297.     printf("Error %x get buffer size\n\r", err);
  298.     printf("size = %x\n\r", mix_size);
  299.     _asm
  300.     {
  301.       mov eax, -1
  302.       int 0x40
  303.     };      
  304.   };
  305.   mix_size= mix_size/2;
  306.      
  307.   printf("mixer size %d\n\r", mix_size);
  308.  
  309.   if(err=PlayBuffer(hMixBuff, 0))
  310.   {
  311.     printf("Error %x play buffer\n\r", err);
  312.     _asm
  313.     {
  314.       mov eax, -1
  315.       int 0x40
  316.     };      
  317.   }
  318.  
  319.   mixbuffer = malloc(mix_size);
  320.  
  321.   while(sound_state)
  322.   {
  323.      GetNotify(&evnt);
  324.  
  325.      if(evnt.code != 0xFF000001)
  326.      {
  327.        printf("invalid code %d\n\r", evnt.code);
  328.        continue;
  329.      }    
  330.      
  331.      if(evnt.stream != hMixBuff)
  332.      {
  333.        printf("invalid stream %d hMixBuff= %d\n\r", evnt.stream, hMixBuff);
  334.        continue;
  335.      };
  336.      mix_offset= evnt.offset;
  337.      I_UpdateSound();
  338.   };
  339.  
  340.   //flush sound buffers
  341.  
  342.   for(i=0; i<32; i++)
  343.   {
  344.      GetNotify(&evnt);
  345.  
  346.      if(evnt.code != 0xFF000001)
  347.      {
  348.        printf("invalid code %d\n\r", evnt.code);
  349.        continue;
  350.      }    
  351.      
  352.      if(evnt.stream != hMixBuff)
  353.      {
  354.        printf("invalid stream %d hMixBuff= %d\n\r", evnt.stream, hMixBuff);
  355.        continue;
  356.      };
  357.      mix_offset= evnt.offset;
  358.      I_UpdateSound();
  359.   };  
  360.  
  361.   _asm
  362.   {
  363.     mov eax, -1
  364.     int 0x40
  365.   };      
  366.  
  367. };
  368.  
  369. //
  370. // Per level startup code.
  371. // Kills playing sounds at start of level,
  372. //  determines music if any, changes music.
  373. //
  374. void S_Start(void)
  375. {
  376.   int cnum;
  377.   int mnum;
  378.  
  379.   // kill all playing sounds at start of level
  380.   //  (trust me - a good idea)
  381.   for (cnum=0 ; cnum<numChannels ; cnum++)
  382.     if (channels[cnum].sfxinfo)
  383.       S_StopChannel(cnum);
  384.  
  385.   // start new music for the level
  386.   mus_paused = 0;
  387.  
  388.   if (gamemode == commercial)
  389.           mnum = mus_runnin + gamemap - 1;
  390.   else
  391.   {
  392.           int spmus[]=
  393.           {
  394.                   // Song - Who? - Where?
  395.                 mus_e3m4,       // American     e4m1
  396.                 mus_e3m2,       // Romero       e4m2
  397.                 mus_e3m3,       // Shawn        e4m3
  398.                 mus_e1m5,       // American     e4m4
  399.                 mus_e2m7,       // Tim  e4m5
  400.                 mus_e2m4,       // Romero       e4m6
  401.                 mus_e2m6,       // J.Anderson   e4m7 CHIRON.WAD
  402.                 mus_e2m5,       // Shawn        e4m8
  403.                 mus_e1m9        // Tim          e4m9
  404.           };
  405.          
  406.           if (gameepisode < 4)
  407.                   mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1;
  408.           else
  409.                   mnum = spmus[gamemap-1];
  410.   }    
  411.  
  412.   // HACK FOR COMMERCIAL
  413.   //  if (commercial && mnum > mus_e3m9)        
  414.   //      mnum -= mus_e3m9;
  415.  
  416.   S_ChangeMusic(mnum, true);
  417.  
  418.   nextcleanup = 15;
  419. }      
  420.  
  421. void S_StartSoundAtVolume( void *origin_p, int sfx_id, int volume )
  422.    {
  423.     int        rc;
  424.     int        sep;
  425.     int        pitch;
  426.     int        priority;
  427.     sfxinfo_t *sfx;
  428.     int        cnum;
  429.     // int        chnum;  <-- 10.9.98 compiler warning
  430.  
  431.     mobj_t*     origin = (mobj_t *)origin_p;
  432.  
  433.     //WriteDebug("S_StartSoundAtVolume...\n");
  434.  
  435.     // Debug.
  436.     /*fprintf( stderr,"S_StartSoundAtVolume: playing sound %d (%s)\n",sfx_id, S_sfx[sfx_id].name );*/
  437.  
  438.     // check for bogus sound #
  439.     if (sfx_id < 1 || sfx_id > NUMSFX)
  440.         I_Error("Bad sfx #: %d", sfx_id);
  441.  
  442.     sfx = &S_sfx[sfx_id];
  443.  
  444.     // Initialize sound parameters
  445.     if (sfx->link)
  446.        {
  447.         pitch = sfx->pitch;
  448.         priority = sfx->priority;
  449.         volume += sfx->volume;
  450.    
  451.         if (volume < 1)
  452.            {
  453.             //WriteDebug("Volume off...\n");
  454.             return;
  455.            }
  456.    
  457.         if (volume > snd_SfxVolume)
  458.             volume = snd_SfxVolume;
  459.        }        
  460.     else
  461.        {
  462.         pitch = NORM_PITCH;
  463.         priority = NORM_PRIORITY;
  464.        }
  465.  
  466.  
  467.     // Check to see if it is audible,
  468.     //  and if not, modify the params
  469.     if (origin && origin != players[consoleplayer].mo)
  470.        {
  471.         rc = S_AdjustSoundParams(players[consoleplayer].mo, origin, &volume, &sep, &pitch);
  472.         if ( origin->x == players[consoleplayer].mo->x && origin->y == players[consoleplayer].mo->y)
  473.            {    
  474.             sep = NORM_SEP;
  475.            }
  476.         if (!rc)
  477.            {
  478.             //WriteDebug("No rc from S_AdjustSoundParams...\n");
  479.             return;
  480.            }
  481.        }        
  482.     else
  483.        {
  484.         sep = NORM_SEP;
  485.        }
  486.  
  487.     // hacks to vary the sfx pitches
  488.     if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
  489.        {        
  490.         pitch += 8 - (M_Random()&15);
  491.         if (pitch < 0)
  492.             pitch = 0;
  493.         else
  494.         if (pitch>255)
  495.             pitch = 255;
  496.        }
  497.     else
  498.     if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
  499.        {
  500.         pitch += 16 - (M_Random()&31);
  501.         if (pitch<0)
  502.             pitch = 0;
  503.         else
  504.         if (pitch > 255)
  505.             pitch = 255;
  506.        }
  507.  
  508.   // kill old sound
  509.   S_StopSound(origin);
  510.  
  511.   // try to find a channel
  512.   cnum = S_getChannel(origin, sfx, sfx_id);
  513.  
  514.   if (cnum<0)
  515.      {
  516.         //WriteDebug("cnum < 0 -- no channel...\n");
  517.     return;
  518.      }
  519.  
  520.   //
  521.   // This is supposed to handle the loading/caching.
  522.   // For some odd reason, the caching is done nearly
  523.   //  each time the sound is needed?
  524.   //
  525.  
  526.   // get lumpnum if necessary
  527.   if (sfx->lumpnum < 0)
  528.     sfx->lumpnum = I_GetSfxLumpNum(sfx);
  529.  
  530.   // cache data if necessary
  531.   if (!sfx->data)
  532.   {
  533.     sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC);
  534.    
  535.   }
  536.  
  537.   // increase the usefulness
  538.   if (sfx->usefulness++ < 0)
  539.       sfx->usefulness = 1;
  540.  
  541.   // Assigns the handle to one of the channels in the
  542.   //  mix/output buffer.
  543.   //WriteDebug("I_StartSound...\n");
  544.   channels[cnum].handle = I_StartSound(sfx_id,volume,sep,pitch,priority);
  545.   channels[cnum].handle = cnum;
  546.   channels[cnum].sfxinfo = sfx;
  547.   channels[cnum].origin = origin;
  548. }      
  549.  
  550. void S_StartSound( void *origin, int sfx_id )
  551.    {
  552. #ifdef SAWDEBUG
  553.     // if (sfx_id == sfx_sawful)
  554.     // sfx_id = sfx_itemup;
  555. #endif
  556.  
  557.     S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume);
  558.  
  559.  
  560.     // UNUSED. We had problems, had we not?
  561. #ifdef SAWDEBUG
  562. {
  563.     int i;
  564.     int n;
  565.        
  566.     static mobj_t*      last_saw_origins[10] = {1,1,1,1,1,1,1,1,1,1};
  567.     static int          first_saw=0;
  568.     static int          next_saw=0;
  569.        
  570.     if (sfx_id == sfx_sawidl
  571.         || sfx_id == sfx_sawful
  572.         || sfx_id == sfx_sawhit)
  573.     {
  574.         for (i=first_saw;i!=next_saw;i=(i+1)%10)
  575.             if (last_saw_origins[i] != origin)
  576.                 fprintf(stderr, "old origin 0x%lx != "
  577.                         "origin 0x%lx for sfx %d\n",
  578.                         last_saw_origins[i],
  579.                         origin,
  580.                         sfx_id);
  581.            
  582.         last_saw_origins[next_saw] = origin;
  583.         next_saw = (next_saw + 1) % 10;
  584.         if (next_saw == first_saw)
  585.             first_saw = (first_saw + 1) % 10;
  586.            
  587.         for (n=i=0; i<numChannels ; i++)
  588.         {
  589.             if (channels[i].sfxinfo == &S_sfx[sfx_sawidl]
  590.                 || channels[i].sfxinfo == &S_sfx[sfx_sawful]
  591.                 || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) n++;
  592.         }
  593.            
  594.         if (n>1)
  595.         {
  596.             for (i=0; i<numChannels ; i++)
  597.             {
  598.                 if (channels[i].sfxinfo == &S_sfx[sfx_sawidl]
  599.                     || channels[i].sfxinfo == &S_sfx[sfx_sawful]
  600.                     || channels[i].sfxinfo == &S_sfx[sfx_sawhit])
  601.                 {
  602.                     fprintf(stderr,
  603.                             "chn: sfxinfo=0x%lx, origin=0x%lx, "
  604.                             "handle=%d\n",
  605.                             channels[i].sfxinfo,
  606.                             channels[i].origin,
  607.                             channels[i].handle);
  608.                 }
  609.             }
  610.             fprintf(stderr, "\n");
  611.         }
  612.     }
  613. }
  614. #endif
  615.  
  616. }
  617.  
  618.  
  619.  
  620.  
  621. void S_StopSound(void *origin)
  622. {
  623.  
  624.     int cnum;
  625.  
  626.     for (cnum=0 ; cnum<numChannels ; cnum++)
  627.     {
  628.         if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
  629.         {
  630.             S_StopChannel(cnum);
  631.             break;
  632.         }
  633.     }
  634. }
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644. //
  645. // Stop and resume music, during game PAUSE.
  646. //
  647. void S_PauseSound(void)
  648. {
  649.     if (mus_playing && !mus_paused)
  650.     {
  651.         I_PauseSong(mus_playing->handle);
  652.         mus_paused = true;
  653.     }
  654. }
  655.  
  656. void S_ResumeSound(void)
  657. {
  658.     if (mus_playing && mus_paused)
  659.     {
  660.         I_ResumeSong(mus_playing->handle);
  661.         mus_paused = false;
  662.     }
  663. }
  664.  
  665.  
  666. //
  667. // Updates music & sounds
  668. //
  669. void S_UpdateSounds(void* listener_p)
  670. {
  671.     int         audible;
  672.     int         cnum;
  673.     int         volume;
  674.     int         sep;
  675.     int         pitch;
  676.     sfxinfo_t*  sfx;
  677.     channel_t*  c;
  678.    
  679.     mobj_t*     listener = (mobj_t*)listener_p;
  680.  
  681.  
  682.    
  683.     // Clean up unused data.
  684.     // This is currently not done for 16bit (sounds cached static).
  685.     // DOS 8bit remains.
  686.     /*if (gametic > nextcleanup)
  687.     {
  688.         for (i=1 ; i<NUMSFX ; i++)
  689.         {
  690.             if (S_sfx[i].usefulness < 1
  691.                 && S_sfx[i].usefulness > -1)
  692.             {
  693.                 if (--S_sfx[i].usefulness == -1)
  694.                 {
  695.                     Z_ChangeTag(S_sfx[i].data, PU_CACHE);
  696.                     S_sfx[i].data = 0;
  697.                 }
  698.             }
  699.         }
  700.         nextcleanup = gametic + 15;
  701.     }*/
  702.    
  703.     for (cnum=0 ; cnum<numChannels ; cnum++)
  704.     {
  705.         c = &channels[cnum];
  706.         sfx = c->sfxinfo;
  707.  
  708.         if (c->sfxinfo)
  709.         {
  710.             if (I_SoundIsPlaying(c->handle))
  711.             {
  712.                 // initialize parameters
  713.                 volume = snd_SfxVolume;
  714.                 pitch = NORM_PITCH;
  715.                 sep = NORM_SEP;
  716.  
  717.                 if (sfx->link)
  718.                 {
  719.                     pitch = sfx->pitch;
  720.                     volume += sfx->volume;
  721.                     if (volume < 1)
  722.                     {
  723.                         S_StopChannel(cnum);
  724.                         continue;
  725.                     }
  726.                     else if (volume > snd_SfxVolume)
  727.                     {
  728.                         volume = snd_SfxVolume;
  729.                     }
  730.                 }
  731.  
  732.                 // check non-local sounds for distance clipping
  733.                 //  or modify their params
  734.                 if (c->origin && listener_p != c->origin)
  735.                 {
  736.                     audible = S_AdjustSoundParams(listener,
  737.                                                   c->origin,
  738.                                                   &volume,
  739.                                                   &sep,
  740.                                                   &pitch);
  741.                    
  742.                     if (!audible)
  743.                     {
  744.                         S_StopChannel(cnum);
  745.                     }
  746.                     else
  747.                         I_UpdateSoundParams(c->handle, volume, sep, pitch);
  748.                 }
  749.             }
  750.             else
  751.             {
  752.                 // if channel is allocated but sound has stopped,
  753.                 //  free it
  754.                 S_StopChannel(cnum);
  755.             }
  756.         }
  757.     }
  758.     // kill music if it is a single-play && finished
  759.     // if (     mus_playing
  760.     //      && !I_QrySongPlaying(mus_playing->handle)
  761.     //      && !mus_paused )
  762.     // S_StopMusic();
  763. }
  764.  
  765.  
  766. void S_SetMusicVolume(int volume)
  767. {
  768.     if (volume < 0 || volume > 127)
  769.     {
  770.         I_Error("Attempt to set music volume at %d",
  771.                 volume);
  772.     }    
  773.  
  774.     I_SetMusicVolume(127);
  775.     I_SetMusicVolume(volume);
  776.     snd_MusicVolume = volume;
  777. }
  778.  
  779.  
  780.  
  781. void S_SetSfxVolume(int volume)
  782. {
  783.  
  784.     if (volume < 0 || volume > 127)
  785.         I_Error("Attempt to set sfx volume at %d", volume);
  786.  
  787.     snd_SfxVolume = volume;
  788.  
  789. }
  790.  
  791. //
  792. // Starts some music with the music id found in sounds.h.
  793. //
  794. void S_StartMusic(int m_id)
  795. {
  796. //    S_ChangeMusic(m_id, false);
  797. }
  798.  
  799.  
  800. // clean-up&code for orig midi 10.9.98-dlw
  801. void S_ChangeMusic(int musicnum, int looping)
  802. {
  803.  
  804.     // I_PlaySong(music->handle, looping);
  805. //      mus_playing = music;
  806. }
  807.  
  808.  
  809. void S_StopMusic(void)
  810. {
  811.     if (mus_playing)
  812.     {
  813.                 if (mus_paused) I_ResumeSong(mus_playing->handle);
  814.                 I_StopSong(mus_playing->handle);
  815.                 I_UnRegisterSong(mus_playing->handle);
  816.                 Z_ChangeTag(mus_playing->data, PU_CACHE);
  817.                 mus_playing->data = 0;
  818.                 mus_playing = 0;
  819.     }
  820. }
  821.  
  822. void S_StopChannel(int cnum)
  823. {
  824.  
  825.     int         i;
  826.     channel_t*  c = &channels[cnum];
  827.  
  828.     if (c->sfxinfo)
  829.     {
  830.         // stop the sound playing
  831.         if (I_SoundIsPlaying(c->handle))
  832.         {
  833. #ifdef SAWDEBUG
  834.             if (c->sfxinfo == &S_sfx[sfx_sawful])
  835.                 fprintf(stderr, "stopped\n");
  836. #endif
  837.             I_StopSound(c->handle);
  838.         }
  839.  
  840.         // check to see
  841.         //  if other channels are playing the sound
  842.         for (i=0 ; i<numChannels ; i++)
  843.         {
  844.             if (cnum != i
  845.                 && c->sfxinfo == channels[i].sfxinfo)
  846.             {
  847.                 break;
  848.             }
  849.         }
  850.        
  851.         // degrade usefulness of sound data
  852.         c->sfxinfo->usefulness--;
  853.  
  854.         c->sfxinfo = 0;
  855.     }
  856. }
  857.  
  858.  
  859. //
  860. // Changes volume, stereo-separation, and pitch variables
  861. //  from the norm of a sound effect to be played.
  862. // If the sound is not audible, returns a 0.
  863. // Otherwise, modifies parameters and returns 1.
  864. //
  865. int
  866. S_AdjustSoundParams (mobj_t* listener, mobj_t* source,
  867.                      int* vol, int* sep, int* pitch)
  868. {
  869.     fixed_t     approx_dist;
  870.     fixed_t     adx;
  871.     fixed_t     ady;
  872.     angle_t     angle;
  873.  
  874.     // calculate the distance to sound origin
  875.     //  and clip it if necessary
  876.     adx = abs(listener->x - source->x);
  877.     ady = abs(listener->y - source->y);
  878.  
  879.     // From _GG1_ p.428. Appox. eucledian distance fast.
  880.     approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
  881.    
  882.     if (gamemap != 8
  883.         && approx_dist > S_CLIPPING_DIST)
  884.     {
  885.         return 0;
  886.     }
  887.    
  888.     // angle of source to listener
  889.     angle = R_PointToAngle2(listener->x,
  890.                             listener->y,
  891.                             source->x,
  892.                             source->y);
  893.  
  894.     if (angle > listener->angle)
  895.         angle = angle - listener->angle;
  896.     else
  897.         angle = angle + (0xffffffff - listener->angle);
  898.  
  899.     angle >>= ANGLETOFINESHIFT;
  900.  
  901.     // stereo separation
  902.     *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS);
  903.  
  904.     // volume calculation
  905.     if (approx_dist < S_CLOSE_DIST)
  906.     {
  907.         *vol = snd_SfxVolume;
  908.     }
  909.     else if (gamemap == 8)
  910.     {
  911.         if (approx_dist > S_CLIPPING_DIST)
  912.             approx_dist = S_CLIPPING_DIST;
  913.  
  914.         *vol = 15+ ((snd_SfxVolume-15)
  915.                     *((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
  916.             / S_ATTENUATOR;
  917.     }
  918.     else
  919.     {
  920.         // distance effect
  921.         *vol = (snd_SfxVolume
  922.                 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
  923.             / S_ATTENUATOR;
  924.     }
  925.    
  926.     return (*vol > 0);
  927. }
  928.  
  929. //
  930. // S_getChannel :
  931. //   If none available, return -1.  Otherwise channel #.
  932. //
  933. int S_getChannel( void *origin, sfxinfo_t *sfxinfo, int sfxid )
  934.    {
  935.     // channel number to use
  936.     int         cnum;
  937.        
  938.     channel_t*  c;
  939.  
  940.     // Find an open channel
  941.     //for (cnum = 0; cnum < numChannels; cnum++)
  942.     for (cnum = 0; cnum < NUM_CHANNELS; cnum++)
  943.        {
  944.         if (!channels[cnum].sfxinfo)
  945.             break;
  946.         else
  947.         if (origin && channels[cnum].origin == origin)
  948.            {
  949.             S_StopChannel(cnum);
  950.             break;
  951.            }
  952.        }
  953.  
  954.     // None available
  955.     if (cnum == NUM_CHANNELS)
  956.        {
  957.         // Look for lower priority
  958.         for (cnum = NUMSFX; cnum < NUM_CHANNELS; cnum++)
  959.              if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
  960.                  break;
  961.  
  962.         if (cnum == numChannels)
  963.            {
  964.             // FUCK!  No lower priority.  Sorry, Charlie.    
  965.             return -1;
  966.            }
  967.         else
  968.            {
  969.             // Otherwise, kick out lower priority.
  970.             S_StopChannel(cnum);
  971.            }
  972.        }
  973.  
  974.     c = &channels[cnum];
  975.  
  976.     // channel is decided to be cnum.
  977.     c->sfxinfo = sfxinfo;
  978.     c->origin = origin;
  979.  
  980.     return cnum;
  981.    }
  982.  
  983.  
  984.  
  985.  
  986.