mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +00:00
Sound refactor backport step 1: flattened splitscreen-sound-fix
branch
This commit is contained in:
parent
80abf38648
commit
732861f0d4
1 changed files with 185 additions and 473 deletions
658
src/s_sound.c
658
src/s_sound.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue