Sound refactor backport step 1: flattened splitscreen-sound-fix branch

This commit is contained in:
toaster 2022-12-17 12:58:28 +00:00
parent 80abf38648
commit 732861f0d4

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;
} }
@ -433,23 +424,37 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
} }
} }
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}; 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 +463,26 @@ 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;
if (i == 0 && democam.soundmobj)
{ {
listenmobj3 = players[displayplayers[2]].mo; listenmobj[i] = democam.soundmobj;
if (players[displayplayers[2]].awayviewtics) continue;
listenmobj3 = players[displayplayers[2]].awayviewmobj; }
if (splitscreen > 2) if (player->awayviewtics)
{ {
listenmobj4 = players[displayplayers[3]].mo; listenmobj[i] = player->awayviewmobj;
if (players[displayplayers[3]].awayviewtics) }
listenmobj4 = players[displayplayers[3]].awayviewmobj; else
} {
listenmobj[i] = player->mo;
} }
} }
@ -490,75 +494,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; {
listener[i].x = camera[i].x;
listener[i].y = camera[i].y;
listener[i].z = camera[i].z;
listener[i].angle = camera[i].angle;
anyListeners = true;
}
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;
}
} }
else if (listenmobj)
if (origin && anyListeners == false)
{ {
listener.x = listenmobj->x; // If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound?
listener.y = listenmobj->y;
listener.z = listenmobj->z;
listener.angle = listenmobj->angle;
}
else if (origin)
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 #
@ -578,36 +539,40 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
pitch = NORM_PITCH; pitch = NORM_PITCH;
priority = NORM_PRIORITY; priority = NORM_PRIORITY;
if (splitscreen && origin) for (i = splitscreen; i >= 0; i--)
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 // Copy the sound for the splitscreen players!
if (origin && origin != listenmobj2) if (listenmobj[i] == NULL && i != 0)
{ {
INT32 rc; continue;
rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx); }
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj[i])
{
boolean rc = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
if (!rc) if (!rc)
goto dontplay; // Maybe the other player can hear it... {
continue; // Maybe the other player can hear it...
}
if (origin->x == listener2.x && origin->y == listener2.y) if (origin->x == listener[i].x && origin->y == listener[i].y)
{
sep = NORM_SEP; sep = NORM_SEP;
}
} }
else if (!origin) else if (i > 0 && !origin)
// Do not play origin-less sounds for the second player. {
// Do not play origin-less sounds for the splitscreen players.
// The first player will be able to hear it just fine, // The first player will be able to hear it just fine,
// we really don't want it playing twice. // we really don't want it playing twice.
goto dontplay; continue;
}
else else
{
sep = NORM_SEP; 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. // 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
@ -616,185 +581,40 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// 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
#ifdef SURROUND #ifdef SURROUND
&& sep != SURROUND_SEP && sep != SURROUND_SEP
#endif #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:
if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player
{
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj3)
{ {
INT32 rc; sep = (~sep) & 255;
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 // At this point it is determined that a sound can and should be played, so find a free channel to play it on
cnum = S_getChannel(origin, sfx); cnum = S_getChannel(origin, sfx);
if (cnum < 0) 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:
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; return; // If there's no free channels, there won't be any for anymore players either
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 // Now that we know we are going to play a sound, fill out this info
cnum = S_getChannel(origin, sfx); channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
if (cnum < 0) channels[cnum].volume = initial_volume;
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); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay4:
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx);
if (!rc)
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.
// 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].volume = initial_volume;
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)
@ -900,23 +720,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 +743,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 +754,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;
if (i == 0 && democam.soundmobj)
{ {
listenmobj3 = players[displayplayers[2]].mo; listenmobj[i] = democam.soundmobj;
if (players[displayplayers[2]].awayviewtics) continue;
listenmobj3 = players[displayplayers[2]].awayviewmobj; }
if (splitscreen > 2) if (player->awayviewtics)
{ {
listenmobj4 = players[displayplayers[3]].mo; listenmobj[i] = player->awayviewmobj;
if (players[displayplayers[3]].awayviewtics) }
listenmobj4 = players[displayplayers[3]].awayviewmobj; else
} {
listenmobj[i] = player->mo;
} }
} }
if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
{
listener.x = camera[0].x;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
}
else if (listenmobj)
{
listener.x = listenmobj->x;
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 +790,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)
{ {
listener3.x = camera[2].x; listener[i].x = camera[i].x;
listener3.y = camera[2].y; listener[i].y = camera[i].y;
listener3.z = camera[2].z; listener[i].z = camera[i].z;
listener3.angle = camera[2].angle; listener[i].angle = camera[i].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 +823,53 @@ 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)
for (i = 0; i <= splitscreen; i++)
{
if (c->origin == players[displayplayers[i]].mo)
{
itsUs = true;
break;
}
}
if (itsUs == false)
{ {
const mobj_t *soundmobj = c->origin; const mobj_t *soundmobj = c->origin;
fixed_t recdist = -1; fixed_t recdist = INT32_MAX;
INT32 i, p = -1; UINT8 p = 0;
for (i = 0; i <= splitscreen; i++) for (i = 0; i <= splitscreen; i++)
{ {
fixed_t thisdist = -1; fixed_t thisdist = INT32_MAX;
if (i == 0 && listenmobj) if (!listenmobj[i])
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)) thisdist = P_AproxDistance(listener[i].x - soundmobj->x, listener[i].y - soundmobj->y);
if (thisdist < recdist)
{ {
recdist = thisdist; recdist = thisdist;
p = i; p = i;
} }
} }
if (p != -1) if (listenmobj[p])
{ {
if (p == 1) audible = S_AdjustSoundParams(
{ listenmobj[p], 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 +972,39 @@ 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)
{ {
const boolean reverse = (stereoreverse.value ^ encoremode);
fixed_t approx_dist; fixed_t approx_dist;
angle_t angle; angle_t angle;
listener_t listensource; listener_t listensource;
INT32 i;
const boolean reverse = (stereoreverse.value ^ encoremode);
(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 = listener->x;
listensource.y = listener->y;
listensource.z = listener->z;
listensource.angle = listener->angle;
for (i = 0; i <= splitscreen; i++)
{ {
listensource.x = camera[0].x; // If listener is a chasecam player, use the camera instead
listensource.y = camera[0].y; if (listener == players[displayplayers[i]].mo && camera[i].chase)
listensource.z = camera[0].z; {
listensource.angle = camera[0].angle; listensource.x = camera[i].x;
} listensource.y = camera[i].y;
else if (splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase) listensource.z = camera[i].z;
{ listensource.angle = camera[i].angle;
listensource.x = camera[1].x; break;
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.y = listener->y;
listensource.z = listener->z;
listensource.angle = listener->angle;
} }
if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case
@ -1339,7 +1054,7 @@ 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;
// angle of source to listener // angle of source to listener
angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
@ -1374,9 +1089,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);
} }