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