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 #include "common/config-manager.h"
24 #include "common/file.h"
25 #include "common/textconsole.h"
26 #include "common/memstream.h"
27 
28 #include "agos/agos.h"
29 #include "agos/midi.h"
30 
31 #include "agos/drivers/accolade/mididriver.h"
32 #include "agos/drivers/accolade/adlib.h"
33 #include "agos/drivers/accolade/mt32.h"
34 #include "agos/drivers/simon1/adlib.h"
35 // Miles Audio for Simon 2
36 #include "audio/miles.h"
37 
38 // PKWARE data compression library decompressor required for Simon 2
39 #include "common/dcl.h"
40 
41 #include "gui/message.h"
42 
43 namespace AGOS {
44 
45 
46 // MidiParser_S1D is not considered part of the standard
47 // MidiParser suite, but we still try to mask its details
48 // and just provide a factory function.
49 extern MidiParser *MidiParser_createS1D();
50 
MidiPlayer()51 MidiPlayer::MidiPlayer() {
52 	// Since initialize() is called every time the music changes,
53 	// this is where we'll initialize stuff that must persist
54 	// between songs.
55 	_driver = 0;
56 	_map_mt32_to_gm = false;
57 
58 	_adLibMusic = false;
59 	_enable_sfx = true;
60 	_current = 0;
61 
62 	_musicVolume = 255;
63 	_sfxVolume = 255;
64 
65 	resetVolumeTable();
66 	_paused = false;
67 
68 	_currentTrack = 255;
69 	_loopTrack = 0;
70 	_queuedTrack = 255;
71 	_loopQueuedTrack = 0;
72 
73 	_musicMode = kMusicModeDisabled;
74 }
75 
~MidiPlayer()76 MidiPlayer::~MidiPlayer() {
77 	stop();
78 
79 	Common::StackLock lock(_mutex);
80 	if (_driver) {
81 		_driver->setTimerCallback(0, 0);
82 		_driver->close();
83 		delete _driver;
84 	}
85 	_driver = NULL;
86 	clearConstructs();
87 }
88 
open(int gameType,bool isDemo)89 int MidiPlayer::open(int gameType, bool isDemo) {
90 	// Don't call open() twice!
91 	assert(!_driver);
92 
93 	Common::String accoladeDriverFilename;
94 	musicType = MT_INVALID;
95 
96 	switch (gameType) {
97 	case GType_ELVIRA1:
98 		_musicMode = kMusicModeAccolade;
99 		accoladeDriverFilename = "INSTR.DAT";
100 		break;
101 	case GType_ELVIRA2:
102 	case GType_WW:
103 		// Attention: Elvira 2 shipped with INSTR.DAT and MUSIC.DRV
104 		// MUSIC.DRV is the correct one. INSTR.DAT seems to be a left-over
105 		_musicMode = kMusicModeAccolade;
106 		accoladeDriverFilename = "MUSIC.DRV";
107 		break;
108 	case GType_SIMON1:
109 		if (isDemo) {
110 			_musicMode = kMusicModeAccolade;
111 			accoladeDriverFilename = "MUSIC.DRV";
112 		} else if (Common::File::exists("MT_FM.IBK")) {
113 			_musicMode = kMusicModeSimon1;
114 		}
115 		break;
116 	case GType_SIMON2:
117 		//_musicMode = kMusicModeMilesAudio;
118 		// currently disabled, because there are a few issues
119 		// MT32 seems to work fine now, AdLib seems to use bad instruments and is also outputting music on
120 		// the right speaker only. The original driver did initialize the panning to 0 and the Simon2 XMIDI
121 		// tracks don't set panning at all. We can reset panning to be centered, which would solve this
122 		// issue, but we still don't know who's setting it in the original interpreter.
123 		break;
124 	default:
125 		break;
126 	}
127 
128 	MidiDriver::DeviceHandle dev;
129 	int ret = 0;
130 
131 	if (_musicMode != kMusicModeDisabled) {
132 		dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32);
133 		musicType = MidiDriver::getMusicType(dev);
134 
135 		switch (musicType) {
136 		case MT_ADLIB:
137 		case MT_MT32:
138 			break;
139 		case MT_GM:
140 			if (!ConfMan.getBool("native_mt32")) {
141 				// Not a real MT32 / no MUNT
142 				::GUI::MessageDialog dialog(("You appear to be using a General MIDI device,\n"
143 											"but your game only supports Roland MT32 MIDI.\n"
144 											"We try to map the Roland MT32 instruments to\n"
145 											"General MIDI ones. It is still possible that\n"
146 											"some tracks sound incorrect."));
147 				dialog.runModal();
148 			}
149 			// Switch to MT32 driver in any case
150 			musicType = MT_MT32;
151 			break;
152 		default:
153 			_musicMode = kMusicModeDisabled;
154 			break;
155 		}
156 	}
157 
158 	switch (_musicMode) {
159 	case kMusicModeAccolade: {
160 		// Setup midi driver
161 		switch (musicType) {
162 		case MT_ADLIB:
163 			_driver = MidiDriver_Accolade_AdLib_create(accoladeDriverFilename);
164 
165 			break;
166 		case MT_MT32:
167 			_driver = MidiDriver_Accolade_MT32_create(accoladeDriverFilename);
168 			break;
169 		default:
170 			assert(0);
171 			break;
172 		}
173 		if (!_driver)
174 			return 255;
175 
176 		ret = _driver->open();
177 		if (ret == 0) {
178 			// Reset is done inside our MIDI driver
179 			_driver->setTimerCallback(this, &onTimer);
180 		}
181 
182 		//setTimerRate(_driver->getBaseTempo());
183 		return 0;
184 	}
185 
186 	case kMusicModeMilesAudio: {
187 		switch (musicType) {
188 		case MT_ADLIB: {
189 			Common::File instrumentDataFile;
190 			if (instrumentDataFile.exists("MIDPAK.AD")) {
191 				// if there is a file called MIDPAK.AD, use it directly
192 				warning("SIMON 2: using MIDPAK.AD");
193 				_driver = Audio::MidiDriver_Miles_AdLib_create("MIDPAK.AD", "MIDPAK.AD");
194 			} else {
195 				// if there is no file called MIDPAK.AD, try to extract it from the file SETUP.SHR
196 				// if we didn't do this, the user would be forced to "install" the game instead of simply
197 				// copying all files from CD-ROM.
198 				Common::SeekableReadStream *midpakAdLibStream;
199 				midpakAdLibStream = simon2SetupExtractFile("MIDPAK.AD");
200 				if (!midpakAdLibStream)
201 					error("MidiPlayer: could not extract MIDPAK.AD from SETUP.SHR");
202 
203 				// Pass this extracted data to the driver
204 				warning("SIMON 2: using MIDPAK.AD extracted from SETUP.SHR");
205 				_driver = Audio::MidiDriver_Miles_AdLib_create("", "", midpakAdLibStream);
206 				delete midpakAdLibStream;
207 			}
208 			// TODO: not sure what's going wrong with AdLib
209 			// it doesn't seem to matter if we use the regular XMIDI tracks or the 2nd set meant for MT32
210 			break;
211 		}
212 		case MT_MT32:
213 			_driver = Audio::MidiDriver_Miles_MT32_create("");
214 			_nativeMT32 = true; // use 2nd set of XMIDI tracks
215 			break;
216 		case MT_GM:
217 			if (ConfMan.getBool("native_mt32")) {
218 				_driver = Audio::MidiDriver_Miles_MT32_create("");
219 				_nativeMT32 = true; // use 2nd set of XMIDI tracks
220 			}
221 			break;
222 
223 		default:
224 			break;
225 		}
226 		if (!_driver)
227 			return 255;
228 
229 		ret = _driver->open();
230 		if (ret == 0) {
231 			// Reset is done inside our MIDI driver
232 			_driver->setTimerCallback(this, &onTimer);
233 		}
234 		return 0;
235 	}
236 
237 	case kMusicModeSimon1: {
238 		// This only handles the original AdLib driver of Simon1.
239 		if (musicType == MT_ADLIB) {
240 			_adLibMusic = true;
241 			_map_mt32_to_gm = false;
242 			_nativeMT32 = false;
243 
244 			_driver = createMidiDriverSimon1AdLib("MT_FM.IBK");
245 			if (_driver && _driver->open() == 0) {
246 				_driver->setTimerCallback(this, &onTimer);
247 				// Like the original, we enable the rhythm support by default.
248 				_driver->send(0xB0, 0x67, 0x01);
249 				return 0;
250 			}
251 
252 			delete _driver;
253 			_driver = nullptr;
254 		}
255 
256 		_musicMode = kMusicModeDisabled;
257 	}
258 
259 	default:
260 		break;
261 	}
262 
263 	dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | (gameType == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM));
264 	_adLibMusic = (MidiDriver::getMusicType(dev) == MT_ADLIB);
265 	_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
266 
267 	_driver = MidiDriver::createMidi(dev);
268 	if (!_driver)
269 		return 255;
270 
271 	if (_nativeMT32)
272 		_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
273 
274 	_map_mt32_to_gm = (gameType != GType_SIMON2 && !_nativeMT32);
275 
276 	ret = _driver->open();
277 	if (ret)
278 		return ret;
279 	_driver->setTimerCallback(this, &onTimer);
280 
281 	if (_nativeMT32)
282 		_driver->sendMT32Reset();
283 	else
284 		_driver->sendGMReset();
285 
286 	return 0;
287 }
288 
send(uint32 b)289 void MidiPlayer::send(uint32 b) {
290 	if (!_current)
291 		return;
292 
293 	if (_musicMode != kMusicModeDisabled) {
294 		// Handle volume control for Simon1 output.
295 		if (_musicMode == kMusicModeSimon1) {
296 			// The driver does not support any volume control, thus we simply
297 			// scale the velocities on note on for now.
298 			// TODO: We should probably handle this at output level at some
299 			// point. Then we can allow volume changes to affect already
300 			// playing notes too. For now this simple change allows us to
301 			// have some simple volume control though.
302 			if ((b & 0xF0) == 0x90) {
303 				byte volume = (b >> 16) & 0x7F;
304 
305 				if (_current == &_sfx) {
306 					volume = volume * _sfxVolume / 255;
307 				} else if (_current == &_music) {
308 					volume = volume * _musicVolume / 255;
309 				}
310 
311 				b = (b & 0xFF00FFFF) | (volume << 16);
312 			}
313 		}
314 
315 		// Send directly to Accolade/Miles/Simon1 Audio driver
316 		_driver->send(b);
317 		return;
318 	}
319 
320 	byte channel = (byte)(b & 0x0F);
321 	if ((b & 0xFFF0) == 0x07B0) {
322 		// Adjust volume changes by master music and master sfx volume.
323 		byte volume = (byte)((b >> 16) & 0x7F);
324 		_current->volume[channel] = volume;
325 		if (_current == &_sfx)
326 			volume = volume * _sfxVolume / 255;
327 		else if (_current == &_music)
328 			volume = volume * _musicVolume / 255;
329 		b = (b & 0xFF00FFFF) | (volume << 16);
330 	} else if ((b & 0xF0) == 0xC0 && _map_mt32_to_gm) {
331 		b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
332 	} else if ((b & 0xFFF0) == 0x007BB0) {
333 		// Only respond to an All Notes Off if this channel
334 		// has already been allocated.
335 		if (!_current->channel[b & 0x0F])
336 			return;
337 	} else if ((b & 0xFFF0) == 0x79B0) {
338 		// "Reset All Controllers". There seems to be some confusion
339 		// about what this message should do to the volume controller.
340 		// See http://www.midi.org/about-midi/rp15.shtml for more
341 		// information.
342 		//
343 		// If I understand it correctly, the current standard indicates
344 		// that the volume should be reset, but the next revision will
345 		// exclude it. On my system, both ALSA and FluidSynth seem to
346 		// reset it, while AdLib does not. Let's follow the majority.
347 
348 		_current->volume[channel] = 127;
349 	}
350 
351 	// Allocate channels if needed
352 	if (!_current->channel[channel])
353 		_current->channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
354 
355 	if (_current->channel[channel]) {
356 		if (channel == 9) {
357 			if (_current == &_sfx)
358 				_current->channel[9]->volume(_current->volume[9] * _sfxVolume / 255);
359 			else if (_current == &_music)
360 				_current->channel[9]->volume(_current->volume[9] * _musicVolume / 255);
361 		}
362 		_current->channel[channel]->send(b);
363 		if ((b & 0xFFF0) == 0x79B0) {
364 			// We have received a "Reset All Controllers" message
365 			// and passed it on to the MIDI driver. This may or may
366 			// not have affected the volume controller. To ensure
367 			// consistent behavior, explicitly set the volume to
368 			// what we think it should be.
369 
370 			if (_current == &_sfx)
371 				_current->channel[channel]->volume(_current->volume[channel] * _sfxVolume / 255);
372 			else if (_current == &_music)
373 				_current->channel[channel]->volume(_current->volume[channel] * _musicVolume / 255);
374 		}
375 	}
376 }
377 
metaEvent(byte type,byte * data,uint16 length)378 void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
379 	// Only thing we care about is End of Track.
380 	if (!_current || type != 0x2F) {
381 		return;
382 	} else if (_current == &_sfx) {
383 		clearConstructs(_sfx);
384 	} else if (_loopTrack) {
385 		_current->parser->jumpToTick(0);
386 	} else if (_queuedTrack != 255) {
387 		_currentTrack = 255;
388 		byte destination = _queuedTrack;
389 		_queuedTrack = 255;
390 		_loopTrack = _loopQueuedTrack;
391 		_loopQueuedTrack = false;
392 
393 		// Remember, we're still inside the locked mutex.
394 		// Have to unlock it before calling jump()
395 		// (which locks it itself), and then relock it
396 		// upon returning.
397 		_mutex.unlock();
398 		startTrack(destination);
399 		_mutex.lock();
400 	} else {
401 		stop();
402 	}
403 }
404 
onTimer(void * data)405 void MidiPlayer::onTimer(void *data) {
406 	MidiPlayer *p = (MidiPlayer *)data;
407 	Common::StackLock lock(p->_mutex);
408 
409 	if (!p->_paused) {
410 		if (p->_music.parser && p->_currentTrack != 255) {
411 			p->_current = &p->_music;
412 			p->_music.parser->onTimer();
413 		}
414 	}
415 	if (p->_sfx.parser) {
416 		p->_current = &p->_sfx;
417 		p->_sfx.parser->onTimer();
418 	}
419 	p->_current = 0;
420 }
421 
startTrack(int track)422 void MidiPlayer::startTrack(int track) {
423 	Common::StackLock lock(_mutex);
424 
425 	if (track == _currentTrack)
426 		return;
427 
428 	if (_music.num_songs > 0) {
429 		if (track >= _music.num_songs)
430 			return;
431 
432 		if (_music.parser) {
433 			_current = &_music;
434 			delete _music.parser;
435 			_current = 0;
436 			_music.parser = 0;
437 		}
438 
439 		MidiParser *parser = MidiParser::createParser_SMF();
440 		parser->property (MidiParser::mpMalformedPitchBends, 1);
441 		parser->setMidiDriver(this);
442 		parser->setTimerRate(_driver->getBaseTempo());
443 		if (!parser->loadMusic(_music.songs[track], _music.song_sizes[track])) {
444 			warning("Error reading track %d", track);
445 			delete parser;
446 			parser = 0;
447 		}
448 
449 		_currentTrack = (byte)track;
450 		_music.parser = parser; // That plugs the power cord into the wall
451 	} else if (_music.parser) {
452 		if (!_music.parser->setTrack(track)) {
453 			return;
454 		}
455 		_currentTrack = (byte)track;
456 		_current = &_music;
457 		_music.parser->jumpToTick(0);
458 		_current = 0;
459 	}
460 }
461 
stop()462 void MidiPlayer::stop() {
463 	Common::StackLock lock(_mutex);
464 
465 	if (_music.parser) {
466 		_current = &_music;
467 		_music.parser->jumpToTick(0);
468 	}
469 	_current = 0;
470 	_currentTrack = 255;
471 }
472 
pause(bool b)473 void MidiPlayer::pause(bool b) {
474 	if (_paused == b || !_driver)
475 		return;
476 	_paused = b;
477 
478 	Common::StackLock lock(_mutex);
479 	// if using the driver Accolade_AdLib call setVolume() to turn off\on the volume on all channels
480 	if (musicType == MT_ADLIB && _musicMode == kMusicModeAccolade) {
481 		static_cast <MidiDriver_Accolade_AdLib*> (_driver)->setVolume(_paused ? 0 : 128);
482 	}
483 	for (int i = 0; i < 16; ++i) {
484 		if (_music.channel[i])
485 			_music.channel[i]->volume(_paused ? 0 : (_music.volume[i] * _musicVolume / 255));
486 		if (_sfx.channel[i])
487 			_sfx.channel[i]->volume(_paused ? 0 : (_sfx.volume[i] * _sfxVolume / 255));
488 	}
489 }
490 
setVolume(int musicVol,int sfxVol)491 void MidiPlayer::setVolume(int musicVol, int sfxVol) {
492 	musicVol = CLIP(musicVol, 0, 255);
493 	sfxVol   = CLIP(sfxVol,   0, 255);
494 
495 	if (_musicVolume == musicVol && _sfxVolume == sfxVol)
496 		return;
497 
498 	_musicVolume = musicVol;
499 	_sfxVolume   = sfxVol;
500 
501 	// Now tell all the channels this.
502 	Common::StackLock lock(_mutex);
503 	if (_driver && !_paused) {
504 		for (int i = 0; i < 16; ++i) {
505 			if (_music.channel[i])
506 				_music.channel[i]->volume(_music.volume[i] * _musicVolume / 255);
507 			if (_sfx.channel[i])
508 				_sfx.channel[i]->volume(_sfx.volume[i] * _sfxVolume / 255);
509 		}
510 	}
511 }
512 
setLoop(bool loop)513 void MidiPlayer::setLoop(bool loop) {
514 	Common::StackLock lock(_mutex);
515 
516 	_loopTrack = loop;
517 }
518 
queueTrack(int track,bool loop)519 void MidiPlayer::queueTrack(int track, bool loop) {
520 	_mutex.lock();
521 	if (_currentTrack == 255) {
522 		_mutex.unlock();
523 		setLoop(loop);
524 		startTrack(track);
525 	} else {
526 		_queuedTrack = track;
527 		_loopQueuedTrack = loop;
528 		_mutex.unlock();
529 	}
530 }
531 
clearConstructs()532 void MidiPlayer::clearConstructs() {
533 	clearConstructs(_music);
534 	clearConstructs(_sfx);
535 }
536 
clearConstructs(MusicInfo & info)537 void MidiPlayer::clearConstructs(MusicInfo &info) {
538 	int i;
539 	if (info.num_songs > 0) {
540 		for (i = 0; i < info.num_songs; ++i)
541 			free(info.songs[i]);
542 		info.num_songs = 0;
543 	}
544 
545 	free(info.data);
546 	info.data = 0;
547 
548 	delete info.parser;
549 	info.parser = 0;
550 
551 	if (_driver) {
552 		for (i = 0; i < 16; ++i) {
553 			if (info.channel[i]) {
554 				info.channel[i]->allNotesOff();
555 				info.channel[i]->release();
556 			}
557 		}
558 	}
559 	info.clear();
560 }
561 
resetVolumeTable()562 void MidiPlayer::resetVolumeTable() {
563 	int i;
564 	for (i = 0; i < 16; ++i) {
565 		_music.volume[i] = _sfx.volume[i] = 127;
566 		if (_driver)
567 			_driver->send(((_musicVolume >> 1) << 16) | 0x7B0 | i);
568 	}
569 }
570 
571 static const int simon1_gmf_size[] = {
572 	8900, 12166, 2848, 3442, 4034, 4508, 7064, 9730, 6014, 4742, 3138,
573 	6570, 5384, 8909, 6457, 16321, 2742, 8968, 4804, 8442, 7717,
574 	9444, 5800, 1381, 5660, 6684, 2456, 4744, 2455, 1177, 1232,
575 	17256, 5103, 8794, 4884, 16
576 };
577 
loadSMF(Common::File * in,int song,bool sfx)578 void MidiPlayer::loadSMF(Common::File *in, int song, bool sfx) {
579 	Common::StackLock lock(_mutex);
580 
581 	MusicInfo *p = sfx ? &_sfx : &_music;
582 	clearConstructs(*p);
583 
584 	uint32 startpos = in->pos();
585 	byte header[4];
586 	in->read(header, 4);
587 	bool isGMF = !memcmp(header, "GMF\x1", 4);
588 	in->seek(startpos, SEEK_SET);
589 
590 	uint32 size = in->size() - in->pos();
591 	if (isGMF) {
592 		if (sfx) {
593 			// Multiple GMF resources are stored in the SFX files,
594 			// but each one is referenced by a pointer at the
595 			// beginning of the file. Those pointers can be used
596 			// to determine file size.
597 			in->seek(0, SEEK_SET);
598 			uint16 value = in->readUint16LE() >> 2; // Number of resources
599 			if (song != value - 1) {
600 				in->seek(song * 2 + 2, SEEK_SET);
601 				value = in->readUint16LE();
602 				size = value - startpos;
603 			}
604 			in->seek(startpos, SEEK_SET);
605 		} else if (size >= 64000) {
606 			// For GMF resources not in separate
607 			// files, we're going to have to use
608 			// hardcoded size tables.
609 			size = simon1_gmf_size[song];
610 		}
611 	}
612 
613 	// When allocating space, add 4 bytes in case
614 	// this is a GMF and we have to tack on our own
615 	// End of Track event.
616 	p->data = (byte *)calloc(size + 4, 1);
617 	in->read(p->data, size);
618 
619 	uint32 timerRate = _driver->getBaseTempo();
620 
621 	if (isGMF) {
622 		// The GMF header
623 		// 3 BYTES: 'GMF'
624 		// 1 BYTE : Major version
625 		// 1 BYTE : Minor version
626 		// 1 BYTE : Ticks (Ranges from 2 - 8, always 2 for SFX)
627 		// 1 BYTE : Loop control. 0 = no loop, 1 = loop (Music only)
628 		if (!sfx) {
629 			// In the original, the ticks value indicated how many
630 			// times the music timer was called before it actually
631 			// did something. The larger the value the slower the
632 			// music.
633 			//
634 			// We, on the other hand, have a timer rate which is
635 			// used to control by how much the music advances on
636 			// each onTimer() call. The larger the value, the
637 			// faster the music.
638 			//
639 			// It seems that 4 corresponds to our base tempo, so
640 			// this should be the right way to calculate it.
641 			timerRate = (4 * _driver->getBaseTempo()) / p->data[5];
642 
643 			// According to bug #1004919 calling setLoop() from
644 			// within a lock causes a lockup, though I have no
645 			// idea when this actually happens.
646 			_loopTrack = (p->data[6] != 0);
647 		}
648 	}
649 
650 	MidiParser *parser = MidiParser::createParser_SMF();
651 	parser->property(MidiParser::mpMalformedPitchBends, 1);
652 	parser->setMidiDriver(this);
653 	parser->setTimerRate(timerRate);
654 	if (!parser->loadMusic(p->data, size)) {
655 		warning("Error reading track");
656 		delete parser;
657 		parser = 0;
658 	}
659 
660 	if (!sfx) {
661 		_currentTrack = 255;
662 		resetVolumeTable();
663 	}
664 	p->parser = parser; // That plugs the power cord into the wall
665 }
666 
loadMultipleSMF(Common::File * in,bool sfx)667 void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) {
668 	// This is a special case for Simon 2 Windows.
669 	// Instead of having multiple sequences as
670 	// separate tracks in a Type 2 file, simon2win
671 	// has multiple songs, each of which is a Type 1
672 	// file. Thus, preceding the songs is a single
673 	// byte specifying how many songs are coming.
674 	// We need to load ALL the songs and then
675 	// treat them as separate tracks -- for the
676 	// purpose of jumps, anyway.
677 	Common::StackLock lock(_mutex);
678 
679 	MusicInfo *p = sfx ? &_sfx : &_music;
680 	clearConstructs(*p);
681 
682 	p->num_songs = in->readByte();
683 	if (p->num_songs > 16) {
684 		warning("playMultipleSMF: %d is too many songs to keep track of", (int)p->num_songs);
685 		return;
686 	}
687 
688 	byte i;
689 	for (i = 0; i < p->num_songs; ++i) {
690 		byte buf[5];
691 		uint32 pos = in->pos();
692 
693 		// Make sure there's a MThd
694 		in->read(buf, 4);
695 		if (memcmp(buf, "MThd", 4) != 0) {
696 			warning("Expected MThd but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
697 			return;
698 		}
699 		in->seek(in->readUint32BE(), SEEK_CUR);
700 
701 		// Now skip all the MTrk blocks
702 		while (true) {
703 			in->read(buf, 4);
704 			if (memcmp(buf, "MTrk", 4) != 0)
705 				break;
706 			in->seek(in->readUint32BE(), SEEK_CUR);
707 		}
708 
709 		uint32 pos2 = in->pos() - 4;
710 		uint32 size = pos2 - pos;
711 		p->songs[i] = (byte *)calloc(size, 1);
712 		in->seek(pos, SEEK_SET);
713 		in->read(p->songs[i], size);
714 		p->song_sizes[i] = size;
715 	}
716 
717 	if (!sfx) {
718 		_currentTrack = 255;
719 		resetVolumeTable();
720 	}
721 }
722 
loadXMIDI(Common::File * in,bool sfx)723 void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) {
724 	Common::StackLock lock(_mutex);
725 	MusicInfo *p = sfx ? &_sfx : &_music;
726 	clearConstructs(*p);
727 
728 	char buf[4];
729 	uint32 pos = in->pos();
730 	uint32 size = 4;
731 	in->read(buf, 4);
732 	if (!memcmp(buf, "FORM", 4)) {
733 		int i;
734 		for (i = 0; i < 16; ++i) {
735 			if (!memcmp(buf, "CAT ", 4))
736 				break;
737 			size += 2;
738 			memcpy(buf, &buf[2], 2);
739 			in->read(&buf[2], 2);
740 		}
741 		if (memcmp(buf, "CAT ", 4) != 0) {
742 			error("Could not find 'CAT ' tag to determine resource size");
743 		}
744 		size += 4 + in->readUint32BE();
745 		in->seek(pos, 0);
746 		p->data = (byte *)calloc(size, 1);
747 		in->read(p->data, size);
748 	} else {
749 		error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
750 	}
751 
752 	// In the DOS version of Simon the Sorcerer 2, the music contains lots
753 	// of XMIDI callback controller events. As far as we know, they aren't
754 	// actually used, so we disable the callback handler explicitly.
755 
756 	MidiParser *parser = MidiParser::createParser_XMIDI(NULL);
757 	parser->setMidiDriver(this);
758 	parser->setTimerRate(_driver->getBaseTempo());
759 	if (!parser->loadMusic(p->data, size))
760 		error("Error reading track");
761 
762 	if (!sfx) {
763 		_currentTrack = 255;
764 		resetVolumeTable();
765 	}
766 	p->parser = parser; // That plugs the power cord into the wall
767 }
768 
loadS1D(Common::File * in,bool sfx)769 void MidiPlayer::loadS1D(Common::File *in, bool sfx) {
770 	Common::StackLock lock(_mutex);
771 	MusicInfo *p = sfx ? &_sfx : &_music;
772 	clearConstructs(*p);
773 
774 	uint16 size = in->readUint16LE();
775 	if (size != in->size() - 2) {
776 		error("Size mismatch in MUS file (%ld versus reported %d)", (long)in->size() - 2, (int)size);
777 	}
778 
779 	p->data = (byte *)calloc(size, 1);
780 	in->read(p->data, size);
781 
782 	MidiParser *parser = MidiParser_createS1D();
783 	parser->setMidiDriver(this);
784 	parser->setTimerRate(_driver->getBaseTempo());
785 	if (!parser->loadMusic(p->data, size))
786 		error("Error reading track");
787 
788 	if (!sfx) {
789 		_currentTrack = 255;
790 		resetVolumeTable();
791 	}
792 	p->parser = parser; // That plugs the power cord into the wall
793 }
794 
795 #define MIDI_SETUP_BUNDLE_HEADER_SIZE 56
796 #define MIDI_SETUP_BUNDLE_FILEHEADER_SIZE 48
797 #define MIDI_SETUP_BUNDLE_FILENAME_MAX_SIZE 12
798 
799 // PKWARE data compression library (called "DCL" in ScummVM) was used for storing files within SETUP.SHR
800 // we need it to be able to get the file MIDPAK.AD, otherwise we would have to require the user
801 // to "install" the game before being able to actually play it, when using AdLib.
802 //
803 // SETUP.SHR file format:
804 //  [bundle file header]
805 //    [compressed file header] [compressed file data]
806 //     * compressed file count
simon2SetupExtractFile(const Common::String & requestedFileName)807 Common::SeekableReadStream *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFileName) {
808 	Common::File *setupBundleStream = new Common::File();
809 	uint32        bundleSize = 0;
810 	uint32        bundleBytesLeft = 0;
811 	byte          bundleHeader[MIDI_SETUP_BUNDLE_HEADER_SIZE];
812 	byte          bundleFileHeader[MIDI_SETUP_BUNDLE_FILEHEADER_SIZE];
813 	uint16        bundleFileCount = 0;
814 	uint16        bundleFileNr = 0;
815 
816 	Common::String fileName;
817 	uint32         fileCompressedSize = 0;
818 	byte          *fileCompressedDataPtr = nullptr;
819 
820 	Common::SeekableReadStream *extractedStream = nullptr;
821 
822 	if (!setupBundleStream->open("setup.shr"))
823 		error("MidiPlayer: could not open setup.shr");
824 
825 	bundleSize = setupBundleStream->size();
826 	bundleBytesLeft = bundleSize;
827 
828 	if (bundleSize < MIDI_SETUP_BUNDLE_HEADER_SIZE)
829 		error("MidiPlayer: unexpected EOF in setup.shr");
830 
831 	if (setupBundleStream->read(bundleHeader, MIDI_SETUP_BUNDLE_HEADER_SIZE) != MIDI_SETUP_BUNDLE_HEADER_SIZE)
832 		error("MidiPlayer: setup.shr read error");
833 	bundleBytesLeft -= MIDI_SETUP_BUNDLE_HEADER_SIZE;
834 
835 	// Verify header byte
836 	if (bundleHeader[13] != 't')
837 		error("MidiPlayer: setup.shr bundle header data mismatch");
838 
839 	bundleFileCount = READ_LE_UINT16(&bundleHeader[14]);
840 
841 	// Search for requested file
842 	while (bundleFileNr < bundleFileCount) {
843 		if (bundleBytesLeft < sizeof(bundleFileHeader))
844 			error("MidiPlayer: unexpected EOF in setup.shr");
845 
846 		if (setupBundleStream->read(bundleFileHeader, sizeof(bundleFileHeader)) != sizeof(bundleFileHeader))
847 			error("MidiPlayer: setup.shr read error");
848 		bundleBytesLeft -= MIDI_SETUP_BUNDLE_FILEHEADER_SIZE;
849 
850 		// Extract filename from file-header
851 		fileName.clear();
852 		for (byte curPos = 0; curPos < MIDI_SETUP_BUNDLE_FILENAME_MAX_SIZE; curPos++) {
853 			if (!bundleFileHeader[curPos]) // terminating NUL
854 				break;
855 			fileName.insertChar(bundleFileHeader[curPos], curPos);
856 		}
857 
858 		// Get compressed
859 		fileCompressedSize = READ_LE_UINT32(&bundleFileHeader[20]);
860 		if (!fileCompressedSize)
861 			error("MidiPlayer: compressed file is 0 bytes, data corruption?");
862 		if (bundleBytesLeft < fileCompressedSize)
863 			error("MidiPlayer: unexpected EOF in setup.shr");
864 
865 		if (fileName == requestedFileName) {
866 			// requested file found
867 			fileCompressedDataPtr = new byte[fileCompressedSize];
868 
869 			if (setupBundleStream->read(fileCompressedDataPtr, fileCompressedSize) != fileCompressedSize)
870 				error("MidiPlayer: setup.shr read error");
871 
872 			Common::MemoryReadStream *compressedStream = nullptr;
873 
874 			compressedStream = new Common::MemoryReadStream(fileCompressedDataPtr, fileCompressedSize);
875 			// we don't know the unpacked size, let decompressor figure it out
876 			extractedStream = Common::decompressDCL(compressedStream);
877 			delete compressedStream;
878 			break;
879 		}
880 
881 		// skip compressed size
882 		setupBundleStream->skip(fileCompressedSize);
883 		bundleBytesLeft -= fileCompressedSize;
884 
885 		bundleFileNr++;
886 	}
887 	setupBundleStream->close();
888 	delete setupBundleStream;
889 
890 	return extractedStream;
891 }
892 
893 } // End of namespace AGOS
894