aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamieson Christian2003-05-24 03:55:37 +0000
committerJamieson Christian2003-05-24 03:55:37 +0000
commit807f3e1e865162b43a991967c2aca0b14c7fd8a5 (patch)
tree72604c19d34b66474784598fbfba44ee80d15f26
parentcd37b391b2a9c46c5cecb4f1b9662b4fb7f8bbb7 (diff)
downloadscummvm-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.cpp26
-rw-r--r--simon/midi.h10
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));
}
};