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 #ifdef ENABLE_EOB
24 
25 #include "kyra/sound/sound_intern.h"
26 #include "kyra/resource/resource.h"
27 #include "kyra/sound/drivers/audiomaster2.h"
28 
29 #include "common/config-manager.h"
30 #include "common/memstream.h"
31 
32 namespace Kyra {
33 
SoundAmiga_EoB(KyraEngine_v1 * vm,Audio::Mixer * mixer)34 SoundAmiga_EoB::SoundAmiga_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer),
35 	_vm(vm), _driver(0), _currentResourceSet(-1), _ready(false) {
36 	_fileBuffer = new uint8[64000];
37 	memset(_resInfo, 0, sizeof(_resInfo));
38 }
39 
~SoundAmiga_EoB()40 SoundAmiga_EoB::~SoundAmiga_EoB() {
41 	delete _driver;
42 	delete[] _fileBuffer;
43 	for (int i = 0; i < 3; i++)
44 		initAudioResourceInfo(i, 0);
45 }
46 
getMusicType() const47 Sound::kType SoundAmiga_EoB::getMusicType() const {
48 	return kAmiga;
49 }
50 
init()51 bool SoundAmiga_EoB::init() {
52 	_driver = new AudioMaster2(_mixer);
53 	if (!_driver->init())
54 		return false;
55 
56 	_ready = true;
57 
58 	return true;
59 }
60 
initAudioResourceInfo(int set,void * info)61 void SoundAmiga_EoB::initAudioResourceInfo(int set, void *info) {
62 	delete _resInfo[set];
63 	_resInfo[set] = info ? new SoundResourceInfo_AmigaEoB(*(SoundResourceInfo_AmigaEoB*)info) : 0;
64 }
65 
selectAudioResourceSet(int set)66 void SoundAmiga_EoB::selectAudioResourceSet(int set) {
67 	if (set == _currentResourceSet || !_ready)
68 		return;
69 
70 	_driver->flushAllResources();
71 	if (!_resInfo[set])
72 		return;
73 
74 	for (uint i = 0; i < _resInfo[set]->fileListSize; ++i)
75 		loadSoundFile(_resInfo[set]->fileList[i]);
76 
77 	_currentResourceSet = set;
78 }
79 
loadSoundFile(Common::String file)80 void SoundAmiga_EoB::loadSoundFile(Common::String file) {
81 	if (!_ready)
82 		return;
83 
84 	Common::SeekableReadStream *in = _vm->resource()->createReadStream(file);
85 	debugC(6, kDebugLevelSound, "SoundAmiga_EoB::loadSoundFile(): Attempting to load sound file '%s'...%s", file.c_str(), in ? "SUCCESS" : "FILE NOT FOUND");
86 	if (!in)
87 		return;
88 
89 	// This value can deviate up to 5 bytes from the real size in EOB II Amiga.
90 	// The original simply tries to read 64000 bytes from the file (ignoring this
91 	// value). We do the same.
92 	// EOB I strangely always seems to have correct values.
93 	uint16 readSize = in->readUint16LE() - 10;
94 	uint8 cmp = in->readByte();
95 	in->seek(1, SEEK_CUR);
96 	uint32 outSize = in->readUint32LE();
97 	in->seek(2, SEEK_CUR);
98 
99 	readSize = in->read(_fileBuffer, 64000);
100 	delete in;
101 
102 	if (cmp == 0 && readSize < outSize)
103 		outSize = readSize;
104 
105 	uint8 *buf = new uint8[outSize];
106 
107 	if (cmp == 0) {
108 		memcpy(buf, _fileBuffer, outSize);
109 	} else if (cmp == 3) {
110 		Screen::decodeFrame3(_fileBuffer, buf, outSize, true);
111 	} else if (cmp == 4) {
112 		Screen::decodeFrame4(_fileBuffer, buf, outSize);
113 	} else {
114 		error("SoundAmiga_EoB::loadSoundFile(): Failed to load sound file '%s'", file.c_str());
115 	}
116 
117 	Common::MemoryReadStream soundFile(buf, outSize);
118 	if (!_driver->loadRessourceFile(&soundFile))
119 		error("SoundAmiga_EoB::loadSoundFile(): Failed to load sound file '%s'", file.c_str());
120 
121 	delete[] buf;
122 }
123 
unloadSoundFile(Common::String file)124 void SoundAmiga_EoB::unloadSoundFile(Common::String file) {
125 	if (!_ready)
126 		return;
127 	debugC(5, kDebugLevelSound, "SoundAmiga_EoB::unloadSoundFile(): Attempting to free resource '%s'...%s", file.c_str(), _driver->stopSound(file) ? "SUCCESS" : "FAILURE");
128 	_driver->flushResource(file);
129 }
130 
playTrack(uint8 track)131 void SoundAmiga_EoB::playTrack(uint8 track) {
132 	if (!_musicEnabled || !_ready)
133 		return;
134 
135 	Common::String newSound;
136 	if (_vm->game() == GI_EOB1) {
137 		if (_currentResourceSet == kMusicIntro) {
138 			if (track == 1)
139 				newSound = "NEWINTRO1.SMUS";
140 			else if (track == 20)
141 				newSound = "CHARGEN1.SMUS";
142 		} else if (_currentResourceSet == kMusicFinale) {
143 			newSound = "FINALE.SMUS";
144 		}
145 	} else if (_vm->game() == GI_EOB2) {
146 		if (_currentResourceSet == kMusicIntro) {
147 			if (track > 11 && track < 16) {
148 				const char *const songs[] = { "INTRO1A.SMUS", "CHARGEN3.SMUS", "INTRO1B.SMUS", "INTRO1C.SMUS" };
149 				newSound = songs[track - 12];
150 			}
151 		} else if (_currentResourceSet == kMusicFinale) {
152 			if (track > 0 && track < 4) {
153 				const char *const songs[] = { "FINALE1B.SMUS", "FINALE1C.SMUS", "FINALE1D.SMUS" };
154 				newSound = songs[track - 1];
155 			}
156 		}
157 	}
158 
159 	if (!newSound.empty() && _ready) {
160 		_driver->startSound(newSound);
161 		_lastSound = newSound;
162 	}
163 }
164 
haltTrack()165 void SoundAmiga_EoB::haltTrack() {
166 	if (!_lastSound.empty())
167 		_driver->stopSound(_lastSound);
168 	_lastSound.clear();
169 }
170 
playSoundEffect(uint8 track,uint8 volume)171 void SoundAmiga_EoB::playSoundEffect(uint8 track, uint8 volume) {
172 	if (_currentResourceSet == -1 || !_sfxEnabled || !_ready)
173 		return;
174 
175 	if (_vm->game() == GI_EOB2 && _currentResourceSet == kMusicIntro && track == 14) {
176 		_driver->startSound("TELEPORT.SAM");
177 		return;
178 	}
179 
180 	if (!_resInfo[_currentResourceSet]->soundList || track >= 120 || !_sfxEnabled)
181 		return;
182 
183 	if (_vm->game() == GI_EOB2 && track == 2) {
184 		beginFadeOut(60);
185 		return;
186 	}
187 
188 	Common::String newSound = _resInfo[_currentResourceSet]->soundList[track];
189 	const char *suffix = (_vm->game() == GI_EOB1) ? "1.SAM" : ((track > 51 && track < 68) ? ".SMUS" : ".SAM");
190 
191 	if (!newSound.empty()) {
192 		if (volume == 255) {
193 			if (_driver->startSound(newSound + suffix)) {
194 				_lastSound = newSound + suffix;
195 				return;
196 			} else {
197 				volume = 1;
198 			}
199 		}
200 
201 		if (volume > 0 && volume < 5)
202 			newSound = Common::String::format("%s%d", newSound.c_str(), volume);
203 
204 		if (!_driver->startSound(newSound)) {
205 			// WORKAROUND for wrongly named resources. This applies to at least 'BLADE' in the EOB II dungeons (instead of 'BLADE1').
206 			newSound = _resInfo[_currentResourceSet]->soundList[track];
207 			if (_driver->startSound(newSound))
208 				debugC(5, kDebugLevelSound, "SoundAmiga_EoB::playSoundEffect(): Triggered workaround for wrongly named resource: '%s'", newSound.c_str());
209 		}
210 
211 		_lastSound = newSound;
212 	}
213 }
214 
beginFadeOut(int delay)215 void SoundAmiga_EoB::beginFadeOut(int delay) {
216 	_driver->fadeOut(delay);
217 	while (_driver->isFading() && !_vm->shouldQuit())
218 		_vm->delay(5);
219 	haltTrack();
220 }
221 
updateVolumeSettings()222 void SoundAmiga_EoB::updateVolumeSettings() {
223 	if (!_driver || !_ready)
224 		return;
225 
226 	bool mute = false;
227 	if (ConfMan.hasKey("mute"))
228 		mute = ConfMan.getBool("mute");
229 
230 	_driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume")));
231 	_driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume")));
232 }
233 
checkTrigger()234 int SoundAmiga_EoB::checkTrigger() {
235 	return _driver->getPlayDuration();
236 }
237 
238 } // End of namespace Kyra
239 
240 #endif
241