[Scummvm-git-logs] scummvm master -> 3b4810aab41a1e3ebcaf9b64e355c851b741c8c8

bluegr bluegr at gmail.com
Fri Feb 28 06:27:16 UTC 2020


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
3b4810aab4 AUDIO: Added dump-midi mechanism


Commit: 3b4810aab41a1e3ebcaf9b64e355c851b741c8c8
    https://github.com/scummvm/scummvm/commit/3b4810aab41a1e3ebcaf9b64e355c851b741c8c8
Author: Zvika Haramaty (haramaty.zvika at gmail.com)
Date: 2020-02-28T08:27:12+02:00

Commit Message:
AUDIO: Added dump-midi mechanism

This mechanism is enabled by '--dump-midi' command line parameter.
The midi events are printed to screen, and dumped to 'dump.mid' file.

Changed paths:
    README.md
    audio/adlib.cpp
    audio/mididrv.cpp
    audio/mididrv.h
    audio/midiplayer.h
    audio/miles_adlib.cpp
    audio/miles_mt32.cpp
    audio/softsynth/eas.cpp
    audio/softsynth/fluidsynth.cpp
    audio/softsynth/mt32.cpp
    backends/midi/alsa.cpp
    backends/midi/camd.cpp
    backends/midi/coreaudio.cpp
    backends/midi/coremidi.cpp
    backends/midi/dmedia.cpp
    backends/midi/seq.cpp
    backends/midi/sndio.cpp
    backends/midi/stmidi.cpp
    backends/midi/timidity.cpp
    backends/midi/windows.cpp
    base/commandLine.cpp
    base/main.cpp


diff --git a/README.md b/README.md
index cf46c4154d..a530c81def 100644
--- a/README.md
+++ b/README.md
@@ -1428,6 +1428,8 @@ arguments -- see the next section.
                               supported by some MIDI drivers)
     --multi-midi             Enable combination of AdLib and native MIDI
     --native-mt32            True Roland MT-32 (disable GM emulation)
+    --dump-midi              Dumps MIDI events to 'dump.mid', until quitting from game
+                              (if file already exists, it will be overwritten)
     --enable-gs              Enable Roland GS mode for MIDI playback
     --output-rate=RATE       Select output sample rate in Hz (e.g. 22050)
     --opl-driver=DRIVER      Select AdLib (OPL) emulator (db, mame, nuked)
diff --git a/audio/adlib.cpp b/audio/adlib.cpp
index c1e68fcad2..09bc8cb3df 100644
--- a/audio/adlib.cpp
+++ b/audio/adlib.cpp
@@ -935,7 +935,7 @@ public:
 
 	int open();
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void send(byte channel, uint32 b); // Supports higher than channel 15
 	uint32 property(int prop, uint32 param);
 	bool isOpen() const { return _isOpen; }
diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index d75c098065..ca5cd592a5 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -28,6 +28,7 @@
 #include "common/textconsole.h"
 #include "common/translation.h"
 #include "common/util.h"
+#include "common/file.h"
 #include "gui/message.h"
 #include "audio/mididrv.h"
 #include "audio/musicplugin.h"
@@ -441,3 +442,128 @@ void MidiDriver::sendGMReset() {
 	sysEx(resetSysEx, sizeof(resetSysEx));
 	g_system->delayMillis(100);
 }
