Skip to content

Commit

Permalink
Save-state: correctly stop & play Mockingboard sound buffer across sa…
Browse files Browse the repository at this point in the history
…ve-state loading transition (#609)
  • Loading branch information
tomcw committed Feb 24, 2019
1 parent de3f0d8 commit be81458
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 22 deletions.
51 changes: 31 additions & 20 deletions source/Mockingboard.cpp
Expand Up @@ -1418,10 +1418,15 @@ void MB_Initialize()
g_bCritSectionValid = true;
}

void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType);

// NB. Mockingboard voice is *already* muted because showing 'Select Load State file' dialog
// . and voice will be demuted when dialog is closed
void MB_InitializeForLoadingSnapshot() // GH#609
{
MB_Reset();
InitSoundcardType();
MockingboardVoice.lpDSBvoice->Stop(); // Reason: 'MB voice is playing' then loading a save-state where 'no MB present'
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1629,6 +1634,26 @@ static BYTE __stdcall PhasorIO(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL

//-----------------------------------------------------------------------------

SS_CARDTYPE MB_GetSoundcardType()
{
return g_SoundcardType;
}

static void MB_SetSoundcardType(const SS_CARDTYPE NewSoundcardType)
{
if (NewSoundcardType == g_SoundcardType)
return;

if (NewSoundcardType == CT_Empty)
MB_Mute(); // Call MB_Mute() before setting g_SoundcardType = CT_Empty

g_SoundcardType = NewSoundcardType;

g_bPhasorEnable = (g_SoundcardType == CT_Phasor);
}

//-----------------------------------------------------------------------------

void MB_InitializeIO(LPBYTE pCxRomPeripheral, UINT uSlot4, UINT uSlot5)
{
// Mockingboard: Slot 4 & 5
Expand All @@ -1650,6 +1675,12 @@ void MB_InitializeIO(LPBYTE pCxRomPeripheral, UINT uSlot4, UINT uSlot5)
RegisterIoHandler(uSlot5, IO_Null, IO_Null, MB_Read, MB_Write, NULL, NULL);

MB_SetSoundcardType(g_Slot4);

// Sound buffer may have been stopped by MB_InitializeForLoadingSnapshot().
// NB. DSZeroVoiceBuffer() also zeros the sound buffer, so it's better than directly calling IDirectSoundBuffer::Play():
// - without zeroing, then the previous sound buffer can be heard for a fraction of a second
// - eg. when doing Mockingboard playback, then loading a save-state which is also doing Mockingboard playback
DSZeroVoiceBuffer(&MockingboardVoice, "MB", g_dwDSBufferSize);
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1789,26 +1820,6 @@ void MB_UpdateCycles(ULONG uExecutedCycles)

//-----------------------------------------------------------------------------

SS_CARDTYPE MB_GetSoundcardType()
{
return g_SoundcardType;
}

void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType)
{
if (g_SoundcardType == NewSoundcardType)
return;

g_SoundcardType = NewSoundcardType;

if(g_SoundcardType == CT_Empty)
MB_Mute();

g_bPhasorEnable = (g_SoundcardType == CT_Phasor);
}

//-----------------------------------------------------------------------------

static double MB_GetFramePeriod(void)
{
// TODO: Ideally remove this (slot-4) Phasor-IFR check: [*1]
Expand Down
1 change: 0 additions & 1 deletion source/Mockingboard.h
Expand Up @@ -13,7 +13,6 @@ void MB_EndOfVideoFrame();
void MB_CheckIRQ();
void MB_UpdateCycles(ULONG uExecutedCycles);
SS_CARDTYPE MB_GetSoundcardType();
void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType);
bool MB_IsActive();
DWORD MB_GetVolume();
void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
Expand Down
2 changes: 1 addition & 1 deletion source/SoundCore.cpp
Expand Up @@ -419,7 +419,7 @@ void SoundCore_SetFade(eFADE FadeType)
if(g_nAppMode == MODE_DEBUG)
return;

// Fade in/out just for speaker, the others are demuted/muted
// Fade in/out for speaker, the others are demuted/muted here
if(FadeType != FADE_NONE)
{
for(UINT i=0; i<g_uNumVoices; i++)
Expand Down

0 comments on commit be81458

Please sign in to comment.