- update of the sound engine for unlimited channels per source.

Blood needs this.
This commit is contained in:
Christoph Oelckers 2019-12-17 00:29:38 +01:00
parent fa7638c446
commit 4d5755ca67
19 changed files with 270 additions and 161 deletions

View file

@ -108,7 +108,7 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode,
if (playsound) if (playsound)
{ {
//S_StopSound (CHAN_VOICE); //S_StopSound (CHAN_VOICE);
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", snd_menuvolume, ATTN_NONE); //S_Sound (CHAN_VOICE | CHANF_UI, "menu/prompt", snd_menuvolume, ATTN_NONE);
} }
} }
@ -283,7 +283,7 @@ bool DMessageBoxMenu::MenuEvent(int mkey, bool fromcontroller)
{ {
if ((mkey == MKEY_Up || mkey == MKEY_Down) && m_generic_messagebox) if ((mkey == MKEY_Up || mkey == MKEY_Down) && m_generic_messagebox)
{ {
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); //S_Sound (CHAN_VOICE | CHANF_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
messageSelection = !messageSelection; messageSelection = !messageSelection;
return true; return true;
} }

View file

@ -8,6 +8,32 @@
#include "tarray.h" #include "tarray.h"
#include "zmusic/sounddecoder.h" #include "zmusic/sounddecoder.h"
#include "../../libraries/music_common/fileio.h" #include "../../libraries/music_common/fileio.h"
#include "tflags.h"
enum EChanFlag
{
// modifier flags
CHANF_LISTENERZ = 8,
CHANF_MAYBE_LOCAL = 16,
CHANF_UI = 32, // Do not record sound in savegames.
CHANF_NOPAUSE = 64, // Do not pause this sound in menus.
CHANF_AREA = 128, // Sound plays from all around. Only valid with sector sounds.
CHANF_LOOP = 256,
CHANF_PICKUP = CHANF_MAYBE_LOCAL,
CHANF_IS3D = 1, // internal: Sound is 3D.
CHANF_EVICTED = 2, // internal: Sound was evicted.
CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops.
CHANF_JUSTSTARTED = 512, // internal: Sound has not been updated yet.
CHANF_ABSTIME = 1024, // internal: Start time is absolute and does not depend on current time.
CHANF_VIRTUAL = 2048, // internal: Channel is currently virtual
CHANF_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something.
CHANF_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them.
};
typedef TFlags<EChanFlag> EChanFlags;
DEFINE_TFLAGS_OPERATORS(EChanFlags)
class FileReader; class FileReader;
@ -112,7 +138,7 @@ struct FISoundChannel
float DistanceScale; float DistanceScale;
float DistanceSqr; float DistanceSqr;
bool ManualRolloff; bool ManualRolloff;
int ChanFlags; EChanFlags ChanFlags;
}; };
@ -122,4 +148,5 @@ class SoundStream;
#endif #endif

View file

@ -1672,7 +1672,7 @@ void OpenALSoundRenderer::ChannelPitch(FISoundChannel *chan, float pitch)
alDeferUpdatesSOFT(); alDeferUpdatesSOFT();
ALuint source = GET_PTRID(chan->SysChannel); ALuint source = GET_PTRID(chan->SysChannel);
if (WasInWater && !(chan->ChanFlags & CHAN_UI)) if (WasInWater && !(chan->ChanFlags & CHANF_UI))
alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f)*PITCH_MULT); alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f)*PITCH_MULT);
else else
alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f)); alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f));
@ -1950,7 +1950,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan) while (schan)
{ {
ALuint source = GET_PTRID(schan->SysChannel); ALuint source = GET_PTRID(schan->SysChannel);
if (source && !(schan->ChanFlags & CHAN_UI)) if (source && !(schan->ChanFlags & CHANF_UI))
{ {
alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]); alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]);
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]); alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
@ -1963,7 +1963,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan) while (schan)
{ {
ALuint source = GET_PTRID(schan->SysChannel); ALuint source = GET_PTRID(schan->SysChannel);
if (source && !(schan->ChanFlags & CHAN_UI)) if (source && !(schan->ChanFlags & CHANF_UI))
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT); alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT);
schan = schan->NextChan; schan = schan->NextChan;
} }
@ -1988,7 +1988,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan) while (schan)
{ {
ALuint source = GET_PTRID(schan->SysChannel); ALuint source = GET_PTRID(schan->SysChannel);
if (source && !(schan->ChanFlags & CHAN_UI)) if (source && !(schan->ChanFlags & CHANF_UI))
{ {
alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]); alSourcei(source, AL_DIRECT_FILTER, EnvFilters[0]);
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]); alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
@ -2001,7 +2001,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan) while (schan)
{ {
ALuint source = GET_PTRID(schan->SysChannel); ALuint source = GET_PTRID(schan->SysChannel);
if (source && !(schan->ChanFlags & CHAN_UI)) if (source && !(schan->ChanFlags & CHANF_UI))
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f); alSourcef(source, AL_PITCH, schan->Pitch / 128.0f);
schan = schan->NextChan; schan = schan->NextChan;
} }

View file