+
+
+void MidiDriver_BASE::midiDumpInit() {
+	g_system->displayMessageOnOSD(_("Starting MIDI dump"));
+	_midiDumpCache.clear();
+	_prevMillis = g_system->getMillis(true);
+}
+
+int MidiDriver_BASE::midiDumpVarLength(const uint32 &delta) {
+	// MIDI file format has a very strange representation - "Variable Length Values"
+	// we're using only *7* bits of each byte for the data
+	// the MSB bit is 1 for all bytes, except the last one
+	if (delta <= 127) {
+		// "Variable Length Values" of 1 byte
+		debugN("0x%02x", delta);
+		_midiDumpCache.push_back(delta);
+		return 1;
+	} else {
+		// "Variable Length Values" of 2 bytes
+		// theoretically, "Variable Length Values" can have more than 2 bytes, but it won't happen in our use case
+		byte msb = delta / 128;
+		msb |= 0x80;
+		byte lsb = delta % 128;
+		debugN("0x%02x,0x%02x", msb, lsb);
+		_midiDumpCache.push_back(msb);
+		_midiDumpCache.push_back(lsb);
+		return 2;
+	}
+}
+
+void MidiDriver_BASE::midiDumpDelta() {
+	uint32 millis = g_system->getMillis(true);
+	uint32 delta = millis - _prevMillis;
+	_prevMillis = millis;
+
+	debugN("MIDI : delta(");
+	int varLength = midiDumpVarLength(delta);
+	if (varLength == 1)
+		debugN("),\t ");
+	else
+		debugN("), ");
+}
+
+void MidiDriver_BASE::midiDumpDo(uint32 b) {
+	const byte status = b & 0xff;
+	const byte firstOp = (b >> 8) & 0xff;
+	const byte secondOp = (b >> 16) & 0xff;
+
+	midiDumpDelta();
+	debugN("message(0x%02x 0x%02x", status, firstOp);
+
+	_midiDumpCache.push_back(status);
+	_midiDumpCache.push_back(firstOp);
+
+	if (status < 0xc0 || status > 0xdf) {
+		_midiDumpCache.push_back(secondOp);
+		debug(" 0x%02x)", secondOp);
+	} else
+		debug(")");
+}
+
+void MidiDriver_BASE::midiDumpSysEx(const byte *msg, uint16 length) {
+	midiDumpDelta();
+	_midiDumpCache.push_back(0xf0);
+	debugN("0xf0, length(");
+	midiDumpVarLength(length + 1);		// +1 because of closing 0xf7
+	debugN("), sysex[");
+	for (int i = 0; i < length; i++) {
+		debugN("0x%x, ", msg[i]);
+		_midiDumpCache.push_back(msg[i]);
+	}
+	debug("0xf7]\t\t");
+	_midiDumpCache.push_back(0xf7);
+}
+
+
+void MidiDriver_BASE::midiDumpFinish() {
+	Common::DumpFile *midiDumpFile = new Common::DumpFile();
+	midiDumpFile->open("dump.mid");
+	midiDumpFile->write("MThd\0\0\0\x6\0\x1\0\x2", 12);		// standard MIDI file header, with two tracks
+	midiDumpFile->write("\x1\xf4", 2);						// division - 500 ticks per beat, i.e. a quarter note. Each tick is 1ms
+	midiDumpFile->write("MTrk", 4);							// start of first track - doesn't contain real data, it's just common practice to use two tracks
+	midiDumpFile->writeUint32BE(4);							// first track size
+	midiDumpFile->write("\0\xff\x2f\0", 4);			    	// meta event - end of track
+	midiDumpFile->write("MTrk", 4);							// start of second track
+	midiDumpFile->writeUint32BE(_midiDumpCache.size() + 4);	// track size (+4 because of the 'end of track' event)
+	midiDumpFile->write(_midiDumpCache.data(), _midiDumpCache.size());	
+	midiDumpFile->write("\0\xff\x2f\0", 4);			    	// meta event - end of track
+	midiDumpFile->finalize();
+	midiDumpFile->close();
+	const char msg[] = "Ending MIDI dump, created 'dump.mid'";
+	g_system->displayMessageOnOSD(_(msg));		//TODO: why it doesn't appear?
+	debug(_(msg));
+}
+
+MidiDriver_BASE::MidiDriver_BASE() {
+	_midiDumpEnable = ConfMan.getBool("dump_midi");
+	if (_midiDumpEnable) {
+		midiDumpInit();
+	}
+}
+
+MidiDriver_BASE::~MidiDriver_BASE() {
+	if (_midiDumpEnable && !_midiDumpCache.empty()) {
+		midiDumpFinish();
+	}
+}
+
+void MidiDriver_BASE::send(byte status, byte firstOp, byte secondOp) {
+	send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
+}
+
+void MidiDriver::midiDriverCommonSend(uint32 b) {
+	if (_midiDumpEnable) {
+		midiDumpDo(b);
+	}
+}
+
+void MidiDriver::midiDriverCommonSysEx(const byte *msg, uint16 length) {
+	if (_midiDumpEnable) {
+		midiDumpSysEx(msg, length);
+	}
+}
+
+
diff --git a/audio/mididrv.h b/audio/mididrv.h
index 3b4c1244c9..e6a2f65ede 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -26,6 +26,7 @@
 #include "common/scummsys.h"
 #include "common/str.h"
 #include "common/timer.h"
