home *** CD-ROM | disk | FTP | other *** search
- #define SOUNDPLAY_C
- #include "SoundPlay.h"
- #undef SOUNDPLAY_C
-
-
- #pragma segment More
-
-
- static Boolean gSoundAsync = true;
- static SndChannelPtr gChannel = nil;
-
-
- void
- SndPlayMove (BoardPtr board, FieldsPtr move, short direction)
- {
- short balls = 0;
- Field cur;
-
- // Count the number of balls moved.
-
- for (cur = move[0]; cur != 0 && board->field[cur] != empty; cur = Neighbour (cur, direction))
- balls++;
-
- // Play the right resource for the number of balls moved:
- // The sound resources are ordered; 10001 = 1 ball, 10002 = 2 balls etc.
-
- PlayResource (& gChannel, 10000 + balls);
- }
-
-
-
- void
- SndPlayFlicheMove (BoardPtr board, FieldsPtr move, short direction)
- {
- #if ! defined(__SC__) && ! defined (__MWERKS__)
- #pragma unused (board, direction)
- #endif
-
- // Play the right resource for the number of balls moved:
- // The sound resources are ordered; 20001 = fliche of 2, 20003 = fliche of 3. */
-
- PlayResource (& gChannel, move[2] ? 20003 : 20002);
- }
-
-
-
- void
- SndPlayBallDown (void)
- {
- // Play the resource for a downed ball.
-
- PlayResource (& gChannel, 10000);
- }
-
-
-
- void
- SndPlayBeep (void)
- {
- SndDisposeChannels();
- SysBeep (1);
- }
-
-
-
- SndChannelPtr
- CreateSoundChannel (void)
- {
- # define TURNOFF { Warning (SOUND_TURNED_OFF); DisposeSoundChannel (& channel); gSet.SoundOn = false; return nil; }
- SndChannelPtr channel = nil;
-
- // Problem: to play async, a channel must be allocated and passed to SndPlay.
- // On a Plus, SndPlay seems unwilling to play compressed sounds async,
- // and even to play them at all, if a non-nil channel is passed to it.
- // The unelegant solution I found for this works as follows:
- // First, I create a sound channel, pass it to SndPlay,
- // and if the result tells me not enough hardware is present,
- // I dispose the channel and (automatically, since channel is nil) switch to synchronous play
- // gSoundAsync tells me if it is still worth trying to play async.
-
- if (gSoundAsync)
- {
- // Try to open a sampled sound synthesizer with MACE3 decompression
-
- OSErr error;
- short initParam = initMACE3 + initMono + initNoInterp;
- SndCommand testCmd = { availableCmd, 0, initMACE3 };
-
- if ((error = SndControl (sampledSynth, & testCmd)) != noErr)
- TURNOFF;
-
- if (testCmd.param2 == 0)
- initParam -= initMACE3;
-
- if ((error = SndNewChannel (& channel, sampledSynth, initParam, nil)) != noErr || channel == nil)
- TURNOFF;
- }
- return channel;
- }
-
-
-
- void
- SndDisposeChannels (void)
- {
- DisposeSoundChannel (& gChannel);
- }
-
-
-
- void
- DisposeSoundChannel (SndChannelPtr *channel)
- {
- if (*channel == nil)
- return;
-
- (void) SndDisposeChannel (*channel, false);
- *channel = nil;
- }
-
-
-
- Boolean
- PlayResource (SndChannelPtr *channel, short resID)
- {
- Handle sound;
- OSErr error;
-
- // Set up the sound channel
-
- if (gSoundAsync && gChannel != nil)
- {
- SCStatus status;
- OSErr error;
-
- error = SndChannelStatus (gChannel, sizeof (SCStatus), & status);
- if (status.scChannelBusy)
- DisposeSoundChannel (& gChannel);
- }
- if (gSoundAsync && gChannel == nil)
- gChannel = CreateSoundChannel();
-
- // Get the requested sound resource
-
- if ((sound = GetResource ('snd ', resID)) == nil)
- {
- Warning (SND_RESOURCE_MISSING);
- DisposeSoundChannel (channel);
- gSet.SoundOn = false;
- return false;
- }
-
- // Try to play the sound; if (still) gSoundAsync, try asynchronous.
-
- MoveHHi (sound);
- HNoPurge (sound);
- HLock (sound);
-
- #if defined(THINK_C)
- error = SndPlay (*channel, sound, gSoundAsync);
- #else
- error = SndPlay (*channel, (SndListHandle) sound, gSoundAsync);
- #endif
-
- HUnlock (sound);
- HPurge (sound);
-
- if (error != noErr)
- {
- // if an error occurred, see if this is a result of trying to play asynchronous
- // on a Mac that does not seem to support this */
-
- if (gSoundAsync && (error == -200 || error == -201)) // yep, not enough hardware error
- {
- // Switch to synchronous; dispose of the channel.
- // Don't bother telling the user:
- // he/she has no choise in the matter.
-
- DisposeSoundChannel (channel);
- gSoundAsync = false;
- return PlayResource (channel, resID); // recursive call, with gSoundAsync changed
- }
- else
- {
- // worse yet than 'not enough hardware, so turn sound off completely.
-
- Warning (SOUND_TURNED_OFF);
- DisposeSoundChannel (channel);
- gSet.SoundOn = false;
- return false;
- }
- }
- return true;
- }