- more refactoring on SW's sound system:

* removed all cases of getting a sound handle and checking it later.
* In particular, refactor the cases where the handle is stored in a static local variable. These are fundamentally unsafe because nothing maintains these local variables.
* finished rewriting the PlaySound function. Let's hope this is what was intended, the entire coding here was not particularly good, mixing high and low level sound handling all on the same level.
* call the update routine each tic and not merely every 4th or 8th one, this kind of granularity was ok in 1997 but not with a modern sound engine.
This commit is contained in:
Christoph Oelckers 2019-12-18 19:17:37 +01:00
parent 43c66d07ae
commit a087d566ee
18 changed files with 373 additions and 491 deletions

View file

@ -96,7 +96,7 @@ CUSTOM_CVARD(Int, cl_crosshairscale, 50, CVAR_ARCHIVE, "changes the size of the
CUSTOM_CVARD(Int, cl_autoaim, 1, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disable weapon autoaim") CUSTOM_CVARD(Int, cl_autoaim, 1, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disable weapon autoaim")
{ {
if (self < 0 || self > (playing_blood? 2 : 3)) self = 1; // The Shadow Warrior backend only has a bool for this. if (self < 0 || self > ((g_gameType & GAMEFLAG_BLOOD)? 2 : 3)) self = 1; // The Shadow Warrior backend only has a bool for this.
//UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.) //UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.)
}; };
@ -104,7 +104,7 @@ CUSTOM_CVARD(Int, cl_weaponswitch, 3, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disabl
{ {
if (self < 0) self = 0; if (self < 0) self = 0;
if (self > 3 && playing_blood) self = 3; if (self > 3 && (g_gameType & GAMEFLAG_BLOOD)) self = 3;
if (self > 7) self = 7; if (self > 7) self = 7;
//UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.) //UpdatePlayerFromMenu(); todo: networking (only operational in EDuke32 frontend anyway.)
} }

View file

@ -28,7 +28,7 @@ enum EChanFlag
CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops. CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops.
CHANF_JUSTSTARTED = 512, // internal: Sound has not been updated yet. 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_ABSTIME = 1024, // internal: Start time is absolute and does not depend on current time.
CHANF_VIRTUAL = 2048, // internal: Channel is currently virtual CHANF_VIRTUAL = 2048, // Channel only plays on demand but won't get deleted automatically.
CHANF_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something. 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. CHANF_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them.
}; };

View file

@ -479,7 +479,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// If the sound is blocked and not looped, return now. If the sound // If the sound is blocked and not looped, return now. If the sound
// is blocked and looped, pretend to play it so that it can // is blocked and looped, pretend to play it so that it can
// eventually play for real. // eventually play for real.
if ((chanflags & (CHANF_EVICTED | CHANF_LOOP)) == CHANF_EVICTED) if ((chanflags & (CHANF_EVICTED | CHANF_LOOP | CHANF_VIRTUAL)) == CHANF_EVICTED)
{ {
return NULL; return NULL;
} }
@ -550,7 +550,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
// sound is paused and a non-looped sound is being started. // sound is paused and a non-looped sound is being started.
// Such a sound would play right after unpausing which wouldn't sound right. // Such a sound would play right after unpausing which wouldn't sound right.
if (!(chanflags & CHANF_LOOP) && !(chanflags & (CHANF_UI|CHANF_NOPAUSE)) && SoundPaused) if (!(chanflags & (CHANF_LOOP|CHANF_VIRTUAL)) && !(chanflags & (CHANF_UI|CHANF_NOPAUSE)) && SoundPaused)
{ {
return NULL; return NULL;
} }
@ -587,7 +587,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL); chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL);
} }
} }
if (chan == NULL && (chanflags & CHANF_LOOP)) if (chan == NULL && (chanflags & CHANF_LOOP|CHANF_VIRTUAL))
{ {
chan = (FSoundChan*)GetChannel(NULL); chan = (FSoundChan*)GetChannel(NULL);
GSnd->MarkStartTime(chan); GSnd->MarkStartTime(chan);
@ -1014,7 +1014,7 @@ void SoundEngine::RelinkSound (int sourcetype, const void *from, const void *to,
{ {
chan->Source = to; chan->Source = to;
} }
else if (!(chan->ChanFlags & CHANF_LOOP) && optpos) else if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL)) && optpos)
{ {
chan->Source = NULL; chan->Source = NULL;
chan->SourceType = SOURCE_Unattached; chan->SourceType = SOURCE_Unattached;
@ -1154,7 +1154,7 @@ bool SoundEngine::IsSourcePlayingSomething (int sourcetype, const void *actor, i
{ {
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
{ {
if (chan->SourceType == sourcetype && chan->Source == actor) if (chan->SourceType == sourcetype && (sourcetype == SOURCE_None || sourcetype == SOURCE_Unattached || chan->Source == actor))
{ {
if (channel == 0 || chan->EntChannel == channel) if (channel == 0 || chan->EntChannel == channel)
{ {
@ -1217,7 +1217,7 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan)
if (chan->ChanFlags & CHANF_EVICTED) if (chan->ChanFlags & CHANF_EVICTED)
{ {
RestartChannel(chan); RestartChannel(chan);
if (!(chan->ChanFlags & CHANF_LOOP)) if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL)))
{ {
if (chan->ChanFlags & CHANF_EVICTED) if (chan->ChanFlags & CHANF_EVICTED)
{ // Still evicted and not looping? Forget about it. { // Still evicted and not looping? Forget about it.
@ -1229,7 +1229,7 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan)
} }
} }
} }
else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_LOOP)) == CHANF_FORGETTABLE) else if (chan->SysChannel == NULL && (chan->ChanFlags & (CHANF_FORGETTABLE | CHANF_LOOP | CHANF_VIRTUAL)) == CHANF_FORGETTABLE)
{ {
ReturnChannel(chan); ReturnChannel(chan);
} }
@ -1345,7 +1345,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
{ {
evicted = false; evicted = false;
} }
else if (schan->ChanFlags & (CHANF_LOOP | CHANF_EVICTED)) else if (schan->ChanFlags & (CHANF_LOOP | CHANF_VIRTUAL | CHANF_EVICTED))
{ {
evicted = true; evicted = true;
} }

View file

@ -168,13 +168,14 @@ struct FSoundChan : public FISoundChannel
FSoundID OrgID; // Sound ID of sound used to start this channel. FSoundID OrgID; // Sound ID of sound used to start this channel.
float Volume; float Volume;
int16_t Pitch; // Pitch variation. int16_t Pitch; // Pitch variation.
uint8_t EntChannel; // Actor's sound channel. int32_t EntChannel; // Actor's sound channel.
int8_t Priority; int8_t Priority;
int16_t NearLimit; int16_t NearLimit;
uint8_t SourceType; uint8_t SourceType;
float LimitRange; float LimitRange;
const void *Source; const void *Source;
float Point[3]; // Sound is not attached to any source. float Point[3]; // Sound is not attached to any source.
int UserData; // One word of data for user-specific data
}; };

