[Scummvm-cvs-logs] SF.net SVN: scummvm:[33763] scummvm/trunk

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Sun Aug 10 19:59:45 CEST 2008


Revision: 33763
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33763&view=rev
Author:   eriktorbjorn
Date:     2008-08-10 17:59:42 +0000 (Sun, 10 Aug 2008)

Log Message:
-----------
Committed my patch #2040074 ("XMIDI callback control events"). At the moment, I'm
not aware of any game that actually uses this XMIDI feature, so its primary
function right now is to silence lots of warnings while running the DOS version
of Simon the Sorcerer 2.

Modified Paths:
--------------
    scummvm/trunk/engines/agos/midi.cpp
    scummvm/trunk/sound/midiparser.h
    scummvm/trunk/sound/midiparser_xmidi.cpp

Modified: scummvm/trunk/engines/agos/midi.cpp
===================================================================
--- scummvm/trunk/engines/agos/midi.cpp	2008-08-10 17:37:40 UTC (rev 33762)
+++ scummvm/trunk/engines/agos/midi.cpp	2008-08-10 17:59:42 UTC (rev 33763)
@@ -538,7 +538,11 @@
 		error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
 	}
 
-	MidiParser *parser = MidiParser::createParser_XMIDI();
+	// In the DOS version of Simon the Sorcerer 2, the music contains lots
+	// of XMIDI callback controller events. As far as we know, they aren't
+	// actually used, so we disable the callback handler explicitly.
+
+	MidiParser *parser = MidiParser::createParser_XMIDI(NULL);
 	parser->setMidiDriver(this);
 	parser->setTimerRate(_driver->getBaseTempo());
 	if (!parser->loadMusic(p->data, size))

Modified: scummvm/trunk/sound/midiparser.h
===================================================================
--- scummvm/trunk/sound/midiparser.h	2008-08-10 17:37:40 UTC (rev 33762)
+++ scummvm/trunk/sound/midiparser.h	2008-08-10 17:59:42 UTC (rev 33763)
@@ -352,6 +352,8 @@
 	};
 
 public:
+	typedef void (*XMidiCallbackProc)(byte eventData, void *refCon);
+
 	MidiParser();
 	virtual ~MidiParser() { allNotesOff(); }
 
@@ -370,8 +372,10 @@
 	uint32 getPPQN() { return _ppqn; }
 	virtual uint32 getTick() { return _position._play_tick; }
 
+	static void defaultXMidiCallback(byte eventData, void *refCon);
+
 	static MidiParser *createParser_SMF();
-	static MidiParser *createParser_XMIDI();
+	static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback, void *refCon = 0);
 	static void timerCallback(void *data) { ((MidiParser *) data)->onTimer(); }
 };
 

Modified: scummvm/trunk/sound/midiparser_xmidi.cpp
===================================================================
--- scummvm/trunk/sound/midiparser_xmidi.cpp	2008-08-10 17:37:40 UTC (rev 33762)
+++ scummvm/trunk/sound/midiparser_xmidi.cpp	2008-08-10 17:59:42 UTC (rev 33763)
@@ -46,13 +46,16 @@
 	Loop _loop[4];
 	int _loopCount;
 
+	XMidiCallbackProc _callbackProc;
+	void *_callbackData;
+
 protected:
 	uint32 readVLQ2(byte * &data);
 	void resetTracking();
 	void parseNextEvent(EventInfo &info);
 
 public:
-	MidiParser_XMIDI() : _inserted_delta(0) {}
+	MidiParser_XMIDI(XMidiCallbackProc proc, void *data) : _inserted_delta(0), _callbackProc(proc), _callbackData(data) {}
 	~MidiParser_XMIDI() { }
 
 	bool loadMusic(byte *data, uint32 size);
@@ -103,23 +106,22 @@
 		info.basic.param1 = *(_position._play_pos++);
 		info.basic.param2 = *(_position._play_pos++);
 
+		// This isn't a full XMIDI implementation, but it should
+		// hopefully be "good enough" for most things.
+
+		switch (info.basic.param1) {
 		// Simplified XMIDI looping.
-		//
-		// I would really like to turn the loop events into some sort
-		// of NOP event (perhaps a dummy META event?), but for now we
-		// just pass them on to the MIDI driver. That has worked in the
-		// past, so it shouldn't cause any actual damage...
+		case 0x74: {	// XMIDI_CONTROLLER_FOR_LOOP
+				byte *pos = _position._play_pos;
+				if (_loopCount < ARRAYSIZE(_loop) - 1)
+					_loopCount++;
 
-		if (info.basic.param1 == 0x74) {
-			// XMIDI_CONTROLLER_FOR_LOOP
-			byte *pos = _position._play_pos;
-			if (_loopCount < ARRAYSIZE(_loop) - 1)
-				_loopCount++;
+				_loop[_loopCount].pos = pos;
+				_loop[_loopCount].repeat = info.basic.param2;
+				break;
+			}
 
-			_loop[_loopCount].pos = pos;
-			_loop[_loopCount].repeat = info.basic.param2;
-		} else if (info.basic.param1 == 0x75) {
-			// XMIDI_CONTROLLER_NEXT_BREAK
+		case 0x75:	// XMIDI_CONTORLLER_NEXT_BREAK
 			if (_loopCount >= 0) {
 				if (info.basic.param2 < 64) {
 					// End the current loop.
@@ -133,10 +135,26 @@
 					}
 				}
 			}
-		} else if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
-			warning("Unsupported XMIDI controller %d (0x%2x)",
-				info.basic.param1, info.basic.param1);
+			break;
+
+		case 0x77:	// XMIDI_CONTROLLER_CALLBACK_TRIG
+			if (_callbackProc)
+				_callbackProc(info.basic.param2, _callbackData);
+			break;
+
+		default:
+			if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
+				warning("Unsupported XMIDI controller %d (0x%2x)",
+					info.basic.param1, info.basic.param1);
+			}
+			break;
 		}
+
+		// Should we really keep passing the XMIDI controller events to
+		// the MIDI driver, or should we turn them into some kind of
+		// NOP events? (Dummy meta events, perhaps?) Ah well, it has
+		// worked so far, so it shouldn't cause any damage...
+
 		break;
 
 	case 0xF: // Meta or SysEx event
@@ -336,4 +354,10 @@
 	_inserted_delta = 0;
 }
 
-MidiParser *MidiParser::createParser_XMIDI() { return new MidiParser_XMIDI; }
+void MidiParser::defaultXMidiCallback(byte eventData, void *data) {
+	warning("MidiParser: defaultXMidiCallback(%d)", eventData);
+}
+
+MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data) {
+	return new MidiParser_XMIDI(proc, data);
+}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list