@ -285,7 +285,7 @@ TArray<FSoundChan*> SoundEngine::AllActiveChannels()
// If the sound is forgettable, this is as good a time as // If the sound is forgettable, this is as good a time as
// any to forget about it. And if it's a UI sound, it shouldn't // any to forget about it. And if it's a UI sound, it shouldn't
// be stored in the savegame. // be stored in the savegame.
if (!(chan->ChanFlags & (CHAN_FORGETTABLE | CHAN_UI))) if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI)))
{ {
chans.Push(chan); chans.Push(chan);
} }
@ -306,7 +306,7 @@ FString SoundEngine::ListSoundChannels()
int count = 0; int count = 0;
for (chan = Channels; chan != nullptr; chan = chan->NextChan) for (chan = Channels; chan != nullptr; chan = chan->NextChan)
{ {
if (!(chan->ChanFlags & CHAN_EVICTED)) if (!(chan->ChanFlags & CHANF_EVICTED))
{ {
FVector3 chanorigin; FVector3 chanorigin;
@ -376,11 +376,11 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a
//========================================================================== //==========================================================================
FSoundChan *SoundEngine::StartSound(int type, const void *source, FSoundChan *SoundEngine::StartSound(int type, const void *source,
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, const FVector3 *pt, int channel, EChanFlags flags, FSoundID sound_id, float volume, float attenuation,
FRolloffInfo *forcedrolloff, float spitch) FRolloffInfo *forcedrolloff, float spitch)
{ {
sfxinfo_t *sfx; sfxinfo_t *sfx;
int chanflags; EChanFlags chanflags = flags;
int basepriority; int basepriority;
int org_id; int org_id;
int pitch; int pitch;
@ -396,8 +396,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
if (type == SOURCE_Unattached && pt == nullptr) type = SOURCE_None; if (type == SOURCE_Unattached && pt == nullptr) type = SOURCE_None;
org_id = sound_id; org_id = sound_id;
chanflags = channel & ~7;
channel &= 7;
CalcPosVel(type, source, &pt->X, channel, chanflags, sound_id, &pos, &vel); CalcPosVel(type, source, &pt->X, channel, chanflags, sound_id, &pos, &vel);
@ -461,7 +459,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// If this is a singular sound, don't play it if it's already playing. // If this is a singular sound, don't play it if it's already playing.
if (sfx->bSingular && CheckSingular(sound_id)) if (sfx->bSingular && CheckSingular(sound_id))
{ {
chanflags |= CHAN_EVICTED; chanflags |= CHANF_EVICTED;
} }
// If the sound is unpositioned or comes from the listener, it is // If the sound is unpositioned or comes from the listener, it is
@ -475,13 +473,13 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// that's what would happen. (Does this really need the SOURCE_Actor restriction?) // that's what would happen. (Does this really need the SOURCE_Actor restriction?)
if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, type == SOURCE_Actor? source : nullptr, channel)) if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, type == SOURCE_Actor? source : nullptr, channel))
{ {
chanflags |= CHAN_EVICTED; chanflags |= CHANF_EVICTED;
} }
// If the sound is blocked and not looped, return now. If the sound // If the sound is blocked and not looped, return now. If the sound
// is blocked and looped, pretend to play it so that it can // is blocked and looped, pretend to play it so that it can
// eventually play for real. // eventually play for real.
if ((chanflags & (CHAN_EVICTED | CHAN_LOOP)) == CHAN_EVICTED) if ((chanflags & (CHANF_EVICTED | CHANF_LOOP)) == CHANF_EVICTED)
{ {
return NULL; return NULL;
} }
@ -531,7 +529,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
} }
// If this actor is already playing something on the selected channel, stop it. // If this actor is already playing something on the selected channel, stop it.
if (type != SOURCE_None && ((source == NULL && channel != CHAN_AUTO) || (source != NULL && IsChannelUsed(type, source, channel, &seen)))) if (!(chanflags & CHANF_OVERLAP) && type != SOURCE_None && ((source == NULL && channel != CHAN_AUTO) || (source != NULL && IsChannelUsed(type, source, channel, &seen))))
{ {
for (chan = Channels; chan != NULL; chan = chan->NextChan) for (chan = Channels; chan != NULL; chan = chan->NextChan)
{ {
@ -552,7 +550,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// sound is paused and a non-looped sound is being started. // sound is paused and a non-looped sound is being started.
// Such a sound would play right after unpausing which wouldn't sound right. // Such a sound would play right after unpausing which wouldn't sound right.
if (!(chanflags & CHAN_LOOP) && !(chanflags & (CHAN_UI|CHAN_NOPAUSE)) && SoundPaused) if (!(chanflags & CHANF_LOOP) && !(chanflags & (CHANF_UI|CHANF_NOPAUSE)) && SoundPaused)
{ {
return NULL; return NULL;
} }
@ -567,17 +565,17 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
pitch = DEFAULT_PITCH; pitch = DEFAULT_PITCH;
} }
if (chanflags & CHAN_EVICTED) if (chanflags & CHANF_EVICTED)
{ {
chan = NULL; chan = NULL;
} }
else else
{ {
int startflags = 0; int startflags = 0;
if (chanflags & CHAN_LOOP) startflags |= SNDF_LOOP; if (chanflags & CHANF_LOOP) startflags |= SNDF_LOOP;
if (chanflags & CHAN_AREA) startflags |= SNDF_AREA; if (chanflags & CHANF_AREA) startflags |= SNDF_AREA;
if (chanflags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE; if (chanflags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chanflags & CHAN_UI) startflags |= SNDF_NOREVERB; if (chanflags & CHANF_UI) startflags |= SNDF_NOREVERB;
if (attenuation > 0) if (attenuation > 0)
{ {
@ -589,19 +587,19 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL); chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL);
} }
} }
if (chan == NULL && (chanflags & CHAN_LOOP)) if (chan == NULL && (chanflags & CHANF_LOOP))
{ {
chan = (FSoundChan*)GetChannel(NULL); chan = (FSoundChan*)GetChannel(NULL);
GSnd->MarkStartTime(chan); GSnd->MarkStartTime(chan);
chanflags |= CHAN_EVICTED; chanflags |= CHANF_EVICTED;
} }
if (attenuation > 0) if (attenuation > 0)
{ {
chanflags |= CHAN_IS3D | CHAN_JUSTSTARTED; chanflags |= CHANF_IS3D | CHANF_JUSTSTARTED;
} }
else else
{ {
chanflags |= CHAN_LISTENERZ | CHAN_JUSTSTARTED; chanflags |= CHANF_LISTENERZ | CHANF_JUSTSTARTED;
} }
if (chan != NULL) if (chan != NULL)
{ {
@ -642,7 +640,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
void SoundEngine::RestartChannel(FSoundChan *chan) void SoundEngine::RestartChannel(FSoundChan *chan)
{ {
assert(chan->ChanFlags & CHAN_EVICTED); assert(chan->ChanFlags & CHANF_EVICTED);
FSoundChan *ochan; FSoundChan *ochan;
sfxinfo_t *sfx = &S_sfx[chan->SoundID]; sfxinfo_t *sfx = &S_sfx[chan->SoundID];
@ -660,15 +658,15 @@ void SoundEngine::RestartChannel(FSoundChan *chan)
return; return;
} }
int oldflags = chan->ChanFlags; EChanFlags oldflags = chan->ChanFlags;
int startflags = 0; int startflags = 0;
if (chan->ChanFlags & CHAN_LOOP) startflags |= SNDF_LOOP; if (chan->ChanFlags & CHANF_LOOP) startflags |= SNDF_LOOP;
if (chan->ChanFlags & CHAN_AREA) startflags |= SNDF_AREA; if (chan->ChanFlags & CHANF_AREA) startflags |= SNDF_AREA;
if (chan->ChanFlags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE; if (chan->ChanFlags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chan->ChanFlags & CHAN_ABSTIME) startflags |= SNDF_ABSTIME; if (chan->ChanFlags & CHANF_ABSTIME) startflags |= SNDF_ABSTIME;
if (chan->ChanFlags & CHAN_IS3D) if (chan->ChanFlags & CHANF_IS3D)
{ {
FVector3 pos, vel; FVector3 pos, vel;
@ -687,13 +685,13 @@ void SoundEngine::RestartChannel(FSoundChan *chan)
} }
LoadSound3D(sfx, &SoundBuffer); LoadSound3D(sfx, &SoundBuffer);
chan->ChanFlags &= ~(CHAN_EVICTED|CHAN_ABSTIME); chan->ChanFlags &= ~(CHANF_EVICTED|CHANF_ABSTIME);
ochan = (FSoundChan*)GSnd->StartSound3D(sfx->data3d, &listener, chan->Volume, &chan->Rolloff, chan->DistanceScale, chan->Pitch, ochan = (FSoundChan*)GSnd->StartSound3D(sfx->data3d, &listener, chan->Volume, &chan->Rolloff, chan->DistanceScale, chan->Pitch,
chan->Priority, pos, vel, chan->EntChannel, startflags, chan); chan->Priority, pos, vel, chan->EntChannel, startflags, chan);
} }
else else
{ {
chan->ChanFlags &= ~(CHAN_EVICTED|CHAN_ABSTIME); chan->ChanFlags &= ~(CHANF_EVICTED|CHANF_ABSTIME);
ochan = (FSoundChan*)GSnd->StartSound(sfx->data, chan->Volume, chan->Pitch, startflags, chan); ochan = (FSoundChan*)GSnd->StartSound(sfx->data, chan->Volume, chan->Pitch, startflags, chan);
} }
assert(ochan == NULL || ochan == chan); assert(ochan == NULL || ochan == chan);
@ -884,7 +882,7 @@ bool SoundEngine::CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_
for (chan = Channels, count = 0; chan != NULL && count < near_limit; chan = chan->NextChan) for (chan = Channels, count = 0; chan != NULL && count < near_limit; chan = chan->NextChan)
{ {
if (!(chan->ChanFlags & CHAN_EVICTED) && &S_sfx[chan->SoundID] == sfx) if (!(chan->ChanFlags & CHANF_EVICTED) && &S_sfx[chan->SoundID] == sfx)
{ {
FVector3 chanorigin; FVector3 chanorigin;
@ -940,7 +938,7 @@ void SoundEngine::StopSound (int channel, int sound_id)
while (chan != NULL) while (chan != NULL)
{ {
FSoundChan *next = chan->NextChan; FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_None && (sound_id == -1 || sound_id == chan->OrgID)) if ((chan->SourceType == SOURCE_None && (sound_id == -1 || sound_id == chan->OrgID)) && (channel == CHAN_AUTO || channel == chan->EntChannel))
{ {
StopChannel(chan); StopChannel(chan);
} }
@ -1015,7 +1013,7 @@ void SoundEngine::RelinkSound (int sourcetype, const void *from, const void *to,
{ {
chan->Source = to; chan->Source = to;
} }
else if (!(chan->ChanFlags & CHAN_LOOP) && optpos) else if (!(chan->ChanFlags & CHANF_LOOP) && optpos)
{ {
chan->Source = NULL; chan->Source = NULL;
chan->SourceType = SOURCE_Unattached; chan->SourceType = SOURCE_Unattached;
@ -1183,15 +1181,15 @@ void SoundEngine::EvictAllChannels()
{ {
next = chan->NextChan; next = chan->NextChan;
if (!(chan->ChanFlags & CHAN_EVICTED)) if (!(chan->ChanFlags & CHANF_EVICTED))
{ {
chan->ChanFlags |= CHAN_EVICTED; chan->ChanFlags |= CHANF_EVICTED;
if (chan->SysChannel != NULL) if (chan->SysChannel != NULL)
{ {
if (!(chan->ChanFlags & CHAN_ABSTIME)) if (!(chan->ChanFlags & CHANF_ABSTIME))
{ {
chan->StartTime = GSnd ? GSnd->GetPosition(chan) : 0; chan->StartTime = GSnd ? GSnd->GetPosition(chan) : 0;
chan->ChanFlags |= CHAN_ABSTIME; chan->ChanFlags |= CHANF_ABSTIME;
} }
StopChannel(chan); StopChannel(chan);
} }
@ -1215,22 +1213,22 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan)
return; return;
} }
RestoreEvictedChannel(chan->NextChan); RestoreEvictedChannel(chan->NextChan);
if (chan->ChanFlags & CHAN_EVICTED) if (chan->ChanFlags & CHANF_EVICTED)
{ {
RestartChannel(chan); RestartChannel(chan);
if (!(chan->ChanFlags & CHAN_LOOP)) if (!(chan->ChanFlags & CHANF_LOOP))
{ {
if (chan->ChanFlags & CHAN_EVICTED) if (chan->ChanFlags & CHANF_EVICTED)
{ // Still evicted and not looping? Forget about it. { // Still evicted and not looping? Forget about it.
ReturnChannel(chan); ReturnChannel(chan);
} }
else if (!(chan->ChanFlags & CHAN_JUSTSTARTED)) else if (!(chan->ChanFlags & CHANF_JUSTSTARTED))
{ // Should this sound become evicted again, it's okay to forget about it. { // Should this sound become evicted again, it's okay to forget about it.
chan->ChanFlags |= CHAN_FORGETTABLE; chan->ChanFlags |= CHANF_FORGETTABLE;
} }
} }
} }
else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHAN_FORGETTABLE | CHAN_LOOP)) == CHAN_FORGETTABLE) else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_LOOP)) == CHANF_FORGETTABLE)
{ {
ReturnChannel(chan); ReturnChannel(chan);
} }
@ -1264,16 +1262,16 @@ void SoundEngine::UpdateSounds(int time)
for (FSoundChan* chan = Channels; chan != NULL; chan = chan->NextChan) for (FSoundChan* chan = Channels; chan != NULL; chan = chan->NextChan)
{ {
if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D) if ((chan->ChanFlags & (CHANF_EVICTED | CHANF_IS3D)) == CHANF_IS3D)
{ {
CalcPosVel(chan, &pos, &vel); CalcPosVel(chan, &pos, &vel);
if (ValidatePosVel(chan, pos, vel)) if (ValidatePosVel(chan, pos, vel))
{ {
GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHAN_AREA), pos, vel); GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHANF_AREA), pos, vel);
} }
} }
chan->ChanFlags &= ~CHAN_JUSTSTARTED; chan->ChanFlags &= ~CHANF_JUSTSTARTED;
} }
GSnd->UpdateListener(&listener); GSnd->UpdateListener(&listener);
@ -1342,11 +1340,11 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
// it wasn't evicted. Otherwise, if it's looping, it must have // it wasn't evicted. Otherwise, if it's looping, it must have
// been evicted. If it's not looping, then it was evicted if it // been evicted. If it's not looping, then it was evicted if it
// didn't reach the end of its playback. // didn't reach the end of its playback.
if (schan->ChanFlags & CHAN_FORGETTABLE) if (schan->ChanFlags & CHANF_FORGETTABLE)
{ {
evicted = false; evicted = false;
} }
else if (schan->ChanFlags & (CHAN_LOOP | CHAN_EVICTED)) else if (schan->ChanFlags & (CHANF_LOOP | CHANF_EVICTED))
{ {
evicted = true; evicted = true;
} }
@ -1356,7 +1354,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
unsigned int len = GSnd->GetSampleLength(S_sfx[schan->SoundID].data); unsigned int len = GSnd->GetSampleLength(S_sfx[schan->SoundID].data);
if (pos == 0) if (pos == 0)
{ {
evicted = !!(schan->ChanFlags & CHAN_JUSTSTARTED); evicted = !!(schan->ChanFlags & CHANF_JUSTSTARTED);
} }
else else
{ {
@ -1369,7 +1367,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
} }
else else
{ {
schan->ChanFlags |= CHAN_EVICTED; schan->ChanFlags |= CHANF_EVICTED;
schan->SysChannel = NULL; schan->SysChannel = NULL;
} }
} }
@ -1386,11 +1384,11 @@ void SoundEngine::ChannelVirtualChanged(FISoundChannel *ichan, bool is_virtual)
FSoundChan *schan = static_cast<FSoundChan*>(ichan); FSoundChan *schan = static_cast<FSoundChan*>(ichan);
if (is_virtual) if (is_virtual)
{ {
schan->ChanFlags |= CHAN_VIRTUAL; schan->ChanFlags |= CHANF_VIRTUAL;
} }
else else
{ {
schan->ChanFlags &= ~CHAN_VIRTUAL; schan->ChanFlags &= ~CHANF_VIRTUAL;
} }
} }
@ -1409,9 +1407,9 @@ void SoundEngine::StopChannel(FSoundChan *chan)
{ {
// S_EvictAllChannels() will set the CHAN_EVICTED flag to indicate // S_EvictAllChannels() will set the CHAN_EVICTED flag to indicate
// that it wants to keep all the channel information around. // that it wants to keep all the channel information around.
if (!(chan->ChanFlags & CHAN_EVICTED)) if (!(chan->ChanFlags & CHANF_EVICTED))
{ {
chan->ChanFlags |= CHAN_FORGETTABLE; chan->ChanFlags |= CHANF_FORGETTABLE;
if (chan->SourceType == SOURCE_Actor) if (chan->SourceType == SOURCE_Actor)
{ {
chan->Source = NULL; chan->Source = NULL;
@ -1736,7 +1734,7 @@ FString SoundEngine::NoiseDebug()
for (auto chan = Channels; chan; chan = chan->NextChan) for (auto chan = Channels; chan; chan = chan->NextChan)
{ {
if (!(chan->ChanFlags & CHAN_IS3D)) if (!(chan->ChanFlags & CHANF_IS3D))
{ {
out += "--- --- --- --- "; out += "--- --- --- --- ";
} }
@ -1746,15 +1744,15 @@ FString SoundEngine::NoiseDebug()
out.AppendFormat(TEXTCOLOR_GOLD "%5.0f | %5.0f | %5.0f | %5.0f ", origin.X, origin.Z, origin.Y, (origin - listener).Length()); out.AppendFormat(TEXTCOLOR_GOLD "%5.0f | %5.0f | %5.0f | %5.0f ", origin.X, origin.Z, origin.Y, (origin - listener).Length());
} }
out.AppendFormat("%-.2g %-4d %-4d %s3%sZ%sU%sM%sN%sA%sL%sE%sV" TEXTCOLOR_GOLD " %-5.4f %-4u %d: %s\n", chan->Volume, chan->EntChannel, chan->Priority, out.AppendFormat("%-.2g %-4d %-4d %s3%sZ%sU%sM%sN%sA%sL%sE%sV" TEXTCOLOR_GOLD " %-5.4f %-4u %d: %s\n", chan->Volume, chan->EntChannel, chan->Priority,
(chan->ChanFlags & CHAN_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK, (chan->ChanFlags & CHANF_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID)-1, S_sfx[chan->SoundID].name.GetChars()); GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID)-1, S_sfx[chan->SoundID].name.GetChars());
ch++; ch++;
} }

View file

@ -192,43 +192,20 @@ struct FSoundChan : public FISoundChannel
// CHAN_BODY is for generic body sounds // CHAN_BODY is for generic body sounds
// CHAN_PICKUP can optionally be set as a local sound only for "compatibility" // CHAN_PICKUP can optionally be set as a local sound only for "compatibility"
enum enum EChannel
{ {
CHAN_AUTO = 0, CHAN_AUTO = 0,
CHAN_WEAPON = 1, CHAN_WEAPON = 1,
CHAN_VOICE = 2, CHAN_VOICE = 2,
CHAN_ITEM = 3, CHAN_ITEM = 3,
CHAN_BODY = 4, CHAN_BODY = 4,
CHAN_5 = 5, CHAN_5 = 5,
CHAN_6 = 6, CHAN_6 = 6,
CHAN_7 = 7, CHAN_7 = 7,
// Channel alias for sector sounds. These define how listener height is
// used when calculating 3D sound volume.
CHAN_FLOOR = 1, // Sound comes from the floor.
CHAN_CEILING = 2, // Sound comes from the ceiling.
CHAN_FULLHEIGHT = 3, // Sound comes entire height of the sector.
CHAN_INTERIOR = 4, // Sound comes height between floor and ceiling.
// modifier flags
CHAN_LISTENERZ = 8,
CHAN_MAYBE_LOCAL = 16,
CHAN_UI = 32, // Do not record sound in savegames.
CHAN_NOPAUSE = 64, // Do not pause this sound in menus.
CHAN_AREA = 128, // Sound plays from all around. Only valid with sector sounds.
CHAN_LOOP = 256,
CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL),
CHAN_IS3D = 1, // internal: Sound is 3D.
CHAN_EVICTED = 2, // internal: Sound was evicted.
CHAN_FORGETTABLE = 4, // internal: Forget channel data when sound stops.
CHAN_JUSTSTARTED = 512, // internal: Sound has not been updated yet.
CHAN_ABSTIME = 1024, // internal: Start time is absolute and does not depend on current time.
CHAN_VIRTUAL = 2048, // internal: Channel is currently virtual
CHAN_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something.
}; };
// sound attenuation values // sound attenuation values
#define ATTN_NONE 0.f // full volume the entire level #define ATTN_NONE 0.f // full volume the entire level
#define ATTN_NORM 1.f #define ATTN_NORM 1.f
@ -327,7 +304,7 @@ public:
void UpdateSounds(int time); void UpdateSounds(int time);
FSoundChan* StartSound(int sourcetype, const void* source, FSoundChan* StartSound(int sourcetype, const void* source,
const FVector3* pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f); const FVector3* pt, int channel, EChanFlags flags, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f);
// Stops an origin-less sound from playing from this channel. // Stops an origin-less sound from playing from this channel.
void StopSoundID(int sound_id); void StopSoundID(int sound_id);

View file

@ -0,0 +1,108 @@
/*
** tflags.h
**
**---------------------------------------------------------------------------
** Copyright 2015 Teemu Piippo
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#pragma once
/*
* TFlags
*
* A Qt-inspired type-safe flagset type.
*
* T is the enum type of individual flags,
* TT is the underlying integer type used (defaults to uint32_t)
*/
template<typename T, typename TT = uint32_t>
class TFlags
{
struct ZeroDummy {};
public:
typedef TFlags<T, TT> Self;
typedef T EnumType;
typedef TT IntType;
TFlags() = default;
TFlags(const Self& other) = default;
TFlags (T value) : Value (static_cast<TT> (value)) {}
// This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer.
TFlags (ZeroDummy*) : Value (0) {}
// Relation operators
Self operator| (Self other) const { return Self::FromInt (Value | other.GetValue()); }
Self operator& (Self other) const { return Self::FromInt (Value & other.GetValue()); }
Self operator^ (Self other) const { return Self::FromInt (Value ^ other.GetValue()); }
Self operator| (T value) const { return Self::FromInt (Value | value); }
Self operator& (T value) const { return Self::FromInt (Value & value); }
Self operator^ (T value) const { return Self::FromInt (Value ^ value); }
Self operator~() const { return Self::FromInt (~Value); }
// Assignment operators
Self& operator= (Self other) { Value = other.GetValue(); return *this; }
Self& operator|= (Self other) { Value |= other.GetValue(); return *this; }
Self& operator&= (Self other) { Value &= other.GetValue(); return *this; }
Self& operator^= (Self other) { Value ^= other.GetValue(); return *this; }
Self& operator= (T value) { Value = value; return *this; }
Self& operator|= (T value) { Value |= value; return *this; }
Self& operator&= (T value) { Value &= value; return *this; }
Self& operator^= (T value) { Value ^= value; return *this; }
// Access the value of the flagset
TT GetValue() const { return Value; }
operator TT() const { return Value; }
// Set the value of the flagset manually with an integer.
// Please think twice before using this.
static Self FromInt (TT value) { return Self (static_cast<T> (value)); }
private:
template<typename X> Self operator| (X value) const { return Self::FromInt (Value | value); }
template<typename X> Self operator& (X value) const { return Self::FromInt (Value & value); }
template<typename X> Self operator^ (X value) const { return Self::FromInt (Value ^ value); }
public: // to be removed.
TT Value;
};
/*
* Additional operators for TFlags types.
*/
#define DEFINE_TFLAGS_OPERATORS(T) \
inline T operator| (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \
inline T operator& (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \
inline T operator^ (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \
inline T operator| (T::EnumType a, T b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \
inline T operator& (T::EnumType a, T b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \
inline T operator^ (T::EnumType a, T b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \
inline T operator~ (T::EnumType a) { return T::FromInt (~T::IntType (a)); }

View file

@ -1527,7 +1527,7 @@ ACTOR_STATIC void G_MoveFX(void)
goto next_sprite; goto next_sprite;
} }
#endif #endif
A_PlaySound(pSprite->lotag,spriteNum, CHAN_LOOP); A_PlaySound(pSprite->lotag,spriteNum, CHAN_AUTO, CHANF_LOOP);
T1(spriteNum) = 1; // AMBIENT_SFX_PLAYING T1(spriteNum) = 1; // AMBIENT_SFX_PLAYING
} }
else if (playerDist >= spriteHitag && T1(spriteNum) == 1) else if (playerDist >= spriteHitag && T1(spriteNum) == 1)

View file

@ -364,7 +364,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }
@ -378,7 +378,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }
@ -536,7 +536,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }

View file

@ -481,15 +481,15 @@ void GameInterface::MenuSound(EMenuSounds snd)
switch (snd) switch (snd)
{ {
case CursorSound: case CursorSound:
S_PlaySound(KICK_HIT, CHAN_UI); S_PlaySound(KICK_HIT, CHAN_AUTO, CHANF_UI);
break; break;
case AdvanceSound: case AdvanceSound:
S_PlaySound(PISTOL_BODYHIT, CHAN_UI); S_PlaySound(PISTOL_BODYHIT, CHAN_AUTO, CHANF_UI);
break; break;
case CloseSound: case CloseSound:
S_PlaySound(EXITMENUSOUND, CHAN_UI); S_PlaySound(EXITMENUSOUND, CHAN_AUTO, CHANF_UI);
break; break;
default: default:
@ -570,7 +570,7 @@ void GameInterface::StartGame(FGameStartup& gs)
ud.m_player_skill = gs.Skill + 1; ud.m_player_skill = gs.Skill + 1;
if (menu_sounds && skillsound >= 0 && SoundEnabled()) if (menu_sounds && skillsound >= 0 && SoundEnabled())
{ {
S_PlaySound(skillsound, CHAN_UI); S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI);
while (S_CheckSoundPlaying(skillsound)) while (S_CheckSoundPlaying(skillsound))
{ {

View file

@ -4400,7 +4400,7 @@ int G_StartRTS(int lumpNum, int localPlayer)
auto sid = RTS_GetSoundID(lumpNum - 1); auto sid = RTS_GetSoundID(lumpNum - 1);
if (sid != -1) if (sid != -1)
{ {
S_PlaySound(sid, CHAN_UI); S_PlaySound(sid, CHAN_AUTO, CHANF_UI);
g_RTSPlaying = 7; g_RTSPlaying = 7;
return 1; return 1;
} }
@ -4490,7 +4490,7 @@ void G_HandleLocalKeys(void)
{ {
if (G_ChangeHudLayout(1)) if (G_ChangeHudLayout(1))
{ {
S_PlaySound(THUD, CHAN_UI); S_PlaySound(THUD, CHAN_AUTO, CHANF_UI);
} }
} }
else else
@ -4509,7 +4509,7 @@ void G_HandleLocalKeys(void)
{ {
if (G_ChangeHudLayout(-1)) if (G_ChangeHudLayout(-1))
{ {
S_PlaySound(THUD, CHAN_UI); S_PlaySound(THUD, CHAN_AUTO, CHANF_UI);
} }
} }
else else

View file

@ -4125,7 +4125,7 @@ badindex:
if (S_CheckSoundPlaying(soundNum)) if (S_CheckSoundPlaying(soundNum))
S_StopSound((int16_t)soundNum); S_StopSound((int16_t)soundNum);
dispatch(); dispatch();
case CON_SCREENSOUND: S_PlaySound(soundNum, CHAN_UI); dispatch(); case CON_SCREENSOUND: S_PlaySound(soundNum, CHAN_AUTO, CHANF_UI); dispatch();
} }
} }
dispatch(); dispatch();

View file

@ -299,7 +299,7 @@ void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3]
*/ */
} }
} }
if ((chanflags & CHAN_LISTENERZ) && campos != nullptr && type != SOURCE_None) if ((chanflags & CHANF_LISTENERZ) && campos != nullptr && type != SOURCE_None)
{ {
pos->Y = campos->z / 256.f; pos->Y = campos->z / 256.f;
} }
@ -354,7 +354,7 @@ void S_Update(void)
// //
//========================================================================== //==========================================================================
int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos, int flags) int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos, int channel, EChanFlags flags)
{ {
int sndnum = VM_OnEventWithReturn(EVENT_SOUND, spriteNum, screenpeek, num); int sndnum = VM_OnEventWithReturn(EVENT_SOUND, spriteNum, screenpeek, num);
@ -443,8 +443,8 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos, int flags)
if (explosionp) attenuation = 0.5f; if (explosionp) attenuation = 0.5f;
else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM; else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM;
if (userflags & SF_LOOP) flags |= CHAN_LOOP; if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_Actor, &sprite[spriteNum], &sndpos, flags, sndnum+1, attenuation == ATTN_NONE? 0.8f : 1.f, attenuation, nullptr, S_ConvertPitch(pitch)); auto chan = soundEngine->StartSound(SOURCE_Actor, &sprite[spriteNum], &sndpos, channel, flags, sndnum+1, attenuation == ATTN_NONE? 0.8f : 1.f, attenuation, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1; return chan ? 0 : -1;
} }
@ -454,7 +454,7 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos, int flags)
// //
//========================================================================== //==========================================================================
int S_PlaySound(int num, int flags) int S_PlaySound(int num, int channel, EChanFlags flags)
{ {
int sndnum = VM_OnEventWithReturn(EVENT_SOUND, g_player[screenpeek].ps->i, screenpeek, num); int sndnum = VM_OnEventWithReturn(EVENT_SOUND, g_player[screenpeek].ps->i, screenpeek, num);
@ -466,8 +466,8 @@ int S_PlaySound(int num, int flags)
int const pitch = S_GetPitch(sndnum); int const pitch = S_GetPitch(sndnum);
if (userflags & SF_LOOP) flags |= CHAN_LOOP; if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch)); auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1; return chan ? 0 : -1;
} }
@ -477,19 +477,19 @@ int S_PlaySound(int num, int flags)
// //
//========================================================================== //==========================================================================
int A_PlaySound(int soundNum, int spriteNum, int flags) int A_PlaySound(int soundNum, int spriteNum, int channel, EChanFlags flags)
{ {
return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum, flags) : return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum, flags) :
S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos, flags); S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos, flags);
} }
void S_StopEnvSound(int sndNum, int sprNum, int flags) void S_StopEnvSound(int sndNum, int sprNum, int channel)
{ {
if (sprNum < -1 || sprNum >= MAXSPRITES) return; if (sprNum < -1 || sprNum >= MAXSPRITES) return;
if (sprNum == -1) soundEngine->StopSoundID(sndNum+1); if (sprNum == -1) soundEngine->StopSoundID(sndNum+1);
else if (flags == -1) soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum+1); else if (channel == -1) soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum+1);
else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], flags, -1); else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], channel, -1);
} }
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset) void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
@ -512,11 +512,11 @@ void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
// //
//========================================================================== //==========================================================================
int A_CheckSoundPlaying(int spriteNum, int soundNum, int flags) int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel)
{ {
if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1); if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1);
if ((unsigned)spriteNum >= MAXSPRITES) return false; if ((unsigned)spriteNum >= MAXSPRITES) return false;
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], flags, soundNum+1); return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], channel, soundNum+1);
} }
// Check if actor <i> is playing any sound. // Check if actor <i> is playing any sound.

