Fix music mode change thread safety

This commit is contained in:
elasota
2019-12-26 13:12:56 -05:00
parent c4e93b0ccf
commit b9f1d5222f
2 changed files with 55 additions and 30 deletions

View File

@@ -11,6 +11,9 @@
#include "PLSound.h" #include "PLSound.h"
#include "Environ.h" #include "Environ.h"
#include "Externs.h" #include "Externs.h"
#include "SoundSync.h"
#include "HostMutex.h"
#include "HostSystemServices.h"
#define kBaseBufferMusicID 2000 #define kBaseBufferMusicID 2000
@@ -29,13 +32,22 @@ OSErr CloseMusicChannel (void);
SndCallBackUPP musicCallBackUPP; SndCallBackUPP musicCallBackUPP;
SndChannelPtr musicChannel; SndChannelPtr musicChannel;
Ptr theMusicData[kMaxMusic]; Ptr theMusicData[kMaxMusic];
short musicSoundID, musicCursor;
short musicScore[kLastMusicPiece]; short musicScore[kLastMusicPiece];
short gameScore[kLastGamePiece]; short gameScore[kLastGamePiece];
short musicMode;
Boolean isMusicOn, isPlayMusicIdle, isPlayMusicGame; Boolean isMusicOn, isPlayMusicIdle, isPlayMusicGame;
Boolean failedMusic, dontLoadMusic; Boolean failedMusic, dontLoadMusic;
// Anything accessed from this must do so under the mutex lock, unless music is stopped
struct MusicState
{
short musicMode;
short musicSoundID, musicCursor;
};
MusicState musicState;
PortabilityLayer::HostMutex *musicMutex;
extern Boolean isSoundOn; extern Boolean isSoundOn;
@@ -53,13 +65,16 @@ OSErr StartMusic (void)
if (dontLoadMusic) if (dontLoadMusic)
return(theErr); return(theErr);
if (musicMutex == nullptr)
return(theErr);
UnivGetSoundVolume(&soundVolume, thisMac.hasSM3); UnivGetSoundVolume(&soundVolume, thisMac.hasSM3);
if ((soundVolume != 0) && (!failedMusic)) if ((soundVolume != 0) && (!failedMusic))
{ {
theCommand.cmd = bufferCmd; theCommand.cmd = bufferCmd;
theCommand.param1 = 0; theCommand.param1 = 0;
theCommand.param2 = (intptr_t)(theMusicData[musicSoundID]); theCommand.param2 = (intptr_t)(theMusicData[musicState.musicSoundID]);
theErr = SndDoCommand(musicChannel, &theCommand, false); theErr = SndDoCommand(musicChannel, &theCommand, false);
if (theErr != noErr) if (theErr != noErr)
return (theErr); return (theErr);
@@ -72,14 +87,14 @@ OSErr StartMusic (void)
if (theErr != noErr) if (theErr != noErr)
return (theErr); return (theErr);
musicCursor++; musicState.musicCursor++;
if (musicCursor >= kLastMusicPiece) if (musicState.musicCursor >= kLastMusicPiece)
musicCursor = 0; musicState.musicCursor = 0;
musicSoundID = musicScore[musicCursor]; musicState.musicSoundID = musicScore[musicState.musicCursor];
theCommand.cmd = bufferCmd; theCommand.cmd = bufferCmd;
theCommand.param1 = 0; theCommand.param1 = 0;
theCommand.param2 = (intptr_t)(theMusicData[musicSoundID]); theCommand.param2 = (intptr_t)(theMusicData[musicState.musicSoundID]);
theErr = SndDoCommand(musicChannel, &theCommand, false); theErr = SndDoCommand(musicChannel, &theCommand, false);
if (theErr != noErr) if (theErr != noErr)
return (theErr); return (theErr);
@@ -150,21 +165,23 @@ void SetMusicalMode (short newMode)
if (dontLoadMusic) if (dontLoadMusic)
return; return;
musicMutex->Lock();
switch (newMode) switch (newMode)
{ {
case kKickGameScoreMode: case kKickGameScoreMode:
musicCursor = 2; musicState.musicCursor = 2;
break; break;
case kProdGameScoreMode: case kProdGameScoreMode:
musicCursor = -1; musicState.musicCursor = -1;
break; break;
default: default:
musicMode = newMode; musicState.musicMode = newMode;
musicCursor = 0; musicState.musicCursor = 0;
break; break;
} }
musicMutex->Unlock();
} }
//-------------------------------------------------------------- MusicCallBack //-------------------------------------------------------------- MusicCallBack
@@ -176,32 +193,36 @@ void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand)
// gameA5 = theCommand.param2; // gameA5 = theCommand.param2;
// thisA5 = SetA5(gameA5); // thisA5 = SetA5(gameA5);
switch (musicMode) musicMutex->Lock();
switch (musicState.musicMode)
{ {
case kPlayGameScoreMode: case kPlayGameScoreMode:
musicCursor++; musicState.musicCursor++;
if (musicCursor >= kLastGamePiece) if (musicState.musicCursor >= kLastGamePiece)
musicCursor = 1; musicState.musicCursor = 1;
musicSoundID = gameScore[musicCursor]; musicState.musicSoundID = gameScore[musicState.musicCursor];
if (musicSoundID < 0) if (musicState.musicSoundID < 0)
{ {
musicCursor += musicSoundID; musicState.musicCursor += musicState.musicSoundID;
musicSoundID = gameScore[musicCursor]; musicState.musicSoundID = gameScore[musicState.musicCursor];
} }
break; break;
case kPlayWholeScoreMode: case kPlayWholeScoreMode:
musicCursor++; musicState.musicCursor++;
if (musicCursor >= kLastMusicPiece - 1) if (musicState.musicCursor >= kLastMusicPiece - 1)
musicCursor = 0; musicState.musicCursor = 0;
musicSoundID = musicScore[musicCursor]; musicState.musicSoundID = musicScore[musicState.musicCursor];
break; break;
default: default:
musicSoundID = musicMode; musicState.musicSoundID = musicState.musicMode;
break; break;
} }
short musicSoundID = musicState.musicSoundID;
musicMutex->Unlock();
theCommand->cmd = bufferCmd; theCommand->cmd = bufferCmd;
theCommand->param1 = 0; theCommand->param1 = 0;
theCommand->param2 = (intptr_t)(theMusicData[musicSoundID]); theCommand->param2 = (intptr_t)(theMusicData[musicSoundID]);
@@ -348,9 +369,11 @@ void InitMusic (void)
gameScore[4] = kPlayChorus; gameScore[4] = kPlayChorus;
gameScore[5] = kPlayChorus; gameScore[5] = kPlayChorus;
musicCursor = 0; musicState.musicCursor = 0;
musicSoundID = musicScore[musicCursor]; musicState.musicSoundID = musicScore[musicState.musicCursor];
musicMode = kPlayWholeScoreMode; musicState.musicMode = kPlayWholeScoreMode;
musicMutex = PortabilityLayer::HostSystemServices::GetInstance()->CreateMutex();
PL_NotYetImplemented_TODO("MusicSync"); PL_NotYetImplemented_TODO("MusicSync");
@@ -376,6 +399,7 @@ void KillMusic (void)
theErr = DumpMusicSounds(); theErr = DumpMusicSounds();
theErr = CloseMusicChannel(); theErr = CloseMusicChannel();
musicMutex->Destroy();
} }
//-------------------------------------------------------------- MusicBytesNeeded //-------------------------------------------------------------- MusicBytesNeeded

View File

@@ -13,3 +13,4 @@ struct SoundSyncState
SoundSyncState SoundSync_ReadAll(); SoundSyncState SoundSync_ReadAll();
void SoundSync_ClearPriority(int index); void SoundSync_ClearPriority(int index);
void SoundSync_PutPriority(int index, int16_t priority); void SoundSync_PutPriority(int index, int16_t priority);