View file

@ -52,6 +52,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "colormap.h" #include "colormap.h"
#include "config.h" #include "config.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "sound/s_soundinternal.h"
#include "sounds.h"
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
@ -237,17 +239,20 @@ void GameInterface::StartGame(FGameStartup& gs)
//InitNewGame(); //InitNewGame();
if (Skill == 0) if (Skill == 0)
handle = PlaySound(DIGI_TAUNTAI3, v3df_none); PlaySound(DIGI_TAUNTAI3, v3df_none, CHAN_VOICE);
else if (Skill == 1) else if (Skill == 1)
handle = PlaySound(DIGI_NOFEAR, v3df_none); PlaySound(DIGI_NOFEAR, v3df_none, CHAN_VOICE);
else if (Skill == 2) else if (Skill == 2)
handle = PlaySound(DIGI_WHOWANTSWANG, v3df_none); PlaySound(DIGI_WHOWANTSWANG, v3df_none, CHAN_VOICE);
else if (Skill == 3) else if (Skill == 3)
handle = PlaySound(DIGI_NOPAIN, v3df_none); PlaySound(DIGI_NOPAIN, v3df_none, CHAN_VOICE);
if (handle > FX_Ok) if (handle > FX_Ok)
while (FX_SoundActive(handle)) while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE))
{
DoUpdateSounds();
handleevents(); handleevents();
}
} }
FSavegameInfo GameInterface::GetSaveSig() FSavegameInfo GameInterface::GetSaveSig()

View file

@ -98,6 +98,7 @@ Things required to make savegames work:
#include "statistics.h" #include "statistics.h"
#include "gstrings.h" #include "gstrings.h"
#include "mapinfo.h" #include "mapinfo.h"
#include "sound/s_soundinternal.h"
//#include "crc32.h" //#include "crc32.h"
@ -1309,7 +1310,6 @@ TerminateLevel(void)
memset(Track, 0, sizeof(Track)); memset(Track, 0, sizeof(Track));
StopSound(); StopSound();
Terminate3DSounds(); // Kill the 3d sounds linked list
// Clear all anims and any memory associated with them // Clear all anims and any memory associated with them
// Clear before killing sprites - save a little time // Clear before killing sprites - save a little time
@ -1604,19 +1604,24 @@ void CreditsLevel(void)
videoNextPage(); videoNextPage();
// Lo Wang feel like singing! // Lo Wang feel like singing!
handle = PlaySound(DIGI_JG95012, v3df_none); PlaySound(DIGI_JG95012, v3df_none, CHAN_VOICE);
while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE))
if (handle > 0) {
while (FX_SoundActive(handle)) ; DoUpdateSounds();
handleevents();
}
// try 14 then 2 then quit // try 14 then 2 then quit
if (!PlaySong(nullptr, ThemeSongs[5], ThemeTrack[5], true)) if (!PlaySong(nullptr, ThemeSongs[5], ThemeTrack[5], true))
{ {
if (!PlaySong(nullptr, nullptr, 2, true)) if (!PlaySong(nullptr, nullptr, 2, true))
{ {
handle = PlaySound(DIGI_NOLIKEMUSIC, v3df_none); PlaySound(DIGI_NOLIKEMUSIC, v3df_none, CHAN_VOICE);
if (handle > 0) while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE))
while (FX_SoundActive(handle)) handleevents(); {
DoUpdateSounds();
handleevents();
}
return; return;
} }
} }
@ -2255,7 +2260,6 @@ void BonusScreen(PLAYERp pp)
} }
StopSound(); StopSound();
Terminate3DSounds();
} }
void EndGameSequence(void) void EndGameSequence(void)
@ -2471,7 +2475,6 @@ void StatScreen(PLAYERp mpp)
} }
StopSound(); StopSound();
Terminate3DSounds();
} }
void GameIntro(void) void GameIntro(void)

View file

@ -1210,7 +1210,6 @@ struct PLAYERstruct
unsigned char WpnShotgunLastShell; // Number of last shell fired unsigned char WpnShotgunLastShell; // Number of last shell fired
unsigned char WpnRailType; // Normal Rail Gun or EMP Burst Mode unsigned char WpnRailType; // Normal Rail Gun or EMP Burst Mode
SWBOOL Bloody; // Is player gooey from the slaughter? SWBOOL Bloody; // Is player gooey from the slaughter?
int nukevochandle; // Stuff for the Nuke
SWBOOL InitingNuke; SWBOOL InitingNuke;
SWBOOL TestNukeInit; SWBOOL TestNukeInit;
SWBOOL NukeInitialized; // Nuke already has counted down SWBOOL NukeInitialized; // Nuke already has counted down
@ -2067,30 +2066,48 @@ short ActorFindTrack(short SpriteNum, int8_t player_dir, int track_type, short *
SECT_USERp GetSectUser(short sectnum); SECT_USERp GetSectUser(short sectnum);
// Some sounds were checked by storing handles in static local variables.
// Problems with this design:
// 1. The variables were unmaintained and could refer to handles that had been reused already.
// 2. No proper sound ownership tracking.
// 3. In some cases items that were supposed to use the same check referred to different handle variables.
// In short: I was very broken. This is a list of all sound items used this way, now each one gets a dedicated channel
// so that proper checks can be performed and sound ownership be tracked.
enum
{
CHAN_ToiletFart = 1000,
CHAN_AnimeMad = 1001,
CHAN_AnimeSing = 1002,
CHAN_CoyHandle = 1003,
CHAN_RipHeart = 1004,
};
short SoundDist(int x, int y, int z, int basedist); short SoundDist(int x, int y, int z, int basedist);
short SoundAngle(int x, int y); short SoundAngle(int x, int y);
//void PlaySound(int num, short angle, short vol); //void PlaySound(int num, short angle, short vol);
int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags); int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags, int channel);
inline int PlaySound(int num, SPRITEp sprite, Voc3D_Flags flags) inline void PlaySound(int num, SPRITEp sprite, Voc3D_Flags flags, int channel = 8)
{ {
return _PlaySound(num, sprite, nullptr, nullptr, flags); _PlaySound(num, sprite, nullptr, nullptr, flags, channel);
} }
inline int PlaySound(int num, PLAYERp player, Voc3D_Flags flags) inline void PlaySound(int num, PLAYERp player, Voc3D_Flags flags, int channel = 8)
{ {
return _PlaySound(num, nullptr, player, nullptr, flags); _PlaySound(num, nullptr, player, nullptr, flags, channel);
} }
inline int PlaySound(int num, Voc3D_Flags flags) inline void PlaySound(int num, Voc3D_Flags flags, int channel = 8)
{ {
return _PlaySound(num, nullptr, nullptr, nullptr, flags); _PlaySound(num, nullptr, nullptr, nullptr, flags, channel);
} }
inline int PlaySound(int num, vec3_t *pos, Voc3D_Flags flags) inline void PlaySound(int num, vec3_t *pos, Voc3D_Flags flags, int channel = 8)
{ {
return _PlaySound(num, nullptr, nullptr, pos, flags); _PlaySound(num, nullptr, nullptr, pos, flags, channel);
} }
int _PlayerSound(int num, PLAYERp pp); int _PlayerSound(int num, PLAYERp pp);
inline int PlayerSound(int num, int flags, PLAYERp pp) { return _PlayerSound(num, pp); } inline int PlayerSound(int num, int flags, PLAYERp pp) { return _PlayerSound(num, pp); }
void StopPlayerSound(PLAYERp pp); void StopPlayerSound(PLAYERp pp);
bool SoundValidAndActive(SPRITEp spr, int channel);
ANIMATOR DoActorBeginJump,DoActorJump,DoActorBeginFall,DoActorFall,DoActorDeathMove; ANIMATOR DoActorBeginJump,DoActorJump,DoActorBeginFall,DoActorFall,DoActorDeathMove;

