]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Lots of minor fixes and improvements to the sound engine, plus a few more important...
authormolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 13 Oct 2004 07:03:57 +0000 (07:03 +0000)
committermolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 13 Oct 2004 07:03:57 +0000 (07:03 +0000)
- moved the internal structures and API into a separate file (snd_main.h)
- added a lock mecanism on SFXs to free them as soon as they're no longer used
- simplified the sound API
- minor fixes and comment changes here and there
- independent sound volume for fake CD tracks
- updated MSVC and Dev-C++ project files accordingly
- removed unused functions
- added a SFX flag to make sure the engine complains at most one time for each missing sound file
- made the SFX list a linked list to remove the hardcoded limit for the number of SFX a client can handle
- changed the way ambient sounds are managed to be more consistent with the new API
- factorized some code
- removed the useless IN_Accumulate in the Win32 specific code
- removed the table for 8bit sound mixing (snd_scaletable)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4624 d7cf8633-e32d-0410-b094-e92efae38249

26 files changed:
cd_shared.c
cdaudio.h
cl_main.c
cl_parse.c
cl_screen.c
darkplaces.dev
darkplaces.dsp
dpvsimpledecode.c
menu.c
prvm_cmds.c
quakedef.h
snd_alsa.c
snd_bsd.c
snd_dma.c
snd_main.h [new file with mode: 0644]
snd_mem.c
snd_mix.c
snd_null.c
snd_ogg.c
snd_oss.c
snd_sdl.c
snd_wav.c
snd_win.c
sound.h
todo
vid_wgl.c

index 998f76f4667de97fc4abfd954693c63a3a80450e..c486fe562098e22c75f1dc1c279843c1d4898e19 100644 (file)
@@ -110,14 +110,15 @@ void CDAudio_Play (qbyte track, qboolean looping)
        CDAudio_Stop ();
 
        // Try playing a fake track (sound file) first
-       sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, true);
+       sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, true, false);
        if (sfx != NULL)
        {
                faketrack = S_StartSound (-1, 0, sfx, vec3_origin, cdvolume, 0);
                if (faketrack != -1)
                {
                        if (looping)
-                               S_LoopChannel (faketrack, true);
+                               S_SetChannelFlag (faketrack, CHANNELFLAG_FORCELOOP, true);
+                       S_SetChannelFlag (faketrack, CHANNELFLAG_FULLVOLUME, true);
                        Con_DPrintf ("Fake CD track %u playing...\n", track);
                }
        }
@@ -177,7 +178,7 @@ void CDAudio_Pause (void)
                return;
 
        if (faketrack != -1)
-               S_PauseChannel (faketrack, true);
+               S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, true);
        else if (CDAudio_SysPause() == -1)
                return;
 
@@ -192,7 +193,7 @@ void CDAudio_Resume (void)
                return;
 
        if (faketrack != -1)
-               S_PauseChannel (faketrack, false);
+               S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, false);
        else if (CDAudio_SysResume() == -1)
                return;
        cdPlaying = true;
index e58e766cb41e02c1f92995792c190ea4293e6030..eefb0c985dc414d1ffcd4faf7e870a7fb8a6be57 100644 (file)
--- a/cdaudio.h
+++ b/cdaudio.h
@@ -23,6 +23,8 @@ extern qboolean cdPlaying;
 extern qboolean cdPlayLooping;
 extern qbyte cdPlayTrack;
 
+extern cvar_t cdaudioinitialized;
+
 int CDAudio_Init(void);
 void CDAudio_Open(void);
 void CDAudio_Close(void);
index 1fef3ceab0b38eac23c5aa85fe9dd0147d52c38c..6151d0199e74e6aa4d1b7ffac6226f2c731ccc22 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -170,7 +170,7 @@ void CL_Disconnect(void)
        Con_DPrintf("CL_Disconnect\n");
 
 // stop sounds (especially looping!)
-       S_StopAllSounds (true);
+       S_StopAllSounds ();
 
        // clear contents blends
        cl.cshifts[0].percent = 0;
index d3f52ac21ae8dcc4e122376e7f944e977272fb63..5d3b55e0cd51ce4ce2f457790c2a5b49915adf86 100644 (file)
@@ -152,7 +152,7 @@ void CL_ParseStartSoundPacket(int largesoundindex)
 
        MSG_ReadVector(pos, cl.protocol);
 
-       S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
+       S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0f, attenuation);
 }
 
 /*
@@ -407,13 +407,7 @@ void CL_ParseServerInfo (void)
        Mod_PurgeUnused();
 
        // do the same for sounds
-       S_ClearUsed();
-       for (i = 1;i < numsounds;i++)
-       {
-               CL_KeepaliveMessage();
-               S_TouchSound(parse_sound_precache[i], true);
-       }
-       S_PurgeUnused();
+       S_ServerSounds (parse_sound_precache, numsounds);
 
        // now we try to load everything that is new
 
@@ -435,7 +429,9 @@ void CL_ParseServerInfo (void)
        for (i=1 ; i<numsounds ; i++)
        {
                CL_KeepaliveMessage();
-               cl.sound_precache[i] = S_PrecacheSound(parse_sound_precache[i], true, true);
+
+               // Don't lock the sfx here, S_ServerSounds already did that 
+               cl.sound_precache[i] = S_PrecacheSound(parse_sound_precache[i], true, true, false);
        }
 
        // local state
@@ -794,7 +790,7 @@ void CL_ParseStaticSound (int large)
        vol = MSG_ReadByte ();
        atten = MSG_ReadByte ();
 
-       S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
+       S_StaticSound (cl.sound_precache[sound_num], org, vol/255.0f, atten);
 }
 
 void CL_ParseEffect (void)
@@ -845,13 +841,13 @@ CL_ParseTEnt
 */
 void CL_InitTEnts (void)
 {
-       cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false, true);
-       cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false, true);
-       cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false, true);
-       cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false, true);
-       cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false, true);
-       cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false, true);
-       cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false, true);
+       cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false, true, true);
+       cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false, true, true);
+       cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false, true, true);
+       cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false, true, true);
+       cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false, true, true);
+       cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false, true, true);
+       cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false, true, true);
 }
 
 void CL_ParseBeam (model_t *m, int lightning)
@@ -1551,15 +1547,10 @@ void CL_ParseServerMessage(void)
                case svc_setpause:
                        cl.paused = MSG_ReadByte ();
                        if (cl.paused)
-                       {
                                CDAudio_Pause ();
-                               S_PauseGameSounds ();
-                       }
                        else
-                       {
                                CDAudio_Resume ();
-                               S_ResumeGameSounds ();
-                       }
+                       S_PauseGameSounds (cl.paused);
                        break;
 
                case svc_signonnum:
index 7e191f524158332a6591cacfc3731e9db2530e69..13d8a52c86ee07b94339fd1a6cb2c6483279f7dd 100644 (file)
@@ -314,7 +314,7 @@ void SCR_BeginLoadingPlaque (void)
        if (scr_drawloading)
                return;
 
-       S_StopAllSounds (true);
+       S_StopAllSounds ();
 
        scr_drawloading = true;
        CL_UpdateScreen ();
index ee0acb1b7d2baed61e615b727252521e7722eb75..5d51b189e1b053126bb070b2edbf1f25d631ba7a 100644 (file)
@@ -1,7 +1,7 @@
 [Project]
 FileName=darkplaces.dev
 Name=DarkPlaces
-UnitCount=160
+UnitCount=161
 Type=0
 Ver=1
 ObjFiles=
@@ -1647,3 +1647,13 @@ ProductName=DarkPlaces
 ProductVersion=
 AutoIncBuildNr=0
 
+[Unit161]
+FileName=snd_main.h
+CompileCpp=0
+Folder=Header Files
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
index 5780d4d224bc9849096f21aa91e1ccc739b5b75f..7dd00d4d5f5ced421abc2b28822991f570cf2e77 100644 (file)
@@ -688,6 +688,10 @@ SOURCE=.\sound.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\snd_main.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\spritegn.h\r
 # End Source File\r
 # Begin Source File\r
index 9927a7606e06eab2a1c75c2a709d7f309bc5d613..f403401b27ffadbb621d1bc29ab8c10edf7e4bd0 100644 (file)
@@ -398,7 +398,7 @@ void *dpvsimpledecode_open(char *filename, char **errorstring)
 
                                                                        StripExtension(filename, wavename);
                                                                        strcat(wavename, ".wav");
-                                                                       sfx = S_PrecacheSound (wavename, false, false);
+                                                                       sfx = S_PrecacheSound (wavename, false, false, false);
                                                                        if (sfx != NULL)
                                                                                s->sndchan = S_StartSound (-1, 0, sfx, vec3_origin, 1.0f, 0);
                                                                        else
diff --git a/menu.c b/menu.c
index 735ec3c212fc56eb40613812add597ee374797c5..e99bf9ceb560e0e4fc4ef1502e38c0a09f725bc8 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1215,7 +1215,6 @@ void M_Menu_Options_f (void)
        m_entersound = true;
 }
 
-extern cvar_t snd_staticvolume;
 extern cvar_t slowmo;
 extern dllhandle_t jpeg_dll;
 extern cvar_t gl_texture_anisotropy;
