- Removed the SoundChans bitfield from AActor, since it seems there are race

conditions I don't fully understand where it simply doesn't work.


SVN r1367 (trunk)
This commit is contained in:
Randy Heit 2009-01-25 01:52:38 +00:00
parent b6528a604e
commit 6ebbc920fb
5 changed files with 52 additions and 45 deletions

View file

@ -1,4 +1,6 @@
January 24, 2009
- Removed the SoundChans bitfield from AActor, since it seems there are race
conditions I don't fully understand where it simply doesn't work.
- Removed BaseTime initialization from sdl/i_system.cpp as per Chris's
recommendation.

View file

@ -679,7 +679,6 @@ public:
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
fixed_t SpawnPoint[3]; // For nightmare respawn
WORD SpawnAngle;
BYTE SoundChans; // Bitfield indicating which sound channels are playing.
int skillrespawncount;
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)

View file

@ -135,7 +135,7 @@ public:
int Amount; // Amount of item this instance has
int MaxAmount; // Max amount of item this instance can have
int RespawnTics; // Tics from pickup time to respawn time
FTextureID Icon; // Icon to show on status bar or HUD
FTextureID Icon; // Icon to show on status bar or HUD
int DropTime; // Countdown after dropping
const PClass *SpawnPointClass; // For respawning like Heretic's mace

View file

@ -196,7 +196,8 @@ AInventory *AWeapon::CreateCopy (AActor *other)
//
// A weapon that's tossed out should contain no ammo, so you can't cheat
// by dropping it and then picking it back up.
//=======================
//
//===========================================================================
AInventory *AWeapon::CreateTossable ()
{

View file

@ -100,6 +100,7 @@ extern float S_GetMusicVolume (const char *music);
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit);
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen);
static void S_ActivatePlayList(bool goBack);
static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel);
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly,
@ -572,10 +573,6 @@ FISoundChannel *S_GetChannel(void *syschan)
void S_ReturnChannel(FSoundChan *chan)
{
if (chan->SourceType == SOURCE_Actor && chan->Actor != NULL)
{
chan->Actor->SoundChans &= ~(1 << chan->EntChannel);
}
S_UnlinkChannel(chan);
memset(chan, 0, sizeof(*chan));
S_LinkChannel(chan, &FreeChannels);
@ -950,20 +947,20 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
basepriority = 0;
}
int seen = 0;
if (actor != NULL && channel == CHAN_AUTO)
{ // Select a channel that isn't already playing something.
BYTE mask = actor->SoundChans;
{
// Select a channel that isn't already playing something.
// Try channel 0 first, then travel from channel 7 down.
if ((mask & 1) == 0)
if (!S_IsChannelUsed(actor, 0, &seen))
{
channel = 0;
}
else
{
for (channel = 7; channel > 0; --channel, mask <<= 1)
for (channel = 7; channel > 0; --channel)
{
if ((mask & 0x80) == 0)
if (!S_IsChannelUsed(actor, channel, &seen))
{
break;
}
@ -976,7 +973,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
}
// If this actor is already playing something on the selected channel, stop it.
if (type != SOURCE_None && ((actor == NULL && channel != CHAN_AUTO) || (actor != NULL && actor->SoundChans & (1 << channel))))
if (type != SOURCE_None && ((actor == NULL && channel != CHAN_AUTO) || (actor != NULL && S_IsChannelUsed(actor, channel, &seen))))
{
for (chan = Channels; chan != NULL; chan = chan->NextChan)
{
@ -1068,7 +1065,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
chan->SourceType = type;
switch (type)
{
case SOURCE_Actor: chan->Actor = actor; actor->SoundChans |= 1 << channel; break;
case SOURCE_Actor: chan->Actor = actor; break;
case SOURCE_Sector: chan->Sector = sec; break;
case SOURCE_Polyobj: chan->Poly = poly; break;
case SOURCE_Unattached: chan->Point[0] = pt->X; chan->Point[1] = pt->Y; chan->Point[2] = pt->Z; break;
@ -1139,17 +1136,10 @@ void S_RestartSound(FSoundChan *chan)
ochan = (FSoundChan*)GSnd->StartSound(sfx->data, chan->Volume, chan->Pitch, startflags, chan);
}
assert(ochan == NULL || ochan == chan);
if (ochan != NULL)
if (ochan == NULL)
{
// When called from the savegame loader, the actor's SoundChans
// flags will be cleared. During normal gameplay, they should still
// be set.
if (ochan->SourceType == SOURCE_Actor)
{
if (ochan->Actor != NULL) ochan->Actor->SoundChans |= 1 << ochan->EntChannel;
}
chan->ChanFlags = oldflags;
}
else chan->ChanFlags = oldflags;
}
//==========================================================================
@ -1390,17 +1380,13 @@ void S_StopSound (int channel)
void S_StopSound (AActor *actor, int channel)
{
// No need to search every channel if we know it's not playing anything.
if (actor != NULL && actor->SoundChans & (1 << channel))
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
{
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
if (chan->SourceType == SOURCE_Actor &&
chan->Actor == actor &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
if (chan->SourceType == SOURCE_Actor &&
chan->Actor == actor &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
S_StopChannel(chan);
}
S_StopChannel(chan);
}
}
}
@ -1502,11 +1488,6 @@ void S_RelinkSound (AActor *from, AActor *to)
}
}
}
if (to != NULL)
{
to->SoundChans = from->SoundChans;
}
from->SoundChans = 0;
}
//==========================================================================
@ -1567,6 +1548,36 @@ bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id)
return false;
}
//==========================================================================
//
// S_IsChannelUsed
//
// Returns true if the channel is in use. Also fills in a bitmask of
// channels seen while scanning for this one, to make searching for unused
// channels faster. Initialize seen to 0 for the first call.
//
//==========================================================================
bool S_IsChannelUsed(AActor *actor, int channel, int *seen)
{
if (*seen & (1 << channel))
{
return true;
}
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
{
if (chan->SourceType == SOURCE_Actor && chan->Actor == actor)
{
*seen |= 1 << chan->EntChannel;
if (chan->EntChannel == channel)
{
return true;
}
}
}
return false;
}
//==========================================================================
//
// S_IsActorPlayingSomething
@ -1575,11 +1586,6 @@ bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id)
bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id)
{
if (actor->SoundChans == 0)
{
return false;
}
if (i_compatflags & COMPATF_MAGICSILENCE)
{
channel = 0;
@ -1933,9 +1939,8 @@ void S_StopChannel(FSoundChan *chan)
chan->ChanFlags |= CHAN_FORGETTABLE;
}
if (chan->SourceType == SOURCE_Actor && chan->Actor != NULL)
if (chan->SourceType == SOURCE_Actor)
{
chan->Actor->SoundChans &= ~(1 << chan->EntChannel);
chan->Actor = NULL;
}