View file

@ -83,7 +83,6 @@ void SpawnWallSound(short sndnum, short i)
short SpriteNum; short SpriteNum;
vec3_t mid; vec3_t mid;
SPRITEp sp; SPRITEp sp;
int handle;
SpriteNum = COVERinsertsprite(0, STAT_DEFAULT); SpriteNum = COVERinsertsprite(0, STAT_DEFAULT);
if (SpriteNum < 0) if (SpriteNum < 0)
@ -99,9 +98,7 @@ void SpawnWallSound(short sndnum, short i)
setspritez(SpriteNum, &mid); setspritez(SpriteNum, &mid);
sp = &sprite[SpriteNum]; sp = &sprite[SpriteNum];
handle = PlaySound(sndnum, sp, v3df_dontpan | v3df_doppler); PlaySound(sndnum, sp, v3df_dontpan | v3df_doppler);
if (handle != -1)
Set3DSoundOwner(SpriteNum);
} }
short short
@ -179,7 +176,6 @@ JS_SpriteSetup(void)
short SpriteNum = 0, NextSprite, ndx; short SpriteNum = 0, NextSprite, ndx;
USERp u; USERp u;
short i, num; short i, num;
int handle;
TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite) TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite)
@ -250,21 +246,15 @@ JS_SpriteSetup(void)
case 2720: case 2720:
case 3143: case 3143:
case 3157: case 3157:
handle = PlaySound(DIGI_FIRE1, sp, v3df_follow|v3df_dontpan|v3df_doppler); PlaySound(DIGI_FIRE1, sp, v3df_follow|v3df_dontpan|v3df_doppler);
if (handle != -1)
Set3DSoundOwner(SpriteNum);
break; break;
case 795: case 795:
case 880: case 880:
handle = PlaySound(DIGI_WATERFLOW1, sp, v3df_follow|v3df_dontpan|v3df_doppler); PlaySound(DIGI_WATERFLOW1, sp, v3df_follow|v3df_dontpan|v3df_doppler);
if (handle != -1)
Set3DSoundOwner(SpriteNum);
break; break;
case 460: // Wind Chimes case 460: // Wind Chimes
handle = PlaySound(79, sp, v3df_ambient | v3df_init PlaySound(79, sp, v3df_ambient | v3df_init
| v3df_doppler | v3df_follow); | v3df_doppler | v3df_follow);
if (handle != -1)
Set3DSoundOwner(SpriteNum);
break; break;
} }

View file

