- 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")
{
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.)
};
@ -104,7 +104,7 @@ CUSTOM_CVARD(Int, cl_weaponswitch, 3, CVAR_ARCHIVE|CVAR_USERINFO, "enable/disabl
{
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;
//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_JUSTSTARTED = 512, // internal: Sound has not been updated yet.
CHANF_ABSTIME = 1024, // internal: Start time is absolute and does not depend on current time.
CHANF_VIRTUAL = 2048, // internal: Channel is currently virtual
CHANF_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_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
// is blocked and looped, pretend to play it so that it can
// eventually play for real.
if ((chanflags & (CHANF_EVICTED | CHANF_LOOP)) == CHANF_EVICTED)
if ((chanflags & (CHANF_EVICTED | CHANF_LOOP | CHANF_VIRTUAL)) == CHANF_EVICTED)
{
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.
// 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;
}
@ -587,7 +587,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
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);
GSnd->MarkStartTime(chan);
@ -1014,7 +1014,7 @@ void SoundEngine::RelinkSound (int sourcetype, const void *from, const void *to,
{
chan->Source = to;
}
else if (!(chan->ChanFlags & CHANF_LOOP) && optpos)
else if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL)) && optpos)
{
chan->Source = NULL;
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)
{
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)
{
@ -1217,7 +1217,7 @@ void SoundEngine::RestoreEvictedChannel(FSoundChan *chan)
if (chan->ChanFlags & CHANF_EVICTED)
{
RestartChannel(chan);
if (!(chan->ChanFlags & CHANF_LOOP))
if (!(chan->ChanFlags & (CHANF_LOOP|CHANF_VIRTUAL)))
{
if (chan->ChanFlags & CHANF_EVICTED)
{ // 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);
}
@ -1345,7 +1345,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
{
evicted = false;
}
else if (schan->ChanFlags & (CHANF_LOOP | CHANF_EVICTED))
else if (schan->ChanFlags & (CHANF_LOOP | CHANF_VIRTUAL | CHANF_EVICTED))
{
evicted = true;
}

View file

@ -168,13 +168,14 @@ struct FSoundChan : public FISoundChannel
FSoundID OrgID; // Sound ID of sound used to start this channel.
float Volume;
int16_t Pitch; // Pitch variation.
uint8_t EntChannel; // Actor's sound channel.
int32_t EntChannel; // Actor's sound channel.
int8_t Priority;
int16_t NearLimit;
uint8_t SourceType;
float LimitRange;
const void *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 "config.h"
#include "menu/menu.h"
#include "sound/s_soundinternal.h"
#include "sounds.h"
#include "../../glbackend/glbackend.h"
@ -237,17 +239,20 @@ void GameInterface::StartGame(FGameStartup& gs)
//InitNewGame();
if (Skill == 0)
handle = PlaySound(DIGI_TAUNTAI3, v3df_none);
PlaySound(DIGI_TAUNTAI3, v3df_none, CHAN_VOICE);
else if (Skill == 1)
handle = PlaySound(DIGI_NOFEAR, v3df_none);
PlaySound(DIGI_NOFEAR, v3df_none, CHAN_VOICE);
else if (Skill == 2)
handle = PlaySound(DIGI_WHOWANTSWANG, v3df_none);
PlaySound(DIGI_WHOWANTSWANG, v3df_none, CHAN_VOICE);
else if (Skill == 3)
handle = PlaySound(DIGI_NOPAIN, v3df_none);
PlaySound(DIGI_NOPAIN, v3df_none, CHAN_VOICE);
if (handle > FX_Ok)
while (FX_SoundActive(handle))
while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE))
{
DoUpdateSounds();
handleevents();
}
}
FSavegameInfo GameInterface::GetSaveSig()

View file

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

View file

@ -1210,7 +1210,6 @@ struct PLAYERstruct
unsigned char WpnShotgunLastShell; // Number of last shell fired
unsigned char WpnRailType; // Normal Rail Gun or EMP Burst Mode
SWBOOL Bloody; // Is player gooey from the slaughter?
int nukevochandle; // Stuff for the Nuke
SWBOOL InitingNuke;
SWBOOL TestNukeInit;
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);
// 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 SoundAngle(int x, int y);
//void PlaySound(int num, short angle, short vol);
int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags);
inline int PlaySound(int num, SPRITEp sprite, Voc3D_Flags flags)
int _PlaySound(int num, SPRITEp sprite, PLAYERp player, vec3_t *pos, Voc3D_Flags flags, int channel);
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);
inline int PlayerSound(int num, int flags, PLAYERp pp) { return _PlayerSound(num, pp); }
void StopPlayerSound(PLAYERp pp);
bool SoundValidAndActive(SPRITEp spr, int channel);
ANIMATOR DoActorBeginJump,DoActorJump,DoActorBeginFall,DoActorFall,DoActorDeathMove;

View file

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

View file

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

View file

