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
// Try playing a fake track (sound file) first
sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, false);
// 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)
if (sfx == NULL || sfx->fetcher == NULL)
sfx = S_PrecacheSound (va ("cdtracks/track%03u.wav", track), false, false);
if (sfx != NULL)
SZ_Alloc (&cls.message, 1024, "cls.message");
CL_InitInput ();
SZ_Alloc (&cls.message, 1024, "cls.message");
CL_InitInput ();
//
// register our commands
//
// register our commands
sfx_t *cl_sfx_ric3;
sfx_t *cl_sfx_r_exp3;
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);
void CL_InitTEnts (void)
{
cl_sfx_wizhit = S_PrecacheSound ("sound/wizard/hit.wav", false, true);
buffer = Mem_Alloc (tempmempool, maxsize);
#ifdef FS_USESYSCALLS
lseek (packhandle, filesize - maxsize, SEEK_SET);
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);
#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);
#endif
{
Mem_Free (buffer);
if (cls.state != ca_dedicated)
{
VID_Open();
if (cls.state != ca_dedicated)
{
VID_Open();
+ CL_InitTEnts (); // We must wait after sound startup to load tent sounds
SCR_BeginLoadingPlaque();
MR_Init();
}
SCR_BeginLoadingPlaque();
MR_Init();
}
typedef enum {false, true} qboolean;
typedef enum {false, true} qboolean;
+#ifdef WIN32
+# define ssize_t long
+#endif
+
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef NULL
#define NULL ((void *)0)
#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
// up / down
#define PITCH 0
#define gl_solid_format 3
#define gl_alpha_format 4
#define gl_solid_format 3
#define gl_alpha_format 4
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))))
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))))
cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.1"};
cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "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
// ====================================================================
void S_SoundInfo_f(void)
// ====================================================================
void S_SoundInfo_f(void)
void S_FreeSfx (sfx_t *sfx)
{
// Never free a locked sfx
void S_FreeSfx (sfx_t *sfx)
{
// Never free a locked sfx
+ if (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK))
return;
Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name);
return;
Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name);
unsigned int i;
// Start the ambient sounds and make them loop
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)
{
// 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->flags &= ~SFXFLAG_SERVERSOUND;
}
sfx->flags &= ~SFXFLAG_SERVERSOUND;
}
for (i = 1; i < numsounds; i++)
{
sfx = S_FindName (serversound[i]);
for (i = 1; i < numsounds; i++)
{
sfx = S_FindName (serversound[i]);
- if (sfx != NULL && !(sfx->flags & SFXFLAG_SERVERSOUND))
sfx->flags |= SFXFLAG_SERVERSOUND;
}
}
sfx->flags |= SFXFLAG_SERVERSOUND;
}
}
if (sfx == NULL)
return NULL;
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);
if (!nosound.integer && snd_precache.integer)
S_LoadSound(sfx, complain);
+/*
+==================
+S_LockSfx
+
+Add a lock to a SFX
+==================
+*/
+void S_LockSfx (sfx_t *sfx)
+{
+ sfx->locks++;
+}
+
/*
==================
S_UnlockSfx
/*
==================
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--;
==================
*/
void S_UnlockSfx (sfx_t *sfx)
{
sfx->locks--;
target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
// Lock the SFX during play
target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
// Lock the SFX during play
if (!sound_started || !sfx || nosound.integer)
return -1;
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;
// 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;
S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_NONE, origin, fvol, attenuation, false);
target_chan->entnum = entnum;
target_chan->entchannel = entchannel;
{
channel_t *target_chan;
{
channel_t *target_chan;
+ if (!sound_started || !sfx || nosound.integer)
-
- if (total_channels == MAX_CHANNELS)
- Con_Print("total_channels == MAX_CHANNELS\n");
+ Con_DPrintf ("S_StaticSound: \"%s\" hasn't been precached\n", sfx->name);
- if (!S_LoadSound (sfx, true))
+ if (total_channels == MAX_CHANNELS)
+ {
+ Con_Print("S_StaticSound: total_channels == MAX_CHANNELS\n");
target_chan = &channels[total_channels++];
S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true);
target_chan = &channels[total_channels++];
S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true);
i = 1;
while (i<Cmd_Argc())
{
i = 1;
while (i<Cmd_Argc())
{
strlcpy(name, Cmd_Argv(i), sizeof(name));
if (!strrchr(name, '.'))
strlcat(name, ".wav", sizeof(name));
i++;
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)
// If we need to get the volume from the command line
if (fvol == -1.0f)
- 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;
+ }
{
size = sfx->mempool->totalsize;
total += size;
{
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->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);
}
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);
}
}
Con_Printf("Total resident: %i\n", total);
}
if (!snd_initialized.integer || nosound.integer)
return true;
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;
}
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;
ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 1);
if (ch_ind < 0)
return false;
#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_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
typedef struct snd_fetcher_s snd_fetcher_t;
struct sfx_s
char name[MAX_QPATH];
sfx_t *next;
mempool_t *mempool;
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;
unsigned int flags; // cf SFXFLAG_* defines
snd_format_t format;
int loopstart;
qboolean S_LoadSound (sfx_t *s, qboolean complain);
void S_UnloadSound(sfx_t *s);
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);
void *S_LockBuffer(void);
void S_UnlockBuffer(void);
-void S_UnlockSfx (sfx_t *sfx)
-{
-}
-
void S_Update(const matrix4x4_t *matrix)
{
}
void S_Update(const matrix4x4_t *matrix)
{
}
sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean lock);
void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds);
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);
// 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);