@ -168,32 +168,29 @@ int DoToiletGirl(short SpriteNum)
{ {
if (RANDOM_RANGE(1000) > 980) if (RANDOM_RANGE(1000) > 980)
{ {
static int handle;
short choose_snd; short choose_snd;
choose_snd = RANDOM_P2(1024<<4)>>4; choose_snd = RANDOM_P2(1024<<4)>>4;
if (!FX_SoundValidAndActive(handle)) if (!SoundValidAndActive(sp, CHAN_ToiletFart))
{ {
if (choose_snd > 750) if (choose_snd > 750)
handle = PlaySound(DIGI_TOILETGIRLFART1, sp, v3df_dontpan); PlaySound(DIGI_TOILETGIRLFART1, sp, v3df_dontpan, CHAN_ToiletFart);
else if (choose_snd > 350) else if (choose_snd > 350)
handle = PlaySound(DIGI_TOILETGIRLFART2, sp, v3df_dontpan); PlaySound(DIGI_TOILETGIRLFART2, sp, v3df_dontpan, CHAN_ToiletFart);
else else
handle = PlaySound(DIGI_TOILETGIRLFART3, sp, v3df_dontpan); PlaySound(DIGI_TOILETGIRLFART3, sp, v3df_dontpan, CHAN_ToiletFart);
} }
} }
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
if (RANDOM_RANGE(1000<<8)>>8 > 500) if (RANDOM_RANGE(1000<<8)>>8 > 500)
madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_ToiletGirlUzi); ChangeState(SpriteNum,s_ToiletGirlUzi);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -233,14 +230,12 @@ int NullToiletGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
if (RANDOM_RANGE(1000<<8)>>8 > 500) if (RANDOM_RANGE(1000<<8)>>8 > 500)
madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_ToiletGirlUzi); ChangeState(SpriteNum,s_ToiletGirlUzi);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -406,7 +401,6 @@ int DoWashGirl(short SpriteNum)
USERp u = User[SpriteNum]; USERp u = User[SpriteNum];
SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp sp = User[SpriteNum]->SpriteP;
short rnd_range = 0; short rnd_range = 0;
static int handle=0;
SWBOOL ICanSee = FALSE; SWBOOL ICanSee = FALSE;
DoActorPickClosePlayer(SpriteNum); DoActorPickClosePlayer(SpriteNum);
@ -414,14 +408,12 @@ int DoWashGirl(short SpriteNum)
if (RANDOM_RANGE(1000) > 980 && u->ShellNum <= 0) if (RANDOM_RANGE(1000) > 980 && u->ShellNum <= 0)
{ {
static int handle; if (!SoundValidAndActive(sp, CHAN_AnimeSing))
if (!FX_SoundValidAndActive(handle))
{ {
if (RANDOM_P2(1024<<4)>>4 > 500) if (RANDOM_P2(1024<<4)>>4 > 500)
handle = PlaySound(DIGI_ANIMESING1, sp, v3df_dontpan); PlaySound(DIGI_ANIMESING1, sp, v3df_dontpan, CHAN_AnimeSing);
else else
handle = PlaySound(DIGI_ANIMESING2, sp, v3df_dontpan); PlaySound(DIGI_ANIMESING2, sp, v3df_dontpan, CHAN_AnimeSing);
} }
ChangeState(SpriteNum,s_WashGirlStandScrub); ChangeState(SpriteNum,s_WashGirlStandScrub);
@ -444,14 +436,12 @@ int DoWashGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
if (RANDOM_RANGE(1000<<8)>>8 > 500) if (RANDOM_RANGE(1000<<8)>>8 > 500)
madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_WashGirlUzi); ChangeState(SpriteNum,s_WashGirlUzi);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -488,14 +478,12 @@ int NullWashGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
if (RANDOM_RANGE(1000<<8)>>8 > 500) if (RANDOM_RANGE(1000<<8)>>8 > 500)
madhandle = PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan); PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_WashGirlUzi); ChangeState(SpriteNum,s_WashGirlUzi);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -1303,21 +1291,19 @@ int DoCarGirl(short SpriteNum)
{ {
if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI049, sp, v3df_dontpan); PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI051, sp, v3df_dontpan); PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI052, sp, v3df_dontpan); PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI054, sp, v3df_dontpan); PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_CarGirlUzi); ChangeState(SpriteNum,s_CarGirlUzi);
u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8); u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8);
@ -1358,21 +1344,19 @@ int NullCarGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI049, sp, v3df_dontpan); PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI051, sp, v3df_dontpan); PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI052, sp, v3df_dontpan); PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI054, sp, v3df_dontpan); PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_CarGirlUzi); ChangeState(SpriteNum,s_CarGirlUzi);
u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8); u->WaitTics = SEC(3)+SEC(RANDOM_RANGE(2<<8)>>8);
@ -1530,21 +1514,19 @@ int DoMechanicGirl(short SpriteNum)
{ {
if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI073, sp, v3df_dontpan); PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI075, sp, v3df_dontpan); PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI077, sp, v3df_dontpan); PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI079, sp, v3df_dontpan); PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_MechanicGirlDrill); ChangeState(SpriteNum,s_MechanicGirlDrill);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8);
@ -1585,21 +1567,19 @@ int NullMechanicGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI073, sp, v3df_dontpan); PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI075, sp, v3df_dontpan); PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI077, sp, v3df_dontpan); PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI079, sp, v3df_dontpan); PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_MechanicGirlDrill); ChangeState(SpriteNum,s_MechanicGirlDrill);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(2<<8)>>8);
@ -1758,9 +1738,7 @@ int DoSailorGirl(short SpriteNum)
{ {
if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
@ -1769,14 +1747,14 @@ int DoSailorGirl(short SpriteNum)
{ {
ActorCoughItem(SpriteNum); ActorCoughItem(SpriteNum);
alreadythrew++; alreadythrew++;
madhandle = PlaySound(DIGI_LANI060, sp, v3df_dontpan); PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad);
} }
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI063, sp, v3df_dontpan); PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI065, sp, v3df_dontpan); PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI066, sp, v3df_dontpan); PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_SailorGirlThrow); ChangeState(SpriteNum,s_SailorGirlThrow);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -1818,9 +1796,7 @@ int NullSailorGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
@ -1829,14 +1805,14 @@ int NullSailorGirl(short SpriteNum)
{ {
ActorCoughItem(SpriteNum); ActorCoughItem(SpriteNum);
alreadythrew++; alreadythrew++;
madhandle = PlaySound(DIGI_LANI060, sp, v3df_dontpan); PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad);
} }
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI063, sp, v3df_dontpan); PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI065, sp, v3df_dontpan); PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI066, sp, v3df_dontpan); PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad);
} }
ChangeState(SpriteNum,s_SailorGirlThrow); ChangeState(SpriteNum,s_SailorGirlThrow);
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
@ -1968,7 +1944,6 @@ int DoPruneGirl(short SpriteNum)
USERp u = User[SpriteNum]; USERp u = User[SpriteNum];
SPRITEp sp = User[SpriteNum]->SpriteP; SPRITEp sp = User[SpriteNum]->SpriteP;
short rnd_range = 0; short rnd_range = 0;
static int madhandle, coyhandle;
SWBOOL ICanSee = FALSE; SWBOOL ICanSee = FALSE;
DoActorPickClosePlayer(SpriteNum); DoActorPickClosePlayer(SpriteNum);
@ -1978,19 +1953,19 @@ int DoPruneGirl(short SpriteNum)
{ {
if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
if (!FX_SoundValidAndActive(madhandle)) if (!SoundValidAndActive(sp, CHAN_AnimeMad))
{ {
short choose; short choose;
choose = STD_RANDOM_RANGE(1000); choose = STD_RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI089, sp, v3df_dontpan); PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI093, sp, v3df_dontpan); PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI095, sp, v3df_dontpan); PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad);
} }
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
u->FlagOwner = 0; u->FlagOwner = 0;
@ -1998,19 +1973,19 @@ int DoPruneGirl(short SpriteNum)
} }
else else
{ {
if (!FX_SoundValidAndActive(coyhandle)) if (!SoundValidAndActive(sp, CHAN_CoyHandle))
{ {
short choose; short choose;
choose = STD_RANDOM_RANGE(1000); choose = STD_RANDOM_RANGE(1000);
if (choose > 990) if (choose > 990)
coyhandle = PlaySound(DIGI_PRUNECACKLE, sp, v3df_dontpan); PlaySound(DIGI_PRUNECACKLE, sp, v3df_dontpan, CHAN_CoyHandle);
else if (choose > 985) else if (choose > 985)
coyhandle = PlaySound(DIGI_PRUNECACKLE2, sp, v3df_dontpan); PlaySound(DIGI_PRUNECACKLE2, sp, v3df_dontpan, CHAN_CoyHandle);
else if (choose > 980) else if (choose > 980)
coyhandle = PlaySound(DIGI_PRUNECACKLE3, sp, v3df_dontpan); PlaySound(DIGI_PRUNECACKLE3, sp, v3df_dontpan, CHAN_CoyHandle);
else if (choose > 975) else if (choose > 975)
coyhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_CoyHandle);
} }
} }
@ -2047,21 +2022,19 @@ int NullPruneGirl(short SpriteNum)
} }
else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee)
{ {
static int madhandle; if (!SoundValidAndActive(sp, CHAN_AnimeMad))
if (!FX_SoundValidAndActive(madhandle))
{ {
short choose; short choose;
choose = RANDOM_RANGE(1000); choose = RANDOM_RANGE(1000);
if (choose > 750) if (choose > 750)
madhandle = PlaySound(DIGI_LANI089, sp, v3df_dontpan); PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 500) else if (choose > 500)
madhandle = PlaySound(DIGI_LANI091, sp, v3df_dontpan); PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad);
else if (choose > 250) else if (choose > 250)
madhandle = PlaySound(DIGI_LANI093, sp, v3df_dontpan); PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad);
else else
madhandle = PlaySound(DIGI_LANI095, sp, v3df_dontpan); PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad);
} }
u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8); u->WaitTics = SEC(1)+SEC(RANDOM_RANGE(3<<8)>>8);
u->FlagOwner = 0; u->FlagOwner = 0;

