[Scummvm-cvs-logs] scummvm master -> a0e0b21d91e6addb2524dc5ff5477892630b0d20
wjp
wjp at usecode.org
Sat Sep 21 20:11:07 CEST 2013
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6c5a5cd8e9 AUDIO: Split event processing from MidiParser::onTimer
da81c59308 AUDIO: Let jumpToTick use processEvent too
86c2fe47e0 AUDIO: Simplify MidiTracker::processEvent return value
11d425b76c SCI: Move MIDI event processing out of parseNextEvent
3792af8e95 AUDIO: Simplify SCI inFastForward flag by moving it to MidiParser
a6d902df28 SCI: Handle !fireEvents in processEvent
4b5ca10f68 Merge branch 'master' into sci_midiparser
a0e0b21d91 Merge pull request #398 from wjp/sci_midiparser
Commit: 6c5a5cd8e90fcaafae6fd6f409fde04b29fa7e7a
https://github.com/scummvm/scummvm/commit/6c5a5cd8e90fcaafae6fd6f409fde04b29fa7e7a
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-20T15:22:56-07:00
Commit Message:
AUDIO: Split event processing from MidiParser::onTimer
This is to prepare for overriding more of this functionality in SCI.
Changed paths:
audio/midiparser.cpp
audio/midiparser.h
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index 9c144c2..0a81836 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -204,44 +204,18 @@ void MidiParser::onTimer() {
return;
}
- if (info.event == 0xF0) {
- // SysEx event
- // Check for trailing 0xF7 -- if present, remove it.
- if (info.ext.data[info.length-1] == 0xF7)
- _driver->sysEx(info.ext.data, (uint16)info.length-1);
+ if (info.command() == 0x8) {
+ activeNote(info.channel(), info.basic.param1, false);
+ } else if (info.command() == 0x9) {
+ if (info.length > 0)
+ hangingNote(info.channel(), info.basic.param1, info.length * _psecPerTick - (endTime - eventTime));
else
- _driver->sysEx(info.ext.data, (uint16)info.length);
- } else if (info.event == 0xFF) {
- // META event
- if (info.ext.type == 0x2F) {
- // End of Track must be processed by us,
- // as well as sending it to the output device.
- if (_autoLoop) {
- jumpToTick(0);
- parseNextEvent(_nextEvent);
- } else {
- stopPlaying();
- _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
- }
- return;
- } else if (info.ext.type == 0x51) {
- if (info.length >= 3) {
- setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
- }
- }
- _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
- } else {
- if (info.command() == 0x8) {
- activeNote(info.channel(), info.basic.param1, false);
- } else if (info.command() == 0x9) {
- if (info.length > 0)
- hangingNote(info.channel(), info.basic.param1, info.length * _psecPerTick - (endTime - eventTime));
- else
- activeNote(info.channel(), info.basic.param1, true);
- }
- sendToDriver(info.event, info.basic.param1, info.basic.param2);
+ activeNote(info.channel(), info.basic.param1, true);
}
+ bool ret = processEvent(info);
+ if (!ret)
+ return;
if (!_abortParse) {
_position._lastEventTime = eventTime;
@@ -255,6 +229,41 @@ void MidiParser::onTimer() {
}
}
+bool MidiParser::processEvent(const EventInfo &info) {
+ if (info.event == 0xF0) {
+ // SysEx event
+ // Check for trailing 0xF7 -- if present, remove it.
+ if (info.ext.data[info.length-1] == 0xF7)
+ _driver->sysEx(info.ext.data, (uint16)info.length-1);
+ else
+ _driver->sysEx(info.ext.data, (uint16)info.length);
+ } else if (info.event == 0xFF) {
+ // META event
+ if (info.ext.type == 0x2F) {
+ // End of Track must be processed by us,
+ // as well as sending it to the output device.
+ if (_autoLoop) {
+ jumpToTick(0);
+ parseNextEvent(_nextEvent);
+ } else {
+ stopPlaying();
+ _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
+ }
+ return false;
+ } else if (info.ext.type == 0x51) {
+ if (info.length >= 3) {
+ setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
+ }
+ }
+ _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
+ } else {
+ sendToDriver(info.event, info.basic.param1, info.basic.param2);
+ }
+
+ return true;
+}
+
+
void MidiParser::allNotesOff() {
if (!_driver)
return;
diff --git a/audio/midiparser.h b/audio/midiparser.h
index bb9749b..4470d7d 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -105,8 +105,8 @@ struct EventInfo {
///< will occur, and the MidiParser will have to generate one itself.
///< For all other events, this value should always be zero.
- byte channel() { return event & 0x0F; } ///< Separates the MIDI channel from the event.
- byte command() { return event >> 4; } ///< Separates the command code from the event.
+ byte channel() const { return event & 0x0F; } ///< Separates the MIDI channel from the event.
+ byte command() const { return event >> 4; } ///< Separates the command code from the event.
};
/**
@@ -293,6 +293,7 @@ protected:
virtual void resetTracking();
virtual void allNotesOff();
virtual void parseNextEvent(EventInfo &info) = 0;
+ virtual bool processEvent(const EventInfo &info);
void activeNote(byte channel, byte note, bool active);
void hangingNote(byte channel, byte note, uint32 ticksLeft, bool recycle = true);
Commit: da81c593081ffebb33740ada85d9c2a5084f7d0a
https://github.com/scummvm/scummvm/commit/da81c593081ffebb33740ada85d9c2a5084f7d0a
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-20T15:22:58-07:00
Commit Message:
AUDIO: Let jumpToTick use processEvent too
Changed paths:
audio/midiparser.cpp
audio/midiparser.h
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index 0a81836..23da903 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -229,14 +229,16 @@ void MidiParser::onTimer() {
}
}
-bool MidiParser::processEvent(const EventInfo &info) {
+bool MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (info.event == 0xF0) {
// SysEx event
// Check for trailing 0xF7 -- if present, remove it.
- if (info.ext.data[info.length-1] == 0xF7)
- _driver->sysEx(info.ext.data, (uint16)info.length-1);
- else
- _driver->sysEx(info.ext.data, (uint16)info.length);
+ if (fireEvents) {
+ if (info.ext.data[info.length-1] == 0xF7)
+ _driver->sysEx(info.ext.data, (uint16)info.length-1);
+ else
+ _driver->sysEx(info.ext.data, (uint16)info.length);
+ }
} else if (info.event == 0xFF) {
// META event
if (info.ext.type == 0x2F) {
@@ -247,7 +249,8 @@ bool MidiParser::processEvent(const EventInfo &info) {
parseNextEvent(_nextEvent);
} else {
stopPlaying();
- _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
+ if (fireEvents)
+ _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
}
return false;
} else if (info.ext.type == 0x51) {
@@ -255,9 +258,11 @@ bool MidiParser::processEvent(const EventInfo &info) {
setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
}
}
- _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
+ if (fireEvents)
+ _driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
} else {
- sendToDriver(info.event, info.basic.param1, info.basic.param2);
+ if (fireEvents)
+ sendToDriver(info.event, info.basic.param1, info.basic.param2);
}
return true;
@@ -399,34 +404,18 @@ bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool d
_position._playTick = _position._lastEventTick;
_position._playTime = _position._lastEventTime;
- if (info.event == 0xFF) {
- if (info.ext.type == 0x2F) { // End of track
- _position = currentPos;
- _nextEvent = currentEvent;
- return false;
- } else {
- if (info.ext.type == 0x51 && info.length >= 3) // Tempo
- setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
- if (fireEvents)
- _driver->metaEvent(info.ext.type, info.ext.data, (uint16) info.length);
- }
- } else if (fireEvents) {
- if (info.event == 0xF0) {
- if (info.ext.data[info.length-1] == 0xF7)
- _driver->sysEx(info.ext.data, (uint16)info.length-1);
- else
- _driver->sysEx(info.ext.data, (uint16)info.length);
- } else {
- // The note on sending code is used by the SCUMM engine. Other engine using this code
- // (such as SCI) have issues with this, as all the notes sent can be heard when a song
- // is fast-forwarded. Thus, if the engine requests it, don't send note on events.
- if (info.command() == 0x9 && dontSendNoteOn) {
- // Don't send note on; doing so creates a "warble" with some instruments on the MT-32.
- // Refer to patch #3117577
- } else {
- sendToDriver(info.event, info.basic.param1, info.basic.param2);
- }
- }
+ // Some special processing for the fast-forward case
+ if (info.command() == 0x9 && dontSendNoteOn) {
+ // Don't send note on; doing so creates a "warble" with
+ // some instruments on the MT-32. Refer to patch #3117577
+ } else if (info.event == 0xFF && info.ext.type == 0x2F) {
+ // End of track
+ // This means that we failed to find the right tick.
+ _position = currentPos;
+ _nextEvent = currentEvent;
+ return false;
+ } else {
+ processEvent(info, fireEvents);
}
parseNextEvent(_nextEvent);
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 4470d7d..e9a8881 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -293,7 +293,7 @@ protected:
virtual void resetTracking();
virtual void allNotesOff();
virtual void parseNextEvent(EventInfo &info) = 0;
- virtual bool processEvent(const EventInfo &info);
+ virtual bool processEvent(const EventInfo &info, bool fireEvents = true);
void activeNote(byte channel, byte note, bool active);
void hangingNote(byte channel, byte note, uint32 ticksLeft, bool recycle = true);
Commit: 86c2fe47e04449602e4c005fa0a9c183bc8bba39
https://github.com/scummvm/scummvm/commit/86c2fe47e04449602e4c005fa0a9c183bc8bba39
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-20T16:08:26-07:00
Commit Message:
AUDIO: Simplify MidiTracker::processEvent return value
Changed paths:
audio/midiparser.cpp
audio/midiparser.h
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index 23da903..dcb83bb 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -213,14 +213,13 @@ void MidiParser::onTimer() {
activeNote(info.channel(), info.basic.param1, true);
}
- bool ret = processEvent(info);
- if (!ret)
- return;
+ processEvent(info);
- if (!_abortParse) {
- _position._lastEventTime = eventTime;
- parseNextEvent(_nextEvent);
- }
+ if (_abortParse)
+ break;
+
+ _position._lastEventTime = eventTime;
+ parseNextEvent(_nextEvent);
}
if (!_abortParse) {
@@ -229,7 +228,7 @@ void MidiParser::onTimer() {
}
}
-bool MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
+void MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (info.event == 0xF0) {
// SysEx event
// Check for trailing 0xF7 -- if present, remove it.
@@ -252,7 +251,8 @@ bool MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (fireEvents)
_driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
}
- return false;
+ _abortParse = true;
+ return;
} else if (info.ext.type == 0x51) {
if (info.length >= 3) {
setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
@@ -264,8 +264,6 @@ bool MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (fireEvents)
sendToDriver(info.event, info.basic.param1, info.basic.param2);
}
-
- return true;
}
diff --git a/audio/midiparser.h b/audio/midiparser.h
index e9a8881..28f39e6 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -293,7 +293,7 @@ protected:
virtual void resetTracking();
virtual void allNotesOff();
virtual void parseNextEvent(EventInfo &info) = 0;
- virtual bool processEvent(const EventInfo &info, bool fireEvents = true);
+ virtual void processEvent(const EventInfo &info, bool fireEvents = true);
void activeNote(byte channel, byte note, bool active);
void hangingNote(byte channel, byte note, uint32 ticksLeft, bool recycle = true);
Commit: 11d425b76c7d6cdae8b72a1c3c438cc74e9c37a0
https://github.com/scummvm/scummvm/commit/11d425b76c7d6cdae8b72a1c3c438cc74e9c37a0
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-20T16:43:04-07:00
Commit Message:
SCI: Move MIDI event processing out of parseNextEvent
Changed paths:
engines/sci/sound/midiparser_sci.cpp
engines/sci/sound/midiparser_sci.h
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 4b4333a..0af8e7a 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -53,11 +53,6 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) :
_masterVolume = 15;
_volume = 127;
- _signalSet = false;
- _signalToSet = 0;
- _dataincAdd = false;
- _dataincToAdd = 0;
- _jumpToHoldTick = false;
_resetOnPause = false;
_pSnd = 0;
}
@@ -440,26 +435,6 @@ void MidiParser_SCI::sendToDriver(uint32 midi) {
}
void MidiParser_SCI::parseNextEvent(EventInfo &info) {
- // Set signal AFTER waiting for delta, otherwise we would set signal too soon resulting in all sorts of bugs
- if (_dataincAdd) {
- _dataincAdd = false;
- _pSnd->dataInc += _dataincToAdd;
- _pSnd->signal = 0x7f + _pSnd->dataInc;
- debugC(4, kDebugLevelSound, "datainc %04x", _dataincToAdd);
- }
- if (_signalSet) {
- _signalSet = false;
- _pSnd->setSignal(_signalToSet);
-
- debugC(4, kDebugLevelSound, "signal %04x", _signalToSet);
- }
- if (_jumpToHoldTick) {
- _jumpToHoldTick = false;
- _pSnd->inFastForward = true;
- jumpToTick(_loopTick, false, false);
- _pSnd->inFastForward = false;
- }
-
info.start = _position._playPos;
info.delta = 0;
while (*_position._playPos == 0xF8) {
@@ -481,6 +456,76 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0xC:
info.basic.param1 = *(_position._playPos++);
info.basic.param2 = 0;
+ break;
+ case 0xD:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = 0;
+ break;
+
+ case 0xB:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ info.length = 0;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xE:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ if (info.command() == 0x9 && info.basic.param2 == 0)
+ info.event = info.channel() | 0x80;
+ info.length = 0;
+ break;
+
+ case 0xF: // System Common, Meta or SysEx event
+ switch (info.event & 0x0F) {
+ case 0x2: // Song Position Pointer
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ break;
+
+ case 0x3: // Song Select
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = 0;
+ break;
+
+ case 0x6:
+ case 0x8:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xE:
+ info.basic.param1 = info.basic.param2 = 0;
+ break;
+
+ case 0x0: // SysEx
+ info.length = readVLQ(_position._playPos);
+ info.ext.data = _position._playPos;
+ _position._playPos += info.length;
+ break;
+
+ case 0xF: // META event
+ info.ext.type = *(_position._playPos++);
+ info.length = readVLQ(_position._playPos);
+ info.ext.data = _position._playPos;
+ _position._playPos += info.length;
+ break;
+ default:
+ warning(
+ "MidiParser_SCI::parseNextEvent: Unsupported event code %x",
+ info.event);
+ } // // System Common, Meta or SysEx event
+ }// switch (info.command())
+}
+
+void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
+
+ // TODO: Properly handle fireEvents
+
+ switch (info.command()) {
+ case 0xC:
if (info.channel() == 0xF) {// SCI special case
if (info.basic.param1 != kSetSignalLoop) {
// At least in kq5/french&mac the first scene in the intro has
@@ -497,27 +542,23 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
// of the stream, but at a fixed location a few commands later.
// That is probably why this signal isn't triggered
// immediately there.
- if (_soundVersion <= SCI_VERSION_0_LATE ||
- _position._playTick || info.delta) {
+ if (_soundVersion <= SCI_VERSION_0_LATE || _position._playTick) {
if (!_pSnd->inFastForward) {
- _signalSet = true;
- _signalToSet = info.basic.param1;
+ _pSnd->setSignal(info.basic.param1);
+ debugC(4, kDebugLevelSound, "signal %04x", info.basic.param1);
}
}
} else {
- _loopTick = _position._playTick + info.delta;
+ _loopTick = _position._playTick;
}
+
+ // Done with this event.
+ return;
}
- break;
- case 0xD:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = 0;
- break;
+ // Break to let parent handle the rest.
+ break;
case 0xB:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
-
// Reference for some events:
// http://wiki.scummvm.org/index.php/SCI/Specifications/Sound/SCI0_Resource_Format#Status_Reference
// Handle common special events
@@ -539,50 +580,51 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
switch (info.basic.param1) {
case kSetReverb:
// Already handled above
- break;
+ return;
case kMidiHold:
// Check if the hold ID marker is the same as the hold ID
// marker set for that song by cmdSetSoundHold.
// If it is, loop back, but don't stop notes when jumping.
- // We need to wait for the delta of the current event before
- // jumping, thus the jump will be performed on the next
- // parseNextEvent() call, like with the signal set events.
- // In LSL6, room 360, song 381, this ends up jumping forward
- // one tick (the hold marker occurs at playtick 27, with
- // _loopTick being 15 and the event itself having a delta of
- // 13, total = 28) - bug #3614566.
if (info.basic.param2 == _pSnd->hold) {
- _jumpToHoldTick = true;
+ _pSnd->inFastForward = true;
+ jumpToTick(_loopTick, false, false);
+ _pSnd->inFastForward = false;
+ // Done with this event.
+ return;
}
- break;
+ return;
case kUpdateCue:
if (!_pSnd->inFastForward) {
- _dataincAdd = true;
+ int inc;
switch (_soundVersion) {
case SCI_VERSION_0_EARLY:
case SCI_VERSION_0_LATE:
- _dataincToAdd = info.basic.param2;
+ inc = info.basic.param2;
break;
case SCI_VERSION_1_EARLY:
case SCI_VERSION_1_LATE:
case SCI_VERSION_2_1:
- _dataincToAdd = 1;
+ inc = 1;
break;
default:
error("unsupported _soundVersion");
}
+ _pSnd->dataInc += inc;
+ _pSnd->signal = 0x7f + inc;
+ debugC(4, kDebugLevelSound, "datainc %04x", inc);
+
}
- break;
+ return;
case kResetOnPause:
_resetOnPause = info.basic.param2;
- break;
+ return;
// Unhandled SCI commands
case 0x46: // LSL3 - binoculars
case 0x61: // Iceman (AdLib?)
case 0x73: // Hoyle
case 0xD1: // KQ4, when riding the unicorn
// Obscure SCI commands - ignored
- break;
+ return;
// Standard MIDI commands
case 0x01: // mod wheel
case 0x04: // foot controller
@@ -597,96 +639,51 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0x4B: // voice mapping
// TODO: is any support for this needed at the MIDI parser level?
warning("Unhanded SCI MIDI command 0x%x - voice mapping (parameter %d)", info.basic.param1, info.basic.param2);
- break;
+ return;
default:
warning("Unhandled SCI MIDI command 0x%x (parameter %d)", info.basic.param1, info.basic.param2);
- break;
+ return;
}
+
}
- info.length = 0;
- break;
- case 0x8:
- case 0x9:
- case 0xA:
- case 0xE:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
- if (info.command() == 0x9 && info.basic.param2 == 0)
- info.event = info.channel() | 0x80;
- info.length = 0;
+ // Break to let parent handle the rest.
break;
+ case 0xF: // META event
+ if (info.ext.type == 0x2F) {// end of track reached
+ if (_pSnd->loop)
+ _pSnd->loop--;
+ // QFG3 abuses the hold flag. Its scripts call kDoSoundSetHold,
+ // but sometimes there's no hold marker in the associated songs
+ // (e.g. song 110, during the intro). The original interpreter
+ // treats this case as an infinite loop (bug #3311911).
+ if (_pSnd->loop || _pSnd->hold > 0) {
+ _pSnd->inFastForward = true;
+ jumpToTick(_loopTick);
+ _pSnd->inFastForward = false;
+
+ // Done with this event.
+ return;
- case 0xF: // System Common, Meta or SysEx event
- switch (info.event & 0x0F) {
- case 0x2: // Song Position Pointer
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
- break;
+ } else {
+ _pSnd->status = kSoundStopped;
+ _pSnd->setSignal(SIGNAL_OFFSET);
- case 0x3: // Song Select
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = 0;
- break;
+ debugC(4, kDebugLevelSound, "signal EOT");
+ }
+ }
- case 0x6:
- case 0x8:
- case 0xA:
- case 0xB:
- case 0xC:
- case 0xE:
- info.basic.param1 = info.basic.param2 = 0;
- break;
+ // Break to let parent handle the rest.
+ break;
- case 0x0: // SysEx
- info.length = readVLQ(_position._playPos);
- info.ext.data = _position._playPos;
- _position._playPos += info.length;
- break;
+ default:
+ // Break to let parent handle the rest.
+ break;
+ }
- case 0xF: // META event
- info.ext.type = *(_position._playPos++);
- info.length = readVLQ(_position._playPos);
- info.ext.data = _position._playPos;
- _position._playPos += info.length;
- if (info.ext.type == 0x2F) {// end of track reached
- if (_pSnd->loop)
- _pSnd->loop--;
- // QFG3 abuses the hold flag. Its scripts call kDoSoundSetHold,
- // but sometimes there's no hold marker in the associated songs
- // (e.g. song 110, during the intro). The original interpreter
- // treats this case as an infinite loop (bug #3311911).
- if (_pSnd->loop || _pSnd->hold > 0) {
- // TODO: this jump is also vulnerable to the same lockup as
- // the MIDI hold one above. However, we can't perform the
- // jump on the next tick like with the MIDI hold jump above,
- // as there aren't any subsequent MIDI events after this one.
- // This assert is here to detect cases where the song ends
- // up jumping forward, like with bug #3614566 (see above).
- // (Exception: delta == 0, in which case the loop points
- // at the previous event, which is fine.)
- assert(_loopTick + info.delta < _position._playTick ||
- ((_loopTick == _position._playTick && info.delta == 0)));
-
- uint32 extraDelta = info.delta;
- _pSnd->inFastForward = true;
- jumpToTick(_loopTick);
- _pSnd->inFastForward = false;
- _nextEvent.delta += extraDelta;
- } else {
- _pSnd->status = kSoundStopped;
- _pSnd->setSignal(SIGNAL_OFFSET);
- debugC(4, kDebugLevelSound, "signal EOT");
- }
- }
- break;
- default:
- warning(
- "MidiParser_SCI::parseNextEvent: Unsupported event code %x",
- info.event);
- } // // System Common, Meta or SysEx event
- }// switch (info.command())
+ // Let parent handle the rest
+ MidiParser::processEvent(info, fireEvents);
}
byte MidiParser_SCI::getSongReverb() {
diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h
index 7bd6899..5784dca 100644
--- a/engines/sci/sound/midiparser_sci.h
+++ b/engines/sci/sound/midiparser_sci.h
@@ -89,6 +89,7 @@ public:
protected:
void parseNextEvent(EventInfo &info);
+ void processEvent(const EventInfo &info, bool fireEvents = true);
byte *midiMixChannels();
byte *midiFilterChannels(int channelMask);
byte midiGetNextChannel(long ticker);
@@ -106,11 +107,6 @@ protected:
byte _masterVolume; // the overall master volume (same for all tracks)
byte _volume; // the global volume of the current track
- bool _signalSet;
- int16 _signalToSet;
- bool _dataincAdd;
- int16 _dataincToAdd;
- bool _jumpToHoldTick;
bool _resetOnPause;
bool _channelUsed[16];
Commit: 3792af8e955bea5a07359c808361a16b15481327
https://github.com/scummvm/scummvm/commit/3792af8e955bea5a07359c808361a16b15481327
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-21T00:31:08-07:00
Commit Message:
AUDIO: Simplify SCI inFastForward flag by moving it to MidiParser
Changed paths:
audio/midiparser.cpp
audio/midiparser.h
engines/sci/sound/midiparser_sci.cpp
engines/sci/sound/music.cpp
engines/sci/sound/music.h
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index dcb83bb..2454575 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -44,7 +44,8 @@ _centerPitchWheelOnUnload(false),
_sendSustainOffOnNotesOff(false),
_numTracks(0),
_activeTrack(255),
-_abortParse(0) {
+_abortParse(false),
+_jumpingToTick(false) {
memset(_activeNotes, 0, sizeof(_activeNotes));
memset(_tracks, 0, sizeof(_tracks));
_nextEvent.start = NULL;
@@ -382,6 +383,9 @@ bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool d
if (_activeTrack >= _numTracks)
return false;
+ assert(!_jumpingToTick); // This function is not re-entrant
+ _jumpingToTick = true;
+
Tracker currentPos(_position);
EventInfo currentEvent(_nextEvent);
@@ -411,6 +415,7 @@ bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool d
// This means that we failed to find the right tick.
_position = currentPos;
_nextEvent = currentEvent;
+ _jumpingToTick = false;
return false;
} else {
processEvent(info, fireEvents);
@@ -437,6 +442,7 @@ bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool d
}
_abortParse = true;
+ _jumpingToTick = false;
return true;
}
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 28f39e6..05d0cbe 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -287,6 +287,7 @@ protected:
///< so each event is parsed only once; this permits
///< simulated events in certain formats.
bool _abortParse; ///< If a jump or other operation interrupts parsing, flag to abort.
+ bool _jumpingToTick; ///< True if currently inside jumpToTick
protected:
static uint32 readVLQ(byte * &data);
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 0af8e7a..40ae91d 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -543,7 +543,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
// That is probably why this signal isn't triggered
// immediately there.
if (_soundVersion <= SCI_VERSION_0_LATE || _position._playTick) {
- if (!_pSnd->inFastForward) {
+ if (!_jumpingToTick) {
_pSnd->setSignal(info.basic.param1);
debugC(4, kDebugLevelSound, "signal %04x", info.basic.param1);
}
@@ -586,15 +586,13 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
// marker set for that song by cmdSetSoundHold.
// If it is, loop back, but don't stop notes when jumping.
if (info.basic.param2 == _pSnd->hold) {
- _pSnd->inFastForward = true;
jumpToTick(_loopTick, false, false);
- _pSnd->inFastForward = false;
// Done with this event.
return;
}
return;
case kUpdateCue:
- if (!_pSnd->inFastForward) {
+ if (!_jumpingToTick) {
int inc;
switch (_soundVersion) {
case SCI_VERSION_0_EARLY:
@@ -658,9 +656,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
// (e.g. song 110, during the intro). The original interpreter
// treats this case as an infinite loop (bug #3311911).
if (_pSnd->loop || _pSnd->hold > 0) {
- _pSnd->inFastForward = true;
jumpToTick(_loopTick);
- _pSnd->inFastForward = false;
// Done with this event.
return;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 1628a22..8c6d0d6 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -521,11 +521,7 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
pSnd->pMidiParser->jumpToTick(0);
else {
// Fast forward to the last position and perform associated events when loading
- pSnd->inFastForward = true;
- // we set this flag, so that the midiparser doesn't set any signals for scripts
- // if we don't do this, at least accessing the debugger will reset previously set signals
pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
- pSnd->inFastForward = false;
}
// Restore looping and hold
@@ -765,7 +761,6 @@ MusicEntry::MusicEntry() {
resourceId = 0;
isQueued = false;
- inFastForward = false;
dataInc = 0;
ticker = 0;
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 5924a0f..1f798c9 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -65,7 +65,6 @@ public:
uint16 resourceId;
bool isQueued; // for SCI0 only!
- bool inFastForward; // if we are currently fast-forwarding (disables any signals to scripts)
uint16 dataInc;
uint16 ticker;
Commit: a6d902df2827b91dc641b6f51c0a070b70a09179
https://github.com/scummvm/scummvm/commit/a6d902df2827b91dc641b6f51c0a070b70a09179
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-21T05:42:59-07:00
Commit Message:
SCI: Handle !fireEvents in processEvent
Changed paths:
engines/sci/sound/midiparser_sci.cpp
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 40ae91d..3332edd 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -521,8 +521,11 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
}
void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
-
- // TODO: Properly handle fireEvents
+ if (!fireEvents) {
+ // We don't do any processing that should be done while skipping events
+ MidiParser::processEvent(info, fireEvents);
+ return;
+ }
switch (info.command()) {
case 0xC:
Commit: 4b5ca10f68effb88e297d72f6ea366d760acf9ed
https://github.com/scummvm/scummvm/commit/4b5ca10f68effb88e297d72f6ea366d760acf9ed
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-21T11:05:47-07:00
Commit Message:
Merge branch 'master' into sci_midiparser
Conflicts:
engines/sci/sound/midiparser_sci.cpp
Changed paths:
A engines/neverhood/modules/module2800_sprites.cpp
A engines/neverhood/modules/module2800_sprites.h
common/coroutines.h
engines/fullpipe/scene.cpp
engines/fullpipe/sound.h
engines/fullpipe/utils.h
engines/neverhood/menumodule.cpp
engines/neverhood/module.mk
engines/neverhood/modules/module2400.h
engines/neverhood/modules/module2800.cpp
engines/neverhood/modules/module2800.h
engines/sci/detection_tables.h
engines/sci/engine/savegame.cpp
engines/sci/engine/savegame.h
engines/sci/sound/midiparser_sci.cpp
engines/sci/sound/music.h
engines/sci/sound/soundcmd.cpp
engines/tsage/globals.cpp
engines/tsage/globals.h
engines/tsage/ringworld2/ringworld2_scenes1.cpp
engines/tsage/ringworld2/ringworld2_scenes1.h
diff --cc engines/sci/sound/midiparser_sci.cpp
index 3332edd,b367eee..d6ff4f6
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@@ -610,15 -570,11 +610,14 @@@ void MidiParser_SCI::processEvent(cons
default:
error("unsupported _soundVersion");
}
+ _pSnd->dataInc += inc;
- _pSnd->signal = 0x7f + inc;
+ debugC(4, kDebugLevelSound, "datainc %04x", inc);
+
}
- break;
+ return;
case kResetOnPause:
_resetOnPause = info.basic.param2;
- break;
+ return;
// Unhandled SCI commands
case 0x46: // LSL3 - binoculars
case 0x61: // Iceman (AdLib?)
Commit: a0e0b21d91e6addb2524dc5ff5477892630b0d20
https://github.com/scummvm/scummvm/commit/a0e0b21d91e6addb2524dc5ff5477892630b0d20
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-21T11:10:40-07:00
Commit Message:
Merge pull request #398 from wjp/sci_midiparser
SCI: Move MIDI event processing out of parseNextEvent
Changed paths:
audio/midiparser.cpp
audio/midiparser.h
engines/sci/sound/midiparser_sci.cpp
engines/sci/sound/midiparser_sci.h
engines/sci/sound/music.cpp
engines/sci/sound/music.h
More information about the Scummvm-git-logs
mailing list