@ -2258,7 +2258,6 @@ PlayerDeathReset(PLAYERp pp)
pp->Bloody = FALSE;
pp->TestNukeInit = FALSE;
pp->InitingNuke = FALSE;
pp->nukevochandle = 0;
pp->NukeInitialized = FALSE;
pp->BunnyMode = FALSE;
@ -2348,7 +2347,6 @@ PlayerGameReset(PLAYERp pp)
pp->Bloody = FALSE;
pp->TestNukeInit = FALSE;
pp->InitingNuke = FALSE;
pp->nukevochandle = 0;
pp->NukeInitialized = FALSE;
pp->BunnyMode = FALSE;
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 "menu/menu.h"
#include "swcvar.h"
#include "sound/s_soundinternal.h"
BEGIN_SW_NS
@ -996,11 +997,7 @@ int WeaponOperate(PLAYERp pp)
if (pp->WpnRocketType != 2 || pp->CurWpn != pp->Wpn[WPN_MICRO])
{
pp->InitingNuke = FALSE;
if (pp->nukevochandle > 0)
{
FX_StopSound(pp->nukevochandle);
pp->nukevochandle = 0;
}
soundEngine->StopSound(SOURCE_Player, pp, CHAN_WEAPON);
}
return 0;
@ -3694,8 +3691,6 @@ PANEL_STATE ps_RetractRail[] =
//#define RAIL_XOFF (160+60)
#define RAIL_XOFF (160+6)
static int railvochandle=0;
void
InitWeaponRail(PLAYERp pp)
{
@ -3740,7 +3735,7 @@ InitWeaponRail(PLAYERp pp)
pSetState(psp, psp->PresentState);
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);
FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT);
@ -5007,8 +5002,7 @@ pMicroStandBy(PANEL_SPRITEp psp)
PLAYERp pp = psp->PlayerP;
pMicroOverlays(psp);
pp->nukevochandle =
PlaySound(DIGI_NUKESTDBY, psp->PlayerP, v3df_follow|v3df_dontpan);
PlaySound(DIGI_NUKESTDBY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
}
void
@ -5016,8 +5010,7 @@ pMicroCount(PANEL_SPRITEp psp)
{
PLAYERp pp = psp->PlayerP;
pp->nukevochandle =
PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan);
PlaySound(DIGI_NUKECDOWN, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
}
void
@ -5025,8 +5018,7 @@ pMicroReady(PANEL_SPRITEp psp)
{
PLAYERp pp = psp->PlayerP;
pp->nukevochandle =
PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan);
PlaySound(DIGI_NUKEREADY, pp, v3df_follow|v3df_dontpan, CHAN_WEAPON);
pp->NukeInitialized = TRUE;
}

View file

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

View file

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

View file

@ -748,8 +748,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv)
TerminateLevel();
Terminate3DSounds();
Terminate3DSounds();
MREAD(&Level,sizeof(Level),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))
flags = v3df_follow|v3df_nolookup|v3df_init;
//flags = v3df_follow|v3df_ambient|v3df_nolookup;
// play once and only once
if (TEST_BOOL1(sp))

View file

@ -60,6 +60,10 @@ BEGIN_SW_NS
enum EChanExFlags
{
CHANEXF_AMBIENT = 0x40000000,
CHANEXF_NODOPPLER = 0x20000000,
CHANEXF_DONTPAN = 0x10000000,
CHANEXF_INTERMIT = 0x08000000,
};
// Parentally locked sounds list
@ -118,9 +122,6 @@ void InitFX(void)
newsfx.name = entry.name;
newsfx.lumpnum = lump;
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();
@ -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;
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
@ -250,7 +302,7 @@ typedef struct
} TVOC_INFO, * TVOC_INFOp;
void
DoUpdateSounds3D(void)
DoUpdateSounds(void)
{
VOC3D_INFOp p;
SWBOOL looping;
@ -262,8 +314,7 @@ DoUpdateSounds3D(void)
TVOC_INFO TmpVocArray[32];
int i;
if (M_Active()) return;
// Zero out the temporary array
// Zero out the temporary array
//memset(&TmpVocArray[0],0,sizeof(TmpVocArray));
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.
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;
}
}
*/
// 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);
priority = v3p->priority;
unsigned i;
for (i=0; i<sizeof(PLocked_Sounds); i++)
{
if (num == PLocked_Sounds[i])
return -1;
}
}
/*
if (!CacheSound(num, CACHE_SOUND_PLAY))
{
v3p->flags = v3df_kill;
v3p->handle = -1;
v3p->dist = 0;
v3p->deleted = TRUE; // Sound init failed, remove it!
if (Prediction || !SoundEnabled())
return -1;
}*/
if (sound_dist < 5)
angle = 0;
if (TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup)) // Look for invalid ambient numbers
{
// 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 (vp->pitch_lo > vp->pitch_hi)
ASSERT(vp->pitch_lo <= vp->pitch_hi);
// 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;
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;
else if (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.
if (vp->voc_flags & vf_loop)
{
short loopvol=0;
float fpitch = S_ConvertPitch(pitch);
if ((loopvol = 255-sound_dist) <= 0)
loopvol = 0;
if (sound_dist < 255 || (flags & v3df_init))
auto rolloff = GetRolloff(vp->voc_distance);
auto spos = GetSoundPos(pos);
auto chan = soundEngine->StartSound(sourcetype, source, &spos, CHAN_BODY, cflags, num, 1.f, ATTN_NORM, &rolloff, fpitch);
if (chan)
{
voice = FX_Play((char *)vp->data, vp->datalen, 0, 0,
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
if (flags & v3df_intermit)
{
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
{
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!
chan->UserData = maxtics; // counter for intermittent delay.
}
else
voice = -1;
}
// If sound played, update our counter
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;
return 1;
}
//==========================================================================
@ -1012,6 +909,11 @@ void StopPlayerSound(PLAYERp pp)
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);
}
void StopSound(void)
{
soundEngine->StopAllChannels();
Mus_Stop();
}
END_SW_NS

View file

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

View file

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