1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef PARALLACTION_MUSIC_H
24 #define PARALLACTION_MUSIC_H
25 
26 #include "common/util.h"
27 #include "common/mutex.h"
28 
29 #include "audio/mixer.h"
30 #include "audio/audiostream.h"
31 #include "audio/decoders/iff_sound.h"
32 
33 #define PATH_LEN 200
34 
35 class MidiParser;
36 class MidiDriver;
37 
38 namespace Parallaction {
39 
40 class Parallaction_ns;
41 class MidiPlayer;
42 class Parallaction_br;
43 class MidiPlayer_MSC;
44 
45 MidiDriver *createAdLibDriver();
46 
47 class SoundManImpl {
48 public:
49 	virtual void execute(int command, const char *parm = 0) = 0;
~SoundManImpl()50 	virtual ~SoundManImpl() { }
51 };
52 
53 class SoundMan {
54 	SoundManImpl *_impl;
55 public:
SoundMan(SoundManImpl * impl)56 	SoundMan(SoundManImpl *impl) : _impl(impl) { }
~SoundMan()57 	virtual ~SoundMan() { delete _impl; }
execute(int command,int32 parm)58 	void execute(int command, int32 parm) {
59 		char n[12];
60 		sprintf(n, "%i", parm);
61 		execute(command, n);
62 	}
63 	void execute(int command, const char *parm = 0) {
64 		if (_impl) {
65 			_impl->execute(command, parm);
66 		}
67 	}
68 };
69 
70 enum {
71 	// soundMan commands
72 	SC_PLAYMUSIC,
73 	SC_STOPMUSIC,
74 	SC_SETMUSICTYPE,
75 	SC_SETMUSICFILE,
76 	SC_PLAYSFX,
77 	SC_STOPSFX,
78 	SC_SETSFXCHANNEL,
79 	SC_SETSFXLOOPING,
80 	SC_SETSFXVOLUME,
81 	SC_SETSFXRATE,
82 	SC_PAUSE
83 };
84 
85 struct Channel {
86 	Audio::AudioStream *stream;
87 	Audio::SoundHandle	handle;
88 	uint32				volume;
89 };
90 
91 
92 
93 class SoundMan_ns : public SoundManImpl {
94 public:
95 	enum {
96 		MUSIC_ANY,
97 		MUSIC_CHARACTER,
98 		MUSIC_LOCATION
99 	};
100 
101 protected:
102 	Parallaction_ns	*_vm;
103 	Audio::Mixer	*_mixer;
104 	char			_musicFile[PATH_LEN];
105 
106 	bool	_sfxLooping;
107 	int		_sfxVolume;
108 	int		_sfxRate;
109 	uint	_sfxChannel;
110 
111 	int		_musicType;
112 
113 public:
114 	SoundMan_ns(Parallaction_ns *vm);
~SoundMan_ns()115 	virtual ~SoundMan_ns() {}
116 
117 	virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1) { }
stopSfx(uint channel)118 	virtual void stopSfx(uint channel) { }
119 
120 	void setMusicFile(const char *filename);
121 	virtual void playMusic() = 0;
122 	virtual void stopMusic() = 0;
123 	virtual void playCharacterMusic(const char *character) = 0;
124 	virtual void playLocationMusic(const char *location) = 0;
pause(bool p)125 	virtual void pause(bool p) { }
126 	virtual void execute(int command, const char *parm);
127 
128 	void setMusicVolume(int value);
129 };
130 
131 class DosSoundMan_ns : public SoundMan_ns {
132 
133 	MidiPlayer	*_midiPlayer;
134 	bool		_playing;
135 
136 	bool isLocationSilent(const char *locationName);
137 	bool locationHasOwnSoftMusic(const char *locationName);
138 
139 
140 public:
141 	DosSoundMan_ns(Parallaction_ns *vm);
142 	~DosSoundMan_ns();
143 	void playMusic();
144 	void stopMusic();
145 
146 	void playCharacterMusic(const char *character);
147 	void playLocationMusic(const char *location);
148 
149 	void pause(bool p);
150 };
151 
152 #define NUM_SFX_CHANNELS 4
153 
154 class AmigaSoundMan_ns : public SoundMan_ns {
155 
156 	Audio::AudioStream *_musicStream;
157 	Audio::SoundHandle	_musicHandle;
158 
159 	uint32	beepSoundBufferSize;
160 	int8	*beepSoundBuffer;
161 
162 	Channel _channels[NUM_SFX_CHANNELS];
163 
164 	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
165 
166 public:
167 	AmigaSoundMan_ns(Parallaction_ns *vm);
168 	~AmigaSoundMan_ns();
169 	void playMusic();
170 	void stopMusic();
171 
172 	void playSfx(const char *filename, uint channel, bool looping, int volume);
173 	void stopSfx(uint channel);
174 
175 	void playCharacterMusic(const char *character);
176 	void playLocationMusic(const char *location);
177 };
178 
179 class DummySoundMan : public SoundManImpl {
180 public:
execute(int command,const char * parm)181 	void execute(int command, const char *parm) { }
182 };
183 
184 class SoundMan_br : public SoundManImpl {
185 protected:
186 	Parallaction_br	*_vm;
187 	Audio::Mixer	*_mixer;
188 
189 	Common::String _musicFile;
190 
191 	bool	_sfxLooping;
192 	int		_sfxVolume;
193 	int		_sfxRate;
194 	uint	_sfxChannel;
195 
196 	bool	_musicEnabled;
197 	bool	_sfxEnabled;
198 
199 	Channel _channels[NUM_SFX_CHANNELS];
200 
201 	virtual void playMusic() = 0;
202 	virtual void stopMusic() = 0;
203 	virtual void pause(bool p) = 0;
204 
205 public:
206 	SoundMan_br(Parallaction_br *vm);
207 	~SoundMan_br();
208 
209 	virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1) { }
210 	void stopSfx(uint channel);
211 	void stopAllSfx();
212 
213 	virtual void execute(int command, const char *parm);
214 	void setMusicFile(const char *parm);
215 
216 	void enableSfx(bool enable);
217 	void enableMusic(bool enable);
218 	bool isSfxEnabled() const;
219 	bool isMusicEnabled() const;
220 };
221 
222 class DosSoundMan_br : public SoundMan_br {
223 
224 	MidiPlayer_MSC	*_midiPlayer;
225 
226 	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
227 
228 public:
229 	DosSoundMan_br(Parallaction_br *vm);
230 	~DosSoundMan_br();
231 
232 	void playMusic();
233 	void stopMusic();
234 	void pause(bool p);
235 
236 	void playSfx(const char *filename, uint channel, bool looping, int volume);
237 };
238 
239 class AmigaSoundMan_br : public SoundMan_br {
240 
241 	Audio::AudioStream *_musicStream;
242 	Audio::SoundHandle	_musicHandle;
243 
244 	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
245 
246 public:
247 	AmigaSoundMan_br(Parallaction_br *vm);
248 	~AmigaSoundMan_br();
249 
250 	void playMusic();
251 	void stopMusic();
252 	void pause(bool p);
253 
254 	void playSfx(const char *filename, uint channel, bool looping, int volume);
255 };
256 
257 } // namespace Parallaction
258 
259 #endif
260