- Fixed: Screenwipes now pause sounds, since there can be sounds playing

during it.
- UI sounds are now omitted from savegames.
- Fixed: Menu sounds had been restricted to one at a time again.
- Moved the P_SerializeSounds() call to the end of G_SerializeLevel() so that
  it will occur after the players are loaded.
- Added fixes from FreeBSD for 0-length and very large string buffers
  passed to myvsnprintf.


SVN r1063 (trunk)
This commit is contained in:
Randy Heit 2008-07-05 03:32:44 +00:00
parent 0632a35b18
commit 78890d57bc
14 changed files with 172 additions and 94 deletions

View file

@ -1,4 +1,14 @@
July 4, 2008
- Fixed: Screenwipes now pause sounds, since there can be sounds playing
during it.
- UI sounds are now omitted from savegames.
- Fixed: Menu sounds had been restricted to one at a time again.
- Moved the P_SerializeSounds() call to the end of G_SerializeLevel() so that
it will occur after the players are loaded.
July 2, 2008
- Added fixes from FreeBSD for 0-length and very large string buffers
passed to myvsnprintf.
- Rewrote myvsnprintf to use the StringFormat routines directly so that no
additional memory needs to be allocated from the heap.

View file

@ -688,6 +688,7 @@ void D_Display ()
int wipestart, nowtime, tics;
bool done;
GSnd->SetSfxPaused(true, 1);
screen->WipeEndScreen ();
wipestart = I_GetTime (false);
@ -707,6 +708,7 @@ void D_Display ()
NetUpdate ();
} while (!done);
screen->WipeCleanup();
GSnd->SetSfxPaused(false, 1);
Net_WriteByte (DEM_WIPEOFF);
}

View file

@ -2819,7 +2819,6 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
P_SerializeThinkers (arc, hubLoad);
P_SerializeWorld (arc);
P_SerializePolyobjs (arc);
P_SerializeSounds (arc);
StatusBar->Serialize (arc);
//SerializeInterpolations (arc);
@ -2865,6 +2864,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
P_SerializePlayers (arc);
}
P_SerializeSounds (arc);
}
// Archives the current level

View file