View file

@ -45,8 +45,8 @@ typedef struct
int priority, flags; int priority, flags;
} sound_t; } sound_t;
int A_CheckSoundPlaying(int spriteNum, int soundNum, int flags = 0); int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel = 0);
int A_PlaySound(int soundNum, int spriteNum, int flags = 0); int A_PlaySound(int soundNum, int spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
void S_Callback(intptr_t num); void S_Callback(intptr_t num);
int A_CheckAnySoundPlaying(int spriteNum); int A_CheckAnySoundPlaying(int spriteNum);
int S_CheckSoundPlaying(int soundNum); int S_CheckSoundPlaying(int soundNum);
@ -59,8 +59,8 @@ void S_PlayLevelMusicOrNothing(unsigned int);
int S_TryPlaySpecialMusic(unsigned int); int S_TryPlaySpecialMusic(unsigned int);
void S_PlaySpecialMusicOrNothing(unsigned int); void S_PlaySpecialMusicOrNothing(unsigned int);
void S_ContinueLevelMusic(void); void S_ContinueLevelMusic(void);
int S_PlaySound(int num, int flags = 0); int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0);
int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int flags = 0); int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
void S_StopEnvSound(int sndNum,int sprNum, int flags = -1); void S_StopEnvSound(int sndNum,int sprNum, int flags = -1);
void S_StopAllSounds(void); void S_StopAllSounds(void);
void S_Update(void); void S_Update(void);