index 0ab773f4a4538efd317c38e2ff49db72b749f7e9..6b390e7b59198a58c56122f9401a27f731668004 100644 (file)
@@ -624,14 +624,13 @@ void VM_localsound(void)
 
        s = PRVM_G_STRING(OFS_PARM0);
 
-       if(!S_GetCached(s, true))
+       if(!S_LocalSound(s, true))
        {
-               Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s);
+               Con_Printf("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME);
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }               
 
-       S_LocalSound(s, true);
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
@@ -1104,13 +1103,7 @@ void VM_precache_sound (void)
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
        VM_CheckEmptyString (s);
        
-       if(S_GetCached(s, true))
-       {
-               Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME);
-               return;
-       }
-       
-       if(!S_PrecacheSound(s,true, true))
+       if(!S_PrecacheSound(s,true, true, true))
                Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
 }
 
index 5165ef93c00fd32131afed6604d0c519b5291d35..48a28d3cebfbd4a24f3b5603ddbc8b1dd7ad1d71 100644 (file)
@@ -177,8 +177,6 @@ extern char *buildstring;
 // LordHavoc: increased name limit from 32 to 64 characters
 #define        MAX_SCOREBOARDNAME      64
 
-#define        SOUND_CHANNELS          8
-
 #include "zone.h"
 #include "fs.h"
 #include "common.h"
index d3d2d068bcab48c6bc9b5147ce851c63fed7dc6c..031185b6b14fd6ddc3f6d9fe58c9770f1f419837 100644 (file)
@@ -31,7 +31,6 @@
 #include "quakedef.h"
 
 static int                     snd_inited;
-static int                     snd_blocked = 0;
 static snd_pcm_uframes_t buffer_size;
 
 static const char  *pcmname = NULL;
@@ -307,9 +306,6 @@ void SNDDMA_Submit (void)
        snd_pcm_uframes_t nframes;
        snd_pcm_uframes_t offset;
 
-       if (snd_blocked)
-               return;
-
        nframes = count / shm->format.channels;
 
        snd_pcm_avail_update (pcm);
index ce4c26d5241381dcd9794a268e312f94f2fb8df5..0ca754f1711f3a0b595ba0cc86dfcdd03a0d3c11 100644 (file)
--- a/snd_bsd.c
+++ b/snd_bsd.c
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include <unistd.h>
 
 #include "quakedef.h"
+#include "snd_main.h"
 
 
 static const int tryrates[] = {44100, 22050, 11025, 8000};
index a0ffbc863597ebfc240d3ce6d04934cfbc1b6127..73c5553415d5d32d876492edfbbe2c1a2ed1b4b6 100644 (file)
--- a/snd_dma.c
+++ b/snd_dma.c
@@ -21,6 +21,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
+#include "snd_main.h"
+#include "snd_ogg.h"
+
+// TODO: find a better solution instead of using a define
+#if defined( _WIN32 ) && !defined( USE_SDL )
+# define USE_DSOUND
+#endif
+
 #ifdef USE_DSOUND
 #include <windows.h>
 #include <dsound.h>
@@ -29,16 +37,12 @@ extern LPDIRECTSOUND pDS;
 extern LPDIRECTSOUNDBUFFER pDSBuf;
 #endif
 
-#include "snd_ogg.h"
-
 
 void S_Play(void);
 void S_PlayVol(void);
 void S_Play2(void);
 void S_SoundList(void);
 void S_Update_();
-void S_StopAllSounds(qboolean clear);
-void S_StopAllSoundsC(void);
 
 void S_ClearBuffer (void);
 
@@ -68,12 +72,8 @@ int soundtime;
 int paintedtime;
 
 
-//LordHavoc: increased the client sound limit from 512 to 4096 for the Nehahra movie
-#define MAX_SFX 4096
-sfx_t *known_sfx; // allocated [MAX_SFX]
-int num_sfx;
-
-sfx_t *ambient_sfx[NUM_AMBIENTS];
+// Linked list of known sfx
+sfx_t *known_sfx = NULL;
 
 int sound_started = 0;
 
@@ -99,12 +99,10 @@ cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0"};
 
 //
 // Fake dma is a synchronous faking of the DMA progress used for
-// isolating performance in the renderer.  The fakedma_updates is
-// number of times S_Update() is called per second.
+// isolating performance in the renderer.
 //
 
 qboolean fakedma = false;
-int fakedma_updates = 15;
 
 
 void S_SoundInfo_f(void)
@@ -124,19 +122,6 @@ void S_SoundInfo_f(void)
        Con_Printf("%5u total_channels\n", total_channels);
 }
 
-void S_UnloadSounds(void)
-{
-       int i;
-       for (i = 0;i < num_sfx;i++)
-               S_UnloadSound(known_sfx + i);
-}
-
-void S_LoadSounds(void)
-{
-       int i;
-       for (i = 0;i < num_sfx;i++)
-               S_LoadSound(known_sfx + i, false);
-}
 
 void S_Startup(void)
 {
@@ -146,8 +131,7 @@ void S_Startup(void)
        shm = &sn;
        memset((void *)shm, 0, sizeof(*shm));
 
-// create a piece of DMA memory
-
+       // create a piece of DMA memory
        if (fakedma)
        {
                shm->format.width = 2;
@@ -172,9 +156,7 @@ void S_Startup(void)
 
        Con_DPrintf("Sound sampling rate: %i\n", shm->format.speed);
 
-       //S_LoadSounds();
-
-       S_StopAllSounds(true);
+       S_StopAllSounds ();
 }
 
 void S_Shutdown(void)
@@ -182,8 +164,6 @@ void S_Shutdown(void)
        if (!sound_started)
                return;
 
-       //S_UnloadSounds();
-
        if (fakedma)
                Mem_Free(shm->buffer);
        else
@@ -225,7 +205,7 @@ void S_Init(void)
        Cmd_AddCommand("play", S_Play);
        Cmd_AddCommand("play2", S_Play2);
        Cmd_AddCommand("playvol", S_PlayVol);
-       Cmd_AddCommand("stopsound", S_StopAllSoundsC);
+       Cmd_AddCommand("stopsound", S_StopAllSounds);
        Cmd_AddCommand("soundlist", S_SoundList);
        Cmd_AddCommand("soundinfo", S_SoundInfo_f);
        Cmd_AddCommand("snd_restart", S_Restart_f);
@@ -240,17 +220,11 @@ void S_Init(void)
        Cvar_RegisterVariable(&snd_noextraupdate);
        Cvar_RegisterVariable(&snd_show);
        Cvar_RegisterVariable(&_snd_mixahead);
-       Cvar_RegisterVariable(&snd_swapstereo); // LordHavoc: for people with backwards sound wiring
+       Cvar_RegisterVariable(&snd_swapstereo); // for people with backwards sound wiring
 
        Cvar_SetValueQuick(&snd_initialized, true);
 
-       known_sfx = Mem_Alloc(snd_mempool, MAX_SFX*sizeof(sfx_t));
-       num_sfx = 0;
-
-       SND_InitScaletable ();
-
-       ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav", false, true);
-       ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav", false, true);
+       known_sfx = NULL;
 
        total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;   // no statics
        memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
@@ -264,115 +238,125 @@ void S_Init(void)
 // =======================================================================
 
 /*
-=========
-S_GetCached
+==================
+S_FindName
 
-=========
+==================
 */
-sfx_t *S_GetCached (const char *name, qboolean stdpath)
+sfx_t *S_FindName (const char *name, qboolean stdpath)
 {
-       char namebuffer [MAX_QPATH];
+       sfx_t *sfx;
        size_t len;
-       int i;
+       char namebuffer [MAX_QPATH];
 
        if (!snd_initialized.integer)
                return NULL;
 
-       if (!name)
-               Host_Error("S_GetCached: NULL");
-
        // Add the default sound directory to the path
        len = snprintf (namebuffer, sizeof (namebuffer), stdpath ? "sound/%s" : "%s", name);
        if (len >= sizeof (namebuffer))
-               Host_Error ("S_GetCached: sound name too long (%s)", name);
+               Host_Error ("S_FindName: sound name too long (%s)", name);
+
+       // Look for this sound in the list of known sfx
+       for (sfx = known_sfx; sfx != NULL; sfx = sfx->next)
+               if(!strcmp (sfx->name, namebuffer))
+                       return sfx;
 
-       for(i = 0;i < num_sfx;i++)
-               if(!strcmp(known_sfx[i].name, namebuffer))
-                       return &known_sfx[i];
+       // Add a sfx_t struct for this sound
+       sfx = Mem_Alloc (snd_mempool, sizeof (*sfx));
+       memset (sfx, 0, sizeof(*sfx));
+       strlcpy (sfx->name, namebuffer, sizeof (sfx->name));
+       sfx->next = known_sfx;
+       known_sfx = sfx;
 
-       return NULL;
+       return sfx;
 }
 
+
 /*
 ==================
-S_FindName
+S_FreeSfx
 
 ==================
 */
-sfx_t *S_FindName (const char *name, qboolean stdpath)
+void S_FreeSfx (sfx_t *sfx)
 {
-       sfx_t *sfx;
-
-       if (!snd_initialized.integer)
-               return NULL;
+       // Never free a locked sfx
+       if (sfx->locks > 0)
+               return;
 
-       sfx = S_GetCached (name, stdpath);
+       Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name);
 
-       // If we haven't allocated a sfx_t struct for it yet
-       if (sfx == NULL)
+       // Remove it from the list of known sfx
+       if (sfx == known_sfx)
+               known_sfx = known_sfx->next;
+       else
        {
-               if (num_sfx == MAX_SFX)
-                       Sys_Error ("S_FindName: out of sfx_t");
+               sfx_t *prev_sfx;
 
-               sfx = &known_sfx[num_sfx++];
-               memset (sfx, 0, sizeof(*sfx));
-               snprintf (sfx->name, sizeof (sfx->name), stdpath ? "sound/%s" : "%s", name);
+               for (prev_sfx = known_sfx; prev_sfx != NULL; prev_sfx = prev_sfx->next)
+                       if (prev_sfx->next == sfx)
+                       {
+                               prev_sfx->next = sfx->next;
+                               break;
+                       }
+               if (prev_sfx == NULL)
+                       Sys_Error ("S_FreeSfx: Can't find SFX %s in the list!\n", sfx->name);
        }
-       return sfx;
+
+       // Free it
+       Mem_FreePool (&sfx->mempool);
+       Mem_Free (sfx);
 }
 
 
 /*
 ==================
-S_TouchSound
+S_ServerSounds
 
 ==================
 */
