- 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)
{
//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)
{
//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;
return true;
}

View file

@ -8,6 +8,32 @@
#include "tarray.h"
#include "zmusic/sounddecoder.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;
@ -112,7 +138,7 @@ struct FISoundChannel
float DistanceScale;
float DistanceSqr;
bool ManualRolloff;
int ChanFlags;
EChanFlags ChanFlags;
};
@ -122,4 +148,5 @@ class SoundStream;
#endif

View file

@ -1672,7 +1672,7 @@ void OpenALSoundRenderer::ChannelPitch(FISoundChannel *chan, float pitch)
alDeferUpdatesSOFT();
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);
else
alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f));
@ -1950,7 +1950,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan)
{
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]);
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
@ -1963,7 +1963,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan)
{
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);
schan = schan->NextChan;
}
@ -1988,7 +1988,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan)
{
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]);
alSource3i(source, AL_AUXILIARY_SEND_FILTER, EnvSlot, 0, EnvFilters[1]);
@ -2001,7 +2001,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
while (schan)
{
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);
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
// any to forget about it. And if it's a UI sound, it shouldn't
// be stored in the savegame.
if (!(chan->ChanFlags & (CHAN_FORGETTABLE | CHAN_UI)))
if (!(chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_UI)))
{
chans.Push(chan);
}
@ -306,7 +306,7 @@ FString SoundEngine::ListSoundChannels()
int count = 0;
for (chan = Channels; chan != nullptr; chan = chan->NextChan)
{
if (!(chan->ChanFlags & CHAN_EVICTED))
if (!(chan->ChanFlags & CHANF_EVICTED))
{
FVector3 chanorigin;
@ -376,11 +376,11 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a
//==========================================================================
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)
{
sfxinfo_t *sfx;
int chanflags;
EChanFlags chanflags = flags;
int basepriority;
int org_id;
int pitch;
@ -396,8 +396,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
if (type == SOURCE_Unattached && pt == nullptr) type = SOURCE_None;
org_id = sound_id;
chanflags = channel & ~7;
channel &= 7;
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 (sfx->bSingular && CheckSingular(sound_id))
{
chanflags |= CHAN_EVICTED;
chanflags |= CHANF_EVICTED;
}
// 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?)
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
// is blocked and looped, pretend to play it so that it can
// eventually play for real.
if ((chanflags & (CHAN_EVICTED | CHAN_LOOP)) == CHAN_EVICTED)
if ((chanflags & (CHANF_EVICTED | CHANF_LOOP)) == CHANF_EVICTED)
{
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 (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)
{
@ -552,7 +550,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// sound is paused and a non-looped sound is being started.
// 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;
}
@ -567,17 +565,17 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
pitch = DEFAULT_PITCH;
}
if (chanflags & CHAN_EVICTED)
if (chanflags & CHANF_EVICTED)
{
chan = NULL;
}
else
{
int startflags = 0;
if (chanflags & CHAN_LOOP) startflags |= SNDF_LOOP;
if (chanflags & CHAN_AREA) startflags |= SNDF_AREA;
if (chanflags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chanflags & CHAN_UI) startflags |= SNDF_NOREVERB;
if (chanflags & CHANF_LOOP) startflags |= SNDF_LOOP;
if (chanflags & CHANF_AREA) startflags |= SNDF_AREA;
if (chanflags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chanflags & CHANF_UI) startflags |= SNDF_NOREVERB;
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);
}
}
if (chan == NULL && (chanflags & CHAN_LOOP))
if (chan == NULL && (chanflags & CHANF_LOOP))
{
chan = (FSoundChan*)GetChannel(NULL);
GSnd->MarkStartTime(chan);
chanflags |= CHAN_EVICTED;
chanflags |= CHANF_EVICTED;
}
if (attenuation > 0)
{
chanflags |= CHAN_IS3D | CHAN_JUSTSTARTED;
chanflags |= CHANF_IS3D | CHANF_JUSTSTARTED;
}
else
{
chanflags |= CHAN_LISTENERZ | CHAN_JUSTSTARTED;
chanflags |= CHANF_LISTENERZ | CHANF_JUSTSTARTED;
}
if (chan != NULL)
{
@ -642,7 +640,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
void SoundEngine::RestartChannel(FSoundChan *chan)
{
assert(chan->ChanFlags & CHAN_EVICTED);
assert(chan->ChanFlags & CHANF_EVICTED);
FSoundChan *ochan;
sfxinfo_t *sfx = &S_sfx[chan->SoundID];
@ -660,15 +658,15 @@ void SoundEngine::RestartChannel(FSoundChan *chan)
return;
}
int oldflags = chan->ChanFlags;
EChanFlags oldflags = chan->ChanFlags;
int startflags = 0;
if (chan->ChanFlags & CHAN_LOOP) startflags |= SNDF_LOOP;
if (chan->ChanFlags & CHAN_AREA) startflags |= SNDF_AREA;
if (chan->ChanFlags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chan->ChanFlags & CHAN_ABSTIME) startflags |= SNDF_ABSTIME;
if (chan->ChanFlags & CHANF_LOOP) startflags |= SNDF_LOOP;
if (chan->ChanFlags & CHANF_AREA) startflags |= SNDF_AREA;
if (chan->ChanFlags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE;
if (chan->ChanFlags & CHANF_ABSTIME) startflags |= SNDF_ABSTIME;
if (chan->ChanFlags & CHAN_IS3D)
if (chan->ChanFlags & CHANF_IS3D)
{
FVector3 pos, vel;
@ -687,13 +685,13 @@ void SoundEngine::RestartChannel(FSoundChan *chan)
}
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,
chan->Priority, pos, vel, chan->EntChannel, startflags, chan);
}
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);
}
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)
{
if (!(chan->ChanFlags & CHAN_EVICTED) && &S_sfx[chan->SoundID] == sfx)
if (!(chan->ChanFlags & CHANF_EVICTED) && &S_sfx[chan->SoundID] == sfx)
{
FVector3 chanorigin;
@ -940,7 +938,7 @@ void SoundEngine::StopSound (int channel, int sound_id)
while (chan != NULL)
{
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);
}
@ -1015,7 +1013,7 @@ void SoundEngine::RelinkSound (int sourcetype, const void *from, const void *to,
{
chan->Source = to;
}
else if (!(chan->ChanFlags & CHAN_LOOP) && optpos)
else if (!(chan->ChanFlags & CHANF_LOOP) && optpos)
{
chan->Source = NULL;
chan->SourceType = SOURCE_Unattached;
@ -1183,15 +1181,15 @@ void SoundEngine::EvictAllChannels()
{
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->ChanFlags & CHAN_ABSTIME))
if (!(chan->ChanFlags & CHANF_ABSTIME))
{
chan->StartTime = GSnd ? GSnd->GetPosition(chan) : 0;
chan->ChanFlags |= CHAN_ABSTIME;
chan->ChanFlags |= CHANF_ABSTIME;
}
StopChannel(chan);
}
@ -1215,22 +1213,22 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan)
return;
}
RestoreEvictedChannel(chan->NextChan);
if (chan->ChanFlags & CHAN_EVICTED)
if (chan->ChanFlags & CHANF_EVICTED)
{
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.
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.
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);
}
@ -1264,16 +1262,16 @@ void SoundEngine::UpdateSounds(int time)
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);
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);
@ -1342,11 +1340,11 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
// 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
// didn't reach the end of its playback.
if (schan->ChanFlags & CHAN_FORGETTABLE)
if (schan->ChanFlags & CHANF_FORGETTABLE)
{
evicted = false;
}
else if (schan->ChanFlags & (CHAN_LOOP | CHAN_EVICTED))
else if (schan->ChanFlags & (CHANF_LOOP | CHANF_EVICTED))
{
evicted = true;
}
@ -1356,7 +1354,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
unsigned int len = GSnd->GetSampleLength(S_sfx[schan->SoundID].data);
if (pos == 0)
{
evicted = !!(schan->ChanFlags & CHAN_JUSTSTARTED);
evicted = !!(schan->ChanFlags & CHANF_JUSTSTARTED);
}
else
{
@ -1369,7 +1367,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
}
else
{
schan->ChanFlags |= CHAN_EVICTED;
schan->ChanFlags |= CHANF_EVICTED;
schan->SysChannel = NULL;
}
}
@ -1386,11 +1384,11 @@ void SoundEngine::ChannelVirtualChanged(FISoundChannel *ichan, bool is_virtual)
FSoundChan *schan = static_cast<FSoundChan*>(ichan);
if (is_virtual)
{
schan->ChanFlags |= CHAN_VIRTUAL;
schan->ChanFlags |= CHANF_VIRTUAL;
}
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
// 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)
{
chan->Source = NULL;
@ -1736,7 +1734,7 @@ FString SoundEngine::NoiseDebug()
for (auto chan = Channels; chan; chan = chan->NextChan)
{
if (!(chan->ChanFlags & CHAN_IS3D))
if (!(chan->ChanFlags & CHANF_IS3D))
{
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("%-.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 & CHAN_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHANF_EVICTED) ? 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());
ch++;
}

View file

@ -192,7 +192,7 @@ struct FSoundChan : public FISoundChannel
// CHAN_BODY is for generic body sounds
// CHAN_PICKUP can optionally be set as a local sound only for "compatibility"
enum
enum EChannel
{
CHAN_AUTO = 0,
CHAN_WEAPON = 1,
@ -202,33 +202,10 @@ enum
CHAN_5 = 5,
CHAN_6 = 6,
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
#define ATTN_NONE 0.f // full volume the entire level
#define ATTN_NORM 1.f
@ -327,7 +304,7 @@ public:
void UpdateSounds(int time);
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.
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;
}
#endif
A_PlaySound(pSprite->lotag,spriteNum, CHAN_LOOP);
A_PlaySound(pSprite->lotag,spriteNum, CHAN_AUTO, CHANF_LOOP);
T1(spriteNum) = 1; // AMBIENT_SFX_PLAYING
}
else if (playerDist >= spriteHitag && T1(spriteNum) == 1)

View file

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

View file

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

View file

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

View file

@ -4125,7 +4125,7 @@ badindex:
if (S_CheckSoundPlaying(soundNum))
S_StopSound((int16_t)soundNum);
dispatch();
case CON_SCREENSOUND: S_PlaySound(soundNum, CHAN_UI); dispatch();
case CON_SCREENSOUND: S_PlaySound(soundNum, CHAN_AUTO, CHANF_UI); 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;
}
@ -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);
@ -443,8 +443,8 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t* pos, int flags)
if (explosionp) attenuation = 0.5f;
else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM;
if (userflags & SF_LOOP) flags |= CHAN_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));
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
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;
}
@ -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);
@ -466,8 +466,8 @@ int S_PlaySound(int num, int flags)
int const pitch = S_GetPitch(sndnum);
if (userflags & SF_LOOP) flags |= CHAN_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
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) :
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) soundEngine->StopSoundID(sndNum+1);
else if (flags == -1) soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum+1);
else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], flags, -1);
else if (channel == -1) soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum+1);
else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], channel, -1);
}
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 ((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.

View file

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

View file

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

View file

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

View file

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

View file

@ -5954,7 +5954,7 @@ int G_StartRTS(int lumpNum, int localPlayer)
auto sid = RTS_GetSoundID(lumpNum - 1);
if (sid != -1)
{
S_PlaySound(sid, CHAN_UI);
S_PlaySound(sid, CHAN_AUTO, CHANF_UI);
g_RTSPlaying = 7;
return 1;
}
@ -6043,7 +6043,7 @@ void G_HandleLocalKeys(void)
{
if (G_ChangeHudLayout(1))
{
S_PlaySound(RR ? 341 : THUD, CHAN_UI);
S_PlaySound(RR ? 341 : THUD, CHAN_AUTO, CHANF_UI);
}
}
else
@ -6062,7 +6062,7 @@ void G_HandleLocalKeys(void)
{
if (G_ChangeHudLayout(-1))
{
S_PlaySound(RR ? 341 : THUD, CHAN_UI);
S_PlaySound(RR ? 341 : THUD, CHAN_AUTO, CHANF_UI);
}
}
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;
}
@ -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;
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;
else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM;
if (userflags & SF_LOOP) flags |= CHAN_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));
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
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;
}
@ -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;
@ -467,8 +467,8 @@ int S_PlaySound(int sndnum, int flags)
int const pitch = S_GetPitch(sndnum);
if (userflags & SF_LOOP) flags |= CHAN_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
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) :
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 ((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.

View file

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