This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Oct 30th, 2012  |  syntax: None  |  size: 20.41 KB  |  views: 55  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // Copyright(C) 1993-1996 Id Software, Inc.
  5. // Copyright(C) 2005 Simon Howard
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program; if not, write to the Free Software
  19. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. // 02111-1307, USA.
  21. //
  22. // DESCRIPTION:  none
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28.  
  29. #include "i_system.h"
  30.  
  31. #include "doomfeatures.h"
  32. #include "deh_main.h"
  33.  
  34. #include "doomstat.h"
  35. #include "doomdef.h"
  36.  
  37. #include "sounds.h"
  38. #include "s_sound.h"
  39.  
  40. #include "m_random.h"
  41. #include "m_argv.h"
  42.  
  43. #include "p_local.h"
  44. #include "w_wad.h"
  45. #include "z_zone.h"
  46.  
  47. // when to clip out sounds
  48. // Does not fit the large outdoor areas.
  49.  
  50. #define S_CLIPPING_DIST (1200 * FRACUNIT)
  51.  
  52. // Distance tp origin when sounds should be maxed out.
  53. // This should relate to movement clipping resolution
  54. // (see BLOCKMAP handling).
  55. // In the source code release: (160*FRACUNIT).  Changed back to the
  56. // Vanilla value of 200 (why was this changed?)
  57.  
  58. #define S_CLOSE_DIST (200 * FRACUNIT)
  59.  
  60. // The range over which sound attenuates
  61.  
  62. #define S_ATTENUATOR ((S_CLIPPING_DIST - S_CLOSE_DIST) >> FRACBITS)
  63.  
  64. // Stereo separation
  65.  
  66. #define S_STEREO_SWING (96 * FRACUNIT)
  67.  
  68. #define NORM_PITCH 128
  69. #define NORM_PRIORITY 64
  70. #define NORM_SEP 128
  71.  
  72. typedef struct
  73. {
  74.     // sound information (if null, channel avail.)
  75.     sfxinfo_t *sfxinfo;
  76.  
  77.     // origin of sound
  78.     mobj_t *origin;
  79.  
  80.     // handle of the sound being played
  81.     int handle;
  82.    
  83. } channel_t;
  84.  
  85. // Low-level sound and music modules we are using
  86.  
  87. static sound_module_t *sound_module;
  88. static music_module_t *music_module;
  89.  
  90. // The set of channels available
  91.  
  92. static channel_t *channels;
  93.  
  94. // Maximum volume of a sound effect.
  95. // Internal default is max out of 0-15.
  96.  
  97. int sfxVolume = 8;
  98.  
  99. // Maximum volume of music.
  100.  
  101. int musicVolume = 8;
  102.  
  103. // Sound sample rate to use for digital output (Hz)
  104.  
  105. int snd_samplerate = 44100;
  106.  
  107. // Internal volume level, ranging from 0-127
  108.  
  109. static int snd_SfxVolume;
  110.  
  111. // Whether songs are mus_paused
  112.  
  113. static boolean mus_paused;        
  114.  
  115. // Music currently being played
  116.  
  117. static musicinfo_t *mus_playing = NULL;
  118.  
  119. // Number of channels to use
  120.  
  121. int numChannels = 8;
  122.  
  123. int snd_musicdevice = SNDDEVICE_GENMIDI;
  124. int snd_sfxdevice = SNDDEVICE_SB;
  125.  
  126. // Sound modules
  127.  
  128. extern sound_module_t sound_sdl_module;
  129. extern sound_module_t sound_pcsound_module;
  130. extern music_module_t music_sdl_module;
  131. extern music_module_t music_opl_module;
  132.  
  133. // Compiled-in sound modules:
  134.  
  135. static sound_module_t *sound_modules[] =
  136. {
  137. #ifdef FEATURE_SOUND
  138.     &sound_sdl_module,
  139.     &sound_pcsound_module,
  140. #endif
  141.     NULL,
  142. };
  143.  
  144. // Compiled-in music modules:
  145.  
  146. static music_module_t *music_modules[] =
  147. {
  148. #ifdef FEATURE_SOUND
  149.     &music_sdl_module,
  150.     &music_opl_module,
  151. #endif
  152.     NULL,
  153. };
  154.  
  155. // Check if a sound device is in the given list of devices
  156.  
  157. static boolean SndDeviceInList(snddevice_t device, snddevice_t *list,
  158.                                int len)
  159. {
  160.     int i;
  161.  
  162.     for (i=0; i<len; ++i)
  163.     {
  164.         if (device == list[i])
  165.         {
  166.             return true;
  167.         }
  168.     }
  169.  
  170.     return false;
  171. }
  172.  
  173. // Find and initialize a sound_module_t appropriate for the setting
  174. // in snd_sfxdevice.
  175.  
  176. static void InitSfxModule(void)
  177. {
  178.     int i;
  179.  
  180.     sound_module = NULL;
  181.  
  182.     for (i=0; sound_modules[i] != NULL; ++i)
  183.     {
  184.         // Is the sfx device in the list of devices supported by
  185.         // this module?
  186.  
  187.         if (SndDeviceInList(snd_sfxdevice,
  188.                             sound_modules[i]->sound_devices,
  189.                             sound_modules[i]->num_sound_devices))
  190.         {
  191.             // Initialize the module
  192.  
  193.             if (sound_modules[i]->Init())
  194.             {
  195.                 sound_module = sound_modules[i];
  196.                 return;
  197.             }
  198.         }
  199.     }
  200. }
  201.  
  202. // Initialize music according to snd_musicdevice.
  203.  
  204. static void InitMusicModule(void)
  205. {
  206.     int i;
  207.  
  208.     music_module = NULL;
  209.  
  210.     for (i=0; music_modules[i] != NULL; ++i)
  211.     {
  212.         // Is the music device in the list of devices supported
  213.         // by this module?
  214.  
  215.         if (SndDeviceInList(snd_musicdevice,
  216.                             music_modules[i]->sound_devices,
  217.                             music_modules[i]->num_sound_devices))
  218.         {
  219.             // Initialize the module
  220.  
  221.             if (music_modules[i]->Init())
  222.             {
  223.                 music_module = music_modules[i];
  224.                 return;
  225.             }
  226.         }
  227.     }
  228. }
  229.  
  230. //
  231. // Initializes sound stuff, including volume
  232. // Sets channels, SFX and music volume,
  233. //  allocates channel buffer, sets S_sfx lookup.
  234. //
  235.  
  236. void S_Init(int sfxVolume, int musicVolume)
  237. {  
  238.     boolean nosound, nosfx, nomusic;
  239.     int i;
  240.  
  241.     //!
  242.     // @vanilla
  243.     //
  244.     // Disable all sound output.
  245.     //
  246.  
  247.     nosound = M_CheckParm("-nosound") > 0;
  248.  
  249.     //!
  250.     // @vanilla
  251.     //
  252.     // Disable sound effects.
  253.     //
  254.  
  255.     nosfx = M_CheckParm("-nosfx") > 0;
  256.  
  257.     //!
  258.     // @vanilla
  259.     //
  260.     // Disable music.
  261.     //
  262.  
  263.     nomusic = M_CheckParm("-nomusic") > 0;
  264.  
  265.     // Initialize the sound and music subsystems.
  266.  
  267.     if (!nosound && !screensaver_mode)
  268.     {
  269.         if (!nosfx)
  270.         {
  271.             InitSfxModule();
  272.         }
  273.  
  274.         if (!nomusic)
  275.         {
  276.             InitMusicModule();
  277.         }
  278.     }
  279.  
  280.     S_SetSfxVolume(sfxVolume);
  281.     S_SetMusicVolume(musicVolume);
  282.  
  283.     // Allocating the internal channels for mixing
  284.     // (the maximum numer of sounds rendered
  285.     // simultaneously) within zone memory.
  286.     channels = Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0);
  287.  
  288.     // Free all channels for use
  289.     for (i=0 ; i<numChannels ; i++)
  290.     {
  291.         channels[i].sfxinfo = 0;
  292.     }
  293.  
  294.     // no sounds are playing, and they are not mus_paused
  295.     mus_paused = 0;
  296.  
  297.     // Note that sounds have not been cached (yet).
  298.     for (i=1 ; i<NUMSFX ; i++)
  299.     {
  300.         S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
  301.     }
  302. }
  303.  
  304. void S_Shutdown(void)
  305. {
  306.     if (sound_module != NULL)
  307.     {
  308.         sound_module->Shutdown();
  309.     }
  310.  
  311.     if (music_module != NULL)
  312.     {
  313.         music_module->Shutdown();
  314.     }
  315. }
  316.  
  317. static void S_StopChannel(int cnum)
  318. {
  319.     int i;
  320.     channel_t *c;
  321.  
  322.     c = &channels[cnum];
  323.  
  324.     if (c->sfxinfo)
  325.     {
  326.         // stop the sound playing
  327.  
  328.         if (sound_module != NULL)
  329.         {
  330.             if (sound_module->SoundIsPlaying(c->handle))
  331.             {
  332.                 sound_module->StopSound(c->handle);
  333.             }
  334.         }
  335.  
  336.         // check to see if other channels are playing the sound
  337.  
  338.         for (i=0; i<numChannels; i++)
  339.         {
  340.             if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
  341.             {
  342.                 break;
  343.             }
  344.         }
  345.        
  346.         // degrade usefulness of sound data
  347.  
  348.         c->sfxinfo->usefulness--;
  349.         c->sfxinfo = NULL;
  350.     }
  351. }
  352.  
  353. //
  354. // Per level startup code.
  355. // Kills playing sounds at start of level,
  356. //  determines music if any, changes music.
  357. //
  358.  
  359. void S_Start(void)
  360. {
  361.     int cnum;
  362.     int mnum;
  363.  
  364.     // kill all playing sounds at start of level
  365.     //  (trust me - a good idea)
  366.     for (cnum=0 ; cnum<numChannels ; cnum++)
  367.     {
  368.         if (channels[cnum].sfxinfo)
  369.         {
  370.             S_StopChannel(cnum);
  371.         }
  372.     }
  373.  
  374.     // start new music for the level
  375.     mus_paused = 0;
  376.  
  377.     if (gamemode == commercial)
  378.     {
  379.         mnum = mus_runnin + gamemap - 1;
  380.     }
  381.     else
  382.     {
  383.         int spmus[]=
  384.         {
  385.             // Song - Who? - Where?
  386.  
  387.             mus_e3m4,        // American     e4m1
  388.             mus_e3m2,        // Romero       e4m2
  389.             mus_e3m3,        // Shawn        e4m3
  390.             mus_e1m5,        // American     e4m4
  391.             mus_e2m7,        // Tim          e4m5
  392.             mus_e2m4,        // Romero       e4m6
  393.             mus_e2m6,        // J.Anderson   e4m7 CHIRON.WAD
  394.             mus_e2m5,        // Shawn        e4m8
  395.             mus_e1m9,        // Tim          e4m9
  396.         };
  397.  
  398.         if (gameepisode < 4)
  399.         {
  400.             mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1;
  401.         }
  402.         else
  403.         {
  404.             mnum = spmus[gamemap-1];
  405.         }
  406.     }        
  407.  
  408.     S_ChangeMusic(mnum, true);
  409. }        
  410.  
  411. void S_StopSound(mobj_t *origin)
  412. {
  413.     int cnum;
  414.  
  415.     for (cnum=0 ; cnum<numChannels ; cnum++)
  416.     {
  417.         if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
  418.         {
  419.             S_StopChannel(cnum);
  420.             break;
  421.         }
  422.     }
  423. }
  424.  
  425. //
  426. // S_GetChannel :
  427. //   If none available, return -1.  Otherwise channel #.
  428. //
  429.  
  430. static int S_GetChannel(mobj_t *origin, sfxinfo_t *sfxinfo)
  431. {
  432.     // channel number to use
  433.     int                cnum;
  434.    
  435.     channel_t*        c;
  436.  
  437.     // Find an open channel
  438.     for (cnum=0 ; cnum<numChannels ; cnum++)
  439.     {
  440.         if (!channels[cnum].sfxinfo)
  441.         {
  442.             break;
  443.         }
  444.         else if (origin && channels[cnum].origin == origin)
  445.         {
  446.             S_StopChannel(cnum);
  447.             break;
  448.         }
  449.     }
  450.  
  451.     // None available
  452.     if (cnum == numChannels)
  453.     {
  454.         // Look for lower priority
  455.         for (cnum=0 ; cnum<numChannels ; cnum++)
  456.         {
  457.             if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
  458.             {
  459.                 break;
  460.             }
  461.         }
  462.  
  463.         if (cnum == numChannels)
  464.         {
  465.             // FUCK!  No lower priority.  Sorry, Charlie.    
  466.             return -1;
  467.         }
  468.         else
  469.         {
  470.             // Otherwise, kick out lower priority.
  471.             S_StopChannel(cnum);
  472.         }
  473.     }
  474.  
  475.     c = &channels[cnum];
  476.  
  477.     // channel is decided to be cnum.
  478.     c->sfxinfo = sfxinfo;
  479.     c->origin = origin;
  480.  
  481.     return cnum;
  482. }
  483.  
  484. //
  485. // Changes volume, stereo-separation, and pitch variables
  486. //  from the norm of a sound effect to be played.
  487. // If the sound is not audible, returns a 0.
  488. // Otherwise, modifies parameters and returns 1.
  489. //
  490.  
  491. static int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
  492.                                int *vol, int *sep, int *pitch)
  493. {
  494.     fixed_t        approx_dist;
  495.     fixed_t        adx;
  496.     fixed_t        ady;
  497.     angle_t        angle;
  498.  
  499.     // calculate the distance to sound origin
  500.     //  and clip it if necessary
  501.     adx = abs(listener->x - source->x);
  502.     ady = abs(listener->y - source->y);
  503.  
  504.     // From _GG1_ p.428. Appox. eucledian distance fast.
  505.     approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
  506.    
  507.     if (gamemap != 8 && approx_dist > S_CLIPPING_DIST)
  508.     {
  509.         return 0;
  510.     }
  511.    
  512.     // angle of source to listener
  513.     angle = R_PointToAngle2(listener->x,
  514.                             listener->y,
  515.                             source->x,
  516.                             source->y);
  517.  
  518.     if (angle > listener->angle)
  519.     {
  520.         angle = angle - listener->angle;
  521.     }
  522.     else
  523.     {
  524.         angle = angle + (0xffffffff - listener->angle);
  525.     }
  526.  
  527.     angle >>= ANGLETOFINESHIFT;
  528.  
  529.     // stereo separation
  530.     *sep = 128 - (FixedMul(S_STEREO_SWING, finesine[angle]) >> FRACBITS);
  531.  
  532.     // volume calculation
  533.     if (approx_dist < S_CLOSE_DIST)
  534.     {
  535.         *vol = snd_SfxVolume;
  536.     }
  537.     else if (gamemap == 8)
  538.     {
  539.         if (approx_dist > S_CLIPPING_DIST)
  540.         {
  541.             approx_dist = S_CLIPPING_DIST;
  542.         }
  543.  
  544.         *vol = 15+ ((snd_SfxVolume-15)
  545.                     *((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
  546.             / S_ATTENUATOR;
  547.     }
  548.     else
  549.     {
  550.         // distance effect
  551.         *vol = (snd_SfxVolume
  552.                 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
  553.             / S_ATTENUATOR;
  554.     }
  555.    
  556.     return (*vol > 0);
  557. }
  558.  
  559. void S_StartSound(void *origin_p, int sfx_id)
  560. {
  561.     sfxinfo_t *sfx;
  562.     mobj_t *origin;
  563.     int rc;
  564.     int sep;
  565.         int pitch;
  566.     int priority;
  567.     int cnum;
  568.     int volume;
  569.  
  570.     origin = (mobj_t *) origin_p;
  571.     volume = snd_SfxVolume;
  572.  
  573.     // check for bogus sound #
  574.     if (sfx_id < 1 || sfx_id > NUMSFX)
  575.     {
  576.         I_Error("Bad sfx #: %d", sfx_id);
  577.     }
  578.  
  579.     sfx = &S_sfx[sfx_id];
  580.  
  581.     // Initialize sound parameters
  582.     if (sfx->link)
  583.     {
  584.                 pitch = sfx->pitch;
  585.         priority = sfx->priority;
  586.         volume += sfx->volume;
  587.  
  588.         if (volume < 1)
  589.         {
  590.             return;
  591.         }
  592.  
  593.         if (volume > snd_SfxVolume)
  594.         {
  595.             volume = snd_SfxVolume;
  596.         }
  597.     }        
  598.     else
  599.     {
  600.                 pitch = NORM_PITCH;
  601.         priority = NORM_PRIORITY;
  602.     }
  603.  
  604.  
  605.     // Check to see if it is audible,
  606.     //  and if not, modify the params
  607.     if (origin && origin != players[consoleplayer].mo)
  608.     {
  609.         rc = S_AdjustSoundParams(players[consoleplayer].mo,
  610.                                  origin,
  611.                                  &volume,
  612.                                  &sep,
  613.                                                                  &pitch);
  614.  
  615.         if (origin->x == players[consoleplayer].mo->x
  616.          && origin->y == players[consoleplayer].mo->y)
  617.         {        
  618.             sep = NORM_SEP;
  619.         }
  620.  
  621.         if (!rc)
  622.         {
  623.             return;
  624.         }
  625.     }        
  626.     else
  627.     {
  628.         sep = NORM_SEP;
  629.     }
  630.  
  631.         // hacks to vary the sfx pitches
  632.              if (sfx_id >= sfx_sawup
  633.               && sfx_id <= sfx_sawhit)
  634.              {
  635.                  pitch += 8 - (M_Random()&15);
  636.  
  637.                  if (pitch < 0)
  638.                  {
  639.                      pitch = 0;
  640.                  }
  641.                  else if (pitch > 255)
  642.                  {
  643.                      pitch = 255;
  644.                  }
  645.              }
  646.              else if (sfx_id != sfx_itemup
  647.                    && sfx_id != sfx_tink)
  648.              {
  649.                  pitch += 16 - (M_Random()&31);
  650.  
  651.                  if (pitch < 0)
  652.                  {
  653.                      pitch = 0;
  654.                  }
  655.                  else if (pitch > 255)
  656.                  {      
  657.                      pitch = 255;
  658.                  }
  659.              }
  660.  
  661.     // kill old sound
  662.     S_StopSound(origin);
  663.  
  664.     // try to find a channel
  665.     cnum = S_GetChannel(origin, sfx);
  666.  
  667.     if (cnum < 0)
  668.     {
  669.         return;
  670.     }
  671.  
  672.     // increase the usefulness
  673.     if (sfx->usefulness++ < 0)
  674.     {
  675.         sfx->usefulness = 1;
  676.     }
  677.  
  678.     if (sound_module != NULL)
  679.     {
  680.         // Get lumpnum if necessary
  681.  
  682.         if (sfx->lumpnum < 0)
  683.         {
  684.             sfx->lumpnum = sound_module->GetSfxLumpNum(sfx);
  685.         }
  686.  
  687.         // Assigns the handle to one of the channels in the
  688.         //  mix/output buffer.
  689.  
  690.         channels[cnum].handle = sound_module->StartSound(sfx_id,
  691.                                                          cnum,
  692.                                                          volume,
  693.                                                          sep,
  694.                                                                                                                  pitch,
  695.                                                                                                                  priority);
  696.     }
  697. }        
  698.  
  699. //
  700. // Stop and resume music, during game PAUSE.
  701. //
  702.  
  703. void S_PauseSound(void)
  704. {
  705.     if (mus_playing && !mus_paused)
  706.     {
  707.         if (music_module != NULL)
  708.         {
  709.             music_module->PauseMusic();
  710.         }
  711.         mus_paused = true;
  712.     }
  713. }
  714.  
  715. void S_ResumeSound(void)
  716. {
  717.     if (mus_playing && mus_paused)
  718.     {
  719.         if (music_module != NULL)
  720.         {
  721.             music_module->ResumeMusic();
  722.         }
  723.         mus_paused = false;
  724.     }
  725. }
  726.  
  727. //
  728. // Updates music & sounds
  729. //
  730.  
  731. void S_UpdateSounds(mobj_t *listener)
  732. {
  733.     int                audible;
  734.     int                cnum;
  735.     int                volume;
  736.     int                sep;
  737.         int                pitch;
  738.     sfxinfo_t*        sfx;
  739.     channel_t*        c;
  740.  
  741.     for (cnum=0; cnum<numChannels; cnum++)
  742.     {
  743.         c = &channels[cnum];
  744.         sfx = c->sfxinfo;
  745.  
  746.         if (c->sfxinfo)
  747.         {
  748.             if (sound_module != NULL && sound_module->SoundIsPlaying(c->handle))
  749.             {
  750.                 // initialize parameters
  751.                 volume = snd_SfxVolume;
  752.                                 pitch = NORM_PITCH;
  753.                 sep = NORM_SEP;
  754.  
  755.                 if (sfx->link)
  756.                 {
  757.                                         pitch = sfx->pitch;
  758.                     volume += sfx->volume;
  759.                     if (volume < 1)
  760.                     {
  761.                         S_StopChannel(cnum);
  762.                         continue;
  763.                     }
  764.                     else if (volume > snd_SfxVolume)
  765.                     {
  766.                         volume = snd_SfxVolume;
  767.                     }
  768.                 }
  769.  
  770.                 // check non-local sounds for distance clipping
  771.                 //  or modify their params
  772.                 if (c->origin && listener != c->origin)
  773.                 {
  774.                     audible = S_AdjustSoundParams(listener,
  775.                                                   c->origin,
  776.                                                   &volume,
  777.                                                   &sep,
  778.                                                                                                   &pitch);
  779.                    
  780.                     if (!audible)
  781.                     {
  782.                         S_StopChannel(cnum);
  783.                     }
  784.                     else
  785.                     {
  786.                         I_UpdateSoundParams(c->handle, volume, sep, pitch);
  787.                     }
  788.                 }
  789.             }
  790.             else
  791.             {
  792.                 // if channel is allocated but sound has stopped,
  793.                 //  free it
  794.                 S_StopChannel(cnum);
  795.             }
  796.         }
  797.     }
  798. }
  799.  
  800. void S_SetMusicVolume(int volume)
  801. {
  802.     if (volume < 0 || volume > 127)
  803.     {
  804.         I_Error("Attempt to set music volume at %d",
  805.                 volume);
  806.     }    
  807.  
  808.     if (music_module != NULL)
  809.     {
  810.         music_module->SetMusicVolume(volume);
  811.     }
  812. }
  813.  
  814. void S_SetSfxVolume(int volume)
  815. {
  816.     if (volume < 0 || volume > 127)
  817.     {
  818.         I_Error("Attempt to set sfx volume at %d", volume);
  819.     }
  820.  
  821.     snd_SfxVolume = volume;
  822. }
  823.  
  824. //
  825. // Starts some music with the music id found in sounds.h.
  826. //
  827.  
  828. void S_StartMusic(int m_id)
  829. {
  830.     S_ChangeMusic(m_id, false);
  831. }
  832.  
  833. void S_ChangeMusic(int musicnum, int looping)
  834. {
  835.     musicinfo_t *music = NULL;
  836.     char namebuf[9];
  837.     void *handle;
  838.  
  839.     // The Doom IWAD file has two versions of the intro music: d_intro
  840.     // and d_introa.  The latter is used for OPL playback.
  841.  
  842.     if (musicnum == mus_intro && (snd_musicdevice == SNDDEVICE_ADLIB
  843.                                || snd_musicdevice == SNDDEVICE_SB))
  844.     {
  845.         musicnum = mus_introa;
  846.     }
  847.  
  848.     if (musicnum <= mus_None || musicnum >= NUMMUSIC)
  849.     {
  850.         I_Error("Bad music number %d", musicnum);
  851.     }
  852.     else
  853.     {
  854.         music = &S_music[musicnum];
  855.     }
  856.  
  857.     if (mus_playing == music)
  858.     {
  859.         return;
  860.     }
  861.  
  862.     // shutdown old music
  863.     S_StopMusic();
  864.  
  865.     // get lumpnum if neccessary
  866.     if (!music->lumpnum)
  867.     {
  868.         sprintf(namebuf, "d_%s", DEH_String(music->name));
  869.         music->lumpnum = W_GetNumForName(namebuf);
  870.     }
  871.  
  872.     if (music_module != NULL)
  873.     {
  874.         // Load & register it
  875.  
  876.         music->data = W_CacheLumpNum(music->lumpnum, PU_STATIC);
  877.         handle = music_module->RegisterSong(music->data,
  878.                                             W_LumpLength(music->lumpnum));
  879.         music->handle = handle;
  880.  
  881.         // Play it
  882.  
  883.         music_module->PlaySong(handle, looping);
  884.     }
  885.  
  886.     mus_playing = music;
  887. }
  888.  
  889. boolean S_MusicPlaying(void)
  890. {
  891.     if (music_module != NULL)
  892.     {
  893.         return music_module->MusicIsPlaying();
  894.     }
  895.     else
  896.     {
  897.         return false;
  898.     }
  899. }
  900.  
  901. void S_StopMusic(void)
  902. {
  903.     if (mus_playing)
  904.     {
  905.         if (music_module != NULL)
  906.         {
  907.             if (mus_paused)
  908.             {
  909.                 music_module->ResumeMusic();
  910.             }
  911.  
  912.             music_module->StopSong();
  913.             music_module->UnRegisterSong(mus_playing->handle);
  914.             W_ReleaseLumpNum(mus_playing->lumpnum);
  915.            
  916.             mus_playing->data = NULL;
  917.         }
  918.  
  919.         mus_playing = NULL;
  920.     }
  921. }
clone this paste RAW Paste Data