View file

@ -1392,7 +1392,7 @@ ACTOR_STATIC void G_MoveFX(void)
goto next_sprite; goto next_sprite;
} }
#endif #endif
A_PlaySound(pSprite->lotag, spriteNum, CHAN_LOOP); A_PlaySound(pSprite->lotag, spriteNum, CHAN_AUTO, CHANF_LOOP);
T1(spriteNum) = 1; // AMBIENT_SFX_PLAYING T1(spriteNum) = 1; // AMBIENT_SFX_PLAYING
} }
else if (playerDist >= spriteHitag && T1(spriteNum) == 1) else if (playerDist >= spriteHitag && T1(spriteNum) == 1)

View file

@ -396,7 +396,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }
@ -410,7 +410,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }
@ -566,7 +566,7 @@ int32_t Anim_Play(const char *fn)
if (sound == -1) if (sound == -1)
FX_StopAllSounds(); FX_StopAllSounds();
else else
S_PlaySound(sound, CHAN_UI); S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++; soundidx++;
} }

View file

@ -361,15 +361,15 @@ void GameInterface::MenuSound(EMenuSounds snd)
switch (snd) switch (snd)
{ {
case CursorSound: case CursorSound:
S_PlaySound(RR ? 335 : KICK_HIT, CHAN_UI); S_PlaySound(RR ? 335 : KICK_HIT, CHAN_AUTO, CHANF_UI);
break; break;
case AdvanceSound: case AdvanceSound:
S_PlaySound(RR? 341 : PISTOL_BODYHIT, CHAN_UI); S_PlaySound(RR? 341 : PISTOL_BODYHIT, CHAN_AUTO, CHANF_UI);
break; break;
case CloseSound: case CloseSound:
S_PlaySound(EXITMENUSOUND, CHAN_UI); S_PlaySound(EXITMENUSOUND, CHAN_AUTO, CHANF_UI);
break; break;
default: default:
@ -445,7 +445,7 @@ void GameInterface::StartGame(FGameStartup& gs)
ud.m_player_skill = gs.Skill + 1; ud.m_player_skill = gs.Skill + 1;
if (menu_sounds && skillsound >= 0 && SoundEnabled()) if (menu_sounds && skillsound >= 0 && SoundEnabled())
{ {
S_PlaySound(skillsound, CHAN_UI); S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI);
while (S_CheckSoundPlaying(skillsound)) while (S_CheckSoundPlaying(skillsound))
{ {

View file

@ -5954,7 +5954,7 @@ int G_StartRTS(int lumpNum, int localPlayer)
auto sid = RTS_GetSoundID(lumpNum - 1); auto sid = RTS_GetSoundID(lumpNum - 1);
if (sid != -1) if (sid != -1)
{ {
S_PlaySound(sid, CHAN_UI); S_PlaySound(sid, CHAN_AUTO, CHANF_UI);
g_RTSPlaying = 7; g_RTSPlaying = 7;
return 1; return 1;
} }
@ -6043,7 +6043,7 @@ void G_HandleLocalKeys(void)
{ {
if (G_ChangeHudLayout(1)) if (G_ChangeHudLayout(1))
{ {
S_PlaySound(RR ? 341 : THUD, CHAN_UI); S_PlaySound(RR ? 341 : THUD, CHAN_AUTO, CHANF_UI);
} }
} }
else else
@ -6062,7 +6062,7 @@ void G_HandleLocalKeys(void)
{ {
if (G_ChangeHudLayout(-1)) if (G_ChangeHudLayout(-1))
{ {
S_PlaySound(RR ? 341 : THUD, CHAN_UI); S_PlaySound(RR ? 341 : THUD, CHAN_AUTO, CHANF_UI);
} }
} }
else else

View file

@ -299,7 +299,7 @@ void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3]
*/ */
} }
} }
if ((chanflags & CHAN_LISTENERZ) && campos != nullptr && type != SOURCE_None) if ((chanflags & CHANF_LISTENERZ) && campos != nullptr && type != SOURCE_None)
{ {
pos->Y = campos->z / 256.f; pos->Y = campos->z / 256.f;
} }
@ -359,7 +359,7 @@ void S_Update(void)
// //
//========================================================================== //==========================================================================
int S_PlaySound3D(int sndnum, int spriteNum, const vec3_t* pos, int flags) int S_PlaySound3D(int sndnum, int spriteNum, const vec3_t* pos, int channel, EChanFlags flags)
{ {
auto const pPlayer = g_player[myconnectindex].ps; auto const pPlayer = g_player[myconnectindex].ps;
if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled() || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) || if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled() || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) ||
@ -446,8 +446,8 @@ int S_PlaySound3D(int sndnum, int spriteNum, const vec3_t* pos, int flags)
if (explosionp) attenuation = 0.5f; if (explosionp) attenuation = 0.5f;
else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM; else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM;
if (userflags & SF_LOOP) flags |= CHAN_LOOP; if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_Actor, &sprite[spriteNum], &sndpos, flags, sndnum+1, attenuation == ATTN_NONE? 0.8f : 1.f, attenuation, nullptr, S_ConvertPitch(pitch)); auto chan = soundEngine->StartSound(SOURCE_Actor, &sprite[spriteNum], &sndpos, CHAN_AUTO, flags, sndnum+1, attenuation == ATTN_NONE? 0.8f : 1.f, attenuation, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1; return chan ? 0 : -1;
} }
@ -457,7 +457,7 @@ int S_PlaySound3D(int sndnum, int spriteNum, const vec3_t* pos, int flags)
// //
//========================================================================== //==========================================================================
int S_PlaySound(int sndnum, int flags) int S_PlaySound(int sndnum, int channel, EChanFlags flags)
{ {
if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled()) return -1; if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled()) return -1;
@ -467,8 +467,8 @@ int S_PlaySound(int sndnum, int flags)
int const pitch = S_GetPitch(sndnum); int const pitch = S_GetPitch(sndnum);
if (userflags & SF_LOOP) flags |= CHAN_LOOP; if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch)); auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1; return chan ? 0 : -1;
} }
@ -478,7 +478,7 @@ int S_PlaySound(int sndnum, int flags)
// //
//========================================================================== //==========================================================================
int A_PlaySound(int soundNum, int spriteNum, int flags) int A_PlaySound(int soundNum, int spriteNum, int channel, EChanFlags flags)
{ {
return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum, flags) : return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum, flags) :
S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos, flags); S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos, flags);
@ -513,11 +513,11 @@ void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
// //
//========================================================================== //==========================================================================
int A_CheckSoundPlaying(int spriteNum, int soundNum, int flags) int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel)
{ {
if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1); if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1);
if ((unsigned)spriteNum >= MAXSPRITES) return false; if ((unsigned)spriteNum >= MAXSPRITES) return false;
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], flags, soundNum+1); return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], channel, soundNum+1);
} }
// Check if actor <i> is playing any sound. // Check if actor <i> is playing any sound.