View file

@ -2258,7 +2258,6 @@ PlayerDeathReset(PLAYERp pp)
pp->Bloody = FALSE; pp->Bloody = FALSE;
pp->TestNukeInit = FALSE; pp->TestNukeInit = FALSE;
pp->InitingNuke = FALSE; pp->InitingNuke = FALSE;
pp->nukevochandle = 0;
pp->NukeInitialized = FALSE; pp->NukeInitialized = FALSE;
pp->BunnyMode = FALSE; pp->BunnyMode = FALSE;
@ -2348,7 +2347,6 @@ PlayerGameReset(PLAYERp pp)
pp->Bloody = FALSE; pp->Bloody = FALSE;
pp->TestNukeInit = FALSE; pp->TestNukeInit = FALSE;
pp->InitingNuke = FALSE; pp->InitingNuke = FALSE;
pp->nukevochandle = 0;
pp->NukeInitialized = FALSE; pp->NukeInitialized = FALSE;
pp->BunnyMode = FALSE; pp->BunnyMode = FALSE;
pp->SecretsFound = 0; pp->SecretsFound = 0;

View file

@ -46,6 +46,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
#include "fx_man.h" #include "fx_man.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "swcvar.h" #include "swcvar.h"
#include "sound/s_soundinternal.h"
BEGIN_SW_NS BEGIN_SW_NS
@ -996,11 +997,7 @@ int WeaponOperate(PLAYERp pp)
if (pp->WpnRocketType != 2 || pp->CurWpn != pp->Wpn[WPN_MICRO]) if (pp->WpnRocketType != 2 || pp->CurWpn != pp->Wpn[WPN_MICRO])
{ {
pp->InitingNuke = FALSE; pp->InitingNuke = FALSE;
if (pp->nukevochandle > 0) soundEngine->StopSound(SOURCE_Player, pp, CHAN_WEAPON);
{
FX_StopSound(pp->nukevochandle);
pp->nukevochandle = 0;
}
} }
return 0; return 0;
@ -3694,8 +3691,6 @@ PANEL_STATE ps_RetractRail[] =
//#define RAIL_XOFF (160+60) //#define RAIL_XOFF (160+60)
#define RAIL_XOFF (160+6) #define RAIL_XOFF (160+6)
static int railvochandle=0;
void void
InitWeaponRail(PLAYERp pp) InitWeaponRail(PLAYERp pp)
{ {
@ -3740,7 +3735,7 @@ InitWeaponRail(PLAYERp pp)
pSetState(psp, psp->PresentState); pSetState(psp, psp->PresentState);
PlaySound(DIGI_RAIL_UP, pp, v3df_follow); PlaySound(DIGI_RAIL_UP, pp, v3df_follow);
railvochandle = PlaySound(DIGI_RAILREADY, pp, v3df_follow|v3df_dontpan); PlaySound(DIGI_RAILREADY, pp, v3df_follow|v3df_dontpan);
Set3DSoundOwner(psp->PlayerP->PlayerSprite); Set3DSoundOwner(psp->PlayerP->PlayerSprite);
FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT);
@ -5007,8 +5002,7 @@ pMicroStandBy(PANEL_SPRITEp psp)
PLAYERp pp = psp->PlayerP; PLAYERp pp = psp->PlayerP;
pMicroOverlays(psp); pMicroOverlays(psp);
pp->nukevochandle = PlaySound(DIGI_NUKESTDBY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
PlaySound(DIGI_NUKESTDBY, psp->PlayerP, v3df_follow|v3df_dontpan);
} }
void void
@ -5016,8 +5010,7 @@ pMicroCount(PANEL_SPRITEp psp)
{ {
PLAYERp pp = psp->PlayerP; PLAYERp pp = psp->PlayerP;
pp->nukevochandle = PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan);
} }
void void
@ -5025,8 +5018,7 @@ pMicroReady(PANEL_SPRITEp psp)
{ {
PLAYERp pp = psp->PlayerP; PLAYERp pp = psp->PlayerP;
pp->nukevochandle = PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan);
pp->NukeInitialized = TRUE; pp->NukeInitialized = TRUE;
} }

View file

@ -8069,8 +8069,8 @@ domovethings(void)
MultiPlayLimits(); MultiPlayLimits();
if (MoveSkip8 == 0) // 8=5x 4=10x, 2=20x, 0=40x per second //if (MoveSkip8 == 0) // 8=5x 4=10x, 2=20x, 0=40x per second
DoUpdateSounds3D(); DoUpdateSounds();
CorrectPrediction(movefifoplc - 1); CorrectPrediction(movefifoplc - 1);

View file

