Merge branch 'sound-refactor-backport' into 'master'

Sound refactor backport

Closes #22

See merge request KartKrew/Kart-Public!325
This commit is contained in:
Sal 2022-12-20 10:06:25 +00:00
commit 20a5adde02

View file

@ -46,7 +46,7 @@ extern INT32 msg_id;
// 3D Sound Interface // 3D Sound Interface
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
#else #else
static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
#endif #endif
CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}}; CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}};
@ -189,8 +189,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
// channel number to use // channel number to use
INT32 cnum; INT32 cnum;
channel_t *c;
// Find an open channel // Find an open channel
for (cnum = 0; cnum < numofchannels; cnum++) for (cnum = 0; cnum < numofchannels; cnum++)
{ {
@ -202,7 +200,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND)) else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND))
{ {
return -1; return -1;
break;
} }
else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true) else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true)
{ {
@ -246,12 +243,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
} }
} }
c = &channels[cnum];
// channel is decided to be cnum.
c->sfxinfo = sfxinfo;
c->origin = origin;
return cnum; return cnum;
} }
@ -407,7 +398,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
if (channels[cnum].sfxinfo == &S_sfx[sfx_id] && channels[cnum].origin == origin) if (channels[cnum].sfxinfo == &S_sfx[sfx_id] && channels[cnum].origin == origin)
{ {
S_StopChannel(cnum); S_StopChannel(cnum);
break;
} }
} }
} }
@ -428,28 +418,42 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
if (channels[cnum].sfxinfo == &S_sfx[sfxnum]) if (channels[cnum].sfxinfo == &S_sfx[sfxnum])
{ {
S_StopChannel(cnum); S_StopChannel(cnum);
break;
} }
} }
} }
static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
{
fixed_t root = INT32_MAX;
if (splitscreen == 0)
{
return volume;
}
root = FixedSqrt((splitscreen + 1) * (FRACUNIT/3));
return FixedDiv(
volume * FRACUNIT,
root
) / FRACUNIT;
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{ {
const INT32 initial_volume = volume;
INT32 sep, pitch, priority, cnum;
sfxinfo_t *sfx;
const boolean reverse = (stereoreverse.value ^ encoremode);
const mobj_t *origin = (const mobj_t *)origin_p; const mobj_t *origin = (const mobj_t *)origin_p;
const boolean reverse = (stereoreverse.value ^ encoremode);
const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
listener_t listener = {0,0,0,0}; sfxinfo_t *sfx;
listener_t listener2 = {0,0,0,0}; INT32 sep, pitch, priority, cnum;
listener_t listener3 = {0,0,0,0}; boolean anyListeners = false;
listener_t listener4 = {0,0,0,0}; boolean itsUs = false;
INT32 i;
mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; listener_t listener[MAXSPLITSCREENPLAYERS];
mobj_t *listenmobj2 = NULL; mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
if (sound_disabled || !sound_started) if (sound_disabled || !sound_started)
return; return;
@ -458,27 +462,29 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx_id == sfx_None) if (sfx_id == sfx_None)
return; return;
if (players[displayplayers[0]].awayviewtics) for (i = 0; i <= splitscreen; i++)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
{ {
listenmobj2 = players[displayplayers[1]].mo; player_t *player = &players[displayplayers[i]];
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
if (splitscreen > 1) memset(&listener[i], 0, sizeof (listener[i]));
{ listenmobj[i] = NULL;
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
if (splitscreen > 2) if (i == 0 && democam.soundmobj)
{ {
listenmobj4 = players[displayplayers[3]].mo; listenmobj[i] = democam.soundmobj;
if (players[displayplayers[3]].awayviewtics)
listenmobj4 = players[displayplayers[3]].awayviewmobj;
} }
else if (player->awayviewtics)
{
listenmobj[i] = player->awayviewmobj;
}
else
{
listenmobj[i] = player->mo;
}
if (origin && origin == listenmobj[i])
{
itsUs = true;
} }
} }
@ -490,75 +496,32 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
}; };
#endif #endif
if (camera[0].chase && !players[displayplayers[0]].awayviewtics) for (i = 0; i <= splitscreen; i++)
{ {
listener.x = camera[0].x; player_t *player = &players[displayplayers[i]];
listener.y = camera[0].y;
listener.z = camera[0].z; if (camera[i].chase && !player->awayviewtics)
listener.angle = camera[0].angle;
}
else if (listenmobj)
{ {
listener.x = listenmobj->x; listener[i].x = camera[i].x;
listener.y = listenmobj->y; listener[i].y = camera[i].y;
listener.z = listenmobj->z; listener[i].z = camera[i].z;
listener.angle = listenmobj->angle; listener[i].angle = camera[i].angle;
anyListeners = true;
} }
else if (origin) else if (listenmobj[i])
{
listener[i].x = listenmobj[i]->x;
listener[i].y = listenmobj[i]->y;
listener[i].z = listenmobj[i]->z;
listener[i].angle = listenmobj[i]->angle;
anyListeners = true;
}
}
if (origin && anyListeners == false)
{
// If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound?
return; return;
if (listenmobj2)
{
if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
{
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
listener2.x = listenmobj2->x;
listener2.y = listenmobj2->y;
listener2.z = listenmobj2->z;
listener2.angle = listenmobj2->angle;
}
}
if (listenmobj3)
{
if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
{
listener3.x = camera[2].x;
listener3.y = camera[2].y;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
}
else
{
listener3.x = listenmobj3->x;
listener3.y = listenmobj3->y;
listener3.z = listenmobj3->z;
listener3.angle = listenmobj3->angle;
}
}
if (listenmobj4)
{
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
listener4.x = listenmobj4->x;
listener4.y = listenmobj4->y;
listener4.z = listenmobj4->z;
listener4.angle = listenmobj4->angle;
}
} }
// check for bogus sound # // check for bogus sound #
@ -577,198 +540,51 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// Initialize sound parameters // Initialize sound parameters
pitch = NORM_PITCH; pitch = NORM_PITCH;
priority = NORM_PRIORITY; priority = NORM_PRIORITY;
sep = NORM_SEP;
if (splitscreen && origin) i = 0; // sensible default
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
if (splitscreen && listenmobj2) // Copy the sound for the split player
{ {
// Check to see if it is audible, and if not, modify the params // Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj2) if (origin && !itsUs)
{ {
INT32 rc; boolean audible = false;
rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx); if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
if (!rc) for (; j <= splitscreen; j++)
goto dontplay; // Maybe the other player can hear it... {
fixed_t thisdist = INT32_MAX;
if (origin->x == listener2.x && origin->y == listener2.y) if (!listenmobj[j])
sep = NORM_SEP; {
} continue;
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay;
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay: thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player if (thisdist >= recdist)
{ {
// Check to see if it is audible, and if not, modify the params continue;
if (origin && origin != listenmobj3)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay3; // Maybe the other player can hear it...
if (origin->x == listener3.x && origin->y == listener3.y)
sep = NORM_SEP;
}
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay3;
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay3: recdist = thisdist;
i = j;
if (splitscreen > 2 && listenmobj4) // Copy the sound for the split player
{
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj4)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay4; // Maybe the other player can hear it...
if (origin->x == listener4.x && origin->y == listener4.y)
sep = NORM_SEP;
} }
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay4;
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay4: if (listenmobj[i])
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj)
{ {
INT32 rc; audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx); }
if (!rc) if (!audible)
{
return; return;
if (origin->x == listener.x && origin->y == listener.y)
sep = NORM_SEP;
} }
else }
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return;
// This is supposed to handle the loading/caching. // This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly // For some odd reason, the caching is done nearly
@ -777,11 +593,15 @@ dontplay4:
// cache data if necessary // cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload // NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data) if (!sfx->data)
{
sfx->data = I_GetSfx(sfx); sfx->data = I_GetSfx(sfx);
}
// increase the usefulness // increase the usefulness
if (sfx->usefulness++ < 0) if (sfx->usefulness++ < 0)
{
sfx->usefulness = -1; sfx->usefulness = -1;
}
// Avoid channel reverse if surround // Avoid channel reverse if surround
if (reverse if (reverse
@ -789,12 +609,24 @@ dontplay4:
&& sep != SURROUND_SEP && sep != SURROUND_SEP
#endif #endif
) )
{
sep = (~sep) & 255; sep = (~sep) & 255;
}
// Assigns the handle to one of the channels in the // At this point it is determined that a sound can and should be played, so find a free channel to play it on
// mix/output buffer. cnum = S_getChannel(origin, sfx);
if (cnum < 0)
{
return; // If there's no free channels, there won't be any for anymore players either
}
// Now that we know we are going to play a sound, fill out this info
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume; channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
}
} }
void S_StartSound(const void *origin, sfxenum_t sfx_id) void S_StartSound(const void *origin, sfxenum_t sfx_id)
@ -884,7 +716,6 @@ void S_StopSound(void *origin)
if (channels[cnum].sfxinfo && channels[cnum].origin == origin) if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
{ {
S_StopChannel(cnum); S_StopChannel(cnum);
break;
} }
} }
} }
@ -900,23 +731,13 @@ static INT32 actualmidimusicvolume;
void S_UpdateSounds(void) void S_UpdateSounds(void)
{ {
INT32 audible, cnum, volume, sep, pitch; INT32 cnum, volume, sep, pitch;
boolean audible = false;
channel_t *c; channel_t *c;
INT32 i;
listener_t listener; listener_t listener[MAXSPLITSCREENPLAYERS];
listener_t listener2; mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
listener_t listener3;
listener_t listener4;
mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
memset(&listener, 0, sizeof(listener_t));
memset(&listener2, 0, sizeof(listener_t));
memset(&listener3, 0, sizeof(listener_t));
memset(&listener4, 0, sizeof(listener_t));
// Update sound/music volumes, if changed manually at console // Update sound/music volumes, if changed manually at console
if (actualsfxvolume != cv_soundvolume.value) if (actualsfxvolume != cv_soundvolume.value)
@ -933,7 +754,7 @@ void S_UpdateSounds(void)
{ {
#ifndef NOMUMBLE #ifndef NOMUMBLE
// Stop Mumble cutting out. I'm sick of it. // Stop Mumble cutting out. I'm sick of it.
I_UpdateMumble(NULL, listener); I_UpdateMumble(NULL, listener[0]);
#endif #endif
// Stop cutting FMOD out. WE'RE sick of it. // Stop cutting FMOD out. WE'RE sick of it.
@ -944,47 +765,31 @@ void S_UpdateSounds(void)
if (dedicated || sound_disabled) if (dedicated || sound_disabled)
return; return;
if (players[displayplayers[0]].awayviewtics) for (i = 0; i <= splitscreen; i++)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
{ {
listenmobj2 = players[displayplayers[1]].mo; player_t *player = &players[displayplayers[i]];
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
if (splitscreen > 1) memset(&listener[i], 0, sizeof (listener[i]));
{ listenmobj[i] = NULL;
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
if (splitscreen > 2) if (i == 0 && democam.soundmobj)
{ {
listenmobj4 = players[displayplayers[3]].mo; listenmobj[i] = democam.soundmobj;
if (players[displayplayers[3]].awayviewtics) continue;
listenmobj4 = players[displayplayers[3]].awayviewmobj;
}
}
} }
if (camera[0].chase && !players[displayplayers[0]].awayviewtics) if (player->awayviewtics)
{ {
listener.x = camera[0].x; listenmobj[i] = player->awayviewmobj;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
} }
else if (listenmobj) else
{ {
listener.x = listenmobj->x; listenmobj[i] = player->mo;
listener.y = listenmobj->y; }
listener.z = listenmobj->z;
listener.angle = listenmobj->angle;
} }
#ifndef NOMUMBLE #ifndef NOMUMBLE
I_UpdateMumble(players[consoleplayer].mo, listener); I_UpdateMumble(players[consoleplayer].mo, listener[0]);
#endif #endif
#ifdef HW3SOUND #ifdef HW3SOUND
@ -996,57 +801,23 @@ void S_UpdateSounds(void)
} }
#endif #endif
if (listenmobj2) for (i = 0; i <= splitscreen; i++)
{ {
if (camera[1].chase && !players[displayplayers[1]].awayviewtics) player_t *player = &players[displayplayers[i]];
{
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
listener2.x = listenmobj2->x;
listener2.y = listenmobj2->y;
listener2.z = listenmobj2->z;
listener2.angle = listenmobj2->angle;
}
}
if (listenmobj3) if (camera[i].chase && !player->awayviewtics)
{ {
if (camera[2].chase && !players[displayplayers[2]].awayviewtics) listener[i].x = camera[i].x;
{ listener[i].y = camera[i].y;
listener3.x = camera[2].x; listener[i].z = camera[i].z;
listener3.y = camera[2].y; listener[i].angle = camera[i].angle;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
} }
else else if (listenmobj[i])
{ {
listener3.x = listenmobj3->x; listener[i].x = listenmobj[i]->x;
listener3.y = listenmobj3->y; listener[i].y = listenmobj[i]->y;
listener3.z = listenmobj3->z; listener[i].z = listenmobj[i]->z;
listener3.angle = listenmobj3->angle; listener[i].angle = listenmobj[i]->angle;
}
}
if (listenmobj4)
{
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
listener4.x = listenmobj4->x;
listener4.y = listenmobj4->y;
listener4.z = listenmobj4->z;
listener4.angle = listenmobj4->angle;
} }
} }
@ -1063,83 +834,60 @@ void S_UpdateSounds(void)
pitch = NORM_PITCH; pitch = NORM_PITCH;
sep = NORM_SEP; sep = NORM_SEP;
if (splitscreen && c->origin)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
// check non-local sounds for distance clipping // check non-local sounds for distance clipping
// or modify their params // or modify their params
if (c->origin && ((c->origin != players[consoleplayer].mo) if (c->origin)
|| (splitscreen && c->origin != players[displayplayers[1]].mo)
|| (splitscreen > 1 && c->origin != players[displayplayers[2]].mo)
|| (splitscreen > 2 && c->origin != players[displayplayers[3]].mo)))
{ {
// Whomever is closer gets the sound, but only in splitscreen. boolean itsUs = false;
if (splitscreen)
{
const mobj_t *soundmobj = c->origin;
fixed_t recdist = -1;
INT32 i, p = -1;
for (i = 0; i <= splitscreen; i++) for (i = splitscreen; i >= 0; i--)
{ {
fixed_t thisdist = -1; if (c->origin != listenmobj[i])
if (i == 0 && listenmobj)
thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
else if (i == 1 && listenmobj2)
thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y);
else if (i == 2 && listenmobj3)
thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y);
else if (i == 3 && listenmobj4)
thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y);
else
continue; continue;
if (recdist == -1 || (thisdist != -1 && thisdist < recdist)) itsUs = true;
}
if (itsUs == false)
{ {
const mobj_t *origin = c->origin;
i = 0;
if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
for (; j <= splitscreen; j++)
{
fixed_t thisdist = INT32_MAX;
if (!listenmobj[j])
{
continue;
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist; recdist = thisdist;
p = i; i = j;
} }
} }
if (p != -1) if (listenmobj[i])
{ {
if (p == 1) audible = S_AdjustSoundParams(
{ listenmobj[i], c->origin,
// Player 2 gets the sound &volume, &sep, &pitch,
audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, c->sfxinfo
c->sfxinfo); );
} }
else if (p == 2)
{
// Player 3 gets the sound
audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else if (p == 3)
{
// Player 4 gets the sound
audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
}
else if (listenmobj && !splitscreen)
{
// In the case of a single player, he or she always should get updated sound.
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
if (audible) if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch); I_UpdateSoundParams(c->handle, volume, sep, pitch);
@ -1242,54 +990,38 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
// If the sound is not audible, returns a 0. // If the sound is not audible, returns a 0.
// Otherwise, modifies parameters and returns 1. // Otherwise, modifies parameters and returns 1.
// //
INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
sfxinfo_t *sfxinfo) sfxinfo_t *sfxinfo)
{ {
fixed_t approx_dist;
angle_t angle;
listener_t listensource;
const boolean reverse = (stereoreverse.value ^ encoremode); const boolean reverse = (stereoreverse.value ^ encoremode);
fixed_t approx_dist;
listener_t listensource;
INT32 i;
(void)pitch; (void)pitch;
if (!listener) if (!listener)
return false; return false;
if (listener == players[displayplayers[0]].mo && camera[0].chase) // Init listensource with default listener
{
listensource.x = camera[0].x;
listensource.y = camera[0].y;
listensource.z = camera[0].z;
listensource.angle = camera[0].angle;
}
else if (splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase)
{
listensource.x = camera[1].x;
listensource.y = camera[1].y;
listensource.z = camera[1].z;
listensource.angle = camera[1].angle;
}
else if (splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase)
{
listensource.x = camera[2].x;
listensource.y = camera[2].y;
listensource.z = camera[2].z;
listensource.angle = camera[2].angle;
}
else if (splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase)
{
listensource.x = camera[3].x;
listensource.y = camera[3].y;
listensource.z = camera[3].z;
listensource.angle = camera[3].angle;
}
else
{
listensource.x = listener->x; listensource.x = listener->x;
listensource.y = listener->y; listensource.y = listener->y;
listensource.z = listener->z; listensource.z = listener->z;
listensource.angle = listener->angle; listensource.angle = listener->angle;
for (i = 0; i <= splitscreen; i++)
{
// If listener is a chasecam player, use the camera instead
if (listener == players[displayplayers[i]].mo && camera[i].chase)
{
listensource.x = camera[i].x;
listensource.y = camera[i].y;
listensource.z = camera[i].z;
listensource.angle = camera[i].angle;
break;
}
} }
if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case
@ -1339,10 +1071,16 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
approx_dist = FixedDiv(approx_dist,2*FRACUNIT); approx_dist = FixedDiv(approx_dist,2*FRACUNIT);
if (approx_dist > S_CLIPPING_DIST) if (approx_dist > S_CLIPPING_DIST)
return 0; return false;
if (source->x == listensource.x && source->y == listensource.y)
{
*sep = NORM_SEP;
}
else
{
// angle of source to listener // angle of source to listener
angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); angle_t angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
if (angle > listensource.angle) if (angle > listensource.angle)
angle = angle - listensource.angle; angle = angle - listensource.angle;
@ -1364,6 +1102,7 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
// stereo separation // stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS); *sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
} }
}
// volume calculation // volume calculation
/* not sure if it should be > (no =), but this matches the old behavior */ /* not sure if it should be > (no =), but this matches the old behavior */
@ -1374,9 +1113,6 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR; *vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
} }
if (splitscreen)
*vol = FixedDiv((*vol)<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
return (*vol > 0); return (*vol > 0);
} }