@ -602,28 +602,28 @@ CCMD (menu_help)
CCMD (quicksave)
{ // F6
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", 1, ATTN_NONE);
M_QuickSave();
}
CCMD (quickload)
{ // F9
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", 1, ATTN_NONE);
M_QuickLoad();
}
CCMD (menu_endgame)
{ // F7
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", 1, ATTN_NONE);
M_EndGame(0);
}
CCMD (menu_quit)
{ // F10
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", 1, ATTN_NONE);
M_QuitGame(0);
}
@ -1380,7 +1380,7 @@ void M_QuickSaveResponse (int ch)
if (ch == 'y')
{
M_DoSave (quickSaveSlot);
S_Sound (CHAN_VOICE, "menu/dismiss", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", 1, ATTN_NONE);
}
}
@ -1388,7 +1388,7 @@ void M_QuickSave ()
{
if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer))
{
S_Sound (CHAN_VOICE, "menu/invalid", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", 1, ATTN_NONE);
return;
}
@ -1416,7 +1416,7 @@ void M_QuickLoadResponse (int ch)
if (ch == 'y')
{
M_LoadSelect (quickSaveSlot);
S_Sound (CHAN_VOICE, "menu/dismiss", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", 1, ATTN_NONE);
}
}
@ -1893,7 +1893,7 @@ void M_EndGame(int choice)
choice = 0;
if (!usergame)
{
S_Sound (CHAN_VOICE, "menu/invalid", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", 1, ATTN_NONE);
return;
}
@ -1955,7 +1955,7 @@ void M_QuitResponse(int ch)
{
if (gameinfo.quitSound)
{
S_Sound (CHAN_VOICE, gameinfo.quitSound, 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.quitSound, 1, ATTN_NONE);
I_WaitVBL (105);
}
}
@ -2688,7 +2688,7 @@ void M_StartMessage (const char *string, void (*routine)(int), bool input)
if (input)
{
S_StopSound (CHAN_VOICE);
S_Sound (CHAN_VOICE, "menu/prompt", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", 1, ATTN_NONE);
}
return;
}
@ -2844,7 +2844,7 @@ bool M_Responder (event_t *ev)
}
SB_state = screen->GetPageCount (); // refresh the statbar
BorderNeedRefresh = screen->GetPageCount ();
S_Sound (CHAN_VOICE, "menu/dismiss", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", 1, ATTN_NONE);
return true;
}
@ -2871,7 +2871,7 @@ bool M_Responder (event_t *ev)
if (itemOn+1 > currentMenu->numitems-1)
itemOn = 0;
else itemOn++;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
} while(currentMenu->menuitems[itemOn].status==-1);
return true;
@ -2881,7 +2881,7 @@ bool M_Responder (event_t *ev)
if (!itemOn)
itemOn = currentMenu->numitems-1;
else itemOn--;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
} while(currentMenu->menuitems[itemOn].status==-1);
return true;
@ -2889,7 +2889,7 @@ bool M_Responder (event_t *ev)
if (currentMenu->menuitems[itemOn].routine &&
currentMenu->menuitems[itemOn].status == 2)
{
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
currentMenu->menuitems[itemOn].routine(0);
}
return true;
@ -2898,7 +2898,7 @@ bool M_Responder (event_t *ev)
if (currentMenu->menuitems[itemOn].routine &&
currentMenu->menuitems[itemOn].status == 2)
{
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
currentMenu->menuitems[itemOn].routine(1);
}
return true;
@ -2911,12 +2911,12 @@ bool M_Responder (event_t *ev)
if (currentMenu->menuitems[itemOn].status == 2)
{
currentMenu->menuitems[itemOn].routine(1); // right arrow
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
else
{
currentMenu->menuitems[itemOn].routine(itemOn);
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
}
}
return true;
@ -2945,7 +2945,7 @@ bool M_Responder (event_t *ev)
if (currentMenu->menuitems[i].alphaKey == ch)
{
itemOn = i;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
return true;
}
}
@ -3120,7 +3120,7 @@ void M_StartControlPanel (bool makeSound)
if (makeSound)
{
S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", 1, ATTN_NONE);
}
}
@ -3354,12 +3354,12 @@ void M_PopMenuStack (void)
}
drawSkull = MenuStack[MenuStackDepth].drawSkull;
++MenuStackDepth;
S_Sound (CHAN_VOICE, "menu/backup", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/backup", 1, ATTN_NONE);
}
else
{
M_ClearMenus ();
S_Sound (CHAN_VOICE, "menu/clear", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/clear", 1, ATTN_NONE);
}
}

View file

