1 /*	SCCS Id: @(#)macsnd.c	3.1	92/11/28	*/
2 /* 	Copyright (c) 1992 by Jon Watte */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 /*
6  * This file contains music playing code.
7  *
8  * If we were REALLY determinated, we would make the sound play
9  * asynchronously, but I'll save that one for a rainy day...
10  *
11  * This may break A/UX, since it defines MAC but we need to
12  * check that the toolbox is booted. I'll defer that one too.
13  *
14  * - h+ 921128
15  */
16 
17 #include "hack.h"
18 #include "mactty.h"
19 #include "macwin.h"
20 #if !TARGET_API_MAC_CARBON
21 # include <Sound.h>
22 # include <Resources.h>
23 #else
24 # define freqDurationCmd 40
25 #endif
26 
27 #define SND_BUFFER(s) (&(*s)[20])
28 #define SND_LEN(s) (GetHandleSize(s)-42)
29 
30 
31 void
mac_speaker(struct obj * instr,char * melody)32 mac_speaker (struct obj *instr, char *melody) {
33 	SndChannelPtr theChannel = (SndChannelPtr) 0;
34 	SndCommand theCmd;
35 	Handle theSound;
36 	unsigned char theName [32];
37 	char *n = (char *) &theName [1];
38 	int typ = instr->otyp;
39 	const char *actualn = OBJ_NAME (objects [typ]);
40 
41 	/*
42 	 * First: are we in the library ?
43 	 */
44 	if (flags.silent) {
45 		return;
46 	}
47 
48 	/*
49 	 * Is this a known instrument ?
50 	 */
51 	strcpy (n, actualn);
52 	theName [0] = strlen (n);
53 	theSound = GetNamedResource ('snd ', theName);
54 	if (! theSound) {
55 		return;
56 	}
57 	HLock (theSound);
58 
59 	/*
60 	 * Set up the synth
61 	 */
62 	if (SndNewChannel(&theChannel, sampledSynth, initMono +
63 		initNoInterp, (void *) 0) == noErr) {
64 		char midi_note [] = {57, 59, 60, 62, 64, 65, 67};
65 
66 		short err;
67 		short snd_len = SND_LEN (theSound) / 18;
68 
69 		theCmd.cmd = soundCmd;
70 		theCmd.param1 = 0;
71 		theCmd.param2 = (long) SND_BUFFER (theSound);
72 		err = SndDoCommand (theChannel, &theCmd, false);
73 
74 	/*
75 	 * We rack 'em up all in a row
76 	 * The mac will play them correctly and then end, since
77 	 * we do a sync close below.
78 	 *
79 	 */
80 		while (*melody && ! err) {
81 			while (*melody > 'G') {
82 				*melody -= 8;
83 			}
84 			while (*melody < 'A') {
85 				*melody += 8;
86 			}
87 			theCmd.cmd = freqDurationCmd;
88 			theCmd.param1 = snd_len;
89 			theCmd.param2 = midi_note [*melody - 'A'];
90 			err = SndDoCommand (theChannel, &theCmd, false);
91 			melody ++;
92 		}
93 		SndDisposeChannel (theChannel, false);	/* Sync wait for completion */
94 		ReleaseResource (theSound);
95 	}
96 }
97 
tty_nhbell(void)98 void tty_nhbell (void) {
99 	Handle h = GetNamedResource ('snd ', "\pNetHack Bell");
100 
101 	if (h) {
102 		HLock (h);
103 		SndPlay ((SndChannelPtr) 0, (SndListHandle) h, 0);
104 		ReleaseResource (h);
105 	} else
106 		SysBeep (30);
107 }
108