-void S_TouchSound (const char *name, qboolean stdpath)
+void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds)
 {
        sfx_t *sfx;
+       unsigned int i;
 
-       sfx = S_FindName (name, stdpath);
-
-       // Set the "used" flag for this sound
-       if (sfx != NULL)
-               sfx->flags |= SFXFLAG_USED;
-}
-
-
-/*
-==================
-S_ClearUsed
-
-Reset the "used" flag of all precached sounds
-==================
-*/
-void S_ClearUsed (void)
-{
-       int i;
+       // Start the ambient sounds and make them loop
+       channels[AMBIENT_WATER].sfx = S_PrecacheSound ("ambience/water1.wav", false, true, true);
+       channels[AMBIENT_SKY].sfx = S_PrecacheSound ("ambience/wind2.wav", false, true, true);
+       for (i = 0; i < NUM_AMBIENTS; i++)
+               channels[i].flags |= CHANNELFLAG_FORCELOOP;
 
-       for (i = 0; i < num_sfx; i++)
-               known_sfx[i].flags &= ~SFXFLAG_USED;
-}
+       // Remove 1 lock from all sfx with the SFXFLAG_SERVERSOUND flag, and remove the flag
+       for (sfx = known_sfx; sfx != NULL; sfx = sfx->next)
+               if (sfx->flags & SFXFLAG_SERVERSOUND)
+               {
+                       sfx->locks--;
+                       sfx->flags &= ~SFXFLAG_SERVERSOUND;
+               }
 
+       // Add 1 lock and the SFXFLAG_SERVERSOUND flag to each sfx in "serversound"
+       for (i = 1; i < numsounds; i++)
+       {
+               sfx = S_FindName (serversound[i], true);
+               if (sfx != NULL)
+               {
+                       sfx->locks++;
+                       sfx->flags |= SFXFLAG_SERVERSOUND;
+               }
+       }
 
-/*
-==================
-S_PurgeUnused
+       // Free all unlocked sfx
+       sfx = known_sfx;
+       while (sfx != NULL)
+       {
+               sfx_t* crtsfx;
 
-Free all precached sounds without the "used" flag
-==================
-*/
-void S_PurgeUnused (void)
-{
-       int i;
-       sfx_t *sfx;
+               // We may lose the "next" pointer after S_FreeSfx
+               crtsfx = sfx;
+               sfx = sfx->next;
 
-       for (i = 0; i < num_sfx; i++)
-       {
-               sfx = &known_sfx[i];
-               if (! (sfx->flags & SFXFLAG_USED))
-                       S_UnloadSound (sfx);
+               S_FreeSfx (crtsfx);
        }
 }
 
@@ -383,7 +367,7 @@ S_PrecacheSound
 
 ==================
 */
-sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean stdpath)
+sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean stdpath, qboolean lock)
 {
        sfx_t *sfx;
 
@@ -391,6 +375,11 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean stdpath)
                return NULL;
 
        sfx = S_FindName (name, stdpath);
+       if (sfx == NULL)
+               return NULL;
+
+       if (lock)
+               sfx->locks++;
 
        if (!nosound.integer && snd_precache.integer)
                S_LoadSound(sfx, complain);
@@ -398,6 +387,19 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean stdpath)
        return sfx;
 }
 
+/*
+==================
+S_UnlockSfx
+
+Remove a lock from a SFX and freed it if possible
+==================
+*/
+void S_UnlockSfx (sfx_t *sfx)
+{
+       sfx->locks--;
+       S_FreeSfx (sfx);
+}
+
 
 //=============================================================================
 
@@ -448,8 +450,7 @@ channel_t *SND_PickChannel(int entnum, int entchannel)
        if (first_to_die == -1)
                return NULL;
 
-       if (channels[first_to_die].sfx)
-               channels[first_to_die].sfx = NULL;
+       S_StopChannel (first_to_die);
 
        return &channels[first_to_die];
 }
@@ -461,7 +462,7 @@ SND_Spatialize
 Spatializes a channel
 =================
 */
-void SND_Spatialize(channel_t *ch, int isstatic)
+void SND_Spatialize(channel_t *ch, qboolean isstatic)
 {
        vec_t dist, scale, pan;
        vec3_t source_vec;
@@ -496,7 +497,7 @@ void SND_Spatialize(channel_t *ch, int isstatic)
                ch->rightvol = (int) (scale - pan);
        }
 
-       // LordHavoc: allow adjusting volume of static sounds
+       // Adjust volume of static sounds
        if (isstatic)
        {
                ch->leftvol *= snd_staticvolume.value;
@@ -513,51 +514,57 @@ void SND_Spatialize(channel_t *ch, int isstatic)
 // Start a sound effect
 // =======================================================================
 
-int S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
+void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, vec3_t origin, float fvol, float attenuation, qboolean isstatic)
+{
+       // Initialize the channel
+       memset (target_chan, 0, sizeof (*target_chan));
+       VectorCopy (origin, target_chan->origin);
+       target_chan->master_vol = fvol * 255;
+       target_chan->sfx = sfx;
+       target_chan->end = paintedtime + sfx->total_length;
+       target_chan->lastptime = paintedtime;
+       target_chan->flags = flags;
+
+       // If it's a static sound
+       if (isstatic)
+       {
+               if (sfx->loopstart == -1)
+                       Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name);
+               target_chan->dist_mult = attenuation / (64.0f * sound_nominal_clip_dist);
+       }
+       else
+               target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
+
+       // Lock the SFX during play
+       sfx->locks++;
+}
+
+
+int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 {
        channel_t *target_chan, *check;
-       int             vol;
        int             ch_idx;
        size_t  skip;
 
        if (!sound_started || !sfx || !sfx->fetcher || nosound.integer)
                return -1;
 
-       vol = fvol*255;
-
-// pick a channel to play on
+       // Pick a channel to play on
        target_chan = SND_PickChannel(entnum, entchannel);
        if (!target_chan)
                return -1;
 
-// spatialize
-       memset (target_chan, 0, sizeof(*target_chan));
-       VectorCopy(origin, target_chan->origin);
-       target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
-       target_chan->master_vol = vol;
-       target_chan->entnum = entnum;
-       target_chan->entchannel = entchannel;
-       SND_Spatialize(target_chan, false);
-
-       // LordHavoc: spawn the sound anyway because the player might teleport to it
-       //if (!target_chan->leftvol && !target_chan->rightvol)
-       //      return;         // not audible at all
-
-       // new channel
        if (!S_LoadSound (sfx, true))
-       {
-               target_chan->sfx = NULL;
                return -1;              // couldn't load the sound's data
-       }
 
-       target_chan->sfx = sfx;
-       target_chan->flags = CHANNELFLAG_NONE;
-       target_chan->pos = 0.0;
-       target_chan->end = paintedtime + sfx->total_length;
-       target_chan->lastptime = paintedtime;
+       S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_NONE, origin, fvol, attenuation, false);
+       target_chan->entnum = entnum;
+       target_chan->entchannel = entchannel;
+
+       SND_Spatialize(target_chan, false);
 
