diff --git a/src/s_sound.c b/src/s_sound.c index ea0a1bbe70d0a6139ac45989ade3eda00eeaed0d..d80fa1ca9ed0b3f6c6e77ffc583aac2701e4ef9c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -46,7 +46,7 @@ extern INT32 msg_id; // 3D Sound Interface #include "hardware/hw3sound.h" #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 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 INT32 cnum; - channel_t *c; - // Find an open channel 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)) { return -1; - break; } 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; } @@ -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) { S_StopChannel(cnum); - break; } } } @@ -428,28 +418,42 @@ void S_StopSoundByNum(sfxenum_t sfxnum) if (channels[cnum].sfxinfo == &S_sfx[sfxnum]) { 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) { - 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 boolean reverse = (stereoreverse.value ^ encoremode); + const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume); - listener_t listener = {0,0,0,0}; - listener_t listener2 = {0,0,0,0}; - listener_t listener3 = {0,0,0,0}; - listener_t listener4 = {0,0,0,0}; + sfxinfo_t *sfx; + INT32 sep, pitch, priority, cnum; + boolean anyListeners = false; + boolean itsUs = false; + INT32 i; - mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; - mobj_t *listenmobj2 = NULL; - mobj_t *listenmobj3 = NULL; - mobj_t *listenmobj4 = NULL; + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; if (sound_disabled || !sound_started) return; @@ -458,27 +462,29 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) if (sfx_id == sfx_None) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (splitscreen) + for (i = 0; i <= splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (splitscreen > 1) + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; + + if (i == 0 && democam.soundmobj) + { + listenmobj[i] = democam.soundmobj; + } + else if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + listenmobj[i] = player->mo; + } - if (splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + 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 - 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; - } - else if (origin) - return; - - if (listenmobj2) + for (i = 0; i <= splitscreen; i++) { - 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; - } - } + player_t *player = &players[displayplayers[i]]; - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) + if (camera[i].chase && !player->awayviewtics) { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].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 + else if (listenmobj[i]) { - listener3.x = listenmobj3->x; - listener3.y = listenmobj3->y; - listener3.z = listenmobj3->z; - listener3.angle = listenmobj3->angle; + 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 (listenmobj4) + if (origin && anyListeners == false) { - 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; - } + // If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound? + return; } // check for bogus sound # @@ -577,93 +540,51 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Initialize sound parameters pitch = NORM_PITCH; priority = NORM_PRIORITY; + sep = NORM_SEP; - if (splitscreen && origin) - volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS; + i = 0; // sensible default - if (splitscreen && listenmobj2) // Copy the sound for the split player { // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj2) + if (origin && !itsUs) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - goto dontplay; // Maybe the other player can hear it... - - if (origin->x == listener2.x && origin->y == listener2.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 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; + boolean audible = false; + if (splitscreen > 0) + { + fixed_t recdist = INT32_MAX; + UINT8 j = 0; - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; + for (; j <= splitscreen; j++) + { + fixed_t thisdist = INT32_MAX; - // 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); - } + if (!listenmobj[j]) + { + continue; + } -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 - { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj3) - { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx); + if (thisdist >= recdist) + { + continue; + } + + recdist = thisdist; + i = j; + } + } - if (!rc) - goto dontplay3; // Maybe the other player can hear it... + if (listenmobj[i]) + { + audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx); + } - if (origin->x == listener3.x && origin->y == listener3.y) - sep = NORM_SEP; + if (!audible) + { + return; + } } - 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 @@ -672,129 +593,40 @@ dontplay: // 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; - 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; + sep = (~sep) & 255; } - 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 + // 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); 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; + { + return; // If there's no free channels, there won't be any for anymore players either + } - // Assigns the handle to one of the channels in the - // mix/output buffer. + // 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].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) @@ -884,7 +716,6 @@ void S_StopSound(void *origin) if (channels[cnum].sfxinfo && channels[cnum].origin == origin) { S_StopChannel(cnum); - break; } } } @@ -900,23 +731,13 @@ static INT32 actualmidimusicvolume; void S_UpdateSounds(void) { - INT32 audible, cnum, volume, sep, pitch; + INT32 cnum, volume, sep, pitch; + boolean audible = false; channel_t *c; + INT32 i; - listener_t listener; - listener_t listener2; - 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)); + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; // Update sound/music volumes, if changed manually at console if (actualsfxvolume != cv_soundvolume.value) @@ -933,7 +754,7 @@ void S_UpdateSounds(void) { #ifndef NOMUMBLE // Stop Mumble cutting out. I'm sick of it. - I_UpdateMumble(NULL, listener); + I_UpdateMumble(NULL, listener[0]); #endif // Stop cutting FMOD out. WE'RE sick of it. @@ -944,47 +765,31 @@ void S_UpdateSounds(void) if (dedicated || sound_disabled) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (splitscreen) + for (i = 0; i <= splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (splitscreen > 1) - { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; - if (splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + if (i == 0 && democam.soundmobj) + { + listenmobj[i] = democam.soundmobj; + continue; } - } - 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; + if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else + { + listenmobj[i] = player->mo; + } } #ifndef NOMUMBLE - I_UpdateMumble(players[consoleplayer].mo, listener); + I_UpdateMumble(players[consoleplayer].mo, listener[0]); #endif #ifdef HW3SOUND @@ -996,57 +801,23 @@ void S_UpdateSounds(void) } #endif - if (listenmobj2) + for (i = 0; i <= splitscreen; i++) { - 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; - } - } + player_t *player = &players[displayplayers[i]]; - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) + if (camera[i].chase && !player->awayviewtics) { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].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; } - else + else if (listenmobj[i]) { - 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; + listener[i].x = listenmobj[i]->x; + listener[i].y = listenmobj[i]->y; + listener[i].z = listenmobj[i]->z; + listener[i].angle = listenmobj[i]->angle; } } @@ -1063,83 +834,60 @@ void S_UpdateSounds(void) pitch = NORM_PITCH; sep = NORM_SEP; - if (splitscreen && c->origin) - volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS; - // check non-local sounds for distance clipping // or modify their params - if (c->origin && ((c->origin != players[consoleplayer].mo) - || (splitscreen && c->origin != players[displayplayers[1]].mo) - || (splitscreen > 1 && c->origin != players[displayplayers[2]].mo) - || (splitscreen > 2 && c->origin != players[displayplayers[3]].mo))) + if (c->origin) { - // Whomever is closer gets the sound, but only in splitscreen. - if (splitscreen) + boolean itsUs = false; + + for (i = splitscreen; i >= 0; i--) + { + if (c->origin != listenmobj[i]) + continue; + + itsUs = true; + } + + if (itsUs == false) { - const mobj_t *soundmobj = c->origin; - fixed_t recdist = -1; - INT32 i, p = -1; + const mobj_t *origin = c->origin; + + i = 0; - for (i = 0; i <= splitscreen; i++) + if (splitscreen > 0) { - fixed_t thisdist = -1; - - 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; - - if (recdist == -1 || (thisdist != -1 && thisdist < recdist)) + 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; - p = i; + i = j; } } - if (p != -1) + if (listenmobj[i]) { - if (p == 1) - { - // Player 2 gets the sound - audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, - 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); + audible = S_AdjustSoundParams( + listenmobj[i], c->origin, + &volume, &sep, &pitch, + c->sfxinfo + ); } - } - 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) 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. // 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) { + const boolean reverse = (stereoreverse.value ^ encoremode); + fixed_t approx_dist; - angle_t angle; listener_t listensource; - - const boolean reverse = (stereoreverse.value ^ encoremode); + INT32 i; (void)pitch; + if (!listener) return false; - if (listener == players[displayplayers[0]].mo && camera[0].chase) - { - 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 + // 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 = listener->x; - listensource.y = listener->y; - listensource.z = listener->z; - listensource.angle = listener->angle; + // 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 @@ -1339,30 +1071,37 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v approx_dist = FixedDiv(approx_dist,2*FRACUNIT); if (approx_dist > S_CLIPPING_DIST) - return 0; - - // angle of source to listener - angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); + return false; - if (angle > listensource.angle) - angle = angle - listensource.angle; + if (source->x == listensource.x && source->y == listensource.y) + { + *sep = NORM_SEP; + } else - angle = angle + InvAngle(listensource.angle); + { + // angle of source to listener + angle_t angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); - if (reverse) - angle = InvAngle(angle); + if (angle > listensource.angle) + angle = angle - listensource.angle; + else + angle = angle + InvAngle(listensource.angle); + + if (reverse) + angle = InvAngle(angle); #ifdef SURROUND - // Produce a surround sound for angle from 105 till 255 - if (surround.value == 1 && (angle > ANG105 && angle < ANG255 )) - *sep = SURROUND_SEP; - else + // Produce a surround sound for angle from 105 till 255 + if (surround.value == 1 && (angle > ANG105 && angle < ANG255 )) + *sep = SURROUND_SEP; + else #endif - { - angle >>= ANGLETOFINESHIFT; + { + angle >>= ANGLETOFINESHIFT; - // stereo separation - *sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS); + // stereo separation + *sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS); + } } // volume calculation @@ -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; } - if (splitscreen) - *vol = FixedDiv((*vol)<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS; - return (*vol > 0); }