Subversion Repositories Kolibri OS

Rev

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:
  20. //      System interface for sound.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <stdarg.h>
  30.  
  31. #include <math.h>
  32.  
  33. #include <time.h>
  34. #include <sys/types.h>
  35.  
  36. //#ifndef LINUX
  37. //#include <sys/filio.h>
  38. //#endif
  39.  
  40. #include <fcntl.h>
  41. #include <io.h>
  42. //#include <unistd.h>
  43. //#include <sys/ioctl.h>
  44.  
  45. // Linux voxware output.
  46. //#include <linux/soundcard.h>
  47.  
  48. // Timer stuff. Experimental.
  49. #include <time.h>
  50. #include <signal.h>
  51.  
  52. #include "z_zone.h"
  53.  
  54. #include "i_system.h"
  55. #include "i_sound.h"
  56. #include "m_argv.h"
  57. #include "m_misc.h"
  58. #include "w_wad.h"
  59.  
  60. #include "doomdef.h"
  61.  
  62. typedef unsigned int DWORD;
  63.  
  64. ////////////////////////////////////////////////////////////////////////////
  65. // WinDoom - DirectSound
  66. ////////////////////////////////////////////////////////////////////////////
  67.  
  68. #define NUM_SOUND_FX 128
  69. #define SB_SIZE      20480
  70.  
  71. void CreateSoundBuffer(int Channel, int length, unsigned char *data);
  72. void I_PlaySoundEffect(int sfxid, int Channel, int volume, int pan);
  73.  
  74. #define NUM_DSBUFFERS 256
  75.  
  76. typedef enum { dsb_perm, dsb_temp } dsb_type;
  77.  
  78. typedef struct
  79.    {
  80.     void   *origin;
  81.     int     dsb_type;
  82.     int     sfxid;
  83.    }DSBControl_t;
  84.  
  85. DSBControl_t DSBControl[NUM_DSBUFFERS];
  86.  
  87. extern int swap_stereo;
  88.  
  89. ////////////////////////////////////////////////////////////////////////////
  90.  
  91. // UNIX hack, to be removed.
  92. #ifdef SNDSERV
  93. // Separate sound server process.
  94. FILE*   sndserver=0;
  95. char*   sndserver_filename = "./sndserver ";
  96. #elif SNDINTR
  97.  
  98. // Update all 30 millisecs, approx. 30fps synchronized.
  99. // Linux resolution is allegedly 10 millisecs,
  100. //  scale is microseconds.
  101. #define SOUND_INTERVAL     500
  102.  
  103. // Get the interrupt. Set duration in millisecs.
  104. int I_SoundSetTimer( int duration_of_tick );
  105. void I_SoundDelTimer( void );
  106. #else
  107. // None?
  108. #endif
  109.  
  110.  
  111. // A quick hack to establish a protocol between
  112. // synchronous mix buffer updates and asynchronous
  113. // audio writes. Probably redundant with gametic.
  114. static int flag = 0;
  115.  
  116. // The number of internal mixing channels,
  117. //  the samples calculated for each mixing step,
  118. //  the size of the 16bit, 2 hardware channel (stereo)
  119. //  mixing buffer, and the samplerate of the raw data.
  120.  
  121.  
  122. // Needed for calling the actual sound output.
  123. #define SAMPLECOUNT             512
  124. #define NUM_CHANNELS            16
  125. // It is 2 for 16bit, and 2 for two channels.
  126. #define BUFMUL                  4
  127. #define MIXBUFFERSIZE           (SAMPLECOUNT*BUFMUL)
  128.  
  129. #define SAMPLERATE              11025   // Hz
  130. #define SAMPLESIZE              2       // 16bit
  131.  
  132. // The actual lengths of all sound effects.
  133. int             lengths[NUMSFX];
  134.  
  135. // The actual output device.
  136. //int   audio_fd;
  137.  
  138. // The global mixing buffer.
  139. // Basically, samples from all active internal channels
  140. //  are modifed and added, and stored in the buffer
  141. //  that is submitted to the audio device.
  142. signed short    mixbuffer[MIXBUFFERSIZE];
  143.  
  144.  
  145. // The channel step amount...
  146. unsigned int    channelstep[NUM_CHANNELS];
  147. // ... and a 0.16 bit remainder of last step.
  148. unsigned int    channelstepremainder[NUM_CHANNELS];
  149.  
  150.  
  151. // The channel data pointers, start and end.
  152. unsigned char*  channels[NUM_CHANNELS];
  153. unsigned char*  channelsend[NUM_CHANNELS];
  154.  
  155.  
  156. // Time/gametic that the channel started playing,
  157. //  used to determine oldest, which automatically
  158. //  has lowest priority.
  159. // In case number of active sounds exceeds
  160. //  available channels.
  161. int             channelstart[NUM_CHANNELS];
  162.  
  163. // The sound in channel handles,
  164. //  determined on registration,
  165. //  might be used to unregister/stop/modify,
  166. //  currently unused.
  167. int             channelhandles[NUM_CHANNELS];
  168.  
  169. // SFX id of the playing sound effect.
  170. // Used to catch duplicates (like chainsaw).
  171. int             channelids[NUM_DSBUFFERS];
  172.  
  173. // Pitch to stepping lookup, unused.
  174. int             steptable[256];
  175.  
  176. // Volume lookups.
  177. int             vol_lookup[128*256];
  178.  
  179. // Hardware left and right channel volume lookup.
  180. int*            channelleftvol_lookup[NUM_CHANNELS];
  181. int*            channelrightvol_lookup[NUM_CHANNELS];
  182.  
  183.  
  184. //
  185. // Safe ioctl, convenience.
  186. //
  187. void
  188. myioctl
  189. ( int   fd,
  190.   int   command,
  191.   int*  arg )
  192. {  
  193. // FIXME
  194. /*
  195.     int         rc;
  196.     extern int  errno;
  197.    
  198.     rc = ioctl(fd, command, arg);  
  199.     if (rc < 0)
  200.     {
  201.         fprintf(stderr, "ioctl(dsp,%d,arg) failed\n", command);
  202.         fprintf(stderr, "errno=%d\n", errno);
  203.         exit(-1);
  204.     }
  205. */
  206. }
  207.  
  208.  
  209.  
  210.  
  211.  
  212. //
  213. // This function loads the sound data from the WAD lump,
  214. //  for single sound.
  215. //
  216. void *getsfx( char *sfxname, int *len )
  217.    {
  218.     unsigned char*      sfx;
  219.     unsigned char*      paddedsfx;
  220.     int                 i;
  221.     int                 size;
  222.     int                 paddedsize;
  223.     char                name[20];
  224.     int                 sfxlump;
  225.  
  226.    
  227.     sprintf(name, "ds%s", sfxname);
  228.  
  229.     // Get the sound data from the WAD, allocate lump
  230.     //  in zone memory.
  231.     // Now, there is a severe problem with the
  232.     //  sound handling, in it is not (yet/anymore)
  233.     //  gamemode aware. That means, sounds from
  234.     //  DOOM II will be requested even with DOOM
  235.     //  shareware.
  236.     // The sound list is wired into sounds.c,
  237.     //  which sets the external variable.
  238.     // I do not do runtime patches to that
  239.     //  variable. Instead, we will use a
  240.     //  default sound for replacement.
  241.  
  242.     if ( W_CheckNumForName(name) == -1 )
  243.       sfxlump = W_GetNumForName("dspistol");
  244.     else
  245.       sfxlump = W_GetNumForName(name);
  246.    
  247.     size = W_LumpLength( sfxlump );
  248.  
  249.         // sprintf(MsgText, "Getting sound effect : %s - %d\n", name, size);
  250.     // WriteDebug(MsgText);
  251.  
  252.     // Debug.
  253.     // fprintf( stderr, "." );
  254.     //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
  255.     //       sfxname, sfxlump, size );
  256.     //fflush( stderr );
  257.    
  258.     sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
  259.  
  260.     // Pads the sound effect out to the mixing buffer size.
  261.     // The original realloc would interfere with zone memory.
  262.     paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
  263.  
  264.     // Allocate from zone memory.
  265.     paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
  266.     // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
  267.     // This should interfere with zone memory handling,
  268.     //  which does not kick in in the soundserver.
  269.  
  270.     // Now copy and pad.
  271.     memcpy(  paddedsfx, sfx, size );
  272.     for (i = size; i < paddedsize+8; i++)
  273.         paddedsfx[i] = 128;
  274.  
  275.     // Remove the cached lump.
  276.     Z_Free( sfx );
  277.    
  278.     // Preserve padded length.
  279.     *len = paddedsize;
  280.  
  281.     // Return allocated padded data.
  282.     return (void *) (paddedsfx + 8);
  283.    }
  284.  
  285.  
  286.  
  287. /*
  288.  
  289. //
  290. // This function adds a sound to the
  291. //  list of currently active sounds,
  292. //  which is maintained as a given number
  293. //  (eight, usually) of internal channels.
  294. // Returns a handle.
  295. //
  296. int addsfx( int sfxid, int volume, int step, int seperation )
  297.    {
  298.     static unsigned short       handlenums = 0;
  299.  
  300.     int         i;
  301.     int         rc = -1;
  302.    
  303.     int         oldest = gametic;
  304.     int         oldestnum = 0;
  305.     int         slot;
  306.  
  307.     int         rightvol;
  308.     int         leftvol;
  309.  
  310.     int     iVolume, iPan;
  311.  
  312.     // Chainsaw troubles.
  313.     // Play these sound effects only one at a time.
  314.     if ( sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful ||
  315.          sfxid == sfx_sawhit || sfxid == sfx_stnmov || sfxid == sfx_pistol )
  316.        {
  317.         // Loop all channels, check.
  318.         for (i = 0; i < NUM_CHANNELS; i++)
  319.            {
  320.             // Active, and using the same SFX?
  321.             if ( (channels[i]) && (channelids[i] == sfxid) )
  322.                {
  323.                 // Reset.
  324.                 channels[i] = 0;
  325.                 // We are sure that iff, there will only be one.
  326.                 break;
  327.                }
  328.            }
  329.        }
  330.  
  331.     // Loop all channels to find oldest SFX.
  332.     for (i = 0; (i<NUM_CHANNELS) && (channels[i]); i++)
  333.         {
  334.          if (channelstart[i] < oldest)
  335.             {
  336.              oldestnum = i;
  337.              oldest = channelstart[i];
  338.             }
  339.         }
  340.  
  341.     // Tales from the cryptic.
  342.     // If we found a channel, fine.
  343.     // If not, we simply overwrite the first one, 0.
  344.     // Probably only happens at startup.
  345.     if (i == NUM_CHANNELS)
  346.         slot = oldestnum;
  347.     else
  348.         slot = i;
  349.  
  350.     // Okay, in the less recent channel,
  351.     //  we will handle the new SFX.
  352.     // Set pointer to raw data.
  353.     channels[slot] = (unsigned char *) S_sfx[sfxid].data;
  354.     // Set pointer to end of raw data.
  355.     channelsend[slot] = channels[slot] + lengths[sfxid];
  356.  
  357.     // Reset current handle number, limited to 0..100.
  358.     if (!handlenums)
  359.         handlenums = 100;
  360.  
  361.     // Assign current handle number.
  362.     // Preserved so sounds could be stopped (unused).
  363.     channelhandles[slot] = rc = handlenums++;
  364.  
  365.     // Set stepping???
  366.     // Kinda getting the impression this is never used.
  367.     channelstep[slot] = step;
  368.     // ???
  369.     channelstepremainder[slot] = 0;
  370.     // Should be gametic, I presume.
  371.     channelstart[slot] = gametic;
  372.  
  373.     iVolume = 0-(128*(15-volume));
  374.     if (iVolume < -10000)
  375.        iVolume == -10000;
  376.     iPan = (seperation-128)*20;
  377.     if (iPan < -10000)
  378.        iPan = -10000;
  379.     if (iPan > 10000)
  380.        iPan = 10000;
  381.  
  382.     if (swap_stereo == TRUE)
  383.        iPan *= -1;
  384.  
  385.     // Separation, that is, orientation/stereo.
  386.     //  range is: 1 - 256
  387.  
  388.     seperation += 1;
  389.  
  390.     // Per left/right channel.
  391.     //  x^2 seperation,
  392.     //  adjust volume properly.
  393.     leftvol = volume - ((volume*seperation*seperation) >> 16); //(256*256);
  394.     seperation = seperation - 257;
  395.     rightvol = volume - ((volume*seperation*seperation) >> 16);
  396.  
  397.     // Sanity check, clamp volume.
  398.     if (rightvol < 0 || rightvol > 127)
  399.         I_Error("rightvol out of bounds");
  400.    
  401.     if (leftvol < 0 || leftvol > 127)
  402.         I_Error("leftvol out of bounds");
  403.    
  404.     // Get the proper lookup table piece
  405.     //  for this volume level???
  406.     channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
  407.     channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
  408.  
  409.     // Preserve sound SFX id,
  410.     //  e.g. for avoiding duplicates of chainsaw.
  411.     channelids[slot] = sfxid;
  412.  
  413.     I_PlaySoundEffect(sfxid, iVolume, iPan);
  414.  
  415.     // You tell me.
  416.     //return rc;
  417.     return sfxid;
  418.    }
  419.  
  420. */
  421. //
  422. // This function adds a sound to the
  423. //  list of currently active sounds,
  424. //  which is maintained as a given number
  425. //  (eight, usually) of internal channels.
  426. // Returns a handle.
  427. //
  428.  
  429. //
  430. // SFX API
  431. // Note: this was called by S_Init.
  432. // However, whatever they did in the
  433. // old DPMS based DOS version, this
  434. // were simply dummies in the Linux
  435. // version.
  436. // See soundserver initdata().
  437. //
  438. void I_SetChannels()
  439. {
  440.   // Init internal lookups (raw data, mixing buffer, channels).
  441.   // This function sets up internal lookups used during
  442.   //  the mixing process.
  443.   int           i;
  444.   int           j;
  445.    
  446.   int*  steptablemid = steptable + 128;
  447.  
  448.   // Okay, reset internal mixing channels to zero.
  449.   for (i=0; i<NUM_CHANNELS; i++)
  450.   {
  451.     channels[i] = 0;
  452.   }
  453.  
  454.   // This table provides step widths for pitch parameters.
  455.   // I fail to see that this is currently used.
  456.   for (i=-128 ; i<128 ; i++)
  457.     steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
  458.  
  459.  
  460.   // Generates volume lookup tables
  461.   //  which also turn the unsigned samples
  462.   //  into signed samples.
  463.   for (i=0 ; i<128 ; i++)
  464.     for (j=0 ; j<256 ; j++)
  465.       vol_lookup[i*256+j] = (i*(j-128)*256)/127;
  466. }      
  467.  
  468.  
  469. void I_SetSfxVolume(int volume)
  470. {
  471.   // Identical to DOS.
  472.   // Basically, this should propagate
  473.   //  the menu/config file setting
  474.   //  to the state variable used in
  475.   //  the mixing.
  476.   snd_SfxVolume = volume;
  477. }
  478.  
  479. // MUSIC API - dummy. Some code from DOS version.
  480. void I_SetMusicVolume(int volume)
  481. {
  482.   // Internal state variable.
  483.   snd_MusicVolume = volume;
  484.   // Now set volume on output device.
  485.   // Whatever( snd_MusciVolume );
  486. }
  487.  
  488.  
  489. //
  490. // Retrieve the raw data lump index
  491. //  for a given SFX name.
  492. //
  493. int I_GetSfxLumpNum(sfxinfo_t* sfx)
  494. {
  495.     char namebuf[9];
  496.     sprintf(namebuf, "ds%s", sfx->name);
  497.     return W_GetNumForName(namebuf);
  498. }
  499.  
  500. //
  501. // Starting a sound means adding it
  502. //  to the current list of active sounds
  503. //  in the internal channels.
  504. // As the SFX info struct contains
  505. //  e.g. a pointer to the raw data,
  506. //  it is ignored.
  507. // As our sound handling does not handle
  508. //  priority, it is ignored.
  509. // Pitching (that is, increased speed of playback)
  510. //  is set, but currently not used by mixing.
  511. //
  512. int I_StartSound( int id, int vol, int sep, int pitch, int priority, void *origin )
  513.    {
  514.     // UNUSED
  515.     priority = 0;
  516.  
  517.     // Debug.
  518. //    sprintf(MsgText, "starting sound %d", id );
  519. //    WriteDebug(MsgText);
  520.    
  521.     // Returns a handle (not used).
  522.     id = addsfx( id, vol, steptable[pitch], sep, origin );
  523.  
  524. //    sprintf(MsgText, "/handle is %d\n", id );
  525. //    WriteDebug(MsgText);
  526.  
  527.     return id;
  528.    }
  529.  
  530. //
  531. // This function loops all active (internal) sound
  532. //  channels, retrieves a given number of samples
  533. //  from the raw sound data, modifies it according
  534. //  to the current (internal) channel parameters,
  535. //  mixes the per channel samples into the global
  536. //  mixbuffer, clamping it to the allowed range,
  537. //  and sets up everything for transferring the
  538. //  contents of the mixbuffer to the (two)
  539. //  hardware channels (left and right, that is).
  540. //
  541. // This function currently supports only 16bit.
  542. //
  543. void I_UpdateSound( void )
  544.    {
  545. #ifdef SNDINTR
  546.   // Debug. Count buffer misses with interrupt.
  547.   static int misses = 0;
  548. #endif
  549.  
  550.  
  551.     // Mix current sound data.
  552.     // Data, from raw sound, for right and left.
  553.     register unsigned int       sample;
  554.     register int                dl;
  555.     register int                dr;
  556.  
  557.     // Pointers in global mixbuffer, left, right, end.
  558.     signed short*               leftout;
  559.     signed short*               rightout;
  560.     signed short*               leftend;
  561.     // Step in mixbuffer, left and right, thus two.
  562.     int                         step;
  563.  
  564.     // Mixing channel index.
  565.     int                         chan;
  566.    
  567.     // Left and right channel
  568.     //  are in global mixbuffer, alternating.
  569.     leftout = mixbuffer;
  570.     rightout = mixbuffer+1;
  571.     step = 2;
  572.  
  573.     // Determine end, for left channel only
  574.     //  (right channel is implicit).
  575.     leftend = mixbuffer + SAMPLECOUNT*step;
  576.  
  577.     // Mix sounds into the mixing buffer.
  578.     // Loop over step*SAMPLECOUNT,
  579.     //  that is 512 values for two channels.
  580.     while (leftout != leftend)
  581.     {
  582.         // Reset left/right value.
  583.         dl = 0;
  584.         dr = 0;
  585.  
  586.         // Love thy L2 chache - made this a loop.
  587.         // Now more channels could be set at compile time
  588.         //  as well. Thus loop those  channels.
  589.         for ( chan = 0; chan < NUM_CHANNELS; chan++ )
  590.         {
  591.             // Check channel, if active.
  592.             if (channels[ chan ])
  593.             {
  594.                 // Get the raw data from the channel.
  595.                 sample = *channels[ chan ];
  596.                 // Add left and right part
  597.                 //  for this channel (sound)
  598.                 //  to the current data.
  599.                 // Adjust volume accordingly.
  600.                 dl += channelleftvol_lookup[ chan ][sample];
  601.                 dr += channelrightvol_lookup[ chan ][sample];
  602.                 // Increment index ???
  603.                 channelstepremainder[ chan ] += channelstep[ chan ];
  604.                 // MSB is next sample???
  605.                 channels[ chan ] += channelstepremainder[ chan ] >> 16;
  606.                 // Limit to LSB???
  607.                 channelstepremainder[ chan ] &= 65536-1;
  608.  
  609.                 // Check whether we are done.
  610.                 if (channels[ chan ] >= channelsend[ chan ])
  611.                     channels[ chan ] = 0;
  612.             }
  613.         }
  614.        
  615.         // Clamp to range. Left hardware channel.
  616.         // Has been char instead of short.
  617.         // if (dl > 127) *leftout = 127;
  618.         // else if (dl < -128) *leftout = -128;
  619.         // else *leftout = dl;
  620.  
  621.         if (dl > 0x7fff)
  622.             *leftout = 0x7fff;
  623.         else if (dl < -0x8000)
  624.             *leftout = -0x8000;
  625.         else
  626.             *leftout = dl;
  627.  
  628.         // Same for right hardware channel.
  629.         if (dr > 0x7fff)
  630.             *rightout = 0x7fff;
  631.         else if (dr < -0x8000)
  632.             *rightout = -0x8000;
  633.         else
  634.             *rightout = dr;
  635.  
  636.         // Increment current pointers in mixbuffer.
  637.         leftout += step;
  638.         rightout += step;
  639.     }
  640.  
  641. #ifdef SNDINTR
  642.     // Debug check.
  643.     if ( flag )
  644.     {
  645.       misses += flag;
  646.       flag = 0;
  647.     }
  648.    
  649.     if ( misses > 10 )
  650.     {
  651.       fprintf( stderr, "I_SoundUpdate: missed 10 buffer writes\n");
  652.       misses = 0;
  653.     }
  654.    
  655.     // Increment flag for update.
  656.     flag++;
  657. #endif
  658. }
  659.  
  660.  
  661. //
  662. // This would be used to write out the mixbuffer
  663. //  during each game loop update.
  664. // Updates sound buffer and audio device at runtime.
  665. // It is called during Timer interrupt with SNDINTR.
  666. // Mixing now done synchronous, and
  667. //  only output be done asynchronous?
  668. //
  669. //void
  670. //I_SubmitSound(void)
  671. //{
  672.   // Write it to DSP device.
  673. //  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
  674. //}
  675.  
  676.  
  677.  
  678.  
  679.  
  680. void I_ShutdownSound(void)
  681. {    
  682. //#ifdef SNDSERV
  683. //  if (sndserver)
  684. //  {
  685. //    // Send a "quit" command.
  686. //    fprintf(sndserver, "q\n");
  687. //    fflush(sndserver);
  688. //  }
  689. //#else
  690.   // Wait till all pending sounds are finished.
  691.   int done = 0;
  692.   //int i;
  693.  
  694.  
  695.   // FIXME (below).
  696.   //fprintf( stderr, "I_ShutdownSound: NOT finishing pending sounds\n");
  697.   //fflush( stderr );
  698.  
  699.   //while ( !done )
  700.   //{
  701.   //  for( i=0 ; i<8 && !channels[i] ; i++);
  702.    
  703.     // FIXME. No proper channel output.
  704.     //if (i==8)
  705.     done=1;
  706.   //}
  707. //#ifdef SNDINTR
  708. //  I_SoundDelTimer();
  709. //#endif
  710.  
  711.   // Cleaning up -releasing the DSP device.
  712. //  close( audio_fd );
  713. //#endif
  714.  
  715.   // Done.
  716.   return;
  717. }
  718.  
  719. void I_InitSound()
  720. {
  721.         int i;
  722.  
  723.     I_CreateSound();  
  724.  
  725.         for (i = 1; i < NUMSFX; i++)
  726.         {
  727.                 // Alias? Example is the chaingun sound linked to pistol.
  728.                 if (!S_sfx[i].link)
  729.                 {
  730.                         // Load data from WAD file.
  731.                         S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
  732.                 }
  733.                 else
  734.                 {
  735.                         // Previously loaded already?
  736.                         S_sfx[i].data = S_sfx[i].link->data;
  737.                         lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
  738.                 }
  739.                 //having to crack here cuz crashing out at sound file 86 chgun
  740.                 // incidentally the only 'linked' sound in the whole pile
  741.                 // 10.10.98 dlw  tested good.
  742.                 if(i==86)
  743.                         CreateSoundBuffer(i, lengths[1], S_sfx[1].data);
  744.                 else
  745.                         CreateSoundBuffer(i, lengths[i], S_sfx[i].data);
  746.  
  747.  
  748.                 DSBControl[i].origin = NULL;
  749.                 DSBControl[i].sfxid = i;
  750.                 DSBControl[i].dsb_type = dsb_perm;
  751.         }
  752.         for (; i < NUM_DSBUFFERS; i++)
  753.         {
  754.                 DSBControl[i].origin = NULL;
  755.                 DSBControl[i].sfxid = -1;
  756.                 DSBControl[i].dsb_type = dsb_temp;
  757.         }
  758.  
  759. }
  760.  
  761.  
  762.  
  763.  
  764. //
  765. // MUSIC API.
  766. // Still no music done.
  767. // Remains. Dummies.
  768. //
  769. void I_InitMusic(void)          { }
  770.  
  771. static int      looping=0;
  772. static int      musicdies=-1;
  773.  
  774.  
  775.  
  776. // 10.12.98 dlw - cleanup the music files
  777. void I_ShutdownMusic(void)
  778. {
  779.         int trasherror;  //self explained
  780.        
  781.         trasherror=unlink("doomsong.mus");
  782.         trasherror=unlink("doomsong.mid");
  783.         printf("I_ShutdownMusic...\n");
  784. }
  785.  
  786.  
  787.  
  788.  
  789. void I_PlaySong(int handle, int looping)
  790. {
  791.   // UNUSED.
  792.   handle = looping = 0;
  793.   musicdies = gametic + TICRATE*30;
  794. }
  795.  
  796. void I_PauseSong (int handle)
  797. {
  798.   // UNUSED.
  799.   handle = 0;
  800. }
  801.  
  802. void I_ResumeSong (int handle)
  803. {
  804.   // UNUSED.
  805.   handle = 0;
  806. }
  807.  
  808. void I_StopSong(int handle)
  809. {
  810.   // UNUSED.
  811.   handle = 0;
  812.  
  813.   looping = 0;
  814.   musicdies = 0;
  815. }
  816.  
  817. void I_UnRegisterSong(int handle)
  818. {
  819.   // UNUSED.
  820.   handle = 0;
  821. }
  822.  
  823. int I_RegisterSong(void* data)
  824. {
  825.   // UNUSED.
  826.   data = NULL;
  827.  
  828.   return 1;
  829. }
  830.  
  831. // Is the song playing?
  832. int I_QrySongPlaying(int handle)
  833. {
  834.   // UNUSED.
  835.   handle = 0;
  836.   return looping || musicdies > gametic;
  837. }
  838.  
  839.  
  840. //
  841. // Experimental stuff.
  842. // A Linux timer interrupt, for asynchronous
  843. //  sound output.
  844. // I ripped this out of the Timer class in
  845. //  our Difference Engine, including a few
  846. //  SUN remains...
  847. //  
  848. #ifdef sun
  849.     typedef     sigset_t        tSigSet;
  850. #else    
  851.     typedef     int             tSigSet;
  852. #endif
  853.  
  854.  
  855. // We might use SIGVTALRM and ITIMER_VIRTUAL, if the process
  856. //  time independend timer happens to get lost due to heavy load.
  857. // SIGALRM and ITIMER_REAL doesn't really work well.
  858. // There are issues with profiling as well.
  859.  
  860. // FIXME
  861. #define ITIMER_REAL 0
  862. static int /*__itimer_which*/  itimer = ITIMER_REAL;
  863.  
  864. // FIXME
  865. #define SIGALRM 0
  866. static int sig = SIGALRM;
  867.  
  868. // Interrupt handler.
  869. void I_HandleSoundTimer( int ignore )
  870. {
  871.   // Debug.
  872.   //fprintf( stderr, "%c", '+' ); fflush( stderr );
  873.  
  874.   // Feed sound device if necesary.
  875.   if ( flag )
  876.   {
  877.     // See I_SubmitSound().
  878.     // Write it to DSP device.
  879.     //write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
  880.  
  881.     // Reset flag counter.
  882.     flag = 0;
  883.   }
  884.   else
  885.     return;
  886.  
  887.   // UNUSED, but required.
  888.   ignore = 0;
  889.   return;
  890. }
  891.  
  892. void I_SoundDelTimer()
  893. {
  894.   // Debug.
  895.   //if ( I_SoundSetTimer( 0 ) == -1)
  896.   //  fprintf( stderr, "I_SoundDelTimer: failed to remove interrupt. Doh!\n");
  897. }
  898.  
  899.  
  900.