@ -1472,13 +1472,13 @@ void M_SizeDisplay (int diff)
CCMD (sizedown)
{
M_SizeDisplay (-1);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
CCMD (sizeup)
{
M_SizeDisplay (1);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
// Draws a string in the console font, scaled to the 8x8 cells
@ -2153,7 +2153,7 @@ void M_OptResponder (event_t *ev)
CurrentMenu->items[CurrentItem].a.selmode = modecol;
}
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
}
break;
@ -2217,7 +2217,7 @@ void M_OptResponder (event_t *ev)
if (CurrentMenu->items[CurrentItem].type == screenres)
CurrentMenu->items[CurrentItem].a.selmode = modecol;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
}
break;
@ -2239,7 +2239,7 @@ void M_OptResponder (event_t *ev)
{
++CurrentItem;
}
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
}
break;
@ -2262,7 +2262,7 @@ void M_OptResponder (event_t *ev)
{
++CurrentItem;
}
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
}
break;
@ -2300,12 +2300,12 @@ void M_OptResponder (event_t *ev)
else
item->a.cvar->SetGenericRep (newval, CVAR_Float);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case palettegrid:
SelColorIndex = (SelColorIndex - 1) & 15;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
break;
case discretes:
@ -2335,14 +2335,14 @@ void M_OptResponder (event_t *ev)
if (item->e.values == Depths)
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case ediscrete:
value = item->a.cvar->GetGenericRep(CVAR_String);
value.String = const_cast<char *>(M_FindPrevVal(value.String, item->e.enumvalues, (int)item->b.numvalues));
item->a.cvar->SetGenericRep(value, CVAR_String);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case bitmask:
@ -2361,7 +2361,7 @@ void M_OptResponder (event_t *ev)
value.Int = (value.Int & ~bmask) | int(item->e.values[cur].value);
item->a.cvar->SetGenericRep (value, CVAR_Int);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case discrete_guid:
@ -2376,14 +2376,14 @@ void M_OptResponder (event_t *ev)
*(item->a.guidcvar) = item->e.guidvalues[cur].ID;
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case inverter:
value = item->a.cvar->GetGenericRep (CVAR_Float);
value.Float = -value.Float;
item->a.cvar->SetGenericRep (value, CVAR_Float);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case screenres:
@ -2407,7 +2407,7 @@ void M_OptResponder (event_t *ev)
item->a.selmode = col;
}
}
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
break;
default:
@ -2449,12 +2449,12 @@ void M_OptResponder (event_t *ev)
else
item->a.cvar->SetGenericRep (newval, CVAR_Float);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case palettegrid:
SelColorIndex = (SelColorIndex + 1) & 15;
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
break;
case discretes:
@ -2484,14 +2484,14 @@ void M_OptResponder (event_t *ev)
if (item->e.values == Depths)
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case ediscrete:
value = item->a.cvar->GetGenericRep(CVAR_String);
value.String = const_cast<char *>(M_FindNextVal(value.String, item->e.enumvalues, (int)item->b.numvalues));
item->a.cvar->SetGenericRep(value, CVAR_String);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case bitmask:
@ -2510,7 +2510,7 @@ void M_OptResponder (event_t *ev)
value.Int = (value.Int & ~bmask) | int(item->e.values[cur].value);
item->a.cvar->SetGenericRep (value, CVAR_Int);
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case discrete_guid:
@ -2525,14 +2525,14 @@ void M_OptResponder (event_t *ev)
*(item->a.guidcvar) = item->e.guidvalues[cur].ID;
}
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case inverter:
value = item->a.cvar->GetGenericRep (CVAR_Float);
value.Float = -value.Float;
item->a.cvar->SetGenericRep (value, CVAR_Float);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
break;
case screenres:
@ -2559,7 +2559,7 @@ void M_OptResponder (event_t *ev)
item->a.selmode = col;
}
}
S_Sound (CHAN_VOICE, "menu/cursor", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
break;
default:
@ -2617,7 +2617,7 @@ void M_OptResponder (event_t *ev)
setmodeneeded = true;
NewBits = BitTranslate[DummyDepthCvar];
}
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
SetModesMenu (NewWidth, NewHeight, NewBits);
}
else if ((item->type == more ||
@ -2628,7 +2628,7 @@ void M_OptResponder (event_t *ev)
&& item->e.mfunc)
{
CurrentMenu->lastOn = CurrentItem;
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
if (item->type == safemore || item->type == rsafemore)
{
ActivateConfirm (item->label, item->e.mfunc);
@ -2663,7 +2663,7 @@ void M_OptResponder (event_t *ev)
if (item->e.values == Depths)
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
else if (item->type == control)
{
@ -2676,7 +2676,7 @@ void M_OptResponder (event_t *ev)
else if (item->type == listelement)
{
CurrentMenu->lastOn = CurrentItem;
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
item->e.lfunc (CurrentItem);
}
else if (item->type == inverter)
@ -2684,7 +2684,7 @@ void M_OptResponder (event_t *ev)
value = item->a.cvar->GetGenericRep (CVAR_Float);
value.Float = -value.Float;
item->a.cvar->SetGenericRep (value, CVAR_Float);
S_Sound (CHAN_VOICE, "menu/change", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
}
else if (item->type == screenres)
{
@ -2692,7 +2692,7 @@ void M_OptResponder (event_t *ev)
else if (item->type == colorpicker)
{
CurrentMenu->lastOn = CurrentItem;
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
StartColorPickerMenu (item->label, item->a.colorcvar);
}
else if (item->type == palettegrid)
@ -2728,7 +2728,7 @@ void M_OptResponder (event_t *ev)
NewBits = BitTranslate[DummyDepthCvar];
setmodeneeded = true;
testingmode = I_GetTime(false) + 5 * TICRATE;
S_Sound (CHAN_VOICE, "menu/choose", 1, ATTN_NONE);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
SetModesMenu (NewWidth, NewHeight, NewBits);
}
}

View file

@ -31,6 +31,7 @@
#include "doomstat.h"
#include "sbar.h"
#include "r_interpolate.h"
#include "i_sound.h"
extern gamestate_t wipegamestate;
@ -72,6 +73,13 @@ void P_Ticker (void)
interpolator.UpdateInterpolations ();
r_NoInterpolate = true;
if (!demoplayback)
{
// This is a separate slot from the wipe in D_Display(), because this
// is delayed slightly due to latency. (Even on a singleplayer game!)
GSnd->SetSfxPaused(!!playerswiping, 2);
}
// run the tic
if (paused || (playerswiping && !demoplayback) || P_CheckTickerPaused())
return;

View file

@ -117,6 +117,7 @@ static bool MusicPaused; // whether music is paused
static MusPlayingInfo mus_playing; // music currently being played
static FString LastSong; // last music that was played
static FPlayList *PlayList;
static int RestartEvictionsAt; // do not restart evicted channels before this level.time
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -670,13 +671,13 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
case SOURCE_Unattached:
pos->X = pt[0];
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(players[consoleplayer].camera->z);
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(y);
pos->Z = pt[2];
break;
}
if (type != SOURCE_Unattached)
{
if (chanflags & CHAN_LISTENERZ)
if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL)
{
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
}
@ -932,7 +933,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
}
// If this actor is already playing something on the selected channel, stop it.
if ((actor == NULL && channel != CHAN_AUTO) || (actor != NULL && actor->SoundChans & (1 << channel)))
if (type != SOURCE_None && (actor == NULL && channel != CHAN_AUTO) || (actor != NULL && actor->SoundChans & (1 << channel)))
{
for (chan = Channels; chan != NULL; chan = chan->NextChan)
{
@ -942,7 +943,6 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
switch (type)
{
case SOURCE_None: foundit = true; break;
case SOURCE_Actor: foundit = (chan->Actor == actor); break;
case SOURCE_Sector: foundit = (chan->Sector == sec); break;
case SOURCE_Polyobj: foundit = (chan->Poly == poly); break;
@ -1453,7 +1453,7 @@ void S_PauseSound (bool notmusic)
I_PauseSong (mus_playing.handle);
MusicPaused = true;
}
GSnd->SetSfxPaused (true);
GSnd->SetSfxPaused (true, 0);
}
//==========================================================================
@ -1470,7 +1470,7 @@ void S_ResumeSound ()
I_ResumeSong (mus_playing.handle);
MusicPaused = false;
}
GSnd->SetSfxPaused (false);
GSnd->SetSfxPaused (false, 0);
}
//==========================================================================
@ -1588,7 +1588,11 @@ void S_UpdateSounds (void *listener_p)
GSnd->UpdateListener();
GSnd->UpdateSounds();
S_RestoreEvictedChannels();
if (level.time >= RestartEvictionsAt)
{
RestartEvictionsAt = 0;
S_RestoreEvictedChannels();
}
}
//==========================================================================
@ -1668,8 +1672,9 @@ void S_SerializeSounds(FArchive &arc)
for (chan = Channels; chan != NULL; chan = chan->NextChan)
{
// If the sound is forgettable, this is as good a time as
// any to forget about it.
if (!(chan->ChanFlags & CHAN_FORGETTABLE))
// any to forget about it. And if it's a UI sound, it shouldn't
// be stored in the savegame.
if (!(chan->ChanFlags & (CHAN_FORGETTABLE | CHAN_UI)))
{
chans.Push(chan);
}
@ -1697,9 +1702,16 @@ void S_SerializeSounds(FArchive &arc)
chan = S_GetChannel(NULL);
arc << *chan;
// Sounds always start out evicted when restored from a save.
chan->ChanFlags |= CHAN_EVICTED;
chan->ChanFlags |= CHAN_EVICTED | CHAN_ABSTIME;
}
S_RestoreEvictedChannels();
// The two tic delay is to make sure any screenwipes have finished.
// This needs to be two because the game is run for one tic before
// the wipe so that it can produce a screen to wipe to. So if we
// only waited one tic to restart the sounds, they would start
// playing before the wipe, and depending on the synchronization
// between the main thread and the mixer thread at the time, the
// sounds might be heard briefly before pausing for the wipe.
RestartEvictionsAt = level.time + 2;
}
DSeqNode::SerializeSequences(arc);
GSnd->Sync(false);