View file

@ -45,9 +45,8 @@ typedef struct
int priority, flags; int priority, flags;
} sound_t; } sound_t;
int A_CheckSoundPlaying(int spriteNum, int soundNum, int flags = 0); int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel = 0);
int A_PlaySound(int soundNum, int spriteNum, int flags = 0); int A_PlaySound(int soundNum, int spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
void S_Callback(intptr_t num);
int A_CheckAnySoundPlaying(int spriteNum); int A_CheckAnySoundPlaying(int spriteNum);
int S_CheckSoundPlaying(int soundNum); int S_CheckSoundPlaying(int soundNum);
inline int S_CheckSoundPlaying(int sprnum, int soundNum) { return S_CheckSoundPlaying(soundNum); } inline int S_CheckSoundPlaying(int sprnum, int soundNum) { return S_CheckSoundPlaying(soundNum); }
@ -60,8 +59,8 @@ void S_PlayLevelMusicOrNothing(unsigned int);
int S_TryPlaySpecialMusic(unsigned int); int S_TryPlaySpecialMusic(unsigned int);
void S_PlaySpecialMusicOrNothing(unsigned int); void S_PlaySpecialMusicOrNothing(unsigned int);
void S_ContinueLevelMusic(void); void S_ContinueLevelMusic(void);
int S_PlaySound(int num, int flags = 0); int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0);
int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int flags = 0); int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
void S_StopEnvSound(int sndNum,int sprNum, int flags = -1); void S_StopEnvSound(int sndNum,int sprNum, int flags = -1);
void S_StopAllSounds(void); void S_StopAllSounds(void);
void S_Update(void); void S_Update(void);