diff options
author | Jamieson Christian | 2003-05-24 03:55:37 +0000 |
---|---|---|
committer | Jamieson Christian | 2003-05-24 03:55:37 +0000 |
commit | 807f3e1e865162b43a991967c2aca0b14c7fd8a5 (patch) | |
tree | 72604c19d34b66474784598fbfba44ee80d15f26 | |
parent | cd37b391b2a9c46c5cecb4f1b9662b4fb7f8bbb7 (diff) | |
download | scummvm-rg350-807f3e1e865162b43a991967c2aca0b14c7fd8a5.tar.gz scummvm-rg350-807f3e1e865162b43a991967c2aca0b14c7fd8a5.tar.bz2 scummvm-rg350-807f3e1e865162b43a991967c2aca0b14c7fd8a5.zip |
Fixed MIDI channel conflict between music and MIDI sound effects in simon1dos.
Also added notes about the GMF header for posterity's sake.
svn-id: r7877
-rw-r--r-- | simon/midi.cpp | 26 | ||||
-rw-r--r-- | simon/midi.h | 10 |
2 files changed, 22 insertions, 14 deletions
diff --git a/simon/midi.cpp b/simon/midi.cpp index bb19e43b9f..32e4119130 100644 --- a/simon/midi.cpp +++ b/simon/midi.cpp @@ -88,19 +88,18 @@ void MidiPlayer::send (uint32 b) { volume = (byte) ((b >> 16) & 0xFF) * _masterVolume / 255; _volumeTable [b & 0xF] = volume; b = (b & 0xFF00FFFF) | (volume << 16); - } else if ((b & 0xF0) == 0xC0) { - int chan = b & 0x0F; - if (!_current->in_use [chan]) - _driver->send (0x007BB0 | chan); // All Notes Off - _current->in_use [chan] = true; } else if ((b & 0xFFF0) == 0x007BB0) { // Only respond to an All Notes Off if this channel // has already been marked "in use" by this parser. - if (!_current->in_use [b & 0x0F]) + if (!_current->channel [b & 0x0F]) return; } - _driver->send (b); + byte channel = (byte) (b & 0x0F); + if (!_current->channel [channel]) + _current->channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + if (_current->channel [channel]) + _driver->send ((b & ~0x0F) | _current->channel[channel]->getNumber()); } void MidiPlayer::metaEvent (byte type, byte *data, uint16 length) { @@ -269,8 +268,10 @@ void MidiPlayer::clearConstructs (MusicInfo &info) { delete info.parser; if (_driver) { for (i = 0; i < 16; ++i) { - if (info.in_use[i]) - _driver->send (0x007BB0 | i); // All Notes Off + if (info.channel[i]) { + _driver->send (0x007BB0 | info.channel[i]->getNumber()); // All Notes Off + info.channel[i]->release(); + } } } info.clear(); @@ -299,6 +300,13 @@ void MidiPlayer::loadSMF (File *in, int song, bool sfx) { in->read (p->data, size); if (!memcmp (p->data, "GMF\x1", 4)) { + // BTW, here's what we know about the GMF header, + // the 7 bytes preceding the actual MIDI events. + // 3 BYTES: 'GMF' + // 1 BYTE : Always seems to be 0x01 + // 1 BYTE : Always seems to be 0x00 + // 1 BYTE : Ranges from 0x02 to 0x08 (always 0x02 for SFX, though) + // 1 BYTE : Loop control. 0 = no loop, 1 = loop if (!sfx) setLoop (p->data[6] != 0); diff --git a/simon/midi.h b/simon/midi.h index 02930f8960..2c6c6acbf8 100644 --- a/simon/midi.h +++ b/simon/midi.h @@ -31,17 +31,17 @@ class OSystem; struct MusicInfo { MidiParser *parser; byte * data; - byte num_songs; // For Type 1 SMF resources - byte * songs[16]; // For Type 1 SMF resources - uint32 song_sizes[16]; // For Type 1 SMF resources - bool in_use[16]; // Tracks which resource is using which MIDI channels + byte num_songs; // For Type 1 SMF resources + byte * songs[16]; // For Type 1 SMF resources + uint32 song_sizes[16]; // For Type 1 SMF resources + MidiChannel *channel[16]; // Dynamic remapping of channels to resolve conflicts MusicInfo() { clear(); } void clear() { parser = 0; data = 0; num_songs = 0; memset (songs, 0, sizeof (songs)); memset (song_sizes, 0, sizeof (song_sizes)); - memset (in_use, 0, sizeof (in_use)); + memset (channel, 0, sizeof (channel)); } }; |