-// if an identical sound has also been started this frame, offset the pos
-// a bit to keep it from just making the first one louder
+       // if an identical sound has also been started this frame, offset the pos
+       // a bit to keep it from just making the first one louder
        check = &channels[NUM_AMBIENTS];
        for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++, check++)
        {
@@ -565,7 +572,6 @@ int S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fv
                        continue;
                if (check->sfx == sfx && !check->pos)
                {
-                       // LordHavoc: fixed skip calculations
                        skip = 0.1 * sfx->format.speed;
                        if (skip > sfx->total_length)
                                skip = sfx->total_length;
@@ -590,31 +596,40 @@ void S_StopChannel (unsigned int channel_ind)
        ch = &channels[channel_ind];
        if (ch->sfx != NULL)
        {
-               if (ch->sfx->fetcher != NULL)
+               sfx_t *sfx = ch->sfx;
+
+               if (sfx->fetcher != NULL)
                {
-                       snd_fetcher_end_t fetcher_end = ch->sfx->fetcher->end;
+                       snd_fetcher_end_t fetcher_end = sfx->fetcher->end;
                        if (fetcher_end != NULL)
                                fetcher_end (ch);
                }
+
+               // Remove the lock it holds
+               S_UnlockSfx (sfx);
+
                ch->sfx = NULL;
        }
        ch->end = 0;
 }
 
-void S_PauseChannel (unsigned int channel_ind, qboolean toggle)
-{
-       if (toggle)
-               channels[channel_ind].flags |= CHANNELFLAG_PAUSED;
-       else
-               channels[channel_ind].flags &= ~CHANNELFLAG_PAUSED;
-}
 
-void S_LoopChannel (unsigned int channel_ind, qboolean toggle)
+qboolean S_SetChannelFlag (unsigned int ch_ind, unsigned int flag, qboolean value)
 {
-       if (toggle)
-               channels[channel_ind].flags |= CHANNELFLAG_FORCELOOP;
+       if (ch_ind >= total_channels)
+               return false;
+
+       if (flag != CHANNELFLAG_FORCELOOP &&
+               flag != CHANNELFLAG_PAUSED &&
+               flag != CHANNELFLAG_FULLVOLUME)
+               return false;
+
+       if (value)
+               channels[ch_ind].flags |= flag;
        else
-               channels[channel_ind].flags &= ~CHANNELFLAG_FORCELOOP;
+               channels[ch_ind].flags &= ~flag;
+
+       return true;
 }
 
 void S_StopSound(int entnum, int entchannel)
@@ -629,7 +644,7 @@ void S_StopSound(int entnum, int entchannel)
                }
 }
 
-void S_StopAllSounds(qboolean clear)
+void S_StopAllSounds (void)
 {
        unsigned int i;
 
@@ -639,30 +654,10 @@ void S_StopAllSounds(qboolean clear)
        total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;   // no statics
        memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
 
-       if (clear)
-               S_ClearBuffer();
-}
-
-void S_StopAllSoundsC(void)
-{
-       S_StopAllSounds(true);
-}
-
-void S_PauseGameSounds (void)
-{
-       unsigned int i;
-
-       for (i = 0; i < total_channels; i++)
-       {
-               channel_t *ch;
-
-               ch = &channels[i];
-               if (ch->sfx != NULL && ! (ch->flags & CHANNELFLAG_LOCALSOUND))
-                       ch->flags |= CHANNELFLAG_PAUSED;
-       }
+       S_ClearBuffer ();
 }
 
-void S_ResumeGameSounds (void)
+void S_PauseGameSounds (qboolean toggle)
 {
        unsigned int i;
 
@@ -672,7 +667,7 @@ void S_ResumeGameSounds (void)
 
                ch = &channels[i];
                if (ch->sfx != NULL && ! (ch->flags & CHANNELFLAG_LOCALSOUND))
-                       ch->flags &= ~CHANNELFLAG_PAUSED;
+                       S_SetChannelFlag (i, CHANNELFLAG_PAUSED, toggle);
        }
 }
 
@@ -730,16 +725,16 @@ void S_ClearBuffer(void)
 #endif
        if (shm->buffer)
        {
-               int             setsize = shm->samples * shm->format.width;
-               char    *buf = shm->buffer;
+               int setsize = shm->samples * shm->format.width;
+               unsigned char *buf = shm->buffer;
 
                while (setsize--)
                        *buf++ = clear;
 
-// on i586/i686 optimized versions of glibc, glibc *wrongly* IMO,
-// reads the memory area before writing to it causing a seg fault
-// since the memory is PROT_WRITE only and not PROT_READ|PROT_WRITE
-//             memset(shm->buffer, clear, shm->samples * shm->samplebits/8);
+               // on i586/i686 optimized versions of glibc, glibc *wrongly* IMO,
+               // reads the memory area before writing to it causing a seg fault
+               // since the memory is PROT_WRITE only and not PROT_READ|PROT_WRITE
+               //memset(shm->buffer, clear, shm->samples * shm->format.width);
        }
 }
 
@@ -749,9 +744,9 @@ void S_ClearBuffer(void)
 S_StaticSound
 =================
 */
-void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
+void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 {
-       channel_t       *ss;
+       channel_t       *target_chan;
 
        if (!sfx)
                return;
@@ -765,20 +760,10 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
        if (!S_LoadSound (sfx, true))
                return;
 
-       if (sfx->loopstart == -1)
-               Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name);
+       target_chan = &channels[total_channels++];
+       S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true);
 
-       ss = &channels[total_channels++];
-       memset(ss, 0, sizeof(*ss));
-       ss->flags = CHANNELFLAG_FORCELOOP;
-       ss->sfx = sfx;
-       VectorCopy (origin, ss->origin);
-       ss->master_vol = vol;
-       ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
-       ss->end = paintedtime + sfx->total_length;
-       ss->lastptime = paintedtime;
-
-       SND_Spatialize (ss, true);
+       SND_Spatialize (target_chan, true);
 }
 
 
@@ -787,6 +772,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
 /*
 ===================
 S_UpdateAmbientSounds
+
 ===================
 */
 void S_UpdateAmbientSounds (void)
@@ -796,30 +782,27 @@ void S_UpdateAmbientSounds (void)
        channel_t       *chan;
        qbyte           ambientlevels[NUM_AMBIENTS];
 
-       // LordHavoc: kill ambient sounds until proven otherwise
+       // Mute ambient sounds until proven otherwise
        for (ambient_channel = 0 ; ambient_channel < NUM_AMBIENTS;ambient_channel++)
-               channels[ambient_channel].sfx = NULL;
+               channels[ambient_channel].master_vol = 0;
 
        if (ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brush.AmbientSoundLevelsForPoint)
                return;
 
        cl.worldmodel->brush.AmbientSoundLevelsForPoint(cl.worldmodel, listener_origin, ambientlevels, sizeof(ambientlevels));
 
-// calc ambient sound levels
+       // Calc ambient sound levels
        for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
        {
-               if (ambient_sfx[ambient_channel] &&
-                       (ambient_sfx[ambient_channel]->flags & SFXFLAG_SILENTLYMISSING))
-                       continue;
                chan = &channels[ambient_channel];
-               chan->flags |= CHANNELFLAG_FORCELOOP;
-               chan->sfx = ambient_sfx[ambient_channel];
+               if (chan->sfx == NULL || (chan->sfx->flags & SFXFLAG_FILEMISSING))
+                       continue;
 
                vol = ambient_level.value * ambientlevels[ambient_channel];
                if (vol < 8)
                        vol = 0;
 
-       // don't adjust volume too fast
+               // Don't adjust volume too fast
                if (chan->master_vol < vol)
                {
                        chan->master_vol += host_realframetime * ambient_fade.value;
@@ -944,7 +927,7 @@ void GetSoundtime(void)
                {       // time to chop things off to avoid 32 bit limits
                        buffers = 0;
                        paintedtime = fullsamples;
-                       S_StopAllSounds (true);
+                       S_StopAllSounds ();
                }
        }
        oldsamplepos = samplepos;
@@ -952,15 +935,8 @@ void GetSoundtime(void)
        soundtime = buffers * fullsamples + samplepos / shm->format.channels;
 }
 
-void IN_Accumulate (void);
-
 void S_ExtraUpdate (void)
 {
-
-#ifdef USE_DSOUND
-       IN_Accumulate ();
-#endif
-
        if (snd_noextraupdate.integer)
                return;         // don't pollute timings
        S_Update_();
@@ -1032,7 +1008,7 @@ static void S_Play_Common(float fvol, float attenuation)
                        snprintf(name, sizeof(name), "%s.wav", Cmd_Argv(i));
                else
                        strlcpy(name, Cmd_Argv(i), sizeof(name));
-               sfx = S_PrecacheSound(name, true, true);
+               sfx = S_PrecacheSound(name, true, true, false);
 
                // If we need to get the volume from the command line
                if (fvol == -1.0f)
@@ -1044,7 +1020,11 @@ static void S_Play_Common(float fvol, float attenuation)
                        i++;
 
                ch_ind = S_StartSound(-1, 0, sfx, listener_origin, fvol, attenuation);
-               if (ch_ind >= 0)
+
+               // Free the sfx if the file didn't exist
+               if (ch_ind < 0)
+                       S_FreeSfx (sfx);
+               else
                        channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
        }
 }
