Several changes to the SFX lock code in the sound engine, mainly to make sure SFXs...
authormolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 22 Nov 2004 14:38:33 +0000 (14:38 +0000)
committermolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 22 Nov 2004 14:38:33 +0000 (14:38 +0000)
Moved call to CL_InitTEnts after S_Startup so the tent sounds get properly precached
Added a developer warning when trying to play a non-precached SFX
Made the soundlist command more verbose
Added the ssize_t type for Win32 systems
Some comments and dead code removal

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

cd_shared.c
cl_main.c
cl_parse.c
fs.c
host.c
qtypes.h
render.h
snd_main.c
snd_main.h
snd_null.c
sound.h

index 9cedbac..70a446c 100644 (file)
@@ -115,7 +115,6 @@ void CDAudio_Play (qbyte track, qboolean looping)
 
        // Try playing a fake track (sound file) first
        sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, false);
-       // FIXME: perhaps force it to be always %03u (but for compatibility?):
        if (sfx == NULL || sfx->fetcher == NULL)
                sfx = S_PrecacheSound (va ("cdtracks/track%03u.wav", track), false, false);
        if (sfx != NULL)
index 6ecfefb..41667e5 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1298,7 +1298,6 @@ void CL_Init (void)
        SZ_Alloc (&cls.message, 1024, "cls.message");
 
        CL_InitInput ();
-       CL_InitTEnts ();
 
 //
 // register our commands
index 4e782b6..e49f1c3 100644 (file)
@@ -825,11 +825,7 @@ sfx_t *cl_sfx_ric2;
 sfx_t *cl_sfx_ric3;
 sfx_t *cl_sfx_r_exp3;
 
-/*
-=================
-CL_ParseTEnt
-=================
-*/
+
 void CL_InitTEnts (void)
 {
        cl_sfx_wizhit = S_PrecacheSound ("sound/wizard/hit.wav", false, true);
diff --git a/fs.c b/fs.c
index b358455..2f00c1e 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -405,10 +405,10 @@ qboolean PK3_GetEndOfCentralDir (const char *packfile, FILE *packhandle, pk3_end
        buffer = Mem_Alloc (tempmempool, maxsize);
 #ifdef FS_USESYSCALLS
        lseek (packhandle, filesize - maxsize, SEEK_SET);
-       if (read (packhandle, buffer, maxsize) != (int) maxsize)
+       if (read (packhandle, buffer, maxsize) != (ssize_t) maxsize)
 #else
        fseek (packhandle, filesize - maxsize, SEEK_SET);
-       if (fread (buffer, 1, maxsize, packhandle) != (unsigned int) maxsize)
+       if (fread (buffer, 1, maxsize, packhandle) != (size_t) maxsize)
 #endif
        {
                Mem_Free (buffer);
diff --git a/host.c b/host.c
index 953f394..ad337c5 100644 (file)
--- a/host.c
+++ b/host.c
@@ -934,6 +934,7 @@ void Host_Init (void)
        if (cls.state != ca_dedicated)
        {
                VID_Open();
+               CL_InitTEnts ();  // We must wait after sound startup to load tent sounds
                SCR_BeginLoadingPlaque();
                MR_Init();
        }
index 5e1d575..480b1e7 100644 (file)
--- a/qtypes.h
+++ b/qtypes.h
@@ -9,6 +9,10 @@ typedef unsigned char qbyte;
 
 typedef enum {false, true} qboolean;
 
+#ifdef WIN32
+# define ssize_t long
+#endif
+
 #ifndef NULL
 #define NULL ((void *)0)
 #endif
@@ -18,13 +22,6 @@ typedef enum {false, true} qboolean;
 #define TRUE 1
 #endif
 
-//define       PARANOID                        // speed sapping error checking
-#ifdef _DEBUG
-#define ASSERT(condition) if (!(condition)) Sys_Error("assertion (##condition) failed at " __FILE__ ":" __LINE__ "\n");
-#else
-#define ASSERT(condition)
-#endif
-
 // up / down
 #define        PITCH   0
 
index e0a6a81..6234721 100644 (file)
--- a/render.h
+++ b/render.h
@@ -141,8 +141,6 @@ void R_DrawExplosions(void);
 #define gl_solid_format 3
 #define gl_alpha_format 4
 
-//#define PARANOID 1
-
 int R_CullBox(const vec3_t mins, const vec3_t maxs);
 #define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (cl.worldmodel && cl.worldmodel->brush.BoxTouchingPVS && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, r_pvsbits, (mins), (maxs))))
 
index 7f01b52..af6275c 100644 (file)
@@ -82,9 +82,13 @@ cvar_t snd_show = {0, "snd_show", "0"};
 cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.1"};
 cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0"};
 
+// Ambient sounds
+sfx_t* ambient_sfxs [2] = { NULL, NULL };
+const char* ambient_names [2] = { "sound/ambience/water1.wav", "sound/ambience/wind2.wav" };
+
 
 // ====================================================================
-// User-setable variables
+// Functions
 // ====================================================================
 
 void S_SoundInfo_f(void)
@@ -263,7 +267,7 @@ S_FreeSfx
 void S_FreeSfx (sfx_t *sfx)
 {
        // Never free a locked sfx
-       if (sfx->locks > 0)
+       if (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK))
                return;
 
        Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name);
@@ -303,16 +307,27 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds)
        unsigned int i;
 
        // Start the ambient sounds and make them loop
-       channels[AMBIENT_WATER].sfx = S_PrecacheSound ("sound/ambience/water1.wav", false, true);
-       channels[AMBIENT_SKY].sfx = S_PrecacheSound ("sound/ambience/wind2.wav", false, true);
-       for (i = 0; i < NUM_AMBIENTS; i++)
-               channels[i].flags |= CHANNELFLAG_FORCELOOP;
+       for (i = 0; i < sizeof (ambient_sfxs) / sizeof (ambient_sfxs[0]); i++)
+       {
+               // Precache it if it's not done (request a lock to make sure it will never be freed)
+               if (ambient_sfxs[i] == NULL)
+                       ambient_sfxs[i] = S_PrecacheSound (ambient_names[i], false, true);
+               if (ambient_sfxs[i] != NULL)
+               {
+                       // Add a lock to the SFX while playing. It will be
+                       // removed by S_StopAllSounds at the end of the level
+                       S_LockSfx (ambient_sfxs[i]);
+
+                       channels[i].sfx = ambient_sfxs[i];
+                       channels[i].flags |= CHANNELFLAG_FORCELOOP;
+               }
+       }
 
        // 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--;
+                       S_UnlockSfx (sfx);
                        sfx->flags &= ~SFXFLAG_SERVERSOUND;
                }
 
