[Scummvm-git-logs] scummvm master -> 121fb4798b7e834e75889ec6913703857f0b1ebe

bluegr bluegr at gmail.com
Sun Mar 15 23:45:47 UTC 2020


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

Summary:
a7082b15fa GROOVIE: Send GS SysEx messages
e11d408f0a GROOVIE: Add Roland GS invalid drumkit correction
52d5d60907 GROOVIE: Fix 7th Guest GM initialization
121fb4798b MIDI: Added sysEx function to Miles MT-32 driver


Commit: a7082b15fa4806bdca766de627d0f9a6c354303a
    https://github.com/scummvm/scummvm/commit/a7082b15fa4806bdca766de627d0f9a6c354303a
Author: NMIError (crampen at gmail.com)
Date: 2020-03-16T01:40:10+02:00

Commit Message:
GROOVIE: Send GS SysEx messages

The 7th Guest sends several SysEx messages for Roland GS devices during
startup. ScummVM did not send these messages.

The Groovie MusicPlayerMidi class encapsulates the MidiDriver which is
actually used for sending MIDI events. However, it did not implement the
sysEx method, so the empty implementation of MidiDriver_BASE was used.
I've added a sysEx method which forwards the messages to the actual
MidiDriver.

Changed paths:
    engines/groovie/music.cpp
    engines/groovie/music.h


diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 9244dd7c31..ebb15e3c2a 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -291,6 +291,11 @@ void MusicPlayerMidi::send(uint32 b) {
 		_driver->send(b);
 }
 