@@ -1066,12 +1046,12 @@ void S_PlayVol(void)
 
 void S_SoundList(void)
 {
-       int             i;
+       unsigned int i;
        sfx_t   *sfx;
        int             size, total;
 
        total = 0;
-       for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
+       for (sfx = known_sfx, i = 0; sfx != NULL; sfx = sfx->next, i++)
        {
                if (sfx->fetcher != NULL)
                {
@@ -1081,7 +1061,7 @@ void S_SoundList(void)
                                                (sfx->loopstart >= 0) ? 'L' : ' ',
                                                (sfx->flags & SFXFLAG_STREAMED) ? 'S' : ' ',
                                                sfx->format.width * 8,
-                                               (sfx->format.channels == 2) ? "stereo" : "mono",
+                                               (sfx->format.channels == 1) ? "mono" : "stereo",
                                                size,
                                                sfx->name);
                }
@@ -1090,22 +1070,25 @@ void S_SoundList(void)
 }
 
 
-void S_LocalSound (const char *sound, qboolean stdpath)
+qboolean S_LocalSound (const char *sound, qboolean stdpath)
 {
        sfx_t   *sfx;
        int             ch_ind;
 
        if (!snd_initialized.integer || nosound.integer)
-               return;
+               return true;
 
-       sfx = S_PrecacheSound (sound, true, stdpath);
+       sfx = S_PrecacheSound (sound, true, stdpath, false);
        if (!sfx)
        {
                Con_Printf("S_LocalSound: can't precache %s\n", sound);
-               return;
+               return false;
        }
 
        ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 1);
-       if (ch_ind >= 0)
-               channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
+       if (ch_ind < 0)
+               return false;
+
+       channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
+       return true;
 }
diff --git a/snd_main.h b/snd_main.h
new file mode 100644 (file)
index 0000000..d9ecb0c
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifndef SND_MAIN_H
+#define SND_MAIN_H
+
+#include "sound.h"
+
+
+typedef struct
+{
+       size_t  length;
+       size_t  offset;
+       qbyte   data[4];        // variable sized
+} sfxbuffer_t;
+
+typedef struct
+{
+       unsigned int    speed;
+       unsigned int    width;
+       unsigned int    channels;
+} snd_format_t;
+
+// sfx_t flags
+#define SFXFLAG_NONE                   0
+#define SFXFLAG_FILEMISSING            (1 << 0) // wasn't able to load the associated sound file
+#define SFXFLAG_SERVERSOUND            (1 << 1) // the sfx is part of the server precache list
+#define SFXFLAG_STREAMED               (1 << 2) // informative only. You shouldn't need to know that
+
+typedef struct snd_fetcher_s snd_fetcher_t;
+struct sfx_s
+{
+       char                            name[MAX_QPATH];
+       sfx_t                           *next;
+       mempool_t                       *mempool;
+       unsigned int            locks;                  // A locked sfx_t must not be freed.
+                                                                               // Locks are added by S_PrecacheSound and S_ServerSounds.
+                                                                               // SFX can be freed by S_UnlockSfx or S_ServerSounds.
+       unsigned int            flags;                  // cf SFXFLAG_* defines
+       snd_format_t            format;
+       int                                     loopstart;
+       size_t                          total_length;
+       const snd_fetcher_t     *fetcher;
+       void                            *fetcher_data;  // Per-sfx data for the sound fetching functions
+};
+
+typedef struct
+{
+       snd_format_t    format;
+       int                             samples;                // mono samples in buffer
+       int                             samplepos;              // in mono samples
+       unsigned char   *buffer;
+       int                             bufferlength;   // used only by certain drivers
+} dma_t;
+
+typedef struct
+{
+       sfx_t                   *sfx;                   // sfx number
+       unsigned int    flags;                  // cf CHANNELFLAG_* defines
+       int                             master_vol;             // 0-255 master volume
+       int                             leftvol;                // 0-255 volume
+       int                             rightvol;               // 0-255 volume
+       int                             end;                    // end time in global paintsamples
+       int                             lastptime;              // last time this channel was painted
+       int                             pos;                    // sample position in sfx
+       int                             entnum;                 // to allow overriding a specific sound
+       int                             entchannel;
+       vec3_t                  origin;                 // origin of sound effect
+       vec_t                   dist_mult;              // distance multiplier (attenuation/clipK)
+       void                    *fetcher_data;  // Per-channel data for the sound fetching function
+} channel_t;
+
+typedef const sfxbuffer_t* (*snd_fetcher_getsb_t) (channel_t* ch, unsigned int start, unsigned int nbsamples);
+typedef void (*snd_fetcher_end_t) (channel_t* ch);
+struct snd_fetcher_s
+{
+       snd_fetcher_getsb_t             getsb;
+       snd_fetcher_end_t               end;
+};
+
+void S_PaintChannels(int endtime);
+
+// initializes cycling through a DMA buffer and returns information on it
+qboolean SNDDMA_Init(void);
+
+// gets the current DMA position
+int SNDDMA_GetDMAPos(void);
+
+void SNDDMA_Submit(void);
+
+// shutdown the DMA xfer.
+void SNDDMA_Shutdown(void);
+
+qboolean S_LoadSound (sfx_t *s, qboolean complain);
+void S_UnloadSound(sfx_t *s);
+
+void *S_LockBuffer(void);
+void S_UnlockBuffer(void);
+
+extern size_t ResampleSfx (const qbyte *in_data, size_t in_length, const snd_format_t* in_format, qbyte *out_data, const char* sfxname);
+
+// ====================================================================
+// User-setable variables
+// ====================================================================
+
+// 0 to NUM_AMBIENTS - 1 = water, etc
+// NUM_AMBIENTS to NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS - 1 = normal entity sounds
+// NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS to total_channels = static sounds
+#define        MAX_CHANNELS                    516
+#define        MAX_DYNAMIC_CHANNELS    128
+
+extern channel_t channels[MAX_CHANNELS];
+
+extern unsigned int total_channels;
+
+extern int paintedtime;
+extern int soundtime;
+extern volatile dma_t *shm;
+
+extern cvar_t snd_swapstereo;
+extern cvar_t snd_streaming;
+
+extern int snd_blocked;
+
+
+#endif
index f61a5a98cf5c16e5ce578033708bb1bba9e69032..2ef31444916dbc40c20a8ac4f1c82b1ad5a71411 100644 (file)
--- a/snd_mem.c
+++ b/snd_mem.c
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
+#include "snd_main.h"
 #include "snd_ogg.h"
 #include "snd_wav.h"
 
@@ -156,9 +157,14 @@ qboolean S_LoadSound (sfx_t *s, qboolean complain)
        size_t len;
        qboolean modified_name = false;
 
-       // see if still in memory
        if (!shm || !shm->format.speed)
                return false;
+
+       // If we wasn't able to load it previously, no need to retry
+       if (s->flags & SFXFLAG_FILEMISSING)
+               return false;
+
+       // See if in memory
        if (s->fetcher != NULL)
        {
                if (s->format.speed != shm->format.speed)
@@ -184,10 +190,7 @@ qboolean S_LoadSound (sfx_t *s, qboolean complain)
                return true;
 
        // Can't load the sound!
-       if (!complain)
-               s->flags |= SFXFLAG_SILENTLYMISSING;
-       else
-               s->flags &= ~SFXFLAG_SILENTLYMISSING;
+       s->flags |= SFXFLAG_FILEMISSING;
        if (complain)
        {
                if (modified_name)
@@ -197,20 +200,19 @@ qboolean S_LoadSound (sfx_t *s, qboolean complain)
        return false;
 }
 
-void S_UnloadSound(sfx_t *s)
+void S_UnloadSound (sfx_t *s)
 {
        if (s->fetcher != NULL)
        {
                unsigned int i;
 
+               // Stop all channels that use this sound
+               for (i = 0; i < total_channels ; i++)
+                       if (channels[i].sfx == s)
+                               S_StopChannel (i);
+
                s->fetcher = NULL;
                s->fetcher_data = NULL;
                Mem_FreePool(&s->mempool);
-
-               // At this point, some per-channel data pointers may point to freed zones.
-               // Practically, it shouldn't be a problem; but it's wrong, so we fix that
-               for (i = 0; i < total_channels ; i++)
-                       if (channels[i].sfx == s)
-                               channels[i].fetcher_data = NULL;
        }
 }
index efd562c21de80154a1082b183e2a6db1fe646155..4e42a9674438432bed58fcf05ec39b9477e27010 100644 (file)
--- a/snd_mix.c
+++ b/snd_mix.c
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // snd_mix.c -- portable code to mix sounds for snd_dma.c
 
 #include "quakedef.h"
+#include "snd_main.h"
 
 typedef struct
 {
@@ -30,7 +31,6 @@ typedef struct
 // LordHavoc: was 512, expanded to 2048
 #define        PAINTBUFFER_SIZE 2048
 portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
-int snd_scaletable[32][256];
 
 // FIXME: it desyncs with the video too easily
 extern cvar_t cl_avidemo;
@@ -111,6 +111,7 @@ void S_CaptureAVISound(portable_samplepair_t *buf, size_t length)
        }
 }
 
