Files
Aerofoil/GpApp/Sound.cpp

411 lines
8.9 KiB
C++
Raw Normal View History

2019-11-11 00:11:59 -05:00
//============================================================================
//----------------------------------------------------------------------------
// Sound.c
//----------------------------------------------------------------------------
//============================================================================
#include "PLResources.h"
#include "PLSound.h"
#include "Externs.h"
2019-12-31 04:49:38 -05:00
#include "MemoryManager.h"
2019-12-12 23:37:40 -05:00
#include "SoundSync.h"
2019-12-29 06:38:18 -05:00
#include "VirtualDirectory.h"
2019-11-11 00:11:59 -05:00
#define kBaseBufferSoundID 1000
#define kMaxSounds 64
2019-12-31 04:49:38 -05:00
void CallBack0 (PortabilityLayer::AudioChannel *);
void CallBack1 (PortabilityLayer::AudioChannel *);
void CallBack2 (PortabilityLayer::AudioChannel *);
2019-12-29 06:38:18 -05:00
PLError_t LoadBufferSounds (void);
2019-11-11 00:11:59 -05:00
void DumpBufferSounds (void);
2019-12-29 06:38:18 -05:00
PLError_t OpenSoundChannels (void);
2019-12-31 04:49:38 -05:00
void CloseSoundChannels (void);
2019-11-11 00:11:59 -05:00
2019-12-31 04:49:38 -05:00
PortabilityLayer::AudioChannel *channel0, *channel1, *channel2;
2019-11-11 00:11:59 -05:00
Ptr theSoundData[kMaxSounds];
2019-12-12 23:37:40 -05:00
short numSoundsLoaded;
2019-11-11 00:11:59 -05:00
Boolean soundLoaded[kMaxSounds], dontLoadSounds;
Boolean channelOpen, isSoundOn, failedSound;
//============================================================== Functions
//-------------------------------------------------------------- PlayPrioritySound
void PlayPrioritySound (short which, short priority)
{
short lowestPriority, whosLowest;
if (failedSound || dontLoadSounds)
return;
2019-12-12 23:37:40 -05:00
SoundSyncState ss = SoundSync_ReadAll();
2019-11-11 00:11:59 -05:00
if ((priority == kTriggerPriority) &&
2019-12-12 23:37:40 -05:00
((ss.priority0 == kTriggerPriority) ||
((ss.priority1 == kTriggerPriority)) ||
((ss.priority2 == kTriggerPriority))))
2019-11-11 00:11:59 -05:00
return;
whosLowest = 0;
2019-12-12 23:37:40 -05:00
lowestPriority = ss.priority0;
2019-11-11 00:11:59 -05:00
2019-12-12 23:37:40 -05:00
if (ss.priority1 < lowestPriority)
2019-11-11 00:11:59 -05:00
{
2019-12-12 23:37:40 -05:00
lowestPriority = ss.priority1;
2019-11-11 00:11:59 -05:00
whosLowest = 1;
}
2019-12-12 23:37:40 -05:00
if (ss.priority2 < lowestPriority)
2019-11-11 00:11:59 -05:00
{
2019-12-12 23:37:40 -05:00
lowestPriority = ss.priority2;
2019-11-11 00:11:59 -05:00
whosLowest = 2;
}
if (priority >= lowestPriority)
{
2019-12-12 23:37:40 -05:00
PlayExclusiveSoundChannel(whosLowest, which, lowestPriority, priority);
2019-11-11 00:11:59 -05:00
}
}
//-------------------------------------------------------------- FlushAnyTriggerPlaying
void FlushAnyTriggerPlaying (void)
{
2019-12-12 23:37:40 -05:00
SoundSyncState ss = SoundSync_ReadAll();
2019-11-11 00:11:59 -05:00
2019-12-12 23:37:40 -05:00
if (ss.priority0 == kTriggerPriority)
2019-11-11 00:11:59 -05:00
{
2019-12-31 04:49:38 -05:00
channel0->ClearAllCommands();
channel0->Stop();
2019-11-11 00:11:59 -05:00
}
2019-12-12 23:37:40 -05:00
if (ss.priority1 == kTriggerPriority)
2019-11-11 00:11:59 -05:00
{
2019-12-31 04:49:38 -05:00
channel1->ClearAllCommands();
channel1->Stop();
2019-11-11 00:11:59 -05:00
}
2019-12-12 23:37:40 -05:00
if (ss.priority2 == kTriggerPriority)
2019-11-11 00:11:59 -05:00
{
2019-12-31 04:49:38 -05:00
channel2->ClearAllCommands();
channel2->Stop();
2019-11-11 00:11:59 -05:00
}
}
2019-12-31 04:49:38 -05:00
//-------------------------------------------------------------- CallBack0
void CallBack0(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(0);
}
//-------------------------------------------------------------- CallBack1
void CallBack1(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(1);
}
//-------------------------------------------------------------- CallBack2
void CallBack2(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(2);
}
2019-11-11 00:11:59 -05:00
//-------------------------------------------------------------- PlaySound0
2019-12-12 23:37:40 -05:00
void PlayExclusiveSoundChannel(short channelIndex, short soundID, short oldPriority, short newPriority)
2019-12-31 04:49:38 -05:00
{
2019-11-11 00:11:59 -05:00
if (failedSound || dontLoadSounds)
return;
2019-12-12 23:37:40 -05:00
2019-12-31 04:49:38 -05:00
PortabilityLayer::AudioChannel *channel = nil;
PortabilityLayer::AudioChannelCallback_t callback = nil;
2019-12-12 23:37:40 -05:00
switch (channelIndex)
2019-11-11 00:11:59 -05:00
{
2019-12-12 23:37:40 -05:00
case 0:
channel = channel0;
2019-12-31 04:49:38 -05:00
callback = CallBack0;
2019-12-12 23:37:40 -05:00
break;
case 1:
2019-12-31 04:49:38 -05:00
channel = channel1;
callback = CallBack1;
2019-12-12 23:37:40 -05:00
break;
case 2:
channel = channel2;
2019-12-31 04:49:38 -05:00
callback = CallBack2;
2019-12-12 23:37:40 -05:00
break;
default:
return;
2019-11-11 00:11:59 -05:00
}
if (isSoundOn)
{
2019-12-12 23:37:40 -05:00
if (oldPriority != 0)
{
// Flush the queue and stop the channel, which will remove the pending callback
2019-12-31 04:49:38 -05:00
channel->ClearAllCommands();
channel->Stop();
2019-12-12 23:37:40 -05:00
SoundSync_ClearPriority(channelIndex);
}
2019-11-11 00:11:59 -05:00
2019-12-12 23:37:40 -05:00
SoundSync_PutPriority(channelIndex, newPriority);
2019-11-11 00:11:59 -05:00
2019-12-31 04:49:38 -05:00
bool succeeded = channel->AddBuffer(theSoundData[soundID], false);
succeeded &= channel->AddCallback(callback, false);
2019-11-11 00:11:59 -05:00
2019-12-31 04:49:38 -05:00
if (!succeeded)
2019-12-12 23:37:40 -05:00
SoundSync_ClearPriority(channelIndex);
2019-11-11 00:11:59 -05:00
}
}
//-------------------------------------------------------------- LoadTriggerSound
2019-12-29 06:38:18 -05:00
PLError_t LoadTriggerSound (short soundID)
2019-11-11 00:11:59 -05:00
{
Handle theSound;
long soundDataSize;
2019-12-29 06:38:18 -05:00
PLError_t theErr;
2019-11-11 00:11:59 -05:00
if ((dontLoadSounds) || (theSoundData[kMaxSounds - 1] != nil))
2019-12-29 06:38:18 -05:00
theErr = PLErrors::kFileNotFound;
2019-11-11 00:11:59 -05:00
else
{
// FlushAnyTriggerPlaying();
2019-12-29 06:38:18 -05:00
theErr = PLErrors::kNone;
2019-11-11 00:11:59 -05:00
theSound = GetResource('snd ', soundID);
if (theSound == nil)
{
2019-12-29 06:38:18 -05:00
theErr = PLErrors::kFileNotFound;
2019-11-11 00:11:59 -05:00
}
else
{
soundDataSize = GetHandleSize(theSound) - 20L;
2019-12-31 04:49:38 -05:00
theSoundData[kMaxSounds - 1] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
2019-11-11 00:11:59 -05:00
if (theSoundData[kMaxSounds - 1] == nil)
{
2019-12-29 23:14:37 -05:00
theSound.Dispose();
2019-12-29 06:38:18 -05:00
theErr = PLErrors::kOutOfMemory;
2019-11-11 00:11:59 -05:00
}
else
{
BlockMove((Ptr)((Byte*)(*theSound) + 20L), theSoundData[kMaxSounds - 1], soundDataSize);
2019-12-29 23:14:37 -05:00
theSound.Dispose();
2019-11-11 00:11:59 -05:00
}
}
}
return (theErr);
}
//-------------------------------------------------------------- DumpTriggerSound
void DumpTriggerSound (void)
{
if (theSoundData[kMaxSounds - 1] != nil)
2019-12-31 04:49:38 -05:00
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[kMaxSounds - 1]);
2019-11-11 00:11:59 -05:00
theSoundData[kMaxSounds - 1] = nil;
}
//-------------------------------------------------------------- LoadBufferSounds
2019-12-29 06:38:18 -05:00
PLError_t LoadBufferSounds (void)
2019-11-11 00:11:59 -05:00
{
Handle theSound;
long soundDataSize;
2019-12-29 06:38:18 -05:00
PLError_t theErr;
2019-11-11 00:11:59 -05:00
short i;
2019-12-29 06:38:18 -05:00
theErr = PLErrors::kNone;
2019-11-11 00:11:59 -05:00
for (i = 0; i < kMaxSounds - 1; i++)
{
theSound = GetResource('snd ', i + kBaseBufferSoundID);
if (theSound == nil)
2019-12-29 06:38:18 -05:00
return (PLErrors::kOutOfMemory);
2019-11-11 00:11:59 -05:00
soundDataSize = GetHandleSize(theSound) - 20L;
2019-12-31 04:49:38 -05:00
theSoundData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
2019-11-11 00:11:59 -05:00
if (theSoundData[i] == nil)
2019-12-29 06:38:18 -05:00
return (PLErrors::kOutOfMemory);
2019-11-11 00:11:59 -05:00
BlockMove((Ptr)((Byte*)(*theSound) + 20L), theSoundData[i], soundDataSize);
2019-12-29 23:14:37 -05:00
theSound.Dispose();
2019-11-11 00:11:59 -05:00
}
theSoundData[kMaxSounds - 1] = nil;
return (theErr);
}
//-------------------------------------------------------------- DumpBufferSounds
void DumpBufferSounds (void)
{
short i;
for (i = 0; i < kMaxSounds; i++)
{
if (theSoundData[i] != nil)
2019-12-31 04:49:38 -05:00
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[i]);
2019-11-11 00:11:59 -05:00
theSoundData[i] = nil;
}
}
//-------------------------------------------------------------- OpenSoundChannels
2019-12-29 06:38:18 -05:00
PLError_t OpenSoundChannels (void)
2019-11-11 00:11:59 -05:00
{
if (channelOpen)
2019-12-31 04:49:38 -05:00
return PLErrors::kAudioError;
2019-11-11 00:11:59 -05:00
2019-12-31 04:49:38 -05:00
channel0 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel0)
2019-11-11 00:11:59 -05:00
channelOpen = true;
else
2019-12-31 04:49:38 -05:00
return PLErrors::kAudioError;
channel1 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel1)
2019-11-11 00:11:59 -05:00
channelOpen = true;
else
2019-12-31 04:49:38 -05:00
return PLErrors::kAudioError;
channel2 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel2)
2019-11-11 00:11:59 -05:00
channelOpen = true;
2019-12-31 04:49:38 -05:00
else
return PLErrors::kAudioError;
2019-11-11 00:11:59 -05:00
2019-12-31 04:49:38 -05:00
return PLErrors::kNone;
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- CloseSoundChannels
2019-12-31 04:49:38 -05:00
void CloseSoundChannels (void)
2019-11-11 00:11:59 -05:00
{
if (!channelOpen)
2019-12-31 04:49:38 -05:00
return;
2019-11-11 00:11:59 -05:00
if (channel0 != nil)
2019-12-31 04:49:38 -05:00
channel0->Destroy(false);
2019-11-11 00:11:59 -05:00
channel0 = nil;
if (channel1 != nil)
2019-12-31 04:49:38 -05:00
channel1->Destroy(false);
2019-11-11 00:11:59 -05:00
channel1 = nil;
if (channel2 != nil)
2019-12-31 04:49:38 -05:00
channel2->Destroy(false);
2019-11-11 00:11:59 -05:00
channel2 = nil;
2019-12-31 04:49:38 -05:00
channelOpen = false;
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- InitSound
void InitSound (void)
{
2019-12-29 06:38:18 -05:00
PLError_t theErr;
2019-11-11 00:11:59 -05:00
if (dontLoadSounds)
return;
failedSound = false;
channel0 = nil;
channel1 = nil;
channel2 = nil;
2019-12-12 23:37:40 -05:00
SoundSync_ClearPriority(0);
SoundSync_ClearPriority(1);
SoundSync_ClearPriority(2);
2019-11-11 00:11:59 -05:00
theErr = LoadBufferSounds();
2019-12-29 06:38:18 -05:00
if (theErr != PLErrors::kNone)
2019-11-11 00:11:59 -05:00
{
YellowAlert(kYellowFailedSound, theErr);
failedSound = true;
}
if (!failedSound)
{
theErr = OpenSoundChannels();
2019-12-29 06:38:18 -05:00
if (theErr != PLErrors::kNone)
2019-11-11 00:11:59 -05:00
{
YellowAlert(kYellowFailedSound, theErr);
failedSound = true;
}
}
}
//-------------------------------------------------------------- KillSound
void KillSound (void)
{
if (dontLoadSounds)
return;
DumpBufferSounds();
2019-12-31 04:49:38 -05:00
CloseSoundChannels();
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- SoundBytesNeeded
long SoundBytesNeeded (void)
{
Handle theSound;
long totalBytes;
short i;
totalBytes = 0L;
SetResLoad(false);
for (i = 0; i < kMaxSounds - 1; i++)
{
theSound = GetResource('snd ', i + kBaseBufferSoundID);
if (theSound == nil)
{
SetResLoad(true);
2019-12-29 22:12:11 -05:00
return -1;
2019-11-11 00:11:59 -05:00
}
totalBytes += GetMaxResourceSize(theSound);
// ReleaseResource(theSound);
}
SetResLoad(true);
return totalBytes;
}
//-------------------------------------------------------------- TellHerNoSounds
void TellHerNoSounds (void)
{
#define kNoMemForSoundsAlert 1039
short hitWhat;
// CenterAlert(kNoMemForSoundsAlert);
hitWhat = Alert(kNoMemForSoundsAlert, nil);
}
//-------------------------------------------------------------- BitchAboutSM3
void BitchAboutSM3 (void)
{
#define kNoSoundManager3Alert 1030
short hitWhat;
// CenterAlert(kNoSoundManager3Alert);
hitWhat = Alert(kNoSoundManager3Alert, nil);
}