@ -1246,12 +1246,11 @@ int DoRipper2StandHeart(short SpriteNum)
{ {
SPRITEp sp = &sprite[SpriteNum]; SPRITEp sp = &sprite[SpriteNum];
USERp u = User[SpriteNum]; USERp u = User[SpriteNum];
static int riphearthandle;
NullRipper2(SpriteNum); NullRipper2(SpriteNum);
if (!FX_SoundValidAndActive(riphearthandle)) if (!SoundValidAndActive(sp, CHAN_RipHeart))
riphearthandle = PlaySound(DIGI_RIPPER2HEARTOUT, sp, v3df_none); PlaySound(DIGI_RIPPER2HEARTOUT, sp, v3df_none, CHAN_RipHeart);
if ((u->WaitTics -= ACTORMOVETICS) <= 0) if ((u->WaitTics -= ACTORMOVETICS) <= 0)
NewStateGroup(SpriteNum, sg_Ripper2Run); NewStateGroup(SpriteNum, sg_Ripper2Run);

View file

@ -748,8 +748,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv)
TerminateLevel(); TerminateLevel();
Terminate3DSounds(); Terminate3DSounds();
Terminate3DSounds();
MREAD(&Level,sizeof(Level),1,fil); MREAD(&Level,sizeof(Level),1,fil);
MREAD(&Skill,sizeof(Skill),1,fil); MREAD(&Skill,sizeof(Skill),1,fil);

View file

@ -1242,7 +1242,6 @@ DoSoundSpotMatch(short match, short sound_num, short sound_type)
if (TEST_BOOL2(sp)) if (TEST_BOOL2(sp))
flags = v3df_follow|v3df_nolookup|v3df_init; flags = v3df_follow|v3df_nolookup|v3df_init;
//flags = v3df_follow|v3df_ambient|v3df_nolookup;
// play once and only once // play once and only once
if (TEST_BOOL1(sp)) if (TEST_BOOL1(sp))

View file

@ -60,6 +60,10 @@ BEGIN_SW_NS
enum EChanExFlags enum EChanExFlags
{ {
CHANEXF_AMBIENT = 0x40000000, CHANEXF_AMBIENT = 0x40000000,
CHANEXF_NODOPPLER = 0x20000000,
CHANEXF_DONTPAN = 0x10000000,
CHANEXF_INTERMIT = 0x08000000,
}; };
// Parentally locked sounds list // Parentally locked sounds list
@ -118,9 +122,6 @@ void InitFX(void)
newsfx.name = entry.name; newsfx.name = entry.name;
newsfx.lumpnum = lump; newsfx.lumpnum = lump;
newsfx.NearLimit = 6; newsfx.NearLimit = 6;
newsfx.UserData.Resize(sizeof(void*));
auto p = (VOC_INFOp *)newsfx.UserData.Data();
*p = &entry; // store a link to the static data.
} }
} }
soundEngine->HashSounds(); soundEngine->HashSounds();
@ -133,10 +134,90 @@ void InitFX(void)
//========================================================================== //==========================================================================
// //
// // Sound Distance Calculation
// //
//========================================================================== //==========================================================================
enum
{
MAXLEVLDIST = 19000, // The higher the number, the further away you can hear sound
DECAY_CONST = 4000
};
short SoundDist(int x, int y, int z, int basedist)
{
double tx, ty, tz;
double sqrdist, retval;
extern short screenpeek;
tx = fabs(Player[screenpeek].posx - x);
ty = fabs(Player[screenpeek].posy - y);
tz = fabs((Player[screenpeek].posz - z) >> 4);
// Use the Pythagreon Theorem to compute the magnitude of a 3D vector
sqrdist = fabs(tx * tx + ty * ty + tz * tz);
retval = sqrt(sqrdist);
if (basedist < 0) // if basedist is negative
{
double decayshift = 2;
int decay = labs(basedist) / DECAY_CONST;
for (int i = 0; i < decay; i++)
decayshift *= 2;
if (fabs(double(basedist) / decayshift) >= retval)
retval = 0;
else
retval *= decay;
}
else
{
if (basedist > retval)
retval = 0;
else
retval -= basedist;
}
retval = retval * 256 / MAXLEVLDIST;
if (retval < 0) retval = 0;
if (retval > 255) retval = 255;
return retval;
}
//==========================================================================
//
// Calculate rolloff info.
//
//==========================================================================
FRolloffInfo GetRolloff(int basedist)
{
FRolloffInfo info;
if (basedist < 0) // if basedist is negative
{
double decayshift = 2;
int decay = labs(basedist) / DECAY_CONST;
for (int i = 0; i < decay; i++)
decayshift *= 2;
info.RolloffType = ROLLOFF_Doom;
info.MinDistance = (float)(-basedist / decayshift / 16.);
info.MaxDistance = MAXLEVLDIST / 16.f / decay;
}
else
{
info.RolloffType = ROLLOFF_Doom;
info.MinDistance = basedist / 16.f;
info.MaxDistance = info.MinDistance + MAXLEVLDIST / 16.f;
}
return info;
}
@ -151,35 +232,6 @@ void DumpSounds(void);
SWBOOL Use_SoundSpriteNum = FALSE; SWBOOL Use_SoundSpriteNum = FALSE;
int16_t SoundSpriteNum = -1; // Always set this back to -1 for proper validity checking! int16_t SoundSpriteNum = -1; // Always set this back to -1 for proper validity checking!
SWBOOL FxInitialized = FALSE;
void SoundCallBack(unsigned int num);
#define MUSIC_ID -65536
#define NUM_SAMPLES 10
int music;
int soundfx;
int num_voices;
int NumSounds = 0;
int angle;
int distance;
int voice;
int loopflag;
extern SWBOOL DemoMode;
SWBOOL OpenSound(VOC_INFOp vp, FileReader &handle, int *length);
int ReadSound(FileReader & handle, VOC_INFOp vp, int length);
//
// Routine called when a sound is finished playing
//
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Play a sound // Play a sound
@ -250,7 +302,7 @@ typedef struct
} TVOC_INFO, * TVOC_INFOp; } TVOC_INFO, * TVOC_INFOp;
void void
DoUpdateSounds3D(void) DoUpdateSounds(void)
{ {
VOC3D_INFOp p; VOC3D_INFOp p;
SWBOOL looping; SWBOOL looping;
@ -262,8 +314,7 @@ DoUpdateSounds3D(void)
TVOC_INFO TmpVocArray[32]; TVOC_INFO TmpVocArray[32];
int i; int i;
if (M_Active()) return; // Zero out the temporary array
// Zero out the temporary array // Zero out the temporary array
//memset(&TmpVocArray[0],0,sizeof(TmpVocArray)); //memset(&TmpVocArray[0],0,sizeof(TmpVocArray));
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
@ -500,222 +551,8 @@ DoUpdateSounds3D(void)
} }
void /*
StopFX(void)
{
FX_StopAllSounds_();
}
void
StopSound(void)
{
StopFX();
Mus_Stop();
}
//
// Sound Distance Calculation
//
#define MAXLEVLDIST 19000 // The higher the number, the further away you can hear sound
short SoundDist(int x, int y, int z, int basedist)
{
double tx, ty, tz;
double sqrdist,retval;
double decay,decayshift;
extern short screenpeek;
#define DECAY_CONST 4000
tx = fabs(Player[screenpeek].posx - x);
ty = fabs(Player[screenpeek].posy - y);
tz = fabs((Player[screenpeek].posz - z) >> 4);
// Use the Pythagreon Theorem to compute the magnitude of a 3D vector
sqrdist = fabs(tx*tx + ty*ty + tz*tz);
retval = sqrt(sqrdist);
if (basedist < 0) // if basedist is negative
{
short i;
decayshift=2;
decay = labs(basedist) / DECAY_CONST;
for (i=0; i<decay; i++)
decayshift *= 2;
if (fabs(double(basedist)/decayshift) >= retval)
retval = 0;
else
retval *= decay;
}
else
{
if (basedist > retval)
retval = 0;
else
retval -= basedist;
}
retval = retval * 256 / MAXLEVLDIST;
if (retval < 0) retval = 0;
if (retval > 255) retval = 255;
return retval;
}
//
// Angle calcuations - may need to be checked to make sure they are right
//
short SoundAngle(int x, int y)
{
extern short screenpeek;
short angle, delta_angle;
angle = getangle(x - Player[screenpeek].posx, y - Player[screenpeek].posy);
delta_angle = GetDeltaAngle(angle, Player[screenpeek].pang);
// convert a delta_angle to a real angle if negative
if (delta_angle < 0)
delta_angle = NORM_ANGLE((1024 + delta_angle) + 1024);
// convert 2048 degree angle to 128 degree angle
return delta_angle >> 4;
}
////////////////////////////////////////////////////////////////////////////
// Play a sound
////////////////////////////////////////////////////////////////////////////
#define SOUND_UNIT MAXLEVLDIST/255
// NOTE: If v3df_follow == 1, x,y,z are considered literal coordinates
int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags)
{
VOC_INFOp vp;
VOC3D_INFOp v3p;
int pitch = 0;
short angle, sound_dist;
int tx, ty, tz;
uint8_t priority;
// Weed out parental lock sounds if PLock is active
if (adult_lockout || Global_PLock)
{
unsigned i;
for (i=0; i<sizeof(PLocked_Sounds); i++)
{
if (num == PLocked_Sounds[i])
return -1;
}
}
if (Prediction || !SoundEnabled() || num < 0 || num >= DIGI_MAX)
return -1;
if (TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup)) // Look for invalid ambient numbers
{
if (!snd_ambience) return -1;
if (num < 0 || num > MAX_AMBIENT_SOUNDS)
{
sprintf(ds,"Invalid or out of range ambient sound number %d\n",num);
PutStringInfo(Player+screenpeek, ds);
return -1;
}
v3p->maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics);
// If the ambient flag is set, do a name conversion to point to actual
// digital sound entry.
flags |= ambarray[num].ambient_flags; // Add to flags if any
num = ambarray[num].diginame;
if (num < 0 || num >= DIGI_MAX)
{
return -1;
}
}
//auto chan = soundEngine->StartSound()
v3p->num = num;
v3p->priority = 0;
v3p->FX_Ok = FALSE; // Hasn't played yet
// Reset voice
voice = -1;
// Assign voc to voc pointer
vp = &voc[num];
if (M_Active() && sp == nullptr && pp == nullptr) // Menus sound outdo everything
priority = 100;
else
priority = vp->priority;
v3p->vp = vp;
// Assign voc info to 3d struct for future reference
/*
v3p->x = x;
v3p->y = y;
v3p->z = z;
v3p->fx = *x;
v3p->fy = *y;
v3p->fz = *z;
*/
v3p->flags = flags;
/*
if (flags & v3df_follow)
{
tx = *x;
ty = *y;
if (!z)
tz = 0; // Some sound calls don't have a z
// value
else
tz = *z;
}
else
{
// Don't use pointers to coordinate values.
tx = v3p->fx;
ty = v3p->fy;
tz = v3p->fz;
}
*/
// Special case stuff for sounds being played in a level
/*
if (*x==0 && *y==0 && *z==0)
tx = ty = tz = 0;
*/
if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0 && sp)
{
tx=sp->x;
ty=sp->y;
tz=sp->z;
}
// Calculate sound angle
if (flags & v3df_dontpan) // If true, don't do panning
angle = 0;
else
angle = SoundAngle(tx, ty);
// Calculate sound distance
if (tx == 0 && ty == 0 && tz == 0)
sound_dist = 255; // Special case for menus sounds,etc.
else
sound_dist = SoundDist(tx, ty, tz, vp->voc_distance);
v3p->doplr_delta = sound_dist; // Save of distance for doppler
// effect
// Can the ambient sound see the player? If not, tone it down some. // Can the ambient sound see the player? If not, tone it down some.
if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0) if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0)
@ -733,88 +570,148 @@ int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags)
if (num == DIGI_WHIPME) sound_dist = 255; if (num == DIGI_WHIPME) sound_dist = 255;
} }
} }
*/
// Assign ambient priorities based on distance
if (snd_ambience && TEST(flags, v3df_ambient))
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
float S_ConvertPitch(int lpitch)
{
return pow(2, lpitch / 1200.);
}
//==========================================================================
//
// Play a sound
//
//==========================================================================
int _PlaySound(int num, SPRITEp sp, PLAYERp pp, vec3_t *pos, Voc3D_Flags flags, int channel)
{
VOC_INFOp vp;
VOC3D_INFOp v3p;
int pitch = 0;
short angle, sound_dist;
int tx, ty, tz;
uint8_t priority;
int maxtics = 0;
EChanFlags cflags = channel == 8 ?CHANF_OVERLAP : CHANF_NONE; // for the default channel we do not want to have sounds stopping each other.
// Weed out parental lock sounds if PLock is active
if (adult_lockout || Global_PLock)
{ {
v3p->priority = v3p->vp->priority - (sound_dist / 26); unsigned i;
priority = v3p->priority;
for (i=0; i<sizeof(PLocked_Sounds); i++)
{
if (num == PLocked_Sounds[i])
return -1;
}
} }
/* if (Prediction || !SoundEnabled())
if (!CacheSound(num, CACHE_SOUND_PLAY))
{
v3p->flags = v3df_kill;
v3p->handle = -1;
v3p->dist = 0;
v3p->deleted = TRUE; // Sound init failed, remove it!
return -1; return -1;
}*/
if (sound_dist < 5) if (TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup)) // Look for invalid ambient numbers
angle = 0; {
// Ambient sounds need special treatment
if (!snd_ambience) return -1;
if (num < 0 || num > MAX_AMBIENT_SOUNDS)
{
sprintf(ds,"Invalid or out of range ambient sound number %d\n",num);
PutStringInfo(Player+screenpeek, ds);
return -1;
}
maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics);
// Check for pitch bending // If the ambient flag is set, do a name conversion to point to actual
if (vp->pitch_lo > vp->pitch_hi) // digital sound entry.
ASSERT(vp->pitch_lo <= vp->pitch_hi); flags |= ambarray[num].ambient_flags; // Add to flags if any
num = ambarray[num].diginame;
cflags |= EChanFlags::FromInt(CHANEXF_AMBIENT); // flag the sound as being an ambient sound.
}
//else
{
if (!soundEngine->isValidSoundId(num))
{
return -1;
}
if (vp->pitch_hi == vp->pitch_lo) vp = &voc[num];
int sourcetype = SOURCE_None;
void* source = nullptr;
// If the sound is not supposd to be positioned, it may not be linked to the launching actor.
if (!(flags & v3df_follow))
{
if (sp && !pos)
{
pos = &sp->pos;
sp = nullptr;
}
else if (pp && !pos)
{
pos = (vec3_t*)&pp->posx;
pp = nullptr;
}
}
if (pos != nullptr)
{
sourcetype = SOURCE_Unattached;
}
else if (sp != nullptr)
{
source = sp;
sourcetype = SOURCE_Actor;
}
else if (pp != nullptr)
{
source = pp;
sourcetype = SOURCE_Player;
}
// Otherwise it's an unpositioned sound.
if (!(flags & v3df_doppler))
{
cflags |= EChanFlags::FromInt(CHANEXF_NODOPPLER); // this must ensure that CalcPosVel always zeros the velocity.
}
if (flags & v3df_dontpan)
{
cflags |= EChanFlags::FromInt(CHANEXF_DONTPAN); // beware of hackery to emulate this.
}
if (flags & v3df_init)
{
cflags |= CHANF_VIRTUAL; // don't start right away but keep the channel around until explicitly deleted.
}
if (vp->voc_flags & vf_loop)
{
cflags |= CHANF_LOOP; // with the new sound engine these can just be started and don't have to be stopped ever.
}
if (vp->pitch_hi <= vp->pitch_lo)
pitch = vp->pitch_lo; pitch = vp->pitch_lo;
else if (vp->pitch_hi != vp->pitch_lo) else if (vp->pitch_hi != vp->pitch_lo)
pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo)); pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo));
// Request playback and play it as a looping sound if flag is set. float fpitch = S_ConvertPitch(pitch);
if (vp->voc_flags & vf_loop)
{
short loopvol=0;
if ((loopvol = 255-sound_dist) <= 0) auto rolloff = GetRolloff(vp->voc_distance);
loopvol = 0; auto spos = GetSoundPos(pos);
auto chan = soundEngine->StartSound(sourcetype, source, &spos, CHAN_BODY, cflags, num, 1.f, ATTN_NORM, &rolloff, fpitch);
if (sound_dist < 255 || (flags & v3df_init)) if (chan)
{ {
voice = FX_Play((char *)vp->data, vp->datalen, 0, 0, if (flags & v3df_intermit)
pitch, loopvol, loopvol, loopvol, priority, 1.f, num); // [JM] Should probably utilize floating point volume. !CHECKME!
}
else
voice = -1;
}
else
//if(!flags & v3df_init) // If not initing sound, play it
if (tx==0 && ty==0 && tz==0) // It's a non-inlevel sound
{ {
voice = FX_Play((char *)vp->data, vp->datalen, -1, -1, pitch, 255, 255, 255, priority, 1.f, num); // [JM] And here !CHECKME! chan->ChanFlags |= CHANF_VIRTUAL | EChanFlags::FromInt(CHANEXF_INTERMIT); // for intermittent sounds this must be set after starting the sound so that it actually plays.
} }
else // It's a 3d sound chan->UserData = maxtics; // counter for intermittent delay.
{
if (sound_dist < 255)
{
voice = FX_Play3D((char *)vp->data, vp->datalen, FX_ONESHOT, pitch, angle, sound_dist, priority, 1.f, num); // [JM] And here !CHECKME!
} }
else
voice = -1;
} }
// If sound played, update our counter return 1;
if (voice > FX_Ok)
{
//vp->playing++;
v3p->FX_Ok = TRUE;
}
else
{
vp->lock--;
}
// Assign voc info to 3d struct for future reference
v3p->handle = voice; // Save the current voc handle in struct
v3p->dist = sound_dist;
v3p->tics = 0; // Reset tics
if (flags & v3df_init)
v3p->flags ^= v3df_init; // Turn init off now
return voice;
} }
//========================================================================== //==========================================================================
@ -1012,6 +909,11 @@ void StopPlayerSound(PLAYERp pp)
soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE); soundEngine->StopSound(SOURCE_Player, pp, CHAN_VOICE);
} }
bool SoundValidAndActive(SPRITEp spr, int channel)
{
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, spr, channel);
}
/* /*
============================================================================ ============================================================================
@ -1123,5 +1025,11 @@ SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_tra
return Mus_Play(nullptr, song_file_name, true); return Mus_Play(nullptr, song_file_name, true);
} }
void StopSound(void)
{
soundEngine->StopAllChannels();
Mus_Stop();
}
END_SW_NS END_SW_NS

View file

@ -73,7 +73,7 @@ typedef struct ambientstruct AMB_INFO, *AMB_INFOp;
extern VOC3D_INFOp voc3dstart; extern VOC3D_INFOp voc3dstart;
extern VOC3D_INFOp voc3dend; extern VOC3D_INFOp voc3dend;
void DoUpdateSounds3D(void); void DoUpdateSounds(void);
void Terminate3DSounds(void); void Terminate3DSounds(void);
void Set3DSoundOwner(short spritenum); void Set3DSoundOwner(short spritenum);

View file

@ -719,23 +719,22 @@ int DoZillaMove(short SpriteNum)
SPRITEp sp = &sprite[SpriteNum]; SPRITEp sp = &sprite[SpriteNum];
USERp u = User[SpriteNum]; USERp u = User[SpriteNum];
short choose; short choose;
static int handle;
//if (TEST(u->Flags,SPR_SLIDING)) //if (TEST(u->Flags,SPR_SLIDING))
//DoActorSlide(SpriteNum); //DoActorSlide(SpriteNum);
// Random Zilla taunts // Random Zilla taunts
if (!FX_SoundValidAndActive(handle)) if (!SoundValidAndActive(sp, CHAN_AnimeMad))
{ {
choose = STD_RANDOM_RANGE(1000); choose = STD_RANDOM_RANGE(1000);
if (choose > 990) if (choose > 990)
handle = PlaySound(DIGI_Z16004, sp, v3df_none); PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad);
else if (choose > 985) else if (choose > 985)
handle = PlaySound(DIGI_Z16004, sp, v3df_none); PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad);
else if (choose > 980) else if (choose > 980)
handle = PlaySound(DIGI_Z16004, sp, v3df_none); PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad);
else if (choose > 975) else if (choose > 975)
handle = PlaySound(DIGI_Z16004, sp, v3df_none); PlaySound(DIGI_Z16004, sp, v3df_none, CHAN_AnimeMad);
} }