/* Sound code copied from Water Tower */ #include "SoundManager.h" #include "Settings.h" void InitSoundManager(VSoundManager * sm) { OSErr error; int wSound; sm->NumberOfSounds = NUMBEROFSOUNDS; sm->SoundAvailable = 1; sm->Sounds = (VSound *) NewPtr(sizeof(VSound) * sm->NumberOfSounds); for (wSound = 0; wSound < sm->NumberOfSounds; wSound++) { error = LoadSound(&sm->Sounds[wSound], (wSound + BASESOUNDRESID)); if (error != noErr) { sm->SoundAvailable = 0; break; } } error = AllocateSoundChannels(sm); if (error != noErr) { sm->SoundAvailable = 0; } sm->CurrentSoundChannel = 0; } void CleanUpSoundManager(VSoundManager * sm) { int wSound; CleanUpSoundChannels(sm); for (wSound = 0; wSound < sm->NumberOfSounds; wSound++) { CleanUpSound(&sm->Sounds[wSound]); } DisposePtr((Ptr) sm->Sounds); } void SuspendSoundManager(VSoundManager * sm) { CleanUpSoundChannels(sm); } void ResumeSoundManager(VSoundManager * sm) { OSErr error; error = AllocateSoundChannels(sm); if (error != noErr) { sm->SoundAvailable = 0; } } OSErr AllocateSoundChannels(VSoundManager * sm) { OSErr error; short wChannel; for (wChannel = 0; wChannel < NUMBEROFSOUNDCHANNELS; wChannel++) { sm->SoundChannels[wChannel] = (SndChannelPtr) NewPtr(sizeof(SndChannel)); if (sm->SoundChannels[wChannel] == NULL) return memFullErr; sm->SoundChannels[wChannel]->qLength = 6; error = SndNewChannel(&sm->SoundChannels[wChannel], sampledSynth, initMono, NULL); if (error != noErr) { while (wChannel > 0) { wChannel--; DisposePtr((Ptr) sm->SoundChannels[wChannel]); sm->SoundChannels[wChannel] = NULL; } return error; } } return noErr; } void CleanUpSoundChannels(VSoundManager * sm) { short wChannel; SndCommand cmd; for (wChannel = 0; wChannel < NUMBEROFSOUNDCHANNELS; wChannel++) { if (sm->SoundChannels[wChannel] != NULL) { cmd.cmd = flushCmd; cmd.param1 = 0; cmd.param2 = 0; SndDoImmediate(sm->SoundChannels[wChannel], &cmd); cmd.cmd = quietCmd; SndDoImmediate(sm->SoundChannels[wChannel], &cmd); SndDisposeChannel(sm->SoundChannels[wChannel], 1); DisposePtr((Ptr) sm->SoundChannels[wChannel]); sm->SoundChannels[wChannel] = NULL; } } } OSErr LoadSound(VSound * s, int ResID) { OSErr error; s->ResID = ResID; s->sndList = (SndListHandle) GetResource('snd ', ResID); error = ResError(); if (s->sndList == NULL || error != noErr) { if (error != noErr) error = memFullErr; /* Paranoia */ return error; } HLock((Handle) s->sndList); return noErr; } void CleanUpSound(VSound * s) { if (s->sndList != NULL) { ReleaseResource((Handle) s->sndList); s->sndList = NULL; } } void PlaySound(VSoundManager * sm, int soundID) { OSErr error; SndCommand cmd; long offset; VSettings * s; s = GetSettings(); if (!sm->SoundAvailable || !s->SoundEnabled || sm->SoundChannels[sm->CurrentSoundChannel] == NULL) return; if (soundID >= NUMBEROFSOUNDS || soundID < 0) return; cmd.cmd = flushCmd; cmd.param1 = 0; cmd.param2 = 0; SndDoImmediate(sm->SoundChannels[sm->CurrentSoundChannel], &cmd); cmd.cmd = quietCmd; SndDoImmediate(sm->SoundChannels[sm->CurrentSoundChannel], &cmd); error = GetSoundHeaderOffset(sm->Sounds[soundID].sndList, &offset); if (error != noErr) return; cmd.cmd = bufferCmd; cmd.param1 = 0; cmd.param2 = (long) ((Ptr) *sm->Sounds[soundID].sndList + offset); SndDoCommand(sm->SoundChannels[sm->CurrentSoundChannel], &cmd, 0); sm->CurrentSoundChannel++; if (sm->CurrentSoundChannel >= NUMBEROFSOUNDCHANNELS) sm->CurrentSoundChannel = 0; } Boolean AnySoundsPlaying(VSoundManager * sm) { short wChannel; OSErr error; SCStatus status; for (wChannel = 0; wChannel < NUMBEROFSOUNDCHANNELS; wChannel++) { error = SndChannelStatus(sm->SoundChannels[wChannel], sizeof(SCStatus), &status); if (error == noErr) { if (status.scChannelBusy) return 1; } } return 0; } VSoundManager * GetSoundManager() { static VSoundManager * sm = NULL; if (sm == NULL) { sm = (VSoundManager *) NewPtr(sizeof(VSoundManager)); InitSoundManager(sm); } return sm; }