+void MusicPlayerMidi::sysEx(const byte *msg, uint16 length) {
+	if (_driver)
+		_driver->sysEx(msg, length);
+}
+
 void MusicPlayerMidi::metaEvent(byte type, byte *data, uint16 length) {
 	switch (type) {
 	case 0x2F:
diff --git a/engines/groovie/music.h b/engines/groovie/music.h
index 27bc7a5fbd..fddd866c40 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -98,6 +98,7 @@ public:
 
 	// MidiDriver_BASE interface
 	void send(uint32 b) override;
+	void sysEx(const byte* msg, uint16 length) override;
 	void metaEvent(byte type, byte *data, uint16 length) override;
 
 private:


Commit: e11d408f0ad6e514c6e1028d1624e7cd6843d824
    https://github.com/scummvm/scummvm/commit/e11d408f0ad6e514c6e1028d1624e7cd6843d824
Author: NMIError (crampen at gmail.com)
Date: 2020-03-16T01:40:10+02:00

Commit Message:
GROOVIE: Add Roland GS invalid drumkit correction

The GM music for The 7th Guest contains several drumkit selection
messages which use an incorrect drumkit number. This relied on a
correction mechanism of the Roland SC-55, which would correct these
numbers to valid selections. This mechanism was not present in later
GS and GM devices, causing error messages and wrong drumkits.

I've fixed this by adding code which simulates the correction
mechanism of the SC-55.

Changed paths:
    engines/groovie/music.cpp


diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index ebb15e3c2a..a489b22037 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -492,6 +492,7 @@ void MusicPlayerXMI::send(uint32 b) {
 		return;
 	}
 
+	uint32 bytesToSend = b;
 	if ((b & 0xFFF0) == 0x72B0) { // XMIDI Patch Bank Select 114
 		// From AIL2's documentation: XMIDI Patch Bank Select controller (114)
 		// selects a bank to be used when searching the next patches
@@ -505,9 +506,9 @@ void MusicPlayerXMI::send(uint32 b) {
 		// We intercept the program change when using AdLib or MT32 drivers,
 		// since we have custom timbres for them.  The command is sent
 		// unchanged to GM drivers.
+		byte chan = b & 0xF;
+		byte patch = (b >> 8) & 0xFF;
 		if (_musicType != 0) {
-			byte chan = b & 0xF;
-			byte patch = (b >> 8) & 0xFF;
 
 			debugC(5, kDebugMIDI, "Groovie::Music: Setting custom patch %X from bank %X to channel %X", patch, _chanBanks[chan], chan);
 
@@ -528,9 +529,15 @@ void MusicPlayerXMI::send(uint32 b) {
 
 			// If we got here we couldn't find the patch, and the
 			// received message will be sent unchanged.
+		} else if (chan == 0x9) {
+			// GM program change on the rhythm channel (drumkit selection).
+			// Apply drumkit fallback to correct invalid drumkit numbers.
+			byte correctedPatch = _driver->_gsDrumkitFallbackMap[patch];
+			debugC(5, kDebugMIDI, "Groovie::Music: Selected drumkit %X (requested %X)", correctedPatch, patch);
+			bytesToSend = 0xC0 | chan | (correctedPatch << 8);
 		}
 	}
-	MusicPlayerMidi::send(b);
+	MusicPlayerMidi::send(bytesToSend);
 }
 
 bool MusicPlayerXMI::load(uint32 fileref, bool loop) {


Commit: 52d5d60907f6fdd0b8b9d3e7a92129695fa59667
    https://github.com/scummvm/scummvm/commit/52d5d60907f6fdd0b8b9d3e7a92129695fa59667
Author: NMIError (crampen at gmail.com)
Date: 2020-03-16T01:40:10+02:00

Commit Message:
GROOVIE: Fix 7th Guest GM initialization

The 7th Guest initializes GM devices during the "loading GM drivers"
screen, which is a normal video that plays "audio" that consists of
initialization messages (mostly Roland GS sysexes). The original
interpreter plays this video twice, which is enough time to play the
entire INI_SC.XMI initialization file. ScummVM apparently plays video
a bit faster, and there is not enough time to play the entire init
file. Because of this GM initialization is incomplete.

I've fixed this by making the init video loop until the audio has
finished playing.

Note: I have only tested this with the original DOS version of the
game. I don't know if the file reference I've used to identify the
GM init video is the same on other platforms. If not, this change
might not work and/or have unintended results.

Changed paths:
    engines/groovie/music.h
    engines/groovie/script.cpp
    engines/groovie/script.h


diff --git a/engines/groovie/music.h b/engines/groovie/music.h
index fddd866c40..73194e264f 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -43,6 +43,7 @@ public:
 	void setBackgroundSong(uint32 fileref);
 	void playCD(uint8 track);
 	void startBackground();
+	bool isPlaying() { return _isPlaying; }
 
 	void frameTick();
 	void setBackgroundDelay(uint16 delay);
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 376519c577..1252e97448 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -576,14 +576,25 @@ void Script::o_videofromref() {			// 0x09
 	if (fileref != _videoRef) {
 		debugCN(1, kDebugScript, "\n");
 	}
+
+	// Determine if the GM initialization video is being played
+	bool gmInitVideo = (_version == kGroovieT7G && fileref == 0x2460);
 	// Play the video
-	if (!playvideofromref(fileref)) {
+	// If the GM init video is being played, loop it until the "audio"
+	// (init commands) has finished playing
+	if (!playvideofromref(fileref, gmInitVideo)) {
 		// Move _currentInstruction back
 		_currentInstruction -= 3;
+	} else if (gmInitVideo) {
+		// The script plays the GM init video twice to give the "audio"
+		// enough time to play. It has just looped until the audio finished,
+		// so the second play is no longer necessary.
+		// Skip the next instruction.
+		_currentInstruction += 3;
 	}
 }
 
-bool Script::playvideofromref(uint32 fileref) {
+bool Script::playvideofromref(uint32 fileref, bool loopUntilAudioDone) {
 	// It isn't the current video, open it
 	if (fileref != _videoRef) {
 
@@ -618,8 +629,6 @@ bool Script::playvideofromref(uint32 fileref) {
 			return true;
 		}
 
-		_bitflags = 0;
-
 		// Reset the clicked mouse events
 		_eventMouseClicked = 0;
 	}
@@ -632,6 +641,8 @@ bool Script::playvideofromref(uint32 fileref) {
 		// Reset the skip address
 		_videoSkipAddress = 0;
 
+		_bitflags = 0;
+
 		// End the playback
 		return true;
 	}
@@ -641,7 +652,17 @@ bool Script::playvideofromref(uint32 fileref) {
 		bool endVideo = _vm->_videoPlayer->playFrame();
 		_vm->_musicPlayer->frameTick();
 
-		if (endVideo) {
+		if (endVideo && loopUntilAudioDone && _vm->_musicPlayer->isPlaying()) {
+			// The video has ended, but the audio hasn't. Loop the video.
+			_videoFile->seek(0);
+			// Clear bit flag 9 (fade-in)
+			_vm->_videoPlayer->load(_videoFile, _bitflags & ~(1 << 9));
+			return false;
+		}
+
+		if (endVideo || (loopUntilAudioDone && !_vm->_musicPlayer->isPlaying())) {
+			// The video has ended, or it was being looped and the audio has ended.
+
 			// Close the file
 			delete _videoFile;
 			_videoFile = NULL;
@@ -653,13 +674,19 @@ bool Script::playvideofromref(uint32 fileref) {
 
 			// Newline
 			debugCN(1, kDebugScript, "\n");
+
+			_bitflags = 0;
+
+			// Let the caller know if the video has ended
+			return true;
 		}
 
-		// Let the caller know if the video has ended
-		return endVideo;
+		// The video has not ended yet.
+		return false;
 	}
 
 	// If the file is closed, finish the playback
+	_bitflags = 0;
 	return true;
 }
 
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 7ecb166583..a3bc5724e2 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -146,7 +146,7 @@ private:
 
 	void loadgame(uint slot);
 	void savegame(uint slot);
-	bool playvideofromref(uint32 fileref);
+	bool playvideofromref(uint32 fileref, bool loopUntilAudioDone = false);
 	void printString(Graphics::Surface *surface, const char *str);
 
 	// Opcodes


Commit: 121fb4798b7e834e75889ec6913703857f0b1ebe
    https://github.com/scummvm/scummvm/commit/121fb4798b7e834e75889ec6913703857f0b1ebe
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2020-03-16T01:45:13+02:00

Commit Message:
MIDI: Added sysEx function to Miles MT-32 driver

The Miles MT-32 MIDI driver extends MidiDriver_BASE, but does not
override its sysEx method, which does nothing by default. This
resulted in a few initialization sysex messages for The 7th Guest
not being sent.

I've added an implementation for this method.

Adapted from 3657db3a7b7bf640edb768f6ffc37df9d5073d22

Changed paths:
    audio/miles_mt32.cpp


diff --git a/audio/miles_mt32.cpp b/audio/miles_mt32.cpp
index dc42e84112..e61b3fbc3e 100644
--- a/audio/miles_mt32.cpp
+++ b/audio/miles_mt32.cpp
@@ -80,6 +80,7 @@ public:
 	bool isOpen() const override { return _isOpen; }
 
 	void send(uint32 b) override;
+	void sysEx(const byte* msg, uint16 length) override;
 
 	MidiChannel *allocateChannel() override {
 		if (_driver)
@@ -284,6 +285,20 @@ void MidiDriver_Miles_MT32::resetMT32() {
 	MT32SysEx(0x100001, milesMT32SysExInitReverb);
 }
 
+void MidiDriver_Miles_MT32::sysEx(const byte *msg, uint16 length) {
+	// Send SysEx
+	_driver->sysEx(msg, length);
+
+	// Wait the time it takes to send the SysEx data
+	uint32 delay = (length + 2) * 1000 / 3125;
+
+	// Plus an additional delay for the MT-32 rev00
+	if (_nativeMT32)
+		delay += 40;
+
+	g_system->delayMillis(delay);
+}
+
 void MidiDriver_Miles_MT32::MT32SysEx(const uint32 targetAddress, const byte *dataPtr) {
 	byte   sysExMessage[270];
 	uint16 sysExPos      = 0;
@@ -324,17 +339,7 @@ void MidiDriver_Miles_MT32::MT32SysEx(const uint32 targetAddress, const byte *da
 	assert(sysExPos < sizeof(sysExMessage));
 	sysExMessage[sysExPos++] = sysExChecksum & 0x7f;
 
-	// Send SysEx
-	_driver->sysEx(sysExMessage, sysExPos);
-
-	// Wait the time it takes to send the SysEx data
-	uint32 delay = (sysExPos + 2) * 1000 / 3125;
-
-	// Plus an additional delay for the MT-32 rev00
-	if (_nativeMT32)
-		delay += 40;
-
-	g_system->delayMillis(delay);
+	sysEx(sysExMessage, sysExPos);
 }
 
 // MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php




More information about the Scummvm-git-logs mailing list