+// TODO: rewrite this function
 void S_TransferPaintBuffer(int endtime)
 {
        void *pbuf;
@@ -118,12 +119,10 @@ void S_TransferPaintBuffer(int endtime)
        {
                int i;
                int *snd_p;
-               int snd_vol;
                int lpaintedtime;
                int snd_linear_count;
                int val;
                snd_p = (int *) paintbuffer;
-               snd_vol = volume.value*256;
                lpaintedtime = paintedtime;
                if (shm->format.width == 2)
                {
@@ -145,20 +144,16 @@ void S_TransferPaintBuffer(int endtime)
                                        {
                                                for (i = 0;i < snd_linear_count;i += 2)
                                                {
-                                                       val = (snd_p[i + 1] * snd_vol) >> 8;
-                                                       snd_out[i    ] = bound(-32768, val, 32767);
-                                                       val = (snd_p[i    ] * snd_vol) >> 8;
-                                                       snd_out[i + 1] = bound(-32768, val, 32767);
+                                                       snd_out[i    ] = bound(-32768, snd_p[i + 1], 32767);
+                                                       snd_out[i + 1] = bound(-32768, snd_p[i    ], 32767);
                                                }
                                        }
                                        else
                                        {
                                                for (i = 0;i < snd_linear_count;i += 2)
                                                {
-                                                       val = (snd_p[i    ] * snd_vol) >> 8;
-                                                       snd_out[i    ] = bound(-32768, val, 32767);
-                                                       val = (snd_p[i + 1] * snd_vol) >> 8;
-                                                       snd_out[i + 1] = bound(-32768, val, 32767);
+                                                       snd_out[i    ] = bound(-32768, snd_p[i    ], 32767);
+                                                       snd_out[i + 1] = bound(-32768, snd_p[i + 1], 32767);
                                                }
                                        }
                                        snd_p += snd_linear_count;
@@ -178,7 +173,7 @@ void S_TransferPaintBuffer(int endtime)
                                                snd_linear_count = endtime - lpaintedtime;
                                        for (i = 0;i < snd_linear_count;i++)
                                        {
-                                               val = ((snd_p[i * 2 + 0] + snd_p[i * 2 + 1]) * snd_vol) >> 9;
+                                               val = (snd_p[i * 2 + 0] + snd_p[i * 2 + 1]) >> 1;
                                                snd_out[i] = bound(-32768, val, 32767);
                                        }
                                        snd_p += snd_linear_count << 1;
@@ -206,9 +201,9 @@ void S_TransferPaintBuffer(int endtime)
                                        {
                                                for (i = 0;i < snd_linear_count;i += 2)
                                                {
-                                                       val = ((snd_p[i + 1] * snd_vol) >> 16) + 128;
+                                                       val = (snd_p[i + 1] >> 8) + 128;
                                                        snd_out[i    ] = bound(0, val, 255);
-                                                       val = ((snd_p[i    ] * snd_vol) >> 16) + 128;
+                                                       val = (snd_p[i    ] >> 8) + 128;
                                                        snd_out[i + 1] = bound(0, val, 255);
                                                }
                                        }
@@ -216,9 +211,9 @@ void S_TransferPaintBuffer(int endtime)
                                        {
                                                for (i = 0;i < snd_linear_count;i += 2)
                                                {
-                                                       val = ((snd_p[i    ] * snd_vol) >> 16) + 128;
+                                                       val = (snd_p[i    ] >> 8) + 128;
                                                        snd_out[i    ] = bound(0, val, 255);
-                                                       val = ((snd_p[i + 1] * snd_vol) >> 16) + 128;
+                                                       val = (snd_p[i + 1] >> 8) + 128;
                                                        snd_out[i + 1] = bound(0, val, 255);
                                                }
                                        }
@@ -239,7 +234,7 @@ void S_TransferPaintBuffer(int endtime)
                                                snd_linear_count = endtime - lpaintedtime;
                                        for (i = 0;i < snd_linear_count;i++)
                                        {
-                                               val = (((snd_p[i * 2] + snd_p[i * 2 + 1]) * snd_vol) >> 17) + 128;
+                                               val = ((snd_p[i * 2] + snd_p[i * 2 + 1]) >> 9) + 128;
                                                snd_out[i    ] = bound(0, val, 255);
                                        }
                                        snd_p += snd_linear_count << 1;
@@ -325,7 +320,7 @@ void S_PaintChannels(int endtime)
                                        // If the sound is looped
                                        if (loopstart >= 0)
                                                ch->pos = (ch->pos - sfx->total_length) % (sfx->total_length - loopstart) + loopstart;
-                                       else 
+                                       else
                                                ch->pos = sfx->total_length;
                                        ch->end = paintedtime + sfx->total_length - ch->pos;
                                }
@@ -350,9 +345,9 @@ void S_PaintChannels(int endtime)
                                                ch->rightvol = 255;
 
                                        if (sfx->format.width == 1)
-                                               stop_paint = !SND_PaintChannelFrom8(ch, count);
+                                               stop_paint = !SND_PaintChannelFrom8 (ch, count);
                                        else
-                                               stop_paint = !SND_PaintChannelFrom16(ch, count);
+                                               stop_paint = !SND_PaintChannelFrom16 (ch, count);
 
                                        if (!stop_paint)
                                        {
@@ -391,48 +386,45 @@ void S_PaintChannels(int endtime)
        }
 }
 
-void SND_InitScaletable (void)
-{
-       int i, j;
-
-       for (i = 0;i < 32;i++)
-               for (j = 0;j < 256;j++)
-                       snd_scaletable[i][j] = ((signed char)j) * i * 8;
-}
-
 
+// TODO: Try to merge SND_PaintChannelFrom8 and SND_PaintChannelFrom16
 qboolean SND_PaintChannelFrom8 (channel_t *ch, int count)
 {
-       int *lscale, *rscale;
-       unsigned char *sfx;
+       int snd_vol, leftvol, rightvol;
+       const signed char *sfx;
        const sfxbuffer_t *sb;
-       int i, n;
+       int i;
+
+       // If this channel manages its own volume
+       if (ch->flags & CHANNELFLAG_FULLVOLUME)
+               snd_vol = 256;
+       else
+               snd_vol = volume.value * 256;
 
-       lscale = snd_scaletable[ch->leftvol >> 3];
-       rscale = snd_scaletable[ch->rightvol >> 3];
+       leftvol = ch->leftvol * snd_vol;
+       rightvol = ch->rightvol * snd_vol;
 
        sb = ch->sfx->fetcher->getsb (ch, ch->pos, count);
        if (sb == NULL)
                return false;
 
+       // Stereo sound support
        if (ch->sfx->format.channels == 2)
        {
-               // LordHavoc: stereo sound support, and optimizations
-               sfx = (unsigned char *)sb->data + (ch->pos - sb->offset) * 2;
+               sfx = sb->data + (ch->pos - sb->offset) * 2;
                for (i = 0;i < count;i++)
                {
-                       paintbuffer[i].left += lscale[*sfx++];
-                       paintbuffer[i].right += rscale[*sfx++];
+                       paintbuffer[i].left += (*sfx++ * leftvol) >> 8;
+                       paintbuffer[i].right += (*sfx++ * rightvol) >> 8;
                }
        }
        else
        {
-               sfx = (unsigned char *)sb->data + ch->pos - sb->offset;
+               sfx = sb->data + ch->pos - sb->offset;
                for (i = 0;i < count;i++)
                {
-                       n = *sfx++;
-                       paintbuffer[i].left += lscale[n];
-                       paintbuffer[i].right += rscale[n];
+                       paintbuffer[i].left += (*sfx * leftvol) >> 8;
+                       paintbuffer[i].right += (*sfx++ * rightvol) >> 8;
                }
 
        }
@@ -442,27 +434,33 @@ qboolean SND_PaintChannelFrom8 (channel_t *ch, int count)
 
 qboolean SND_PaintChannelFrom16 (channel_t *ch, int count)
 {
-       int leftvol, rightvol;
+       int snd_vol, leftvol, rightvol;
        signed short *sfx;
        const sfxbuffer_t *sb;
        int i;
 
-       leftvol = ch->leftvol;
-       rightvol = ch->rightvol;
+       // If this channel manages its own volume
+       if (ch->flags & CHANNELFLAG_FULLVOLUME)
+               snd_vol = 256;
+       else
+               snd_vol = volume.value * 256;
+
+       leftvol = ch->leftvol * snd_vol;
+       rightvol = ch->rightvol * snd_vol;
 
        sb = ch->sfx->fetcher->getsb (ch, ch->pos, count);
        if (sb == NULL)
                return false;
 
+       // Stereo sound support
        if (ch->sfx->format.channels == 2)
        {
-               // LordHavoc: stereo sound support, and optimizations
                sfx = (signed short *)sb->data + (ch->pos - sb->offset) * 2;
 
                for (i=0 ; i<count ; i++)
                {
-                       paintbuffer[i].left += (*sfx++ * leftvol) >> 8;
-                       paintbuffer[i].right += (*sfx++ * rightvol) >> 8;
+                       paintbuffer[i].left += (*sfx++ * leftvol) >> 16;
+                       paintbuffer[i].right += (*sfx++ * rightvol) >> 16;
                }
        }
        else
@@ -471,8 +469,8 @@ qboolean SND_PaintChannelFrom16 (channel_t *ch, int count)
 
                for (i=0 ; i<count ; i++)
                {
-                       paintbuffer[i].left += (*sfx * leftvol) >> 8;
-                       paintbuffer[i].right += (*sfx++ * rightvol) >> 8;
+                       paintbuffer[i].left += (*sfx * leftvol) >> 16;
+                       paintbuffer[i].right += (*sfx++ * rightvol) >> 16;
                }
        }
 
index df43df4f200bf9fd250eda56f6f3cf3ec36b0ed4..6e089e6fac85cdea07421d71095758bb3ac3c3f1 100755 (executable)
@@ -44,23 +44,15 @@ void S_Shutdown (void)
 {
 }
 
-void S_TouchSound (const char *sample, qboolean stdpath)
+void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds)
 {
 }
 
-void S_ClearUsed (void)
+void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 {
 }
 
-void S_PurgeUnused (void)
-{
-}
-
-void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
-{
-}
-
-int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol,  float attenuation)
+int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 {
        return -1;
 }
