From ff418964800f14c6041b072c8d510005929c19f2 Mon Sep 17 00:00:00 2001 From: Jamieson Christian Date: Mon, 19 May 2003 05:00:13 +0000 Subject: Fixed Simon 1 music regression. SMF parser now supports malformed Simon pitch bend events. Implemented SMF parser jump method. svn-id: r7669 --- simon/midi.cpp | 23 +++++++++++++++++++++-- simon/midi.h | 2 +- simon/simon.cpp | 9 +++------ 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'simon') diff --git a/simon/midi.cpp b/simon/midi.cpp index 0cb9815d31..8ba97f40a3 100644 --- a/simon/midi.cpp +++ b/simon/midi.cpp @@ -71,11 +71,14 @@ void MidiPlayer::close() { void MidiPlayer::send (uint32 b) { byte volume; - // Only thing we care about is volume control changes. if ((b & 0xFFF0) == 0x07B0) { + // Adjust volume changes by master volume. volume = (byte) ((b >> 16) & 0xFF) * _masterVolume / 255; _volumeTable [b & 0xF] = volume; b = (b & 0xFF00FFFF) | (volume << 16); + } else if ((b & 0xF0) == 0xE0) { + // Skip pitch bends completely. They're screwed up in Simon games. + return; } _driver->send (b); @@ -116,6 +119,7 @@ void MidiPlayer::jump (uint16 track, uint16 tick) { } MidiParser *parser = MidiParser::createParser_SMF(); + parser->property (MidiParser::mpMalformedPitchBends, 1); parser->setMidiDriver (this); parser->setTimerRate (_driver->getBaseTempo()); if (!parser->loadMusic (_songs[track], _song_sizes[track])) { @@ -206,7 +210,14 @@ void MidiPlayer::clearConstructs() { } } -void MidiPlayer::playSMF (File *in) { +static int simon1_gmf_size[] = { + 8900, 12166, 2848, 3442, 4034, 4508, 7064, 9730, 6014, 4742, 3138, + 6570, 5384, 8909, 6457, 16321, 2742, 8968, 4804, 8442, 7717, + 9444, 5800, 1381, 5660, 6684, 2456, 4744, 2455, 1177, 1232, + 17256, 5103, 8794, 4884, 16 +}; + +void MidiPlayer::playSMF (File *in, int song) { _system->lock_mutex (_mutex); clearConstructs(); uint32 size = in->size() - in->pos(); @@ -215,7 +226,15 @@ void MidiPlayer::playSMF (File *in) { _data = (byte *) calloc (size, 1); in->read (_data, size); + // For GMF files, we're going to have to use + // hardcoded size tables. + if (!memcmp (_data, "GMF\x1", 4) && size == 64000) { + size = simon1_gmf_size [song]; + _data[size++] = 0x00; // Trailing 0 makes this match the standalone GMF files + } + MidiParser *parser = MidiParser::createParser_SMF(); + parser->property (MidiParser::mpMalformedPitchBends, 1); parser->setMidiDriver (this); parser->setTimerRate (_driver->getBaseTempo()); if (!parser->loadMusic (_data, size)) { diff --git a/simon/midi.h b/simon/midi.h index 9f66419b05..2fc899dd56 100644 --- a/simon/midi.h +++ b/simon/midi.h @@ -54,7 +54,7 @@ public: MidiPlayer (OSystem *system); virtual ~MidiPlayer(); - void playSMF (File *in); + void playSMF (File *in, int song); void playMultipleSMF (File *in); void playXMIDI (File *in); void jump (uint16 track, uint16 tick); diff --git a/simon/simon.cpp b/simon/simon.cpp index 8f5f4f561f..e216d669e4 100644 --- a/simon/simon.cpp +++ b/simon/simon.cpp @@ -862,10 +862,7 @@ void SimonState::playSting(uint a) { // midi.shutdown(); _mus_file->seek(_mus_offsets[a], SEEK_SET); - // midi.read_all_songs_old(_mus_file, a, _mus_offsets[a+1] - _mus_offsets[a]); - // midi.initialize(); - // midi.play(); - midi.playSMF (_mus_file); + midi.playSMF (_mus_file, a); } Subroutine *SimonState::getSubroutineByID(uint subroutine_id) { @@ -5072,7 +5069,7 @@ void SimonState::playMusic(uint music_unk, uint music) { midi.playMultipleSMF (_game_file); } else if (_game & GF_TALKIE) { _game_file->seek(_game_offsets_ptr[gss->MUSIC_INDEX_BASE + music], SEEK_SET); - midi.playSMF (_game_file); + midi.playSMF (_game_file, music); } else { char buf[50]; File *f = new File(); @@ -5082,7 +5079,7 @@ void SimonState::playMusic(uint music_unk, uint music) { warning("Can't load music from '%s'", buf); return; } - midi.playSMF (f); + midi.playSMF (f, music); delete f; } } -- cgit v1.2.3