Skip to content

Commit

Permalink
Merge PR 'Muffle sounds when the player is under water'
Browse files Browse the repository at this point in the history
See DarkPlacesEngine/DarkPlaces#140

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
  • Loading branch information
bones-was-here committed Mar 10, 2024
2 parents c1bc095 + aa40915 commit cf08534
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 1 deletion.
3 changes: 3 additions & 0 deletions client.h
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,9 @@ typedef struct client_state_s

// used by EntityState5_ReadUpdate
skeleton_t *engineskeletonobjects;

// used by underwater sound filter (snd_waterfx)
qbool view_underwater;
}
client_state_t;

Expand Down
6 changes: 5 additions & 1 deletion snd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ cvar_t snd_spatialization_prologic_frontangle = {CF_CLIENT | CF_ARCHIVE, "snd_sp
cvar_t snd_spatialization_occlusion = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_occlusion", "1", "enable occlusion testing on spatialized sounds, which simply quiets sounds that are blocked by the world; 1 enables PVS method, 2 enables LineOfSight method, 3 enables both"};

// Cvars declared in snd_main.h (shared with other snd_*.c files)
cvar_t snd_waterfx = {CF_CLIENT | CF_ARCHIVE, "snd_waterfx", "1", "underwater sound filter strength"};
cvar_t _snd_mixahead = {CF_CLIENT | CF_ARCHIVE, "_snd_mixahead", "0.15", "how much sound to mix ahead of time"};
cvar_t snd_streaming = {CF_CLIENT | CF_ARCHIVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory); when set to 2, streaming is performed even if this would waste memory"};
cvar_t snd_streaming_length = {CF_CLIENT | CF_ARCHIVE, "snd_streaming_length", "1", "decompress sounds completely if they are less than this play time when snd_streaming is 1"};
Expand Down Expand Up @@ -812,6 +813,7 @@ void S_Init(void)
Cvar_RegisterVariable(&ambient_fade);
Cvar_RegisterVariable(&snd_noextraupdate);
Cvar_RegisterVariable(&snd_show);
Cvar_RegisterVariable(&snd_waterfx);
Cvar_RegisterVariable(&_snd_mixahead);
Cvar_RegisterVariable(&snd_swapstereo); // for people with backwards sound wiring
Cvar_RegisterVariable(&snd_channellayout);
Expand Down Expand Up @@ -1850,7 +1852,6 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true, 0, 0, 0, 1.0f);
}


/*
===================
S_UpdateAmbientSounds
Expand All @@ -1870,7 +1871,10 @@ static void S_UpdateAmbientSounds (void)
if (cl.worldmodel && cl.worldmodel->brush.AmbientSoundLevelsForPoint)
cl.worldmodel->brush.AmbientSoundLevelsForPoint(cl.worldmodel, listener_origin, ambientlevels, sizeof(ambientlevels));


// Calc ambient sound levels
S_SetUnderwaterIntensity();

for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{
chan = &channels[ambient_channel];
Expand Down
3 changes: 3 additions & 0 deletions snd_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ extern snd_ringbuffer_t *snd_renderbuffer;
extern qbool snd_threaded; // enables use of snd_usethreadedmixing, provided that no sound hacks are in effect (like timedemo)
extern qbool snd_usethreadedmixing; // if true, the main thread does not mix sound, soundtime does not advance, and neither does snd_renderbuffer->endframe, instead the audio thread will call S_MixToBuffer as needed

extern struct cvar_s snd_waterfx;
extern struct cvar_s _snd_mixahead;
extern struct cvar_s snd_swapstereo;
extern struct cvar_s snd_streaming;
Expand Down Expand Up @@ -152,6 +153,8 @@ extern qbool simsound;
// Architecture-independent functions
// ====================================================================

void S_SetUnderwaterIntensity(void);

void S_MixToBuffer(void *stream, unsigned int frames);

qbool S_LoadSound (struct sfx_s *sfx, qbool complain);
Expand Down
63 changes: 63 additions & 0 deletions snd_mix.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,66 @@ static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_p
}



/*
===============================================================================
UNDERWATER EFFECT
Muffles the intensity of sounds when the player is underwater
===============================================================================
*/

static struct
{
float intensity;
float alpha;
float accum[SND_LISTENERS];
}
underwater = {0.f, 1.f, {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}};

void S_SetUnderwaterIntensity(void)
{
float target = cl.view_underwater ? bound(0.f, snd_waterfx.value, 2.f) : 0.f;

if (underwater.intensity < target)
{
underwater.intensity += cl.realframetime * 4.f;
underwater.intensity = min(underwater.intensity, target);
}
else if (underwater.intensity > target)
{
underwater.intensity -= cl.realframetime * 4.f;
underwater.intensity = max(underwater.intensity, target);
}

underwater.alpha = exp(-underwater.intensity * log(12.f));
}

static void S_UnderwaterFilter(int endtime)
{
int i;
int sl;

if (!underwater.intensity)
{
if (endtime > 0)
for (sl = 0; sl < SND_LISTENERS; sl++)
underwater.accum[sl] = paintbuffer[endtime-1].sample[sl];
return;
}

for (i = 0; i < endtime; i++)
for (sl = 0; sl < SND_LISTENERS; sl++)
{
underwater.accum[sl] += underwater.alpha * (paintbuffer[i].sample[sl] - underwater.accum[sl]);
paintbuffer[i].sample[sl] = underwater.accum[sl];
}
}



/*
===============================================================================
Expand Down Expand Up @@ -580,6 +640,9 @@ void S_MixToBuffer(void *stream, unsigned int bufferframes)

S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);

S_UnderwaterFilter(totalmixframes);


#ifdef CONFIG_VIDEO_CAPTURE
if (!snd_usethreadedmixing)
S_CaptureAVISound(paintbuffer, totalmixframes);
Expand Down
2 changes: 2 additions & 0 deletions view.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,7 @@ void V_CalcViewBlend(void)
supercontents = CL_PointSuperContents(vieworigin);
if (supercontents & SUPERCONTENTS_LIQUIDSMASK)
{
cl.view_underwater = true;
r_refdef.frustumscale_x *= 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
r_refdef.frustumscale_y *= 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
if (supercontents & SUPERCONTENTS_LAVA)
Expand All @@ -1083,6 +1084,7 @@ void V_CalcViewBlend(void)
}
else
{
cl.view_underwater = false;
cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0;
cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 0;
cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0;
Expand Down

0 comments on commit cf08534

Please sign in to comment.