+#include "common/array.h"
 
 class MidiChannel;
 
@@ -86,7 +87,9 @@ enum MidiDriverFlags {
  */
 class MidiDriver_BASE {
 public:
-	virtual ~MidiDriver_BASE() { }
+	MidiDriver_BASE();
+
+	virtual ~MidiDriver_BASE();
 
 	/**
 	 * Output a packed midi command to the midi stream.
@@ -96,6 +99,7 @@ public:
 	 */
 	virtual void send(uint32 b) = 0;
 
+
 	/**
 	 * Output a midi command to the midi stream. Convenience wrapper
 	 * around the usual 'packed' send method.
@@ -103,10 +107,8 @@ public:
 	 * Do NOT use this for sysEx transmission; instead, use the sysEx()
 	 * method below.
 	 */
-	void send(byte status, byte firstOp, byte secondOp) {
-		send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
-	}
-
+	void send(byte status, byte firstOp, byte secondOp);
+	
 	/**
 	 * Transmit a sysEx to the midi device.
 	 *
@@ -121,6 +123,39 @@ public:
 
 	// TODO: Document this.
 	virtual void metaEvent(byte type, byte *data, uint16 length) { }
+
+protected:
+
+	/**
+	 * Enables midi dumping to a 'dump.mid' file and to debug messages on screen
+	 * It's set by '--dump-midi' command line parameter
+	 */
+	bool _midiDumpEnable;
+
+	/** Used for MIDI dumping delta calculation */
+	uint32 _prevMillis;
+
+	/** Stores all MIDI events, will be written to disk after an engine quits */
+	Common::Array<byte> _midiDumpCache;
+
+	/** Initialize midi dumping mechanism, called only if enabled */
+	void midiDumpInit();
+
+	/** Handles MIDI file variable length dumping */
+	int midiDumpVarLength(const uint32 &delta);
+
+	/** Handles MIDI file time delta dumping */
+	void midiDumpDelta();
+
+	/** Performs dumping of MIDI commands, called only if enabled */
+	void midiDumpDo(uint32 b);
+
+	/** Performs dumping of MIDI SysEx commands, called only if enabled */
+	void midiDumpSysEx(const byte *msg, uint16 length);
+
+	/** Writes the captured MIDI events to disk, called only if enabled */
+	void midiDumpFinish();
+
 };
 
 /**
@@ -166,6 +201,13 @@ public:
 	/** Get the device description string matching the given device handle and the given type. */
 	static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type);
 
+	/** Common operations to be done by all drivers on start of send */
+	void midiDriverCommonSend(uint32 b);
+
+	/** Common operations to be done by all drivers on start of sysEx */
+	void midiDriverCommonSysEx(const byte *msg, uint16 length);
+
+
 private:
 	// If detectDevice() detects MT32 and we have a preferred MT32 device
 	// we use this to force getMusicType() to return MT_MT32 so that we don't
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index 5c06baeff2..f2ffb558c7 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -115,7 +115,7 @@ public:
 	bool hasNativeMT32() const { return _nativeMT32; }
 
 	// MidiDriver_BASE implementation
-	virtual void send(uint32 b);
+	virtual void send(uint32 b) override;
 	virtual void metaEvent(byte type, byte *data, uint16 length);
 
 protected:
diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp
index 4bdb770323..3c39af6b2b 100644
--- a/audio/miles_adlib.cpp
+++ b/audio/miles_adlib.cpp
@@ -123,7 +123,7 @@ public:
 	// MidiDriver
 	int open();
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	MidiChannel *allocateChannel() { return NULL; }
 	MidiChannel *getPercussionChannel() { return NULL; }
 
diff --git a/audio/miles_mt32.cpp b/audio/miles_mt32.cpp
index dff863f119..66c9754773 100644
--- a/audio/miles_mt32.cpp
+++ b/audio/miles_mt32.cpp
@@ -79,7 +79,7 @@ public:
 	void close();
 	bool isOpen() const { return _isOpen; }
 
-	void send(uint32 b);
+	void send(uint32 b) override;
 
 	MidiChannel *allocateChannel() {
 		if (_driver)
diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index 9854c10d27..5a792b9d36 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -70,7 +70,7 @@ public:
 	virtual int open();
 	virtual bool isOpen() const;
 	virtual void close();
-	virtual void send(uint32 b);
+	virtual void send(uint32 b) override;
 	virtual void sysEx(const byte *msg, uint16 length);
 	virtual void setTimerCallback(void *timerParam,
 								Common::TimerManager::TimerProc timerProc);
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index d0fa37aa5f..ed1d442120 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -64,7 +64,7 @@ public:
 
 	int open();
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 
 	MidiChannel *allocateChannel();
 	MidiChannel *getPercussionChannel();
@@ -227,6 +227,8 @@ void MidiDriver_FluidSynth::close() {
 }
 
 void MidiDriver_FluidSynth::send(uint32 b) {
+	midiDriverCommonSend(b);
+
 	//byte param3 = (byte) ((b >> 24) & 0xFF);
 	uint param2 = (byte) ((b >> 16) & 0xFF);
 	uint param1 = (byte) ((b >>  8) & 0xFF);
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index 47ac9f1cdc..2bbcb9ad06 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -122,7 +122,7 @@ public:
 
 	int open();
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void setPitchBendRange(byte channel, uint range);
 	void sysEx(const byte *msg, uint16 length);
 
@@ -227,6 +227,8 @@ int MidiDriver_MT32::open() {
 }
 
 void MidiDriver_MT32::send(uint32 b) {
+	midiDriverCommonSend(b);
+
 	Common::StackLock lock(_mutex);
 	_service.playMsg(b);
 }
@@ -243,6 +245,7 @@ void MidiDriver_MT32::setPitchBendRange(byte channel, uint range) {
 }
 
 void MidiDriver_MT32::sysEx(const byte *msg, uint16 length) {
+	midiDriverCommonSysEx(msg, length);
 	if (msg[0] == 0xf0) {
 		Common::StackLock lock(_mutex);
 		_service.playSysex(msg, length);
diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp
index 14889b2942..a389238b22 100644
--- a/backends/midi/alsa.cpp
+++ b/backends/midi/alsa.cpp
@@ -73,7 +73,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -186,6 +186,8 @@ void MidiDriver_ALSA::send(uint32 b) {
 		return;
 	}
 
+	midiDriverCommonSend(b);
+
 	unsigned int midiCmd[4];
 	ev.type = SND_SEQ_EVENT_OSS;
 
@@ -268,6 +270,8 @@ void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) {
 
 	assert(length + 2 <= ARRAYSIZE(buf));
 
+	midiDriverCommonSysEx(msg, length);
+
 	// Add SysEx frame
 	buf[0] = 0xF0;
 	memcpy(buf + 1, msg, length);
diff --git a/backends/midi/camd.cpp b/backends/midi/camd.cpp
index d91aef5533..86a599f17d 100644
--- a/backends/midi/camd.cpp
+++ b/backends/midi/camd.cpp
@@ -50,7 +50,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -122,6 +122,8 @@ void MidiDriver_CAMD::send(uint32 b) {
 		return;
 	}
 
+	midiDriverCommonSend(b);
+
 	ULONG data = READ_LE_UINT32(&b);
 	_ICamd->PutMidi(_midi_link, data);
 }
diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp
index 140771960b..40acc252b8 100644
--- a/backends/midi/coreaudio.cpp
+++ b/backends/midi/coreaudio.cpp
@@ -99,7 +99,7 @@ public:
 	int open();
 	bool isOpen() const { return _auGraph != 0; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -280,6 +280,8 @@ void MidiDriver_CORE::close() {
 void MidiDriver_CORE::send(uint32 b) {
 	assert(isOpen());
 
+	midiDriverCommonSend(b);
+
 	byte status_byte = (b & 0x000000FF);
 	byte first_byte = (b & 0x0000FF00) >> 8;
 	byte second_byte = (b & 0x00FF0000) >> 16;
diff --git a/backends/midi/coremidi.cpp b/backends/midi/coremidi.cpp
index 37d58c5cbd..39c08fad61 100644
--- a/backends/midi/coremidi.cpp
+++ b/backends/midi/coremidi.cpp
@@ -58,7 +58,7 @@ public:
 	int open();
 	bool isOpen() const { return mOutPort != 0 && mDest != 0; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -118,6 +118,8 @@ void MidiDriver_CoreMIDI::close() {
 void MidiDriver_CoreMIDI::send(uint32 b) {
 	assert(isOpen());
 
+	midiDriverCommonSend(b);
+
 	// Extract the MIDI data
 	byte status_byte = (b & 0x000000FF);
 	byte first_byte = (b & 0x0000FF00) >> 8;
diff --git a/backends/midi/dmedia.cpp b/backends/midi/dmedia.cpp
index 475172c81f..d9ab8d5ab0 100644
--- a/backends/midi/dmedia.cpp
+++ b/backends/midi/dmedia.cpp
@@ -58,7 +58,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -135,6 +135,8 @@ void MidiDriver_DMEDIA::close() {
 }
 
 void MidiDriver_DMEDIA::send(uint32 b) {
+	midiDriverCommonSend(b);
+
 	MDevent event;
 	byte status_byte = (b & 0x000000FF);
 	byte first_byte = (b & 0x0000FF00) >> 8;
@@ -177,6 +179,8 @@ void MidiDriver_DMEDIA::sysEx (const byte *msg, uint16 length) {
 
 	assert(length + 2 <= 256);
 
+	midiDriverCommonSysEx(msg, length);
+
 	memcpy(buf, msg, length);
 	buf[length] = MD_EOX;
 	event.sysexmsg = buf;
diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp
index 2ce25b726c..be768758da 100644
--- a/backends/midi/seq.cpp
+++ b/backends/midi/seq.cpp
@@ -57,7 +57,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -109,6 +109,8 @@ void MidiDriver_SEQ::close() {
 }
 
 void MidiDriver_SEQ::send(uint32 b) {
+	midiDriverCommonSend(b);
+
 	unsigned char buf[256];
 	int position = 0;
 
@@ -157,6 +159,8 @@ void MidiDriver_SEQ::sysEx(const byte *msg, uint16 length) {
 
 	assert(length + 2 <= 266);
 
+	midiDriverCommonSysEx(msg, length);
+
 	buf[position++] = SEQ_MIDIPUTC;
 	buf[position++] = 0xF0;
 	buf[position++] = _device_num;
diff --git a/backends/midi/sndio.cpp b/backends/midi/sndio.cpp
index 5efec4b899..0435697b8d 100644
--- a/backends/midi/sndio.cpp
+++ b/backends/midi/sndio.cpp
@@ -47,7 +47,7 @@ public:
 	int open();
 	bool isOpen() const { return hdl != NULL; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -80,6 +80,8 @@ void MidiDriver_Sndio::send(uint32 b) {
 	unsigned char buf[4];
 	unsigned int len;
 
+	midiDriverCommonSend(b);
+
 	if (!hdl)
 		return;
 	buf[0] = b & 0xff;
@@ -107,6 +109,8 @@ void MidiDriver_Sndio::sysEx(const byte *msg, uint16 length) {
 
 	assert(length + 2 <= ARRAYSIZE(buf));
 
+	midiDriverCommonSysEx(msg, length);
+
 	// Add SysEx frame
 	buf[0] = 0xF0;
 	memcpy(buf + 1, msg, length);
diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp
index de0f05a271..be6ff76d1c 100644
--- a/backends/midi/stmidi.cpp
+++ b/backends/midi/stmidi.cpp
@@ -51,7 +51,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -72,6 +72,7 @@ void MidiDriver_STMIDI::close() {
 }
 
 void MidiDriver_STMIDI::send(uint32 b) {
+	midiDriverCommonSend(b);
 
 	byte status_byte = (b & 0x000000FF);
 	byte first_byte = (b & 0x0000FF00) >> 8;
@@ -109,6 +110,8 @@ void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
 		return;
 	}
 
+	midiDriverCommonSysEx(msg, length);
+
 	const byte *chr = msg;
 	warning("Sending SysEx Message");
 
diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp
index 80dba101ed..61887170b5 100644
--- a/backends/midi/timidity.cpp
+++ b/backends/midi/timidity.cpp
@@ -87,7 +87,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 
 private:
@@ -445,6 +445,8 @@ void MidiDriver_TIMIDITY::send(uint32 b) {
 	unsigned char buf[256];
 	int position = 0;
 
+	midiDriverCommonSend(b);
+
 	switch (b & 0xF0) {
 	case 0x80:
 	case 0x90:
@@ -491,6 +493,8 @@ void MidiDriver_TIMIDITY::sysEx(const byte *msg, uint16 length) {
 
 	assert(length + 2 <= 266);
 
+	midiDriverCommonSysEx(msg, length);
+
 	buf[position++] = SEQ_MIDIPUTC;
 	buf[position++] = 0xF0;
 	buf[position++] = _device_num;
diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp
index f3c48b61e8..36c9f0a94a 100644
--- a/backends/midi/windows.cpp
+++ b/backends/midi/windows.cpp
@@ -36,7 +36,6 @@
 #include "common/translation.h"
 #include "common/textconsole.h"
 #include "common/error.h"
-
 #include <mmsystem.h>
 
 ////////////////////////////////////////
@@ -61,7 +60,7 @@ public:
 	int open();
 	bool isOpen() const { return _isOpen; }
 	void close();
-	void send(uint32 b);
+	void send(uint32 b) override;
 	void sysEx(const byte *msg, uint16 length);
 };
 
@@ -94,6 +93,8 @@ void MidiDriver_WIN::close() {
 void MidiDriver_WIN::send(uint32 b) {
 	assert(_isOpen);
 
+	midiDriverCommonSend(b);
+
 	union {
 		DWORD dwData;
 		BYTE bData[4];
@@ -107,6 +108,7 @@ void MidiDriver_WIN::send(uint32 b) {
 	check_error(midiOutShortMsg(_mo, u.dwData));
 }
 
+
 void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) {
 	if (!_isOpen)
 		return;
@@ -118,6 +120,8 @@ void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) {
 
 	assert(length+2 <= 266);
 
+	midiDriverCommonSysEx(msg, length);
+
 	midiOutUnprepareHeader(_mo, &_streamHeader, sizeof(_streamHeader));
 
 	// Add SysEx frame
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index bb7f93a274..b05ec5ded8 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -131,6 +131,8 @@ static const char HELP_STRING[] =
 	"                           supported by some MIDI drivers)\n"
 	"  --multi-midi             Enable combination AdLib and native MIDI\n"
 	"  --native-mt32            True Roland MT-32 (disable GM emulation)\n"
+	"  --dump-midi              Dumps MIDI events to 'dump.mid', until quitting from game\n"
+	"                           (if file already exists, it will be overwritten)\n"
 	"  --enable-gs              Enable Roland GS mode for MIDI playback\n"
 	"  --output-rate=RATE       Select output sample rate in Hz (e.g. 22050)\n"
 	"  --opl-driver=DRIVER      Select AdLib (OPL) emulator (db, mame"
@@ -233,6 +235,7 @@ void registerDefaults() {
 
 	ConfMan.registerDefault("multi_midi", false);
 	ConfMan.registerDefault("native_mt32", false);
+	ConfMan.registerDefault("dump_midi", false);
 	ConfMan.registerDefault("enable_gs", false);
 	ConfMan.registerDefault("midi_gain", 100);
 
@@ -654,6 +657,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
 			DO_LONG_OPTION_BOOL("native-mt32")
 			END_OPTION
 
+			DO_LONG_OPTION_BOOL("dump-midi")
+			END_OPTION
+
 			DO_LONG_OPTION_BOOL("enable-gs")
 			END_OPTION
 
diff --git a/base/main.cpp b/base/main.cpp
index 92c0bf13ee..0b59e0710d 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -449,6 +449,12 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
 		return res.getCode();
 	}
 
+	if (settings.contains("dump-midi")) {
+		// Store this command line setting in ConfMan, since all transient settings are destroyed
+		ConfMan.registerDefault("dump_midi", true);
+	}
+
+
 	// Init the backend. Must take place after all config data (including
 	// the command line params) was read.
 	system.initBackend();




More information about the Scummvm-git-logs mailing list