[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