@@ -69,23 +61,16 @@ void S_StopChannel (unsigned int channel_ind)
 {
 }
 
-void S_PauseChannel (unsigned int channel_ind, qboolean toggle)
-{
-}
-
-void S_LoopChannel (unsigned int channel_ind, qboolean toggle)
+qboolean S_SetChannelFlag (unsigned int ch_ind, unsigned int flag, qboolean value)
 {
+       return false;
 }
 
 void S_StopSound (int entnum, int entchannel)
 {
 }
 
-void S_PauseGameSounds (void)
-{
-}
-
-void S_ResumeGameSounds (void)
+void S_PauseGameSounds (qboolean toggle)
 {
 }
 
@@ -93,21 +78,20 @@ void S_SetChannelVolume (unsigned int ch_ind, float fvol)
 {
 }
 
-sfx_t *S_GetCached(const char *name, qboolean stdpath)
+sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean stdpath, qboolean lock)
 {
        return NULL;
 }
 
-sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean stdpath)
+void S_UnlockSfx (sfx_t *sfx)
 {
-       return NULL;
 }
 
 void S_Update(const matrix4x4_t *matrix)
 {
 }
 
-void S_StopAllSounds (qboolean clear)
+void S_StopAllSounds (void)
 {
 }
 
@@ -115,6 +99,7 @@ void S_ExtraUpdate (void)
 {
 }
 
-void S_LocalSound (const char *s, qboolean stdpath)
+qboolean S_LocalSound (const char *s, qboolean stdpath)
 {
+       return false;
 }
index fa64393becad0e7ca7deb4962464b34683cfa5ca..74a2e193f708082f2b11762c34117946db69cafb 100644 (file)
--- a/snd_ogg.c
+++ b/snd_ogg.c
@@ -23,6 +23,7 @@
 
 
 #include "quakedef.h"
+#include "snd_main.h"
 #include "snd_ogg.h"
 #include "snd_wav.h"
 
@@ -587,7 +588,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
                long ret;
                sfxbuffer_t *sb;
 
-               Con_DPrintf ("\"%s\" will be streamed\n", filename);
+               Con_DPrintf ("\"%s\" will be cached\n", filename);
 
                // Decode it
                buff = Mem_Alloc (s->mempool, (int)len);
index c2ae5101a739cd310e9c7954156c6bed99ecb1e2..bdb8afcf2275bcd7655a9098a7bb6c4718d8ac73 100644 (file)
--- a/snd_oss.c
+++ b/snd_oss.c
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include <sys/soundcard.h>
 #include <stdio.h>
 #include "quakedef.h"
+#include "snd_main.h"
 
 int audio_fd;
 int snd_inited;