@@ -320,9 +335,9 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds)
        for (i = 1; i < numsounds; i++)
        {
                sfx = S_FindName (serversound[i]);
-               if (sfx != NULL && !(sfx->flags & SFXFLAG_SERVERSOUND))
+               if (sfx != NULL)
                {
-                       sfx->locks++;
+                       S_LockSfx (sfx);
                        sfx->flags |= SFXFLAG_SERVERSOUND;
                }
        }
@@ -359,11 +374,8 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock)
        if (sfx == NULL)
                return NULL;
 
-       if (lock && !(sfx->flags & SFXFLAG_PERMANENT))
-       {
-               sfx->flags |= SFXFLAG_PERMANENT;
-               sfx->locks++;
-       }
+       if (lock)
+               S_LockSfx (sfx);
 
        if (!nosound.integer && snd_precache.integer)
                S_LoadSound(sfx, complain);
@@ -373,15 +385,26 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock)
 
 /*
 ==================
+S_LockSfx
+
+Add a lock to a SFX
+==================
+*/
+void S_LockSfx (sfx_t *sfx)
+{
+       sfx->locks++;
+}
+
+/*
+==================
 S_UnlockSfx
 
-Remove a lock from a SFX and freed it if possible
+Remove a lock from a SFX
 ==================
 */
 void S_UnlockSfx (sfx_t *sfx)
 {
        sfx->locks--;
-       S_FreeSfx (sfx);
 }
 
 
@@ -520,7 +543,7 @@ void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags,
                target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
 
        // Lock the SFX during play
-       sfx->locks++;
+       S_LockSfx (sfx);
 }
 
 
@@ -532,15 +555,17 @@ int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
 
        if (!sound_started || !sfx || nosound.integer)
                return -1;
+       if (!sfx->fetcher)
+       {
+               Con_DPrintf ("S_StartSound: \"%s\" hasn't been precached\n", sfx->name);
+               return -1;
+       }
 
        // Pick a channel to play on
        target_chan = SND_PickChannel(entnum, entchannel);
        if (!target_chan)
                return -1;
 
-       if (!S_LoadSound (sfx, true))
-               return -1;              // couldn't load the sound's data
-
        S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_NONE, origin, fvol, attenuation, false);
        target_chan->entnum = entnum;
        target_chan->entchannel = entchannel;
@@ -701,17 +726,19 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 {
        channel_t       *target_chan;
 
-       if (!sfx)
+       if (!sound_started || !sfx || nosound.integer)
                return;
-
-       if (total_channels == MAX_CHANNELS)
+       if (!sfx->fetcher)
        {
-               Con_Print("total_channels == MAX_CHANNELS\n");
+               Con_DPrintf ("S_StaticSound: \"%s\" hasn't been precached\n", sfx->name);
                return;
        }
 
-       if (!S_LoadSound (sfx, true))
+       if (total_channels == MAX_CHANNELS)
+       {
+               Con_Print("S_StaticSound: total_channels == MAX_CHANNELS\n");
                return;
+       }
 
        target_chan = &channels[total_channels++];
        S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true);
