- Replaced the naive area sound implementation with one that takes into

consideration the size and shape of the sector producing the sound. See
  the lifts on Doom 2 MAP30 and compare with previous versions.
- Fixed: The stop sound for sector-based sound sequences was not played with
  the CHAN_AREA flag.
- Removed the distinction between S_Sound() and S_SoundID() functions. Use
  S_Sound() for both names and IDs from now on.


SVN r1034 (trunk)
This commit is contained in:
Randy Heit 2008-06-15 02:25:09 +00:00
commit 9e42cdaf08
66 changed files with 604 additions and 430 deletions

View file

@ -96,32 +96,56 @@ typedef struct {
class DSeqActorNode : public DSeqNode
{
DECLARE_CLASS (DSeqActorNode, DSeqNode)
DECLARE_CLASS(DSeqActorNode, DSeqNode)
HAS_OBJECT_POINTERS
public:
DSeqActorNode (AActor *actor, int sequence, int modenum);
void Destroy ();
void Serialize (FArchive &arc);
void MakeSound (int loop) { S_SoundID (m_Actor, CHAN_BODY|loop, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
bool IsPlaying () { return S_IsActorPlayingSomething (m_Actor, CHAN_BODY, m_CurrentSoundID); }
void *Source () { return m_Actor; }
DSeqNode *SpawnChild (int seqnum) { return SN_StartSequence (m_Actor, seqnum, SEQ_NOTRANS, m_ModeNum, true); }
DSeqActorNode(AActor *actor, int sequence, int modenum);
void Destroy();
void Serialize(FArchive &arc);
void MakeSound(int loop, FSoundID id)
{
S_Sound(m_Actor, CHAN_BODY|loop, id, clamp(m_Volume, 0.f, 1.f), m_Atten);
}
bool IsPlaying()
{
return S_IsActorPlayingSomething (m_Actor, CHAN_BODY, m_CurrentSoundID);
}
void *Source()
{
return m_Actor;
}
DSeqNode *SpawnChild(int seqnum)
{
return SN_StartSequence (m_Actor, seqnum, SEQ_NOTRANS, m_ModeNum, true);
}
private:
DSeqActorNode () {}
DSeqActorNode() {}
TObjPtr<AActor> m_Actor;
};
class DSeqPolyNode : public DSeqNode
{
DECLARE_CLASS (DSeqPolyNode, DSeqNode)
DECLARE_CLASS(DSeqPolyNode, DSeqNode)
public:
DSeqPolyNode (FPolyObj *poly, int sequence, int modenum);
void Destroy ();
void Serialize (FArchive &arc);
void MakeSound (int loop) { S_SoundID (&m_Poly->startSpot[0], CHAN_BODY|loop, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
bool IsPlaying () { return S_GetSoundPlayingInfo (&m_Poly->startSpot[0], m_CurrentSoundID); }
void *Source () { return m_Poly; }
DSeqNode *SpawnChild (int seqnum) { return SN_StartSequence (m_Poly, seqnum, SEQ_NOTRANS, m_ModeNum, true); }
DSeqPolyNode(FPolyObj *poly, int sequence, int modenum);
void Destroy();
void Serialize(FArchive &arc);
void MakeSound(int loop, FSoundID id)
{
S_Sound (&m_Poly->startSpot[0], CHAN_BODY|loop, id, clamp(m_Volume, 0.f, 1.f), m_Atten);
}
bool IsPlaying()
{
return S_GetSoundPlayingInfo (&m_Poly->startSpot[0], m_CurrentSoundID);
}
void *Source()
{
return m_Poly;
}
DSeqNode *SpawnChild (int seqnum)
{
return SN_StartSequence (m_Poly, seqnum, SEQ_NOTRANS, m_ModeNum, true);
}
private:
DSeqPolyNode () {}
FPolyObj *m_Poly;
@ -129,20 +153,32 @@ private:
class DSeqSectorNode : public DSeqNode
{
DECLARE_CLASS (DSeqSectorNode, DSeqNode)
DECLARE_CLASS(DSeqSectorNode, DSeqNode)
public:
DSeqSectorNode (sector_t *sec, int sequence, int modenum, bool is_door);
void Destroy ();
void Serialize (FArchive &arc);
void MakeSound (int loop) { S_SoundID (&m_Sector->soundorg[0], CHAN_BODY|(m_IsDoor ? 0 : CHAN_AREA)|loop, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); Looping = !!loop; }
bool IsPlaying () { return S_GetSoundPlayingInfo (m_Sector->soundorg, m_CurrentSoundID); }
void *Source () { return m_Sector; }
DSeqNode *SpawnChild (int seqnum) { return SN_StartSequence (m_Sector, seqnum, SEQ_NOTRANS, m_ModeNum, true); }
bool Looping;
DSeqSectorNode(sector_t *sec, int chan, int sequence, int modenum);
void Destroy();
void Serialize(FArchive &arc);
void MakeSound(int loop, FSoundID id)
{
Channel = (Channel & 7) | CHAN_AREA | loop;
S_Sound(m_Sector, Channel, id, clamp(m_Volume, 0.f, 1.f), m_Atten);
}
bool IsPlaying()
{
return S_GetSoundPlayingInfo (m_Sector->soundorg, m_CurrentSoundID);
}
void *Source()
{
return m_Sector;
}
DSeqNode *SpawnChild(int seqnum)
{
return SN_StartSequence (m_Sector, Channel, seqnum, SEQ_NOTRANS, m_ModeNum, true);
}
int Channel;
private:
DSeqSectorNode() {}
sector_t *m_Sector;
bool m_IsDoor;
};
// When destroyed, destroy the sound sequences too.
@ -152,7 +188,7 @@ struct FSoundSequencePtrArray : public TArray<FSoundSequence *>
{
for (unsigned int i = 0; i < Size(); ++i)
{
M_Free ((*this)[i]);
M_Free((*this)[i]);
}
}
};
@ -161,7 +197,7 @@ struct FSoundSequencePtrArray : public TArray<FSoundSequence *>
static void AssignTranslations (FScanner &sc, int seq, seqtype_t type);
static void AssignHexenTranslations (void);
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp, bool bDoorSound);
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp);
static int FindSequence (const char *searchname);
static int FindSequence (FName seqname);
static bool TwiddleSeqNum (int &sequence, seqtype_t type);
@ -271,7 +307,7 @@ void DSeqNode::Serialize (FArchive &arc)
<< m_Prev
<< m_ChildSeqNode
<< m_ParentSeqNode
<< AR_SOUND(m_CurrentSoundID)
<< m_CurrentSoundID
<< Sequences[m_Sequence]->SeqName;
arc.WriteCount (m_SequenceChoices.Size());
@ -283,7 +319,8 @@ void DSeqNode::Serialize (FArchive &arc)
else
{
FName seqName;
int delayTics = 0, id;
int delayTics = 0;
FSoundID id;
float volume;
int atten = ATTN_NORM;
int seqnum;
@ -298,7 +335,7 @@ void DSeqNode::Serialize (FArchive &arc)
<< m_Prev
<< m_ChildSeqNode
<< m_ParentSeqNode
<< AR_SOUND(id)
<< id
<< seqName;
seqnum = FindSequence (seqName);
@ -398,7 +435,7 @@ IMPLEMENT_CLASS (DSeqSectorNode)
void DSeqSectorNode::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << m_Sector << Looping << m_IsDoor;
arc << m_Sector << Channel;
}
//==========================================================================
@ -448,7 +485,6 @@ static void AssignHexenTranslations (void)
if (HexenSequences[i].Seqs[j] & 0x40)
{
trans = 64 * SEQ_DOOR;
Sequences[seq]->bDoorSound |= true;
}
else if (HexenSequences[i].Seqs[j] & 0x80)
trans = 64 * SEQ_ENVIRONMENT;
@ -505,8 +541,6 @@ void S_ParseSndSeq (int levellump)
FScanner sc(lump);
while (sc.GetString ())
{
bool bDoorSound = false;
if (*sc.String == ':' || *sc.String == '[')
{
if (curseq != -1)
@ -531,7 +565,6 @@ void S_ParseSndSeq (int levellump)
ScriptTemp.Clear();
stopsound = 0;
slot = NAME_None;
bDoorSound = false;
if (seqtype == '[')
{
sc.SetCMode (true);
@ -548,7 +581,7 @@ void S_ParseSndSeq (int levellump)
if (sc.String[0] == ']')
{ // End of this definition
ScriptTemp[0] = MakeCommand(SS_CMD_SELECT, (ScriptTemp.Size()-1)/2);
AddSequence (curseq, seqname, slot, stopsound, ScriptTemp, bDoorSound);
AddSequence (curseq, seqname, slot, stopsound, ScriptTemp);
curseq = -1;
sc.SetCMode (false);
}
@ -565,7 +598,6 @@ void S_ParseSndSeq (int levellump)
{
seqtype_t seqtype = seqtype_t(sc.MustMatchString (SSStrings + SS_STRING_PLATFORM));
AssignTranslations (sc, curseq, seqtype);
if (seqtype == SEQ_DOOR) bDoorSound = true;
}
}
continue;
@ -664,7 +696,7 @@ void S_ParseSndSeq (int levellump)
break;
case SS_STRING_END:
AddSequence (curseq, seqname, slot, stopsound, ScriptTemp, bDoorSound);
AddSequence (curseq, seqname, slot, stopsound, ScriptTemp);
curseq = -1;
break;
@ -674,7 +706,6 @@ void S_ParseSndSeq (int levellump)
case SS_STRING_DOOR:
AssignTranslations (sc, curseq, SEQ_DOOR);
bDoorSound = true;
break;
case SS_STRING_ENVIRONMENT:
@ -697,13 +728,12 @@ void S_ParseSndSeq (int levellump)
AssignHexenTranslations ();
}
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp, bool bDoorSound)
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp)
{
Sequences[curseq] = (FSoundSequence *)M_Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size());
Sequences[curseq]->SeqName = seqname;
Sequences[curseq]->Slot = slot;
Sequences[curseq]->StopSound = stopsound;
Sequences[curseq]->bDoorSound = bDoorSound;
memcpy (Sequences[curseq]->Script, &ScriptTemp[0], sizeof(DWORD)*ScriptTemp.Size());
Sequences[curseq]->Script[ScriptTemp.Size()] = MakeCommand(SS_CMD_END, 0);
}
@ -753,12 +783,11 @@ DSeqPolyNode::DSeqPolyNode (FPolyObj *poly, int sequence, int modenum)
{
}
DSeqSectorNode::DSeqSectorNode (sector_t *sec, int sequence, int modenum, bool is_door)
DSeqSectorNode::DSeqSectorNode (sector_t *sec, int chan, int sequence, int modenum)
: DSeqNode (sequence, modenum),
Looping (false),
Channel (chan),
m_Sector (sec)
{
m_IsDoor = is_door;
}
//==========================================================================
@ -802,7 +831,7 @@ DSeqNode *SN_StartSequence (AActor *actor, int sequence, seqtype_t type, int mod
return NULL;
}
DSeqNode *SN_StartSequence (sector_t *sector, int sequence, seqtype_t type, int modenum, bool is_door, bool nostop)
DSeqNode *SN_StartSequence (sector_t *sector, int chan, int sequence, seqtype_t type, int modenum, bool nostop)
{
if (!nostop)
{
@ -810,7 +839,7 @@ DSeqNode *SN_StartSequence (sector_t *sector, int sequence, seqtype_t type, int
}
if (TwiddleSeqNum (sequence, type))
{
return new DSeqSectorNode (sector, sequence, modenum, is_door);
return new DSeqSectorNode (sector, chan, sequence, modenum);
}
return NULL;
}
@ -854,12 +883,12 @@ DSeqNode *SN_StartSequence (AActor *actor, FName seqname, int modenum)
return NULL;
}
DSeqNode *SN_StartSequence (sector_t *sec, const char *seqname, int modenum, bool is_door)
DSeqNode *SN_StartSequence (sector_t *sec, int chan, const char *seqname, int modenum)
{
int seqnum = FindSequence (seqname);
if (seqnum >= 0)
{
return SN_StartSequence (sec, seqnum, SEQ_NOTRANS, modenum, is_door);
return SN_StartSequence (sec, chan, seqnum, SEQ_NOTRANS, modenum);
}
return NULL;
}
@ -940,16 +969,16 @@ void DSeqActorNode::Destroy ()
if (m_StopSound >= 0)
S_StopSound (m_Actor, CHAN_BODY);
if (m_StopSound >= 1)
S_SoundID (m_Actor, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
MakeSound (0, m_StopSound);
Super::Destroy();
}
void DSeqSectorNode::Destroy ()
{
if (m_StopSound >= 0)
S_StopSound (m_Sector->soundorg, CHAN_BODY);
S_StopSound (m_Sector->soundorg, Channel & 7);
if (m_StopSound >= 1)
S_SoundID (m_Sector->soundorg, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
MakeSound (0, m_StopSound);
Super::Destroy();
}
@ -958,7 +987,7 @@ void DSeqPolyNode::Destroy ()
if (m_StopSound >= 0)
S_StopSound (m_Poly->startSpot, CHAN_BODY);
if (m_StopSound >= 1)
S_SoundID (m_Poly->startSpot, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
MakeSound (0, m_StopSound);
Super::Destroy();
}
@ -977,7 +1006,7 @@ bool SN_IsMakingLoopingSound (sector_t *sector)
DSeqNode *next = node->NextSequence();
if (node->Source() == (void *)sector)
{
return static_cast<DSeqSectorNode *> (node)->Looping;
return !!(static_cast<DSeqSectorNode *>(node)->Channel & CHAN_LOOP);
}
node = next;
}
@ -1007,8 +1036,8 @@ void DSeqNode::Tick ()
case SS_CMD_PLAY:
if (!IsPlaying())
{
m_CurrentSoundID = GetData(*m_SequencePtr);
MakeSound (0);
m_CurrentSoundID = FSoundID(GetData(*m_SequencePtr));
MakeSound (0, m_CurrentSoundID);
}
m_SequencePtr++;
break;
@ -1029,16 +1058,16 @@ void DSeqNode::Tick ()
if (!IsPlaying())
{
// Does not advance sequencePtr, so it will repeat as necessary.
m_CurrentSoundID = GetData(*m_SequencePtr);
MakeSound (CHAN_LOOP);
m_CurrentSoundID = FSoundID(GetData(*m_SequencePtr));
MakeSound (CHAN_LOOP, m_CurrentSoundID);
}
return;
case SS_CMD_PLAYLOOP:
// Like SS_CMD_PLAYREPEAT, sequencePtr is not advanced, so this
// command will repeat until the sequence is stopped.
m_CurrentSoundID = GetData(m_SequencePtr[0]);
MakeSound (0);
m_CurrentSoundID = FSoundID(GetData(m_SequencePtr[0]));
MakeSound (0, m_CurrentSoundID);
m_DelayUntilTic = TIME_REFERENCE + m_SequencePtr[1];
return;
@ -1246,7 +1275,7 @@ void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics, float volume,
node->ChangeData (seqOffset, delayTics, volume, currentSoundID);
}
void DSeqNode::ChangeData (int seqOffset, int delayTics, float volume, int currentSoundID)
void DSeqNode::ChangeData (int seqOffset, int delayTics, float volume, FSoundID currentSoundID)
{
m_DelayUntilTic = TIME_REFERENCE + delayTics;
m_Volume = volume;