/* Sound code copied from Water Tower */ #include "SoundManager.h" #include "Settings.h" #include 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); 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; } } } static char * fileNameForSound(int soundID) { switch (soundID) { case PLAYERSHOTSOUND: return "player_shot.m4a"; case ENEMYSHOTSOUND: return "enemy_shot.m4a"; case ROCKETTARGETSOUND: return "rocket_target.m4a"; case EXPLOSIONSOUND: return "explosion.m4a"; case IMPACTSOUND: return "impact.m4a"; case LAUNCHROCKETSOUND: return "rocket.m4a"; case ROCKETEXPLODESOUND: return "rocket_explode.m4a"; case PLAYERHITSOUND: return "player_hit.m4a"; case ENEMYHITSOUND: return "enemy_hit.m4a"; case GETPOWERUPSOUND: return "powerup.m4a"; } return ""; } OSErr LoadSound(VSound * s, int ResID) { OSErr error; FSSpec fileSpec; FSRef fileRef; CFURLRef URL; CFBundleRef bundle; CFStringRef string; short refNum; Track track; Movie movie; s->ResID = ResID; string = CFStringCreateWithCString(NULL, fileNameForSound(ResID), kCFStringEncodingUTF8); bundle = CFBundleGetMainBundle(); URL = CFBundleCopyResourceURL(bundle, string, NULL, NULL); if (URL) { CFURLGetFSRef(URL, &fileRef); error = FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL); CFRelease(URL); } else { error = fnfErr; } CFRelease(string); if (error != noErr) return error; error = EnterMovies(); if (error == noErr) { error = OpenMovieFile(&fileSpec, &refNum, fsRdPerm); if (error == noErr) { error = NewMovieFromFile(&movie, refNum, NULL, NULL, newMovieActive, NULL); if (error == noErr) track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic, (movieTrackCharacteristic | movieTrackEnabledOnly)); if (track != NULL) { s->sndList = (SndListHandle) NewHandle(0); if (s->sndList != NULL) { error = PutMovieIntoTypedHandle(movie, track, soundListRsrc, (Handle) s->sndList, 0, GetTrackDuration(track), 0, NULL); if (error != noErr) { DisposeHandle((Handle) s->sndList); } } DisposeMovieTrack(track); } CloseMovieFile(refNum); } DisposeMovie(movie); ExitMovies(); } return error; } /* 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; }