aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorJamieson Christian2003-07-10 04:34:44 +0000
committerJamieson Christian2003-07-10 04:34:44 +0000
commit4ac4d76718f5ca83b8648bc57278b2135773c2e7 (patch)
treeb247d23fd1c363d44b7a0943ec40d3d7040ffd18 /sound
parent5c543d56056d84e59aca03c2a7d596d81b6fd610 (diff)
downloadscummvm-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.cpp22
-rw-r--r--sound/midiparser.h2
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.