@@ -937,19 +964,11 @@ static void S_Play_Common(float fvol, float attenuation)
        i = 1;
        while (i<Cmd_Argc())
        {
+               // Get the name
                strlcpy(name, Cmd_Argv(i), sizeof(name));
                if (!strrchr(name, '.'))
                        strlcat(name, ".wav", sizeof(name));
                i++;
-               sfx = S_PrecacheSound (name, true, false);
-               // add a lock and the serversound flag to the sfx so it will be kept
-               // until level change
-               if (sfx && !(sfx->flags & SFXFLAG_SERVERSOUND))
-               {
-                       sfx->flags |= SFXFLAG_SERVERSOUND;
-                       sfx->locks++;
-               }
-
 
                // If we need to get the volume from the command line
                if (fvol == -1.0f)
@@ -958,13 +977,17 @@ static void S_Play_Common(float fvol, float attenuation)
                        i++;
                }
 
-               ch_ind = S_StartSound(-1, 0, sfx, listener_origin, fvol, attenuation);
+               sfx = S_PrecacheSound (name, true, false);
+               if (sfx)
+               {
+                       ch_ind = S_StartSound(-1, 0, sfx, listener_origin, fvol, attenuation);
 
-               // Free the sfx if the file didn't exist
-               if (ch_ind < 0)
-                       S_FreeSfx (sfx);
-               else
-                       channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
+                       // Free the sfx if the file didn't exist
+                       if (ch_ind < 0)
+                               S_FreeSfx (sfx);
+                       else
+                               channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
+               }
        }
 }
 
@@ -996,14 +1019,18 @@ void S_SoundList(void)
                {
                        size = sfx->mempool->totalsize;
                        total += size;
-                       Con_Printf ("%c%c(%2db, %6s) %8i : %s\n",
+                       Con_Printf ("%c%c%c%c(%2db, %6s) %8i : %s\n",
                                                (sfx->loopstart >= 0) ? 'L' : ' ',
                                                (sfx->flags & SFXFLAG_STREAMED) ? 'S' : ' ',
+                                               (sfx->locks > 0) ? 'K' : ' ',
+                                               (sfx->flags & SFXFLAG_PERMANENTLOCK) ? 'P' : ' ',
                                                sfx->format.width * 8,
                                                (sfx->format.channels == 1) ? "mono" : "stereo",
                                                size,
                                                sfx->name);
                }
+               else
+                       Con_Printf ("    (  unknown  ) unloaded : %s\n", sfx->name);
        }
        Con_Printf("Total resident: %i\n", total);
 }
@@ -1017,13 +1044,16 @@ qboolean S_LocalSound (const char *sound)
        if (!snd_initialized.integer || nosound.integer)
                return true;
 
-       sfx = S_PrecacheSound (sound, true, true);
+       sfx = S_PrecacheSound (sound, true, false);
        if (!sfx)
        {
                Con_Printf("S_LocalSound: can't precache %s\n", sound);
                return false;
        }
 
+       // Local sounds must not be freed
+       sfx->flags |= SFXFLAG_PERMANENTLOCK;
+
        ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 1);
        if (ch_ind < 0)
                return false;
index aa36d01..d2e37f3 100644 (file)
@@ -43,7 +43,7 @@ typedef struct
 #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
-#define SFXFLAG_PERMANENT              (1 << 3) // the sfx is used by the client code and should not be purged (even if it is also in the server precache list)
+#define SFXFLAG_PERMANENTLOCK  (1 << 3) // can never be freed (ex: used by the client code)
 
 typedef struct snd_fetcher_s snd_fetcher_t;
 struct sfx_s
@@ -51,9 +51,11 @@ 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.
+       int                                     locks;                  // One lock is automatically granted while the sfx is
+                                                                               // playing (and removed when stopped). Locks can also be
+                                                                               // added by S_PrecacheSound and S_ServerSounds.
+                                                                               // A SFX with no lock and no SFXFLAG_PERMANENTLOCK is
+                                                                               // freed at level change by S_ServerSounds.
        unsigned int            flags;                  // cf SFXFLAG_* defines
        snd_format_t            format;
        int                                     loopstart;
@@ -112,6 +114,9 @@ void SNDDMA_Shutdown(void);
 qboolean S_LoadSound (sfx_t *s, qboolean complain);
 void S_UnloadSound(sfx_t *s);
 
+void S_LockSfx (sfx_t *sfx);
+void S_UnlockSfx (sfx_t *sfx);
+
 void *S_LockBuffer(void);
 void S_UnlockBuffer(void);
 
index c276f72..0bd5157 100755 (executable)
@@ -83,10 +83,6 @@ sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean lock)
        return NULL;
 }
 
-void S_UnlockSfx (sfx_t *sfx)
-{
-}
-
 void S_Update(const matrix4x4_t *matrix)
 {
 }
diff --git a/sound.h b/sound.h
index b571be4..b09d89d 100644 (file)
--- a/sound.h
+++ b/sound.h
@@ -64,7 +64,6 @@ void S_ExtraUpdate (void);
 
 sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean lock);
 void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds);
-void S_UnlockSfx (sfx_t *sfx);
 
 // 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);