diff options
author | Jamieson Christian | 2003-07-10 04:34:44 +0000 |
---|---|---|
committer | Jamieson Christian | 2003-07-10 04:34:44 +0000 |
commit | 4ac4d76718f5ca83b8648bc57278b2135773c2e7 (patch) | |
tree | b247d23fd1c363d44b7a0943ec40d3d7040ffd18 /sound | |
parent | 5c543d56056d84e59aca03c2a7d596d81b6fd610 (diff) | |
download | scummvm-rg350-4ac4d76718f5ca83b8648bc57278b2135773c2e7.tar.gz scummvm-rg350-4ac4d76718f5ca83b8648bc57278b2135773c2e7.tar.bz2 scummvm-rg350-4ac4d76718f5ca83b8648bc57278b2135773c2e7.zip |
Fix for Bug [766426]: V5 Games: Adlib SFX not looped
Modified Smart Jump logic to deal with active notes
whose Note On and Note Off events BOTH occur OUTSIDE
the range of the jump. While this is not a thorough
way to deal with Note On events that occur outside
jump points, it at least deals with the issue of
long, unchanging Adlib SFX used by some earlier
SCUMM games.
svn-id: r8892
Diffstat (limited to 'sound')
-rw-r--r-- | sound/midiparser.cpp | 22 | ||||
-rw-r--r-- | sound/midiparser.h | 2 |
2 files changed, 14 insertions, 10 deletions
diff --git a/sound/midiparser.cpp b/sound/midiparser.cpp index 4f083b6566..6caae0508b 100644 --- a/sound/midiparser.cpp +++ b/sound/midiparser.cpp @@ -100,7 +100,7 @@ void MidiParser::activeNote (byte channel, byte note, bool active) { } } -void MidiParser::hangingNote (byte channel, byte note, uint32 time_left) { +void MidiParser::hangingNote (byte channel, byte note, uint32 time_left, bool recycle) { NoteTimer *best = 0; NoteTimer *ptr = _hanging_notes; int i; @@ -112,11 +112,11 @@ void MidiParser::hangingNote (byte channel, byte note, uint32 time_left) { for (i = ARRAYSIZE(_hanging_notes); i; --i, ++ptr) { if (ptr->channel == channel && ptr->note == note) { - if (ptr->time_left && ptr->time_left < time_left) + if (ptr->time_left && ptr->time_left < time_left && recycle) return; best = ptr; if (ptr->time_left) { - _driver->send (0x80 | channel | note << 8); + if (recycle) _driver->send (0x80 | channel | note << 8); --_hanging_notes_count; } break; @@ -272,28 +272,32 @@ bool MidiParser::setTrack (int track) { void MidiParser::hangAllActiveNotes() { // Search for note off events until we have // accounted for every active note. + uint16 temp_active [128]; + memcpy (temp_active, _active_notes, sizeof (temp_active)); + uint32 advance_tick = _position._last_event_tick; while (true) { int i, j; for (i = 0; i < 128; ++i) - if (_active_notes[i] != 0) break; + if (temp_active[i] != 0) break; if (i == 128) break; parseNextEvent (_next_event); advance_tick += _next_event.delta; if (_next_event.command() == 0x8) { - if (_active_notes [_next_event.basic.param1] & (1 << _next_event.channel())) { - hangingNote (_next_event.channel(), _next_event.basic.param1, (advance_tick - _position._last_event_tick) * _psec_per_tick); - _active_notes [_next_event.basic.param1] &= ~ (1 << _next_event.channel()); + if (temp_active[_next_event.basic.param1] & (1 << _next_event.channel())) { + hangingNote (_next_event.channel(), _next_event.basic.param1, (advance_tick - _position._last_event_tick) * _psec_per_tick, false); + temp_active[_next_event.basic.param1] &= ~ (1 << _next_event.channel()); } } else if (_next_event.event == 0xFF && _next_event.ext.type == 0x2F) { // printf ("MidiParser::hangAllActiveNotes(): Hit End of Track with active notes left!\n"); for (i = 0; i < 128; ++i) { for (j = 0; j < 16; ++j) { - if (_active_notes[i] & (1 << j)) + if (temp_active[i] & (1 << j)) { + activeNote (j, i, false); _driver->send (0x80 | j | i << 8); + } } } - memset (_active_notes, 0, sizeof (_active_notes)); break; } } diff --git a/sound/midiparser.h b/sound/midiparser.h index 4ac4a69746..c5fad965d5 100644 --- a/sound/midiparser.h +++ b/sound/midiparser.h @@ -182,7 +182,7 @@ protected: virtual void parseNextEvent (EventInfo &info) = 0; void activeNote (byte channel, byte note, bool active); - void hangingNote (byte channel, byte note, uint32 ticks_left); + void hangingNote (byte channel, byte note, uint32 ticks_left, bool recycle = true); void hangAllActiveNotes(); //! Platform independent BE uint32 read-and-advance. |