View file

@ -263,9 +263,10 @@ void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, floa
#define CHAN_PICKUP (CHAN_ITEM|CHAN_MAYBE_LOCAL)
#define CHAN_IS3D 1 // internal: Sound is 3D.
#define CHAN_EVICTED 2 // internal: Looping sound was evicted.
#define CHAN_FORGETTABLE 4 // internal: Forget sound data when sound stops.
#define CHAN_EVICTED 2 // internal: Sound was evicted.
#define CHAN_FORGETTABLE 4 // internal: Forget channel data when sound stops.
#define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet.
#define CHAN_ABSTIME 1024// internal: Start time is absolute and does not depend on current time.
// sound attenuation values
#define ATTN_NONE 0.f // full volume the entire level

View file

@ -605,7 +605,7 @@ bool FMODSoundRenderer::Init()
int eval;
SFXPaused = false;
SFXPaused = 0;
DSPLocked = false;
MusicGroup = NULL;
SfxGroup = NULL;
@ -1382,7 +1382,7 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
mode = (mode & ~FMOD_LOOP_OFF) | FMOD_LOOP_NORMAL;
}
chan->setMode(mode);
chan->setChannelGroup((!(chanflags & CHAN_NOPAUSE) && !SFXPaused) ? PausableSfx : SfxGroup);
chan->setChannelGroup((chanflags & (CHAN_UI | CHAN_NOPAUSE)) ? SfxGroup : PausableSfx);
if (freq != 0)
{
chan->setFrequency(freq);
@ -1470,7 +1470,8 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float dis
}
mode = SetChanHeadSettings(chan, sfx, pos, channum, chanflags, sector, mode);
chan->setMode(mode);
chan->setChannelGroup((!(chanflags & CHAN_NOPAUSE) && !SFXPaused) ? PausableSfx : SfxGroup);
chan->setChannelGroup((chanflags & (CHAN_UI | CHAN_NOPAUSE)) ? SfxGroup : PausableSfx);
if (freq != 0)
{
chan->setFrequency(freq);
@ -1508,9 +1509,9 @@ void FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reus
QWORD_UNION nowtime;
chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &nowtime.Hi, &nowtime.Lo);
// If the DSP is locked, the sounds are being restored, and
// If CHAN_ABSTIME is set, the sound is being restored, and
// the channel's start time is actually its seek position.
if (DSPLocked)
if (reuse_chan->ChanFlags & CHAN_ABSTIME)
{
unsigned int seekpos = reuse_chan->StartTime.Lo;
if (seekpos > 0)
@ -1518,6 +1519,7 @@ void FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reus
chan->setPosition(seekpos, FMOD_TIMEUNIT_PCM);
}
reuse_chan->StartTime.AsOne = QWORD(nowtime.AsOne - seekpos * OutputRate / freq);
reuse_chan->ChanFlags &= ~CHAN_ABSTIME;
}
else
{
@ -1679,12 +1681,26 @@ unsigned int FMODSoundRenderer::GetPosition(FSoundChan *chan)
//
//==========================================================================
void FMODSoundRenderer::SetSfxPaused(bool paused)
void FMODSoundRenderer::SetSfxPaused(bool paused, int slot)
{
if (SFXPaused != paused)
int oldslots = SFXPaused;
if (paused)
{
PausableSfx->setPaused(paused);
SFXPaused = paused;
SFXPaused |= 1 << slot;
}
else
{
SFXPaused &= ~(1 << slot);
}
Printf("%d\n", SFXPaused);
if (oldslots != 0 && SFXPaused == 0)
{
PausableSfx->setPaused(false);
}
else if (oldslots == 0 && SFXPaused != 0)
{
PausableSfx->setPaused(true);
}
}

View file

@ -38,7 +38,7 @@ public:
void Sync (bool sync);
// Pauses or resumes all sound effect channels.
void SetSfxPaused (bool paused);
void SetSfxPaused (bool paused, int slot);
// Pauses or resumes *every* channel, including environmental reverb.
void SetInactive (bool inactive);
@ -57,7 +57,7 @@ public:
void DrawWaveDebug(int mode);
private:
bool SFXPaused;
int SFXPaused;
bool InitSuccess;
bool DSPLocked;
QWORD_UNION DSPClock;

View file

@ -174,7 +174,7 @@ public:
}
// Pauses or resumes all sound effect channels.
void SetSfxPaused (bool paused)
void SetSfxPaused (bool paused, int slot)
{
}