index 5dcaf529bea0a4f489e1d0bca2d63b008cd02a36..4b262a69ad92869b5eb94b0e0d9a54e67068930a 100644 (file)
--- a/snd_sdl.c
+++ b/snd_sdl.c
@@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 #include "quakedef.h"
+#include "snd_main.h"
 #include <SDL.h>
 
 /*
index 8d4f986bab8a32e5377918e86c4ddfc9bf55d40c..3904df5022af1ad52edd48f54d9ea7cfed07afa1 100644 (file)
--- a/snd_wav.c
+++ b/snd_wav.c
@@ -23,6 +23,7 @@
 
 
 #include "quakedef.h"
+#include "snd_main.h"
 #include "snd_wav.h"
 
 
index a66bae5cc935379d0631fe0c6291869bed0df6c1..d031645b26f7b7feb3eb65c8bf4a76e6e3de01e3 100644 (file)
--- a/snd_win.c
+++ b/snd_win.c
@@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
 #include "quakedef.h"
+#include "snd_main.h"
 #include <windows.h>
 #include <dsound.h>
 
diff --git a/sound.h b/sound.h
index ecbdb78a51af728ff66fbcaf1761a8fe880f7d23..27682799eab91c4050601996acc3ee0b3c139c3e 100644 (file)
--- a/sound.h
+++ b/sound.h
@@ -17,183 +17,67 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
-// sound.h -- client sound i/o functions
 
 #ifndef SOUND_H
 #define SOUND_H
 
 #include "matrixlib.h"
 
-//AK: TODO: find a better solution instead of using a define
-#if defined( _WIN32 ) && !defined( USE_SDL )
-#      define USE_DSOUND
-#endif
+
+// ====================================================================
+// Constants
+// ====================================================================
 
 #define DEFAULT_SOUND_PACKET_VOLUME 255
 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0
 
-typedef struct
-{
-       size_t  length;
-       size_t  offset;
-       qbyte   data[4];        // variable sized
-} sfxbuffer_t;
-
-typedef struct
-{
-       unsigned int    speed;
-       unsigned int    width;
-       unsigned int    channels;
-} snd_format_t;
-
-// sfx_t flags
-#define SFXFLAG_NONE                   0
-#define SFXFLAG_SILENTLYMISSING        (1 << 0) // if the sfx is missing and loaded with complain = false
-#define SFXFLAG_USED                   (1 << 1)
-#define SFXFLAG_STREAMED               (1 << 2) // informative only. You shouldn't need to know that
-
-typedef struct snd_fetcher_s snd_fetcher_t;
-typedef struct sfx_s
-{
-       char                            name[MAX_QPATH];
-       mempool_t                       *mempool;
-       unsigned int            flags;                  // cf SFXFLAG_* defines
-       snd_format_t            format;
-       int                                     loopstart;
-       size_t                          total_length;
-       const snd_fetcher_t     *fetcher;
-       void                            *fetcher_data;  // Per-sfx data for the sound fetching functions
-} sfx_t;
-
-typedef struct
-{
-       snd_format_t    format;
-       int                             samples;                // mono samples in buffer
-       int                             samplepos;              // in mono samples
-       unsigned char   *buffer;
-       int                             bufferlength;   // used only by certain drivers
-} dma_t;
-
-// channel_t flags
+// Channel flags
 #define CHANNELFLAG_NONE               0
 #define CHANNELFLAG_FORCELOOP  (1 << 0) // force looping even if the sound is not looped
-#define CHANNELFLAG_LOCALSOUND (1 << 1) // non-game sound (ex: menu sound)
+#define CHANNELFLAG_LOCALSOUND (1 << 1) // INTERNAL USE. Not settable by S_SetChannelFlag
 #define CHANNELFLAG_PAUSED             (1 << 2)
+#define CHANNELFLAG_FULLVOLUME (1 << 3) // isn't affected by the general volume
 
-typedef struct
-{
-       sfx_t                   *sfx;                   // sfx number
-       unsigned int    flags;                  // cf CHANNELFLAG_* defines
-       int                             leftvol;                // 0-255 volume
-       int                             rightvol;               // 0-255 volume
-       int                             end;                    // end time in global paintsamples
-       int                             lastptime;              // last time this channel was painted
-       int                             pos;                    // sample position in sfx
-       int                             looping;                // where to loop, -1 = no looping
-       int                             entnum;                 // to allow overriding a specific sound
-       int                             entchannel;
-       vec3_t                  origin;                 // origin of sound effect
-       vec_t                   dist_mult;              // distance multiplier (attenuation/clipK)
-       int                             master_vol;             // 0-255 master volume
-       void                    *fetcher_data;  // Per-channel data for the sound fetching function
-} channel_t;
-
-typedef const sfxbuffer_t* (*snd_fetcher_getsb_t) (channel_t* ch, unsigned int start, unsigned int nbsamples);
-typedef void (*snd_fetcher_end_t) (channel_t* ch);
-struct snd_fetcher_s
-{
-       snd_fetcher_getsb_t     getsb;
-       snd_fetcher_end_t       end;
-};
-
-void S_Init (void);
-void S_Startup (void);
-void S_Shutdown (void);
-// S_StartSound returns the channel index, or -1 if an error occurred
-int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol,  float attenuation);
-void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation);
-void S_StopChannel (unsigned int channel_ind);
-void S_PauseChannel (unsigned int channel_ind, qboolean toggle);
-void S_LoopChannel (unsigned int channel_ind, qboolean toggle);
-void S_StopSound (int entnum, int entchannel);
-void S_StopAllSounds(qboolean clear);
-void S_PauseGameSounds (void);
-void S_ResumeGameSounds (void);
-void S_SetChannelVolume (unsigned int ch_ind, float fvol);
-void S_Update(const matrix4x4_t *listenermatrix);
-void S_ExtraUpdate (void);
-
-sfx_t *S_GetCached(const char *name, qboolean stdpath);
-sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean stdpath);
-void S_TouchSound (const char *sample, qboolean stdpath);
-void S_ClearUsed (void);
-void S_PurgeUnused (void);
-void S_PaintChannels(int endtime);
-void S_InitPaintChannels (void);
-
-// initializes cycling through a DMA buffer and returns information on it
-qboolean SNDDMA_Init(void);
-
-// gets the current DMA position
-int SNDDMA_GetDMAPos(void);
-
-// shutdown the DMA xfer.
-void SNDDMA_Shutdown(void);
-
-extern size_t ResampleSfx (const qbyte *in_data, size_t in_length, const snd_format_t* in_format, qbyte *out_data, const char* sfxname);
 
 // ====================================================================
-// User-setable variables
+// Types and variables
 // ====================================================================
 
-// LordHavoc: increased from 128 to 516 (4 for NUM_AMBIENTS)
-#define        MAX_CHANNELS                    516
-// LordHavoc: increased maximum sound channels from 8 to 128
-#define        MAX_DYNAMIC_CHANNELS    128
+typedef struct sfx_s sfx_t;
 
+extern cvar_t bgmvolume;
+extern cvar_t volume;
+extern cvar_t snd_initialized;
+extern cvar_t snd_staticvolume;
 
-extern channel_t channels[MAX_CHANNELS];
-// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds
-// MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc
-// MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds
-
-extern unsigned int total_channels;
 
-//
-// Fake dma is a synchronous faking of the DMA progress used for
-// isolating performance in the renderer.  The fakedma_updates is
-// number of times S_Update() is called per second.
-//
+// ====================================================================
+// Functions
+// ====================================================================
 
-extern qboolean fakedma;
-extern int fakedma_updates;
-extern int paintedtime;
-extern int soundtime;
-extern vec3_t listener_vieworigin;
-extern vec3_t listener_viewforward;
-extern vec3_t listener_viewleft;
-extern vec3_t listener_viewup;
-extern volatile dma_t *shm;
-extern vec_t sound_nominal_clip_dist;
+void S_Init (void);
+void S_Startup (void);
+void S_Shutdown (void);
 
-extern cvar_t bgmvolume;
-extern cvar_t volume;
-extern cvar_t snd_swapstereo;
+void S_Update(const matrix4x4_t *listenermatrix);
+void S_ExtraUpdate (void);
 
-extern cvar_t cdaudioinitialized;
-extern cvar_t snd_initialized;
-extern cvar_t snd_streaming;
+sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean stdpath, qboolean lock);
+void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds);
+void S_UnlockSfx (sfx_t *sfx);
 
-extern int snd_blocked;
+// S_StartSound returns the channel index, or -1 if an error occurred
+int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation);
+qboolean S_LocalSound (const char *s, qboolean stdpath);
 
-void S_LocalSound (const char *s, qboolean stdpath);
-qboolean S_LoadSound (sfx_t *s, qboolean complain);
-void S_UnloadSound(sfx_t *s);
+void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation);
+void S_StopSound (int entnum, int entchannel);
+void S_StopAllSounds (void);
+void S_PauseGameSounds (qboolean toggle);
 
-void SND_InitScaletable (void);
-void SNDDMA_Submit(void);
+void S_StopChannel (unsigned int channel_ind);
+qboolean S_SetChannelFlag (unsigned int ch_ind, unsigned int flag, qboolean value);
+void S_SetChannelVolume (unsigned int ch_ind, float fvol);
 
-void *S_LockBuffer(void);
-void S_UnlockBuffer(void);
 
 #endif
diff --git a/todo b/todo
index fd6fb6d9fa8bdfb7575ef040222589d0c566ce57..b04124864f5765e38e6b4dd4bb971dcb3eb33b61 100644 (file)
--- a/todo
+++ b/todo
@@ -2,6 +2,7 @@
 -(Baalz) d darkplaces input bug: figure out what's wrong with ctrl key in Linux, hitting character keys tends to do nothing, and holding a character key and then hitting ctrl tends to leave the character key stuck on, this sounds like a window manager issue, but somehow quake3 works around it (Baalz)
 -(Kinn) d darkplaces client: all glow trails are bright blue (Kinn)
 -(Kinn) d darkplaces renderer: fix the sometimes non-animating framegroups on sprites (Kinn) 
+-(fuh) d darkplaces sound: make sound precaching not allocate an sfx if the sound is not found, so it complains only once about missing sounds when you connect, rather than constantly, and also so using "play" commands for non-existent files won't eat up sfx slots (fuh)
 0 darkplaces client: add DP_LITSPRITES extension to document the fact that any sprite with a ! in its filename is lit rather than fullbright
 0 darkplaces client: add a swinging weapon motion to replace the removed forward/back movement of the weapon, should be controllable with cl_bob_* cvars (Joel Murdoch)
 0 darkplaces client: add back cl_particles_lighting cvar and add back the particle lighting (romi)
@@ -87,8 +88,6 @@
 0 darkplaces server: make fopen have the ability to disable fopen builtin access to read /, read data/, write data/, or disable fopen builtin entirely
 0 darkplaces server: make server able to work without models, just for sake of completeness
 0 darkplaces sound: Lordhavoc needs to talk to fuh about snd_macos.c (fuh)
-0 darkplaces sound: make sound precaching not allocate an sfx if the sound is not found, so it complains only once about missing sounds when you connect, rather than constantly, and also so using "play" commands for non-existent files won't eat up sfx slots (fuh) 
-0 darkplaces sound: non-cd music tracks should not be affected by sound volume setting (Urre)
 0 darkplaces sound: the new sound engine should have a cvar for random variations of pitch on sounds like in doom (RenegadeC)
 0 dpmod: add flame thrower enforcers back (scar3crow)
 0 dpmod: add flame thrower weapon, and make its altfire drop a canister of fuel (10 fuel units?), which can be ignited to set off as a bomb about the size of a rocket blast, plus some fireballs raining down (scar3crow)
@@ -415,6 +414,7 @@ d darkplaces server: make qc profile command post an error message instead of cr
 d darkplaces server: prevent player name changes faster than once every 5 seconds (sublim3)
 d darkplaces server: stop sound before loading a level to get rid of looping noise (Edward Holness)
 d darkplaces sound: dsound broken, needs to be managed as part of video system (jeremy janzen)
+d darkplaces sound: non-cd music tracks should not be affected by sound volume setting (Urre)
 d darkplaces video: add vid_vsync cvar and also to options menu (metlslime)
 d darkplaces: Host_Name_f validate player names, stripping \r and \n
 d darkplaces: PF_traceline/PF_tracebox now work with world as the edict
index 8f9c2dc83b063bd03bc9d2014581f2c32d5bd485..2200c87e0c22d5dbd7964a3063bd0d46a017707a 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -79,7 +79,6 @@ static DEVMODE gdevmode;
 static qboolean vid_initialized = false;
 static qboolean vid_wassuspended = false;
 static int vid_usingmouse;
-extern qboolean mouseactive;  // from in_win.c
 static HICON hIcon;
 
 HWND mainwindow;
@@ -145,7 +144,7 @@ HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion,
 int                    mouse_buttons;
 int                    mouse_oldbuttonstate;
 POINT          current_pos;
-int                    mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;
+int                    mouse_x, mouse_y, old_mouse_x, old_mouse_y;
 
 static qboolean        restore_spi;
 static int             originalmouseparms[3], newmouseparms[3] = {0, 0, 1};
@@ -1453,10 +1452,8 @@ void IN_MouseMove (usercmd_t *cmd)
        else
        {
                GetCursorPos (&current_pos);
-               mx = current_pos.x - window_center_x + mx_accum;
-               my = current_pos.y - window_center_y + my_accum;
-               mx_accum = 0;
-               my_accum = 0;
+               mx = current_pos.x - window_center_x;
+               my = current_pos.y - window_center_y;
        }
 
        IN_Mouse(cmd, mx, my);
@@ -1482,29 +1479,6 @@ void IN_Move (usercmd_t *cmd)
 }
 
 
-/*
-===========
-IN_Accumulate
-===========
-*/
-void IN_Accumulate (void)
-{
-       if (mouseactive)
-       {
-               if (!dinput)
-               {
-                       GetCursorPos (&current_pos);
-
-                       mx_accum += current_pos.x - window_center_x;
-                       my_accum += current_pos.y - window_center_y;
-
-               // force the mouse to the center, so there's room to move
-                       SetCursorPos (window_center_x, window_center_y);
-               }
-       }
-}
-
-
 /*
 ===================
 IN_ClearStates
@@ -1513,11 +1487,7 @@ IN_ClearStates
 void IN_ClearStates (void)
 {
        if (mouseactive)
-       {
-               mx_accum = 0;
-               my_accum = 0;
                mouse_oldbuttonstate = 0;
-       }
 }