mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- The sound code now handles restarting looping sounds itself. As far as
the rest of the game is concerned, these sounds will never stop once they have been started until they are explicitly stopped. If they are evicted from their channels, the sound code will restart them as soon as possible. This means that instead of this: if (!S_IsActorPlayingSomething(actor, CHAN_WEAPON, -1)) { S_Sound(actor, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); } The following is now just as effective: S_Sound(actor, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); There are also a couple of other ramifications presented by this change: * The full state of the sound system (sans music) is now stored in save games. Any sounds that were playing when you saved will still be playing when you load. (Try saving while Korax is making a speech in Hexen to hear it.) * Using snd_reset will also preserve any playing sounds. * Movie playback is disabled, probably forever. I did not want to update the MovieDisable/ResumeSound stuff for the new eviction tracking code. A properly updated movie player will use the VMR, which doesn't need these functions, since it would pipe the sound straight through the sound system like everything else, so I decided to dump them now, which leaves the movie player in a totally unworkable state. June 26, 2008 - Changed S_Sound() to take the same floating point attenuation that the internal S_StartSound() uses. Now ambient sounds can use the public S_Sound() interface. - Fixed: S_RelinkSound() compared the points of the channels against the from actor's point, rather than checking the channels' mover. - Changed Strife's animated doors so that their sounds originate from the interior of the sector making them and not from the entire vertical height of the map. SVN r1055 (trunk)
This commit is contained in:
parent
095b482624
commit
d0b2c41270
16 changed files with 726 additions and 219 deletions
|
@ -8,7 +8,41 @@ June 28, 2008 (Changes by Graf Zahl)
|
|||
- Fixed: Heretic's ActivatedTimeBomb had the same spawn ID as the inventory item.
|
||||
- fixed: Heretic's mace did not have its spawn ID set.
|
||||
|
||||
June 28, 2008
|
||||
- The sound code now handles restarting looping sounds itself. As far as
|
||||
the rest of the game is concerned, these sounds will never stop once they
|
||||
have been started until they are explicitly stopped. If they are evicted
|
||||
from their channels, the sound code will restart them as soon as possible.
|
||||
This means that instead of this:
|
||||
if (!S_IsActorPlayingSomething(actor, CHAN_WEAPON, -1))
|
||||
{
|
||||
S_Sound(actor, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM);
|
||||
}
|
||||
The following is now just as effective:
|
||||
S_Sound(actor, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM);
|
||||
There are also a couple of other ramifications presented by this change:
|
||||
* The full state of the sound system (sans music) is now stored in save
|
||||
games. Any sounds that were playing when you saved will still be
|
||||
playing when you load. (Try saving while Korax is making a speech in
|
||||
Hexen to hear it.)
|
||||
* Using snd_reset will also preserve any playing sounds.
|
||||
* Movie playback is disabled, probably forever. I did not want to
|
||||
update the MovieDisable/ResumeSound stuff for the new eviction
|
||||
tracking code. A properly updated movie player will use the VMR,
|
||||
which doesn't need these functions, since it would pipe the sound
|
||||
straight through the sound system like everything else, so I decided
|
||||
to dump them now, which leaves the movie player in a totally unworkable
|
||||
state.
|
||||
|
||||
June 26, 2008
|
||||
- Changed S_Sound() to take the same floating point attenuation that the
|
||||
internal S_StartSound() uses. Now ambient sounds can use the public
|
||||
S_Sound() interface.
|
||||
- Fixed: S_RelinkSound() compared the points of the channels against the
|
||||
from actor's point, rather than checking the channels' mover.
|
||||
- Changed Strife's animated doors so that their sounds originate from the
|
||||
interior of the sector making them and not from the entire vertical height
|
||||
of the map.
|
||||
- For controls that are not bound, the customize controls menu now displays
|
||||
a black --- instead of ???.
|
||||
- Applied Gez's BossBrainPatch3.
|
||||
|
|
|
@ -126,6 +126,18 @@ typedef struct _GUID
|
|||
} GUID;
|
||||
#endif
|
||||
|
||||
union QWORD_UNION
|
||||
{
|
||||
QWORD AsOne;
|
||||
struct
|
||||
{
|
||||
#ifdef WORDS_BIG_ENDIAN
|
||||
unsigned int Hi, Lo;
|
||||
#else
|
||||
unsigned int Lo, Hi;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// Bounding box coordinate storage.
|
||||
enum
|
||||
|
|
|
@ -177,6 +177,7 @@ virtual void Read (void *mem, unsigned int len);
|
|||
FArchive& operator<< (WORD &s);
|
||||
FArchive& operator<< (DWORD &i);
|
||||
FArchive& operator<< (QWORD &i);
|
||||
FArchive& operator<< (QWORD_UNION &i) { return operator<< (i.AsOne); }
|
||||
FArchive& operator<< (float &f);
|
||||
FArchive& operator<< (double &d);
|
||||
FArchive& operator<< (char *&str);
|
||||
|
|
|
@ -729,7 +729,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay)
|
|||
MoveCeiling (2048*FRACUNIT, topdist, 1);
|
||||
if (DoorAnimations[m_WhichDoorIndex].OpenSound != NAME_None)
|
||||
{
|
||||
SN_StartSequence (m_Sector, CHAN_FULLHEIGHT, DoorAnimations[m_WhichDoorIndex].OpenSound, 1);
|
||||
SN_StartSequence (m_Sector, CHAN_INTERIOR, DoorAnimations[m_WhichDoorIndex].OpenSound, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ void P_SerializeThinkers (FArchive &arc, bool hubLoad)
|
|||
|
||||
void P_SerializeSounds (FArchive &arc)
|
||||
{
|
||||
S_SerializeSounds (arc);
|
||||
DSeqNode::SerializeSequences (arc);
|
||||
char *name = NULL;
|
||||
BYTE order;
|
||||
|
|
|
@ -186,8 +186,6 @@ MidiDeviceMap MidiDevices;
|
|||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel,
|
||||
FSoundID sound_id, float volume, float attenuation);
|
||||
extern bool IsFloat (const char *str);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
@ -1873,35 +1871,28 @@ void AAmbientSound::Tick ()
|
|||
return;
|
||||
|
||||
AmbientSound *ambient = Ambients[args[0]];
|
||||
int loop = 0;
|
||||
|
||||
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
||||
{
|
||||
if (S_IsActorPlayingSomething (this, CHAN_BODY, -1))
|
||||
return;
|
||||
loop = CHAN_LOOP;
|
||||
}
|
||||
|
||||
if (ambient->sound[0])
|
||||
if (ambient->sound[0])
|
||||
{
|
||||
S_Sound(this, CHAN_BODY | loop, ambient->sound, ambient->volume, ambient->attenuation);
|
||||
if (!loop)
|
||||
{
|
||||
S_StartSound (&this->x, this, NULL, CHAN_BODY|CHAN_LOOP, ambient->sound,
|
||||
ambient->volume, ambient->attenuation);
|
||||
SetTicker (ambient);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy ();
|
||||
NextCheck = INT_MAX;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ambient->sound[0])
|
||||
{
|
||||
S_StartSound (NULL, this, NULL, CHAN_BODY, ambient->sound,
|
||||
ambient->volume, ambient->attenuation);
|
||||
SetTicker (ambient);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -269,10 +269,6 @@ static FRandom pr_sndseq ("SndSeq");
|
|||
|
||||
void DSeqNode::SerializeSequences (FArchive &arc)
|
||||
{
|
||||
if (arc.IsLoading ())
|
||||
{
|
||||
SN_StopAllSequences ();
|
||||
}
|
||||
arc << SequenceListHead;
|
||||
}
|
||||
|
||||
|
|
511
src/s_sound.cpp
511
src/s_sound.cpp
|
@ -63,7 +63,6 @@
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define SELECT_ATTEN(a) ((a)==ATTN_NONE ? 0 : (a)==ATTN_STATIC ? 3 : 1)
|
||||
#ifndef FIXED2FLOAT
|
||||
#define FIXED2FLOAT(f) (((float)(f))/(float)65536)
|
||||
#endif
|
||||
|
@ -91,16 +90,15 @@ extern float S_GetMusicVolume (const char *music);
|
|||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
FSoundChan *S_StartSound(fixed_t *pt, AActor *mover, sector_t *sec, int channel,
|
||||
FSoundID sound_id, float volume, float attenuation);
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static fixed_t P_AproxDistance2(fixed_t *listener, fixed_t x, fixed_t y);
|
||||
static bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int NearLimit);
|
||||
static bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int near_limit);
|
||||
static void S_ActivatePlayList(bool goBack);
|
||||
static void CalcPosVel(fixed_t *pt, AActor *mover, int constz, float pos[3],
|
||||
float vel[3]);
|
||||
static FSoundChan *S_StartSound(fixed_t *pt, AActor *mover, sector_t *sec,
|
||||
int channel, FSoundID sound_id, float volume, float attenuation);
|
||||
static sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -129,32 +127,6 @@ CVAR (Bool, snd_flipstereo, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_AproxDistance2
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static fixed_t P_AproxDistance2 (fixed_t *listener, fixed_t x, fixed_t y)
|
||||
{
|
||||
// calculate the distance to sound origin
|
||||
// and clip it if necessary
|
||||
if (listener)
|
||||
{
|
||||
fixed_t adx = abs (listener[0] - x);
|
||||
fixed_t ady = abs (listener[1] - y);
|
||||
// From _GG1_ p.428. Appox. eucledian distance fast.
|
||||
return adx + ady - ((adx < ady ? adx : ady)>>1);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fixed_t P_AproxDistance2 (AActor *listener, fixed_t x, fixed_t y)
|
||||
{
|
||||
return listener ? P_AproxDistance2 (&listener->x, x, y) : 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_NoiseDebug
|
||||
|
@ -165,6 +137,7 @@ static fixed_t P_AproxDistance2 (AActor *listener, fixed_t x, fixed_t y)
|
|||
void S_NoiseDebug (void)
|
||||
{
|
||||
FSoundChan *chan;
|
||||
FVector3 listener;
|
||||
fixed_t ox, oy, oz;
|
||||
int y, color;
|
||||
|
||||
|
@ -179,6 +152,7 @@ void S_NoiseDebug (void)
|
|||
screen->DrawText (CR_GOLD, 220, y, "vol", TAG_DONE);
|
||||
screen->DrawText (CR_GOLD, 250, y, "dist", TAG_DONE);
|
||||
screen->DrawText (CR_GOLD, 290, y, "chan", TAG_DONE);
|
||||
screen->DrawText (CR_GOLD, 330, y, "flags", TAG_DONE);
|
||||
y += 8;
|
||||
|
||||
if (Channels == NULL)
|
||||
|
@ -186,48 +160,83 @@ void S_NoiseDebug (void)
|
|||
return;
|
||||
}
|
||||
|
||||
// Display the last channel first.
|
||||
listener.X = FIXED2FLOAT(players[consoleplayer].camera->x);
|
||||
listener.Y = FIXED2FLOAT(players[consoleplayer].camera->y);
|
||||
listener.Z = FIXED2FLOAT(players[consoleplayer].camera->z);
|
||||
|
||||
// Display the oldest channel first.
|
||||
for (chan = Channels; chan->NextChan != NULL; chan = chan->NextChan)
|
||||
{ }
|
||||
while (y < SCREENHEIGHT - 16)
|
||||
{
|
||||
char temp[16];
|
||||
fixed_t *origin = chan->Pt;
|
||||
char temp[32];
|
||||
|
||||
if (!(chan->ChanFlags & CHAN_IS3D))
|
||||
{
|
||||
ox = players[consoleplayer].camera->x;
|
||||
oy = players[consoleplayer].camera->y;
|
||||
oz = players[consoleplayer].camera->z;
|
||||
}
|
||||
else if (origin)
|
||||
{
|
||||
ox = origin[0];
|
||||
oy = origin[1];
|
||||
oz = origin[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
ox = chan->X;
|
||||
oy = chan->Y;
|
||||
oz = chan->Z;
|
||||
}
|
||||
assert(chan->Pt != NULL);
|
||||
ox = chan->Pt[0];
|
||||
oy = chan->Pt[1];
|
||||
oz = chan->Pt[2];
|
||||
color = (chan->ChanFlags & CHAN_LOOP) ? CR_BROWN : CR_GREY;
|
||||
|
||||
// Name
|
||||
Wads.GetLumpName (temp, chan->SfxInfo->lumpnum);
|
||||
temp[8] = 0;
|
||||
screen->DrawText (color, 0, y, temp, TAG_DONE);
|
||||
sprintf (temp, "%d", ox >> FRACBITS);
|
||||
screen->DrawText (color, 70, y, temp, TAG_DONE);
|
||||
sprintf (temp, "%d", oy >> FRACBITS);
|
||||
screen->DrawText (color, 120, y, temp, TAG_DONE);
|
||||
sprintf (temp, "%d", oz >> FRACBITS);
|
||||
screen->DrawText (color, 170, y, temp, TAG_DONE);
|
||||
|
||||
if (!(chan->ChanFlags & CHAN_IS3D))
|
||||
{
|
||||
screen->DrawText(color, 70, y, "---", TAG_DONE); // X
|
||||
screen->DrawText(color, 120, y, "---", TAG_DONE); // Y
|
||||
screen->DrawText(color, 170, y, "---", TAG_DONE); // Z
|
||||
screen->DrawText(color, 250, y, "---", TAG_DONE); // Distance
|
||||
}
|
||||
else
|
||||
{
|
||||
// X coordinate
|
||||
sprintf (temp, "%d", ox >> FRACBITS);
|
||||
screen->DrawText (color, 70, y, temp, TAG_DONE);
|
||||
|
||||
// Y coordinate
|
||||
sprintf (temp, "%d", oy >> FRACBITS);
|
||||
screen->DrawText (color, 120, y, temp, TAG_DONE);
|
||||
|
||||
// Z coordinate
|
||||
sprintf (temp, "%d", oz >> FRACBITS);
|
||||
screen->DrawText (color, 170, y, temp, TAG_DONE);
|
||||
|
||||
// Distance
|
||||
if (chan->DistanceScale > 0)
|
||||
{
|
||||
FVector3 sound(ox, oy, oz);
|
||||
sound /= FRACUNIT;
|
||||
sprintf (temp, "%.0f", (sound - listener).Length());
|
||||
screen->DrawText (color, 250, y, temp, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (color, 250, y, "---", TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Volume
|
||||
sprintf (temp, "%g", chan->Volume);
|
||||
screen->DrawText (color, 220, y, temp, TAG_DONE);
|
||||
sprintf (temp, "%d", P_AproxDistance2 (players[consoleplayer].camera, ox, oy) / FRACUNIT);
|
||||
screen->DrawText (color, 250, y, temp, TAG_DONE);
|
||||
|
||||
// Channel
|
||||
sprintf (temp, "%d", chan->EntChannel);
|
||||
screen->DrawText (color, 290, y, temp, TAG_DONE);
|
||||
|
||||
// Flags
|
||||
sprintf (temp, "%s3%sZ%sI%sM%sN%sA%sL%sE",
|
||||
(chan->ChanFlags & CHAN_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
||||
(chan->ChanFlags & CHAN_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
|
||||
(chan->ChanFlags & CHAN_IMMOBILE) ? 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);
|
||||
screen->DrawText (color, 330, y, temp, TAG_DONE);
|
||||
|
||||
y += 8;
|
||||
if (chan->PrevChan == &Channels)
|
||||
{
|
||||
|
@ -638,8 +647,8 @@ void CalcPosVel (fixed_t *pt, AActor *mover, int constz,
|
|||
// calculating volume
|
||||
//==========================================================================
|
||||
|
||||
FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel,
|
||||
FSoundID sound_id, float volume, float attenuation)
|
||||
static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
|
||||
int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
sfxinfo_t *sfx;
|
||||
int chanflags;
|
||||
|
@ -702,7 +711,7 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
|
||||
// When resolving a link we do not want to get the NearLimit of
|
||||
// the referenced sound so some additional checks are required
|
||||
int NearLimit = sfx->NearLimit;
|
||||
int near_limit = sfx->NearLimit;
|
||||
|
||||
// Resolve player sounds, random sounds, and aliases
|
||||
while (sfx->link != sfxinfo_t::NO_LINK)
|
||||
|
@ -710,17 +719,17 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
if (sfx->bPlayerReserve)
|
||||
{
|
||||
sound_id = FSoundID(S_FindSkinnedSound (mover, sound_id));
|
||||
NearLimit = S_sfx[sound_id].NearLimit;
|
||||
near_limit = S_sfx[sound_id].NearLimit;
|
||||
}
|
||||
else if (sfx->bRandomHeader)
|
||||
{
|
||||
sound_id = FSoundID(S_PickReplacement (sound_id));
|
||||
if (NearLimit < 0) NearLimit = S_sfx[sound_id].NearLimit;
|
||||
if (near_limit < 0) near_limit = S_sfx[sound_id].NearLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
sound_id = FSoundID(sfx->link);
|
||||
if (NearLimit < 0) NearLimit = S_sfx[sound_id].NearLimit;
|
||||
if (near_limit < 0) near_limit = S_sfx[sound_id].NearLimit;
|
||||
}
|
||||
sfx = &S_sfx[sound_id];
|
||||
}
|
||||
|
@ -729,21 +738,20 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
if (sfx->bSingular && S_CheckSingular(sound_id))
|
||||
return NULL;
|
||||
|
||||
// If the sound is unpositioned or comes from the listener, it is
|
||||
// never limited.
|
||||
if (pt == NULL || mover == players[consoleplayer].camera)
|
||||
{
|
||||
near_limit = 0;
|
||||
}
|
||||
|
||||
// If this sound doesn't like playing near itself, don't play it if
|
||||
// that's what would happen.
|
||||
if (NearLimit > 0 && pt != NULL && mover != players[consoleplayer].camera &&
|
||||
S_CheckSoundLimit(sfx, pos, NearLimit))
|
||||
if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit))
|
||||
return NULL;
|
||||
|
||||
// Make sure the sound is loaded.
|
||||
if (sfx->data == NULL)
|
||||
{
|
||||
GSnd->LoadSound (sfx);
|
||||
if (sfx->link != sfxinfo_t::NO_LINK)
|
||||
{
|
||||
sfx = &S_sfx[sfx->link];
|
||||
}
|
||||
}
|
||||
sfx = S_LoadSound(sfx);
|
||||
|
||||
// The empty sound never plays.
|
||||
if (sfx->lumpnum == sfx_empty)
|
||||
|
@ -811,18 +819,18 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
|
||||
if (attenuation > 0)
|
||||
{
|
||||
chan = GSnd->StartSound3D (sfx, volume, attenuation, pitch, basepriority, pos, vel, sec, channel, chanflags);
|
||||
chanflags |= CHAN_IS3D;
|
||||
chan = GSnd->StartSound3D (sfx, volume, attenuation, pitch, basepriority, pos, vel, sec, channel, chanflags, NULL);
|
||||
chanflags |= CHAN_IS3D | CHAN_JUSTSTARTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
chan = GSnd->StartSound (sfx, volume, pitch, chanflags);
|
||||
chanflags |= CHAN_LISTENERZ;
|
||||
chan = GSnd->StartSound (sfx, volume, pitch, chanflags, NULL);
|
||||
chanflags |= CHAN_LISTENERZ | CHAN_JUSTSTARTED;
|
||||
}
|
||||
if (chan != NULL)
|
||||
{
|
||||
chan->SoundID = sound_id;
|
||||
chan->OrgID = org_id;
|
||||
chan->OrgID = FSoundID(org_id);
|
||||
chan->Mover = mover;
|
||||
chan->Pt = pt != NULL ? pt : &chan->X;
|
||||
chan->Sector = sec;
|
||||
|
@ -833,6 +841,9 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
chan->Y = y;
|
||||
chan->Z = z;
|
||||
chan->ChanFlags |= chanflags;
|
||||
chan->NearLimit = near_limit;
|
||||
chan->Pitch = pitch;
|
||||
chan->Priority = basepriority;
|
||||
if (mover != NULL)
|
||||
{
|
||||
mover->SoundChans |= 1 << channel;
|
||||
|
@ -841,15 +852,72 @@ FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec, int channel
|
|||
return chan;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_RestartSound
|
||||
//
|
||||
// Attempts to restart looping sounds that were evicted from their channels.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_RestartSound(FSoundChan *chan)
|
||||
{
|
||||
assert(chan->ChanFlags & CHAN_EVICTED);
|
||||
assert(chan->SfxInfo != NULL);
|
||||
|
||||
FSoundChan *ochan;
|
||||
sfxinfo_t *sfx = chan->SfxInfo;
|
||||
|
||||
// If this is a singular sound, don't play it if it's already playing.
|
||||
if (sfx->bSingular && S_CheckSingular(chan->SoundID))
|
||||
return;
|
||||
|
||||
sfx = S_LoadSound(sfx);
|
||||
|
||||
// The empty sound never plays.
|
||||
if (sfx->lumpnum == sfx_empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan->ChanFlags & CHAN_IS3D)
|
||||
{
|
||||
float pos[3], vel[3];
|
||||
|
||||
CalcPosVel(chan->Pt, chan->Mover, chan->ChanFlags & CHAN_LISTENERZ, pos, vel);
|
||||
|
||||
// If this sound doesn't like playing near itself, don't play it if
|
||||
// that's what would happen.
|
||||
ochan = GSnd->StartSound3D(sfx, chan->Volume, chan->DistanceScale, chan->Pitch,
|
||||
chan->Priority, pos, vel, chan->Sector, chan->EntChannel, chan->ChanFlags, chan);
|
||||
}
|
||||
else
|
||||
{
|
||||
ochan = GSnd->StartSound(chan->SfxInfo, chan->Volume, chan->Pitch, chan->ChanFlags, chan);
|
||||
}
|
||||
assert(ochan == NULL || ochan == chan);
|
||||
if (ochan != NULL)
|
||||
{
|
||||
ochan->ChanFlags &= ~CHAN_EVICTED;
|
||||
// When called from the savegame loader, the actor's SoundChans
|
||||
// flags will be cleared. During normal gameplay, they should still
|
||||
// be set.
|
||||
if (ochan->Mover != NULL)
|
||||
{
|
||||
ochan->Mover->SoundChans |= 1 << ochan->EntChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_Sound - Unpositioned version
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (int channel, FSoundID sound_id, float volume, int attenuation)
|
||||
void S_Sound (int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
S_StartSound ((fixed_t *)NULL, NULL, NULL, channel, sound_id, volume, SELECT_ATTEN(attenuation));
|
||||
S_StartSound ((fixed_t *)NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -858,11 +926,11 @@ void S_Sound (int channel, FSoundID sound_id, float volume, int attenuation)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, int attenuation)
|
||||
void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
if (ent->Sector->Flags & SECF_SILENT)
|
||||
return;
|
||||
S_StartSound (&ent->x, ent, NULL, channel, sound_id, volume, SELECT_ATTEN(attenuation));
|
||||
S_StartSound (&ent->x, ent, NULL, channel, sound_id, volume, attenuation);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -871,9 +939,9 @@ void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, int att
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (fixed_t *pt, int channel, FSoundID sound_id, float volume, int attenuation)
|
||||
void S_Sound (fixed_t *pt, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
S_StartSound (pt, NULL, NULL, channel, sound_id, volume, SELECT_ATTEN(attenuation));
|
||||
S_StartSound (pt, NULL, NULL, channel, sound_id, volume, attenuation);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -882,13 +950,13 @@ void S_Sound (fixed_t *pt, int channel, FSoundID sound_id, float volume, int att
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, float volume, int attenuation)
|
||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||
{
|
||||
fixed_t pt[3];
|
||||
pt[0] = x;
|
||||
pt[1] = y;
|
||||
pt[2] = z;
|
||||
S_StartSound (pt, NULL, NULL, channel|CHAN_IMMOBILE, sound_id, volume, SELECT_ATTEN(attenuation));
|
||||
S_StartSound (pt, NULL, NULL, channel|CHAN_IMMOBILE, sound_id, volume, attenuation);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -897,11 +965,32 @@ void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, f
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_Sound (sector_t *sec, int channel, FSoundID sfxid, float volume, int attenuation)
|
||||
void S_Sound (sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation)
|
||||
{
|
||||
S_StartSound (sec->soundorg, NULL, sec, channel, sfxid, volume, attenuation);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_LoadSound
|
||||
//
|
||||
// Returns a pointer to the sfxinfo with the actual sound data.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
|
||||
{
|
||||
if (sfx->data == NULL)
|
||||
{
|
||||
GSnd->LoadSound (sfx);
|
||||
if (sfx->link != sfxinfo_t::NO_LINK)
|
||||
{
|
||||
sfx = &S_sfx[sfx->link];
|
||||
}
|
||||
}
|
||||
return sfx;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_CheckSingular
|
||||
|
@ -933,14 +1022,14 @@ bool S_CheckSingular(int sound_id)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int NearLimit)
|
||||
bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int near_limit)
|
||||
{
|
||||
FSoundChan *chan;
|
||||
int count;
|
||||
|
||||
for (chan = Channels, count = 0; chan != NULL && count < NearLimit; chan = chan->NextChan)
|
||||
for (chan = Channels, count = 0; chan != NULL && count < near_limit; chan = chan->NextChan)
|
||||
{
|
||||
if (chan->SfxInfo == sfx)
|
||||
if (!(chan->ChanFlags & CHAN_EVICTED) && chan->SfxInfo == sfx)
|
||||
{
|
||||
double dx = FIXED2FLOAT(chan->Pt[0]) - pos[0];
|
||||
double dy = FIXED2FLOAT(chan->Pt[1]) - pos[2];
|
||||
|
@ -951,7 +1040,7 @@ bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int NearLimit)
|
|||
}
|
||||
}
|
||||
}
|
||||
return count >= NearLimit;
|
||||
return count >= near_limit;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1015,19 +1104,19 @@ void S_RelinkSound (AActor *from, AActor *to)
|
|||
if (from == NULL || GSnd == NULL)
|
||||
return;
|
||||
|
||||
fixed_t *frompt = &from->x;
|
||||
fixed_t *topt = to ? &to->x : NULL;
|
||||
|
||||
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
|
||||
{
|
||||
if (chan->Pt == frompt)
|
||||
if (chan->Mover == from)
|
||||
{
|
||||
if (to != NULL || !(chan->ChanFlags & CHAN_LOOP))
|
||||
{
|
||||
chan->Pt = topt ? topt : &chan->X;
|
||||
chan->X = frompt[0];
|
||||
chan->Y = frompt[1];
|
||||
chan->Z = frompt[2];
|
||||
if (chan->Pt == &from->x)
|
||||
{
|
||||
chan->Pt = to ? &to->x : &chan->X;
|
||||
chan->X = from->x;
|
||||
chan->Y = from->y;
|
||||
chan->Z = from->z;
|
||||
}
|
||||
chan->Mover = to;
|
||||
}
|
||||
else
|
||||
|
@ -1134,6 +1223,87 @@ void S_ResumeSound ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_EvictAllChannels
|
||||
//
|
||||
// Forcibly evicts all channels so that there are none playing, but all
|
||||
// information needed to restart them is retained.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_EvictAllChannels()
|
||||
{
|
||||
FSoundChan *chan, *next;
|
||||
|
||||
for (chan = Channels; chan != NULL; chan = next)
|
||||
{
|
||||
next = chan->NextChan;
|
||||
|
||||
if (!(chan->ChanFlags & CHAN_EVICTED))
|
||||
{
|
||||
chan->ChanFlags |= CHAN_EVICTED;
|
||||
if (GSnd != NULL && chan->SysChannel != NULL)
|
||||
{
|
||||
GSnd->StopSound(chan);
|
||||
}
|
||||
assert(chan->NextChan == next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_RestoreEvictedChannel
|
||||
//
|
||||
// Recursive helper for S_RestoreEvictedChannels().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_RestoreEvictedChannel(FSoundChan *chan)
|
||||
{
|
||||
if (chan == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
S_RestoreEvictedChannel(chan->NextChan);
|
||||
if (chan->ChanFlags & CHAN_EVICTED)
|
||||
{
|
||||
S_RestartSound(chan);
|
||||
if (!(chan->ChanFlags & CHAN_LOOP))
|
||||
{
|
||||
if (chan->ChanFlags & CHAN_EVICTED)
|
||||
{ // Still evicted and not looping? Forget about it.
|
||||
S_ReturnChannel(chan);
|
||||
}
|
||||
else if (!(chan->ChanFlags & CHAN_JUSTSTARTED))
|
||||
{ // Should this sound become evicted again, it's okay to forget about it.
|
||||
chan->ChanFlags |= CHAN_FORGETTABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_RestoreEvictedChannels
|
||||
//
|
||||
// Restarts as many evicted channels as possible. Any channels that could
|
||||
// not be started and are not looping are moved to the free pool.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_RestoreEvictedChannels()
|
||||
{
|
||||
if (GSnd == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Restart channels in the same order they were originally played.
|
||||
S_RestoreEvictedChannel(Channels);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_UpdateSounds
|
||||
|
@ -1163,22 +1333,25 @@ void S_UpdateSounds (void *listener_p)
|
|||
|
||||
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
|
||||
{
|
||||
if (chan->ChanFlags & CHAN_IS3D)
|
||||
if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D)
|
||||
{
|
||||
CalcPosVel(chan->Pt, chan->Mover, chan->ChanFlags & CHAN_LISTENERZ, pos, vel);
|
||||
GSnd->UpdateSoundParams3D(chan, pos, vel);
|
||||
}
|
||||
chan->ChanFlags &= ~CHAN_JUSTSTARTED;
|
||||
}
|
||||
|
||||
SN_UpdateActiveSequences();
|
||||
|
||||
GSnd->UpdateListener();
|
||||
GSnd->UpdateSounds();
|
||||
|
||||
S_RestoreEvictedChannels();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FArchive & << FSoundID &
|
||||
// (FArchive &) << (FSoundID &)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -1195,6 +1368,134 @@ FArchive &operator<<(FArchive &arc, FSoundID &sid)
|
|||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// (FArchive &) << (FSoundChan &)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static FArchive &operator<<(FArchive &arc, FSoundChan &chan)
|
||||
{
|
||||
BYTE pt_type;
|
||||
|
||||
if (arc.IsStoring())
|
||||
{
|
||||
if (chan.Pt == &chan.X)
|
||||
{
|
||||
pt_type = 2;
|
||||
}
|
||||
else if (chan.Pt == &chan.Mover->x)
|
||||
{
|
||||
pt_type = 1;
|
||||
}
|
||||
else
|
||||
{ // WTF?
|
||||
assert(0);
|
||||
pt_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
arc << pt_type;
|
||||
arc << chan.Mover;
|
||||
arc << chan.Sector;
|
||||
arc << chan.X;
|
||||
arc << chan.Y;
|
||||
arc << chan.Z;
|
||||
arc << chan.SoundID;
|
||||
arc << chan.OrgID;
|
||||
arc << chan.Volume;
|
||||
arc << chan.DistanceScale;
|
||||
arc << chan.Pitch;
|
||||
arc << chan.ChanFlags;
|
||||
arc << chan.EntChannel;
|
||||
arc << chan.Priority;
|
||||
arc << chan.NearLimit;
|
||||
arc << chan.StartTime;
|
||||
|
||||
if (arc.IsLoading())
|
||||
{
|
||||
chan.SfxInfo = &S_sfx[chan.SoundID];
|
||||
if (pt_type == 1)
|
||||
{
|
||||
chan.Pt = &chan.Mover->x;
|
||||
}
|
||||
else if (pt_type == 2)
|
||||
{
|
||||
chan.Pt = &chan.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
chan.Pt = &chan.Mover->x;
|
||||
}
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_SerializeSounds
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_SerializeSounds(FArchive &arc)
|
||||
{
|
||||
FSoundChan *chan;
|
||||
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
GSnd->Sync(true);
|
||||
}
|
||||
|
||||
if (arc.IsStoring())
|
||||
{
|
||||
TArray<FSoundChan *> chans;
|
||||
|
||||
// Count channels and accumulate them so we can store them in
|
||||
// reverse order. That way, they will be in the same order when
|
||||
// reloaded later as they are now.
|
||||
for (chan = Channels; chan != NULL; chan = chan->NextChan)
|
||||
{
|
||||
// If the sound is forgettable, this is as good a time as
|
||||
// any to forget about it.
|
||||
if (!(chan->ChanFlags & CHAN_FORGETTABLE))
|
||||
{
|
||||
chans.Push(chan);
|
||||
}
|
||||
}
|
||||
|
||||
arc.WriteCount(chans.Size());
|
||||
|
||||
for (unsigned int i = chans.Size(); i-- != 0; )
|
||||
{
|
||||
// Replace start time with sample position.
|
||||
QWORD start = chans[i]->StartTime.AsOne;
|
||||
chans[i]->StartTime.AsOne = GSnd ? GSnd->GetPosition(chans[i]) : 0;
|
||||
arc << *chans[i];
|
||||
chans[i]->StartTime.AsOne = start;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
S_StopAllChannels();
|
||||
count = arc.ReadCount();
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
chan = S_GetChannel(NULL);
|
||||
arc << *chan;
|
||||
// Sounds always start out evicted when restored from a save.
|
||||
chan->ChanFlags |= CHAN_EVICTED;
|
||||
}
|
||||
S_RestoreEvictedChannels();
|
||||
}
|
||||
DSeqNode::SerializeSequences(arc);
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
GSnd->Sync(false);
|
||||
GSnd->UpdateSounds();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -177,17 +177,22 @@ struct FSoundChan
|
|||
fixed_t *Pt; // Origin of sound.
|
||||
sfxinfo_t *SfxInfo; // Sound information.
|
||||
fixed_t X,Y,Z; // Origin if Mover is NULL.
|
||||
int SoundID; // Sound ID of playing sound
|
||||
int OrgID; // Sound ID of sound used to start this channel
|
||||
FSoundID SoundID; // Sound ID of playing sound.
|
||||
FSoundID OrgID; // Sound ID of sound used to start this channel.
|
||||
float Volume;
|
||||
float DistanceScale;
|
||||
BYTE EntChannel; // Actor's sound channel.
|
||||
int Pitch; // Pitch variation.
|
||||
int ChanFlags;
|
||||
BYTE EntChannel; // Actor's sound channel.
|
||||
SBYTE Priority;
|
||||
SWORD NearLimit;
|
||||
QWORD_UNION StartTime; // Sound start time in DSP clocks.
|
||||
};
|
||||
extern FSoundChan *Channels;
|
||||
|
||||
FSoundChan *S_GetChannel(void *syschan);
|
||||
void S_ReturnChannel(FSoundChan *chan);
|
||||
void S_EvictAllChannels();
|
||||
|
||||
void S_LinkChannel(FSoundChan *chan, FSoundChan **head);
|
||||
void S_UnlinkChannel(FSoundChan *chan);
|
||||
|
@ -212,11 +217,11 @@ void S_PrecacheLevel ();
|
|||
void S_CacheSound (sfxinfo_t *sfx);
|
||||
|
||||
// Start sound for thing at <ent>
|
||||
void S_Sound (int channel, FSoundID sfxid, float volume, int attenuation);
|
||||
void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, int attenuation);
|
||||
void S_Sound (fixed_t *pt, int channel, FSoundID sfxid, float volume, int attenuation);
|
||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, int attenuation);
|
||||
void S_Sound (sector_t *sec, int channel, FSoundID sfxid, float volume, int attenuation);
|
||||
void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
void S_Sound (fixed_t *pt, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
void S_Sound (sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||
|
||||
// sound channels
|
||||
// channel 0 never willingly overrides
|
||||
|
@ -234,29 +239,34 @@ void S_Sound (sector_t *sec, int channel, FSoundID sfxid, float volume, int atte
|
|||
#define CHAN_VOICE 2
|
||||
#define CHAN_ITEM 3
|
||||
#define CHAN_BODY 4
|
||||
// modifier flags
|
||||
#define CHAN_LISTENERZ 8
|
||||
#define CHAN_IMMOBILE 16
|
||||
#define CHAN_MAYBE_LOCAL 32
|
||||
#define CHAN_NOPAUSE 64 // do not pause this sound in menus
|
||||
#define CHAN_AREA 128 // Sound plays from all around. Only valid with sector sounds.
|
||||
#define CHAN_LOOP 256
|
||||
|
||||
// Channel alias for sector sounds. These define how listener height is
|
||||
// used when calculating 3D sound volume.
|
||||
#define CHAN_FLOOR 1 // Sound comes from the floor.
|
||||
#define CHAN_CEILING 2 // Sound comes from the ceiling.
|
||||
#define CHAN_FULLHEIGHT 3 // Sound comes entire height of the sector.
|
||||
#define CHAN_INTERIOR 4 // Sound comes height between floor and ceiling.
|
||||
|
||||
#define CHAN_IS3D (1<<24) // internal flag
|
||||
// modifier flags
|
||||
#define CHAN_LISTENERZ 8
|
||||
#define CHAN_IMMOBILE 16
|
||||
#define CHAN_MAYBE_LOCAL 32
|
||||
#define CHAN_NOPAUSE 64 // Do not pause this sound in menus.
|
||||
#define CHAN_AREA 128 // Sound plays from all around. Only valid with sector sounds.
|
||||
#define CHAN_LOOP 256
|
||||
|
||||
#define CHAN_PICKUP (CHAN_ITEM|CHAN_MAYBE_LOCAL)
|
||||
|
||||
#define CHAN_IS3D 1 // internal: Sound is 3D.
|
||||
#define CHAN_EVICTED 2 // internal: Looping sound was evicted.
|
||||
#define CHAN_FORGETTABLE 4 // internal: Forget sound data when sound stops.
|
||||
#define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet.
|
||||
|
||||
// sound attenuation values
|
||||
#define ATTN_NONE 0 // full volume the entire level
|
||||
#define ATTN_NORM 1
|
||||
#define ATTN_IDLE 2
|
||||
#define ATTN_STATIC 3 // diminish very rapidly with distance
|
||||
#define ATTN_NONE 0.f // full volume the entire level
|
||||
#define ATTN_NORM 1.f
|
||||
#define ATTN_IDLE 1.001f
|
||||
#define ATTN_STATIC 3.f // diminish very rapidly with distance
|
||||
|
||||
int S_PickReplacement (int refid);
|
||||
void S_CacheRandomSound (sfxinfo_t *sfx);
|
||||
|
@ -279,6 +289,9 @@ bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id);
|
|||
// Moves all sounds from one mobj to another
|
||||
void S_RelinkSound (AActor *from, AActor *to);
|
||||
|
||||
// Stores/retrieves playing channel information in an archive.
|
||||
void S_SerializeSounds(FArchive &arc);
|
||||
|
||||
// Start music using <music_name>
|
||||
bool S_StartMusic (const char *music_name);
|
||||
|
||||
|
@ -304,6 +317,8 @@ void S_ResumeSound ();
|
|||
//
|
||||
void S_UpdateSounds (void *listener);
|
||||
|
||||
void S_RestoreEvictedChannels();
|
||||
|
||||
// [RH] S_sfx "maintenance" routines
|
||||
void S_ParseSndInfo ();
|
||||
void S_ParseReverbDef ();
|
||||
|
|
|
@ -92,11 +92,6 @@ FMOD_RESULT SPC_CreateCodec(FMOD::System *sys);
|
|||
static int Enum_NumForName(const FEnumList *list, const char *name);
|
||||
static const char *Enum_NameForNum(const FEnumList *list, int num);
|
||||
|
||||
static FMOD_RESULT F_CALLBACK Memory_Open(const char *name, int unicode, unsigned int *filesize, void **handle, void **userdata);
|
||||
static FMOD_RESULT F_CALLBACK Memory_Close(void *handle, void *userdata);
|
||||
static FMOD_RESULT F_CALLBACK Memory_Read(void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata);
|
||||
static FMOD_RESULT F_CALLBACK Memory_Seek(void *handle, unsigned int pos, void *userdata);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
EXTERN_CVAR (String, snd_output)
|
||||
|
@ -613,6 +608,7 @@ bool FMODSoundRenderer::Init()
|
|||
int eval;
|
||||
|
||||
SFXPaused = false;
|
||||
DSPLocked = false;
|
||||
MusicGroup = NULL;
|
||||
SfxGroup = NULL;
|
||||
PausableSfx = NULL;
|
||||
|
@ -620,8 +616,7 @@ bool FMODSoundRenderer::Init()
|
|||
WaterLP = NULL;
|
||||
WaterReverb = NULL;
|
||||
PrevEnvironment = DefaultEnvironments[0];
|
||||
DSPClockLo = 0;
|
||||
DSPClockHi = 0;
|
||||
DSPClock.AsOne = 0;
|
||||
ChannelGroupTargetUnit = NULL;
|
||||
|
||||
Printf("I_InitSound: Initializing FMOD\n");
|
||||
|
@ -991,7 +986,7 @@ void FMODSoundRenderer::Shutdown()
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
S_StopAllChannels();
|
||||
//S_StopAllChannels();
|
||||
|
||||
if (MusicGroup != NULL)
|
||||
{
|
||||
|
@ -1179,36 +1174,14 @@ FString FMODSoundRenderer::GatherStats()
|
|||
Sys->getChannelsPlaying(&channels);
|
||||
Sys->getCPUUsage(&dsp, &stream, &update, &total);
|
||||
|
||||
out.Format ("%d channels,%5.2f%% CPU (DSP:%2.2f%% Stream:%2.2f%% Update:%2.2f%%)",
|
||||
out.Format ("%d channels,"TEXTCOLOR_YELLOW"%5.2f"TEXTCOLOR_NORMAL"%% CPU "
|
||||
"(DSP:"TEXTCOLOR_YELLOW"%2.2f"TEXTCOLOR_NORMAL"%% "
|
||||
"Stream:"TEXTCOLOR_YELLOW"%2.2f"TEXTCOLOR_NORMAL"%% "
|
||||
"Update:"TEXTCOLOR_YELLOW"%2.2f"TEXTCOLOR_NORMAL"%%)",
|
||||
channels, total, dsp, stream, update);
|
||||
return out;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: MovieDisableSound
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::MovieDisableSound()
|
||||
{
|
||||
I_ShutdownMusic();
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: MovieResumeSound
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::MovieResumeSound()
|
||||
{
|
||||
Init();
|
||||
S_Init();
|
||||
S_RestartMusic();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: SetSfxVolume
|
||||
|
@ -1377,7 +1350,7 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, int chanflags)
|
||||
FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan)
|
||||
{
|
||||
int id = int(sfx - &S_sfx[0]);
|
||||
FMOD_RESULT result;
|
||||
|
@ -1417,8 +1390,9 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
|
|||
chan->setFrequency(freq);
|
||||
}
|
||||
chan->setVolume(vol);
|
||||
HandleChannelDelay(chan, reuse_chan, freq);
|
||||
chan->setPaused(false);
|
||||
return CommonChannelSetup(chan);
|
||||
return CommonChannelSetup(chan, reuse_chan);
|
||||
}
|
||||
|
||||
DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result);
|
||||
|
@ -1434,7 +1408,8 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
|
|||
CVAR(Float, snd_3dspread, 180, 0)
|
||||
|
||||
FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float distscale,
|
||||
int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags)
|
||||
int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags,
|
||||
FSoundChan *reuse_chan)
|
||||
{
|
||||
int id = int(sfx - &S_sfx[0]);
|
||||
FMOD_RESULT result;
|
||||
|
@ -1460,6 +1435,11 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float dis
|
|||
// Play it.
|
||||
GSfxInfo = sfx;
|
||||
GDistScale = distscale;
|
||||
|
||||
// Experiments indicate that playSound will ignore priorities and always succeed
|
||||
// as long as the paremeters are set properly. It will first try to kick out sounds
|
||||
// with the same priority level but has no problem with kicking out sounds at
|
||||
// higher priority levels if it needs to.
|
||||
result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan);
|
||||
|
||||
// Then set the priority back.
|
||||
|
@ -1503,9 +1483,9 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float dis
|
|||
chan->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel);
|
||||
chan->set3DSpread(snd_3dspread);
|
||||
}
|
||||
chan->setDelay(FMOD_DELAYTYPE_DSPCLOCK_START, DSPClockHi, DSPClockLo);
|
||||
HandleChannelDelay(chan, reuse_chan, freq);
|
||||
chan->setPaused(false);
|
||||
FSoundChan *schan = CommonChannelSetup(chan);
|
||||
FSoundChan *schan = CommonChannelSetup(chan, reuse_chan);
|
||||
schan->DistanceScale = distscale;
|
||||
return schan;
|
||||
}
|
||||
|
@ -1516,7 +1496,50 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float dis
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSound :: SetChanHeadSettings
|
||||
// FMODSoundRenderer :: HandleChannelDelay
|
||||
//
|
||||
// If the sound is restarting, seek it to its proper place.
|
||||
// Otherwise, record its starting time.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reuse_chan, float freq) const
|
||||
{
|
||||
if (reuse_chan != NULL)
|
||||
{ // Sound is being restarted, so seek it to the position
|
||||
// it would be in now if it had never been evicted.
|
||||
QWORD_UNION nowtime;
|
||||
chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &nowtime.Hi, &nowtime.Lo);
|
||||
|
||||
// If the DSP is locked, the sounds are being restored, and
|
||||
// the channel's start time is actually its seek position.
|
||||
if (DSPLocked)
|
||||
{
|
||||
unsigned int seekpos = reuse_chan->StartTime.Lo;
|
||||
if (seekpos > 0)
|
||||
{
|
||||
chan->setPosition(seekpos, FMOD_TIMEUNIT_PCM);
|
||||
}
|
||||
reuse_chan->StartTime.AsOne = QWORD(nowtime.AsOne - seekpos * OutputRate / freq);
|
||||
}
|
||||
else
|
||||
{
|
||||
QWORD difftime = nowtime.AsOne - reuse_chan->StartTime.AsOne;
|
||||
if (difftime > 0)
|
||||
{
|
||||
chan->setPosition((unsigned int)(difftime / OutputRate), FMOD_TIMEUNIT_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->setDelay(FMOD_DELAYTYPE_DSPCLOCK_START, DSPClock.Hi, DSPClock.Lo);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: SetChanHeadSettings
|
||||
//
|
||||
// If this sound is played at the same coordinates as the listener, make
|
||||
// it head relative. Also, area sounds should use no 3D panning if close
|
||||
|
@ -1567,6 +1590,11 @@ FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(FMOD::Channel *chan, sfxinfo_t
|
|||
{
|
||||
cz = MAX(sec->ceilingplane.ZatPoint(cx, cy), players[consoleplayer].camera->z);
|
||||
}
|
||||
else if (channum == CHAN_INTERIOR)
|
||||
{
|
||||
cz = clamp(players[consoleplayer].camera->z, sec->floorplane.ZatPoint(cx, cy),
|
||||
sec->ceilingplane.ZatPoint(cx, cy));
|
||||
}
|
||||
else
|
||||
{
|
||||
cz = players[consoleplayer].camera->z;
|
||||
|
@ -1620,9 +1648,21 @@ FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(FMOD::Channel *chan, sfxinfo_t
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan) const
|
||||
FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FSoundChan *reuse_chan) const
|
||||
{
|
||||
FSoundChan *schan = S_GetChannel(chan);
|
||||
FSoundChan *schan;
|
||||
|
||||
if (reuse_chan != NULL)
|
||||
{
|
||||
schan = reuse_chan;
|
||||
schan->ChanFlags &= ~CHAN_EVICTED;
|
||||
schan->SysChannel = chan;
|
||||
}
|
||||
else
|
||||
{
|
||||
schan = S_GetChannel(chan);
|
||||
chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &schan->StartTime.Hi, &schan->StartTime.Lo);
|
||||
}
|
||||
chan->setUserData(schan);
|
||||
chan->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, ChannelEndCallback, 0);
|
||||
GSfxInfo = NULL;
|
||||
|
@ -1642,8 +1682,38 @@ void FMODSoundRenderer::StopSound(FSoundChan *chan)
|
|||
|
||||
if (chan->SysChannel != NULL)
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
chan->ChanFlags |= CHAN_FORGETTABLE;
|
||||
}
|
||||
((FMOD::Channel *)chan->SysChannel)->stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
S_ReturnChannel(chan);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: GetPosition
|
||||
//
|
||||
// Returns position of sound on this channel, in samples.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
unsigned int FMODSoundRenderer::GetPosition(FSoundChan *chan)
|
||||
{
|
||||
unsigned int pos;
|
||||
|
||||
if (chan == NULL || chan->SysChannel == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
((FMOD::Channel *)chan->SysChannel)->getPosition(&pos, FMOD_TIMEUNIT_PCM);
|
||||
return pos;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1816,6 +1886,29 @@ void FMODSoundRenderer::UpdateListener()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: Sync
|
||||
//
|
||||
// Used by the save/load code to restart sounds at the same position they
|
||||
// were in at the time of saving. Must not be nested.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::Sync(bool sync)
|
||||
{
|
||||
DSPLocked = sync;
|
||||
if (sync)
|
||||
{
|
||||
Sys->lockDSP();
|
||||
Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys->unlockDSP();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: UpdateSounds
|
||||
|
@ -1826,9 +1919,8 @@ void FMODSoundRenderer::UpdateSounds()
|
|||
{
|
||||
// Any sounds played between now and the next call to this function
|
||||
// will start exactly one tic from now.
|
||||
Sys->getDSPClock(&DSPClockHi, &DSPClockLo);
|
||||
FMOD_64BIT_ADD(DSPClockHi, DSPClockLo, 0, OutputRate / TICRATE);
|
||||
|
||||
Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo);
|
||||
DSPClock.AsOne += OutputRate / TICRATE;
|
||||
Sys->update();
|
||||
}
|
||||
|
||||
|
@ -2064,7 +2156,58 @@ FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelEndCallback
|
|||
|
||||
if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL)
|
||||
{
|
||||
S_ReturnChannel(schan);
|
||||
bool evicted;
|
||||
|
||||
// If the sound was stopped with GSnd->StopSound(), then we know
|
||||
// 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)
|
||||
{
|
||||
evicted = false;
|
||||
}
|
||||
else if (schan->ChanFlags & (CHAN_LOOP | CHAN_EVICTED))
|
||||
{
|
||||
evicted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMOD::Sound *sound;
|
||||
unsigned int len, pos;
|
||||
|
||||
evicted = false; // Assume not evicted
|
||||
if (FMOD_OK == chan->getPosition(&pos, FMOD_TIMEUNIT_PCM))
|
||||
{
|
||||
// If position is 0, then this sound either didn't have
|
||||
// a chance to play at all, or it stopped normally.
|
||||
if (pos == 0)
|
||||
{
|
||||
if (schan->ChanFlags & CHAN_JUSTSTARTED)
|
||||
{
|
||||
evicted = true;
|
||||
}
|
||||
}
|
||||
else if (FMOD_OK == chan->getCurrentSound(&sound))
|
||||
{
|
||||
if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_PCM))
|
||||
{
|
||||
if (pos < len)
|
||||
{
|
||||
evicted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!evicted)
|
||||
{
|
||||
S_ReturnChannel(schan);
|
||||
}
|
||||
else
|
||||
{
|
||||
schan->ChanFlags |= CHAN_EVICTED;
|
||||
schan->SysChannel = NULL;
|
||||
}
|
||||
}
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
|
|
@ -25,24 +25,27 @@ public:
|
|||
void StopStream (SoundStream *stream);
|
||||
|
||||
// Starts a sound.
|
||||
FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags);
|
||||
FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, float distscale, int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags);
|
||||
FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan);
|
||||
FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, float distscale, int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags, FSoundChan *reuse_chan);
|
||||
|
||||
// Stops a sound channel.
|
||||
void StopSound (FSoundChan *chan);
|
||||
|
||||
// Returns position of sound on this channel, in samples.
|
||||
unsigned int GetPosition(FSoundChan *chan);
|
||||
|
||||
// Synchronizes following sound startups.
|
||||
void Sync (bool sync);
|
||||
|
||||
// Pauses or resumes all sound effect channels.
|
||||
void SetSfxPaused (bool paused);
|
||||
|
||||
// Pauses or resumes *every* channel, including environmental reverb.
|
||||
void SetInactive (bool inactive);
|
||||
|
||||
// Updates the position of a sound channel.
|
||||
void UpdateSoundParams3D (FSoundChan *chan, float pos[3], float vel[3]);
|
||||
|
||||
// For use by I_PlayMovie
|
||||
void MovieDisableSound ();
|
||||
void MovieResumeSound ();
|
||||
|
||||
void UpdateListener ();
|
||||
void UpdateSounds ();
|
||||
|
||||
|
@ -56,15 +59,16 @@ public:
|
|||
private:
|
||||
bool SFXPaused;
|
||||
bool InitSuccess;
|
||||
unsigned int DSPClockLo;
|
||||
unsigned int DSPClockHi;
|
||||
bool DSPLocked;
|
||||
QWORD_UNION DSPClock;
|
||||
int OutputRate;
|
||||
|
||||
static FMOD_RESULT F_CALLBACK ChannelEndCallback
|
||||
(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, int cmd, unsigned int data1, unsigned int data2);
|
||||
static float F_CALLBACK RolloffCallback(FMOD_CHANNEL *channel, float distance);
|
||||
|
||||
FSoundChan *CommonChannelSetup(FMOD::Channel *chan) const;
|
||||
void HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reuse_chan, float freq) const;
|
||||
FSoundChan *CommonChannelSetup(FMOD::Channel *chan, FSoundChan *reuse_chan) const;
|
||||
FMOD_MODE SetChanHeadSettings(FMOD::Channel *chan, sfxinfo_t *sfx, float pos[3], int channum, int chanflags, sector_t *sec, FMOD_MODE oldmode) const;
|
||||
void DoLoad (void **slot, sfxinfo_t *sfx);
|
||||
void getsfx (sfxinfo_t *sfx);
|
||||
|
|
|
@ -155,16 +155,16 @@ CCMD (snd_status)
|
|||
|
||||
CCMD (snd_reset)
|
||||
{
|
||||
SoundRenderer *snd = GSnd;
|
||||
if (snd != NULL)
|
||||
I_ShutdownMusic();
|
||||
S_EvictAllChannels();
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
snd->MovieDisableSound ();
|
||||
delete GSnd;
|
||||
GSnd = NULL;
|
||||
}
|
||||
I_InitSound ();
|
||||
S_Init ();
|
||||
S_RestartMusic ();
|
||||
if (snd != NULL) delete snd;
|
||||
I_InitSound();
|
||||
S_RestartMusic();
|
||||
S_RestoreEvictedChannels();
|
||||
}
|
||||
|
||||
CCMD (snd_listdrivers)
|
||||
|
|
|
@ -89,12 +89,18 @@ public:
|
|||
virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0;
|
||||
|
||||
// Starts a sound.
|
||||
virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags) = 0;
|
||||
virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, float distscale, int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags) = 0;
|
||||
virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0;
|
||||
virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, float distscale, int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags, FSoundChan *reuse_chan) = 0;
|
||||
|
||||
// Stops a sound channel.
|
||||
virtual void StopSound (FSoundChan *chan) = 0;
|
||||
|
||||
// Returns position of sound on this channel, in samples.
|
||||
virtual unsigned int GetPosition(FSoundChan *chan) = 0;
|
||||
|
||||
// Synchronizes following sound startups.
|
||||
virtual void Sync (bool sync) = 0;
|
||||
|
||||
// Pauses or resumes all sound effect channels.
|
||||
virtual void SetSfxPaused (bool paused) = 0;
|
||||
|
||||
|
@ -104,10 +110,6 @@ public:
|
|||
// Updates the volume, separation, and pitch of a sound channel.
|
||||
virtual void UpdateSoundParams3D (FSoundChan *chan, float pos[3], float vel[3]) = 0;
|
||||
|
||||
// For use by I_PlayMovie
|
||||
virtual void MovieDisableSound () = 0;
|
||||
virtual void MovieResumeSound () = 0;
|
||||
|
||||
virtual void UpdateListener () = 0;
|
||||
virtual void UpdateSounds () = 0;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
// SAVESIG should match SAVEVER.
|
||||
|
||||
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
||||
#define MINSAVEVER 1044
|
||||
#define MINSAVEVER 1055
|
||||
|
||||
#if SVN_REVISION_NUMBER < MINSAVEVER
|
||||
// Never write a savegame with a version lower than what we need
|
||||
|
|
|
@ -811,16 +811,19 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
|
||||
if(GSnd != NULL)
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
#if 0
|
||||
// Do we actually need this here?
|
||||
if (!oldstate && SessionState)
|
||||
{
|
||||
GSnd->MovieDisableSound ();
|
||||
GSnd->SuspendSound ();
|
||||
}
|
||||
else if (oldstate && !SessionState)
|
||||
{
|
||||
GSnd->MovieResumeSound ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
char foo[256];
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
||||
#ifndef I_DO_NOT_LIKE_BIG_DOWNLOADS
|
||||
#define I_DO_NOT_LIKE_BIG_DOWNLOADS
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#define USE_WINDOWS_DWORD
|
||||
|
|
Loading…
Reference in a new issue