View file

@ -102,7 +102,7 @@ public:
virtual void Sync (bool sync) = 0;
// Pauses or resumes all sound effect channels.
virtual void SetSfxPaused (bool paused) = 0;
virtual void SetSfxPaused (bool paused, int slot) = 0;
// Pauses or resumes *every* channel, including environmental reverb.
virtual void SetInactive(bool inactive) = 0;

View file

@ -523,17 +523,24 @@ struct snprintf_state
char *buffer;
size_t maxlen;
size_t curlen;
bool overflow;
int ideallen;
};
static int myvsnprintf_helper(void *data, const char *cstr, int cstr_len)
{
snprintf_state *state = (snprintf_state *)data;
if (INT_MAX - state->ideallen > cstr_len)
{
state->ideallen = INT_MAX;
}
else
{
state->ideallen += cstr_len;
}
if (state->curlen + cstr_len > state->maxlen)
{
cstr_len = (int)(state->maxlen - state->curlen);
state->overflow = true;
}
if (cstr_len > 0)
{
@ -543,14 +550,28 @@ static int myvsnprintf_helper(void *data, const char *cstr, int cstr_len)
return cstr_len;
}
// Unlike the standard C library function snprintf, this one always writes
// a terminating null character to the buffer.
// Unlike the MS CRT function snprintf, this one always writes a terminating
// null character to the buffer. It also returns the full length of the string
// that would have been output if the buffer had been large enough. In other
// words, it follows BSD/Linux rules and not MS rules.
int myvsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
{
snprintf_state state = { buffer, count - 1, 0, false };
size_t originalcount = count;
if (count != 0)
{
count--;
}
if (count > INT_MAX)
{
count = INT_MAX;
}
snprintf_state state = { buffer, count, 0, 0 };
StringFormat::VWorker(myvsnprintf_helper, &state, format, argptr);
buffer[state.curlen] = '\0';
return state.overflow ? -1 : (int)state.curlen;
if (originalcount > 0)
{
buffer[state.curlen] = '\0';
}
return state.ideallen;
}
int mysnprintf(char *buffer, size_t count, const char *format, ...)

View file

@ -2,15 +2,15 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}"
ProjectSection(ProjectDependencies) = postProject
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} = {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}
{8997289F-10BF-4678-8BAA-3BB509C84953} = {8997289F-10BF-4678-8BAA-3BB509C84953}
{E83FD370-2E72-4D4C-9427-FF9D9DED1E88} = {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}
{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}
{6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
{DA47396F-60C1-4BDE-A977-7F7DE461CF77} = {DA47396F-60C1-4BDE-A977-7F7DE461CF77}
{1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F}
{DA47396F-60C1-4BDE-A977-7F7DE461CF77} = {DA47396F-60C1-4BDE-A977-7F7DE461CF77}
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859}
{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}
{E83FD370-2E72-4D4C-9427-FF9D9DED1E88} = {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}
{8997289F-10BF-4678-8BAA-3BB509C84953} = {8997289F-10BF-4678-8BAA-3BB509C84953}
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} = {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}"
@ -21,8 +21,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "re2c", "tools\re2c\re2c.vcp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wadsrc", "wadsrc\wadsrc.vcproj", "{1D179D4B-F008-431B-8C72-111F8372584F}"
ProjectSection(ProjectDependencies) = postProject
{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}
{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}
{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\makewad.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}"
@ -32,8 +32,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\ma
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dehsupp", "tools\dehsupp\dehsupp.vcproj", "{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}"
ProjectSection(ProjectDependencies) = postProject
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updaterevision", "tools\updaterevision\updaterevision.vcproj", "{6077B7D6-349F-4077-B552-3BC302EF5859}"
@ -46,6 +46,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "snes_spc", "snes_spc\snes_s
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumb_static", "dumb\vc6\dumb_static\dumb_static.vcproj", "{8997289F-10BF-4678-8BAA-3BB509C84953}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtoa", "gdtoa\gdtoa.vcproj", "{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -150,6 +152,12 @@ Global
{8997289F-10BF-4678-8BAA-3BB509C84953}.Release|Win32.Build.0 = Release|Win32
{8997289F-10BF-4678-8BAA-3BB509C84953}.Release|x64.ActiveCfg = Release|x64
{8997289F-10BF-4678-8BAA-3BB509C84953}.Release|x64.Build.0 = Release|x64
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Debug|Win32.ActiveCfg = Debug|Win32
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Debug|Win32.Build.0 = Debug|Win32
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Debug|x64.ActiveCfg = Debug|Win32
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Release|Win32.ActiveCfg = Release|Win32
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Release|Win32.Build.0 = Release|Win32
{B7B527BB-DC3A-41EF-96E5-7B057DE8BF9D}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE