[Scummvm-git-logs] scummvm master -> 0f297559cd50ec800646cba372229c6dac1a0472

OMGPizzaGuy 48367439+OMGPizzaGuy at users.noreply.github.com
Fri Jun 12 18:46:35 UTC 2020


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

Summary:
f497753b21 MIDI: Add support for XMIDI sequence branch indexes
69032b4ee6 ULTIMA8: Add support for music starting points
a24e3b2a4f MIDI: Add constant for number of tracks
ee4de6ebee ULTIMA8: Fix warnings when track has no branches
0f297559cd ULTIMA8/MIDI: Rename doNotAutoStartPlayback


Commit: f497753b216b8ba1e442483cc515ee6f2d151947
    https://github.com/scummvm/scummvm/commit/f497753b216b8ba1e442483cc515ee6f2d151947
Author: NMIError (crampen at gmail.com)
Date: 2020-06-12T13:46:27-05:00

Commit Message:
MIDI: Add support for XMIDI sequence branch indexes

This adds support for the "sequence branch index" feature of the XMIDI format.
These "branches" (positions in the MIDI bytestream) are defined in the track
header. I've added two generic methods to the MidiParser interface to set the
current parsing position to one of these positions, or to check for the
existence of a position with a certain number (this is needed for Ultima 8).

Additionally, I've added an option to the MIDI parser to prevent the parser
from starting playback immediately after parsing, so that a starting position
(or a track) can be selected first. Playback can then be started with the new
startPlaying method.

Changed paths:
    audio/midiparser.cpp
    audio/midiparser.h
    audio/midiparser_xmidi.cpp


diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index 063547265a..c200eca539 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -43,10 +43,12 @@ _smartJump(false),
 _centerPitchWheelOnUnload(false),
 _sendSustainOffOnNotesOff(false),
 _disableAllNotesOffMidiEvents(false),
+_doNotAutoStartPlayback(false),
 _numTracks(0),
 _activeTrack(255),
 _abortParse(false),
-_jumpingToTick(false) {
+_jumpingToTick(false),
+_doParse(true) {
 	memset(_activeNotes, 0, sizeof(_activeNotes));
 	memset(_tracks, 0, sizeof(_tracks));
 	_nextEvent.start = NULL;
@@ -72,6 +74,9 @@ void MidiParser::property(int prop, int value) {
 	case mpDisableAllNotesOffMidiEvents:
 		_disableAllNotesOffMidiEvents = (value != 0);
 		break;
+	case mpDoNotAutoStartPlayback:
+		_doNotAutoStartPlayback = (value != 0);
+		break;
 	default:
 		break;
 	}
@@ -176,7 +181,7 @@ void MidiParser::onTimer() {
 	uint32 endTime;
 	uint32 eventTime;
 
-	if (!_position._playPos || !_driver)
+	if (!_position._playPos || !_driver || !_doParse)
 		return;
 
 	_abortParse = false;
@@ -348,6 +353,8 @@ bool MidiParser::setTrack(int track) {
 
 	resetTracking();
 	memset(_activeNotes, 0, sizeof(_activeNotes));
+	if (_doNotAutoStartPlayback)
+		_doParse = false;
 	_activeTrack = track;
 	_position._playPos = _tracks[track];
 	parseNextEvent(_nextEvent);
@@ -359,6 +366,17 @@ void MidiParser::stopPlaying() {
 	resetTracking();
 }
 
+bool MidiParser::startPlaying() {
+	if (_activeTrack < 0 || _activeTrack >= _numTracks)
+		return false;
+	if (!_position._playPos) {
+		_position._playPos = _tracks[_activeTrack];
+		parseNextEvent(_nextEvent);
+	}
+	_doParse = true;
+	return true;
+}
+
 void MidiParser::hangAllActiveNotes() {
 	// Search for note off events until we have
 	// accounted for every active note.
diff --git a/audio/midiparser.h b/audio/midiparser.h
index ff3cc987c0..da8e74e3d7 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -279,6 +279,7 @@ protected:
 	bool   _centerPitchWheelOnUnload;  ///< Center the pitch wheels when unloading a song
 	bool   _sendSustainOffOnNotesOff;   ///< Send a sustain off on a notes off event, stopping hanging notes
 	bool   _disableAllNotesOffMidiEvents;   ///< Don't send All Notes Off MIDI messages
+	bool   _doNotAutoStartPlayback;  ///< Do not automatically start playback after parsing MIDI data or setting the track
 	byte  *_tracks[120];    ///< Multi-track MIDI formats are supported, up to 120 tracks.
 	byte   _numTracks;     ///< Count of total tracks for multi-track MIDI formats. 1 for single-track formats.
 	byte   _activeTrack;   ///< Keeps track of the currently active track, in multi-track formats.
@@ -289,6 +290,7 @@ protected:
 	                        ///< 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
+	bool   _doParse;       ///< True if the parser should be parsing; false if it should be active
 
 protected:
 	static uint32 readVLQ(byte * &data);
@@ -377,7 +379,14 @@ public:
 		  * Any active notes registered by this parser will still be turned
 		  * off.
 		  */
-		 mpDisableAllNotesOffMidiEvents = 6
+		 mpDisableAllNotesOffMidiEvents = 6,
+
+		 /**
+		  * Does not automatically start playback after parsing MIDI data
+		  * or setting the track. Use startPlaying to start playback.
+		  * Note that not every parser implementation might support this.
+		  */
+		  mpDoNotAutoStartPlayback = 7
 	};
 
 public:
@@ -396,11 +405,35 @@ public:
 	void setTempo(uint32 tempo);
 	void onTimer();
 
-	bool isPlaying() const { return (_position._playPos != 0); }
+	bool isPlaying() const { return (_position._playPos != 0 && _doParse); }
+	/**
+	 * Start playback from the current position in the current track, or at
+	 * the beginning if there is no current position.
+	 * If the parser is already playing or there is no valid current track,
+	 * this function does nothing.
+	 */
+	bool startPlaying();
+	/**
+	 * Stops playback. This resets the current playback position.
+	 */
 	void stopPlaying();
 
 	bool setTrack(int track);
 	bool jumpToTick(uint32 tick, bool fireEvents = false, bool stopNotes = true, bool dontSendNoteOn = false);
+	/**
+	 * Returns true if the active track has a jump point defined for the
+	 * specified index number.
+	 * Can be implemented for MIDI formats with support for some form of index
+	 * points.
+	 */
+	virtual bool hasJumpIndex(uint8 index) { return false; }
+	/**
+	 * Stops playback and resumes it at the position defined for the specified
+	 * index number.
+	 * Can be implemented for MIDI formats with support for some form of index
+	 * points.
+	 */
+	virtual bool jumpToIndex(uint8 index, bool stopNotes = true) { return false; }
 
 	uint32 getPPQN() { return _ppqn; }
 	virtual uint32 getTick() { return _position._playTick; }
diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp
index 0e421d5c4b..6c3a479484 100644
--- a/audio/midiparser_xmidi.cpp
+++ b/audio/midiparser_xmidi.cpp
@@ -33,6 +33,8 @@
  */
 class MidiParser_XMIDI : public MidiParser {
 protected:
+	static const uint8 MAXIMUM_TRACK_BRANCHES = 128;
+
 	struct Loop {
 		byte *pos;
 		byte repeat;
@@ -49,6 +51,11 @@ protected:
 	 * of MIDI messages and multiple source functionality is disabled.
 	 */
 	int8 _source;
+	/**
+	 * The sequence branches defined for each track. These point to
+	 * positions in the MIDI data.
+	 */
+	byte *_trackBranches[ARRAYSIZE(_tracks)][MAXIMUM_TRACK_BRANCHES];
 
 	XMidiCallbackProc _callbackProc;
 	void *_callbackData;
@@ -71,6 +78,14 @@ protected:
 
 protected:
 	uint32 readVLQ2(byte * &data);
+	/**
+	 * Platform independent LE uint32 read-and-advance.
+	 * This helper function reads Little Endian 32-bit numbers
+	 * from a memory pointer, at the same time advancing
+	 * the pointer.
+	 */
+	uint32 read4low(byte *&data);
+
 	void parseNextEvent(EventInfo &info);
 
 	virtual void resetTracking() {
@@ -91,15 +106,17 @@ public:
 			_activeTrackTimbreList(NULL),
 			_activeTrackTimbreListSize(0) {
 		memset(_loop, 0, sizeof(_loop));
+		memset(_trackBranches, 0, sizeof(_trackBranches));
 		memset(_tracksTimbreList, 0, sizeof(_tracksTimbreList));
 		memset(_tracksTimbreListSize, 0, sizeof(_tracksTimbreListSize));
 	}
 	~MidiParser_XMIDI() { }
 
 	bool loadMusic(byte *data, uint32 size);
+	bool hasJumpIndex(uint8 index) override;
+	bool jumpToIndex(uint8 index, bool stopNotes) override;
 };
 
-
 // This is a special XMIDI variable length quantity
 uint32 MidiParser_XMIDI::readVLQ2(byte * &pos) {
 	uint32 value = 0;
@@ -109,6 +126,49 @@ uint32 MidiParser_XMIDI::readVLQ2(byte * &pos) {
 	return value;
 }
 
+uint32 MidiParser_XMIDI::read4low(byte *&data) {
+	uint32 val = READ_LE_UINT32(data);
+	data += 4;
+	return val;
+}
+
+bool MidiParser_XMIDI::hasJumpIndex(uint8 index) {
+	if (_activeTrack < 0 || _activeTrack >= _numTracks)
+		return false;
+
+	return index < MAXIMUM_TRACK_BRANCHES && _trackBranches[_activeTrack][index] != 0;
+}
+
+bool MidiParser_XMIDI::jumpToIndex(uint8 index, bool stopNotes) {
+	if (_activeTrack < 0 || _activeTrack >= _numTracks)
+		return false;
+
+	if (index >= MAXIMUM_TRACK_BRANCHES || _trackBranches[_activeTrack][index] == 0) {
+		warning("MidiParser-XMIDI: jumpToIndex called with invalid sequence branch index %x", index);
+		return false;
+	}
+
+	// Prevent concurrent execution of multiple jumps
+	assert(!_jumpingToTick);
+	_jumpingToTick = true;
+
+	if (stopNotes) {
+		if (!_smartJump || !_position._playPos) {
+			allNotesOff();
+		} else {
+			hangAllActiveNotes();
+		}
+	}
+
+	resetTracking();
+	_position._playPos = _trackBranches[_activeTrack][index];
+	parseNextEvent(_nextEvent);
+
+	_jumpingToTick = false;
+
+	return true;
+}
+
 void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
 	info.start = _position._playPos;
 	info.delta = readVLQ2(_position._playPos);
@@ -184,6 +244,12 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
 				_callbackProc(info.basic.param2, _callbackData);
 			break;
 
+		case 0x78:	// XMIDI_CONTROLLER_SEQ_BRANCH_INDEX
+			// This controller marks a branch point. It is converted
+			// to an entry in the RBRN header by the XMIDI conversion
+			// tool. For playback it is unnecessary.
+			break;
+
 		case 0x6e:	// XMIDI_CONTROLLER_CHAN_LOCK
 		case 0x6f:	// XMIDI_CONTROLLER_CHAN_LOCK_PROT
 		case 0x70:	// XMIDI_CONTROLLER_VOICE_PROT
@@ -194,9 +260,8 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
 
 		case 0x73:	// XMIDI_CONTROLLER_IND_CTRL_PREFIX
 		case 0x76:	// XMIDI_CONTROLLER_CLEAR_BB_COUNT
-		case 0x78:	// XMIDI_CONTROLLER_SEQ_BRANCH_INDEX
 		default:
-			if (info.basic.param1 >= 0x73 && info.basic.param1 <= 0x78) {
+			if (info.basic.param1 >= 0x73 && info.basic.param1 <= 0x76) {
 				warning("Unsupported XMIDI controller %d (0x%2x)",
 					info.basic.param1, info.basic.param1);
 			}
@@ -363,6 +428,8 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
 		}
 
 		int tracksRead = 0;
+		uint32 branchOffsets[128];
+		memset(branchOffsets, 0, sizeof(branchOffsets));
 		while (tracksRead < _numTracks) {
 			if (!memcmp(pos, "FORM", 4)) {
 				// Skip this plus the 4 bytes after it.
@@ -388,13 +455,40 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
 				pos += 4;
 				len = read4high(pos);
 				pos += (len + 1) & ~1;
+				// Calculate branch index positions using the track position we just found
+				for (int j = 0; j < MAXIMUM_TRACK_BRANCHES; ++j) {
+					if (branchOffsets[j] != 0) {
+						byte *branchPos = _tracks[tracksRead] + branchOffsets[j];
+						if (branchPos >= pos) {
+							warning("Invalid sequence branch position (after track end)");
+							branchPos = _tracks[tracksRead];
+						}
+						_trackBranches[tracksRead][j] = branchPos;
+					}
+				}
+				// Clear the branch offsets for the next track
+				memset(branchOffsets, 0, sizeof(branchOffsets));
 				++tracksRead;
 			} else if (!memcmp(pos, "RBRN", 4)) {
-				// optional branch point offsets. Ignored
+				// optional branch point offsets
 				pos += 4;
 				len = read4high(pos);
-				pos += (len + 1) & ~1;
-
+				uint16 numBranches = (len - 2) / 6;
+				uint16 numBranches2 = read2low(pos);
+				if (numBranches != numBranches2) {
+					warning("Number of sequence branch definitions %d does not match RBRN block length %d", numBranches2, len);
+					numBranches = 0;
+				}
+				for (int j = 0; j < numBranches; ++j) {
+					uint16 index = read2low(pos);
+					if (index >= MAXIMUM_TRACK_BRANCHES) {
+						warning("Invalid sequence branch index value %x", index);
+						pos += 4;
+						continue;
+					}
+					// This is the offset from the start of the track
+					branchOffsets[index] = read4low(pos);
+				}
 			} else {
 				warning("Hit invalid block '%c%c%c%c' while scanning for track locations", pos[0], pos[1], pos[2], pos[3]);
 				return false;


Commit: 69032b4ee6bba5407ce0e2eab05b5b165f530a73
    https://github.com/scummvm/scummvm/commit/69032b4ee6bba5407ce0e2eab05b5b165f530a73
Author: NMIError (crampen at gmail.com)
Date: 2020-06-12T13:46:27-05:00

Commit Message:
ULTIMA8: Add support for music starting points

The Ultima 8 music files define different positions for starting playback using
XMIDI sequence branches. This adds support for using these starting positions.

Because the XMIDI data must be read first to determine which starting points
are available, starting music playback has been split in two functions: load
and play. Between these two calls, the starting point can be selected.

Changed paths:
    engines/ultima/ultima8/audio/midi_player.cpp
    engines/ultima/ultima8/audio/midi_player.h
    engines/ultima/ultima8/audio/u8_music_process.cpp
    engines/ultima/ultima8/audio/u8_music_process.h


diff --git a/engines/ultima/ultima8/audio/midi_player.cpp b/engines/ultima/ultima8/audio/midi_player.cpp
index 939c69d362..139bb0578e 100644
--- a/engines/ultima/ultima8/audio/midi_player.cpp
+++ b/engines/ultima/ultima8/audio/midi_player.cpp
@@ -53,7 +53,7 @@ MidiPlayer::~MidiPlayer() {
 	_driver->close();
 }
 
-void MidiPlayer::play(byte *data, size_t size, int seqNo, int trackNo, bool speedHack) {
+void MidiPlayer::load(byte *data, size_t size, int seqNo, bool speedHack) {
 	if (!_driver)
 		return;
 
@@ -62,31 +62,56 @@ void MidiPlayer::play(byte *data, size_t size, int seqNo, int trackNo, bool spee
 	stop();
 
 	if (size < 4)
-		error("play() wrong music resource size");
+		error("load() wrong music resource size");
 
 	if (READ_BE_UINT32(data) != MKTAG('F', 'O', 'R', 'M')) {
-		warning("play() Unexpected signature");
+		warning("load() Unexpected signature");
 		_isPlaying = false;
 	} else {
 		_parser = MidiParser::createParser_XMIDI(xmidiCallback, _callbackData + seqNo);
 
-		if (!_parser->loadMusic(data, size))
-			error("play() wrong music resource");
-
-		_parser->setTrack(trackNo);
 		_parser->setMidiDriver(this);
 		_parser->setTimerRate(_driver->getBaseTempo());
 		if (speedHack)
 			_parser->setTempo(_driver->getBaseTempo() * 2);
 		_parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
 		_parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+		_parser->property(MidiParser::mpDoNotAutoStartPlayback, 1);
 
 		int volume = g_engine->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
 		setVolume(volume);
+
+		if (!_parser->loadMusic(data, size))
+			error("load() wrong music resource");
+	}
+}
+void MidiPlayer::play(int trackNo, int branchIndex) {
+	if (!_parser)
+		return;
+
+	if (!_parser->setTrack(trackNo)) {
+		warning("play() invalid track number %i", trackNo);
+		return;
+	}
+		
+	if (branchIndex >= 0) {
+		if (!_parser->jumpToIndex(branchIndex, false)) {
+			warning("play() invalid branch index %i", branchIndex);
+			// Track will play from the beginning instead
+		}
+	}
+
+	if (!_parser->startPlaying()) {
+		warning("play() failed to start playing");
+	} else {
 		_isPlaying = true;
 	}
 }
 
+bool MidiPlayer::hasBranchIndex(uint8 index) {
+	return _parser && _parser->hasJumpIndex(index);
+}
+
 void MidiPlayer::setLooping(bool loop) {
 	_parser->property(MidiParser::mpAutoLoop, loop);
 }
diff --git a/engines/ultima/ultima8/audio/midi_player.h b/engines/ultima/ultima8/audio/midi_player.h
index 9f2dccb33e..ec21cdbd4e 100644
--- a/engines/ultima/ultima8/audio/midi_player.h
+++ b/engines/ultima/ultima8/audio/midi_player.h
@@ -35,15 +35,28 @@ public:
 	~MidiPlayer() override;
 
 	/**
-	 * Play the specified music
+	 * Load the specified music data
 	 */
-	void play(byte *data, size_t size, int seqNo, int trackNo, bool speedHack);
+	void load(byte *data, size_t size, int seqNo, bool speedHack);
+
+	/**
+	 * Play the specified music track, starting at the
+	 * specified branch. Use branchNo -1 to start from the
+	 * beginning.
+	 */
+	void play(int trackNo, int branchNo);
 
 	/**
 	 * Sets whether the music should loop
 	 */
 	void setLooping(bool loop);
 
+	/**
+	 * Returns true if the current music track has a branch
+	 * defined for the specified index.
+	 */
+	bool hasBranchIndex(uint8 index);
+
 	bool isFMSynth() const {
 		return _isFMSynth;
 	};
diff --git a/engines/ultima/ultima8/audio/u8_music_process.cpp b/engines/ultima/ultima8/audio/u8_music_process.cpp
index ae96996254..2222f92f8c 100644
--- a/engines/ultima/ultima8/audio/u8_music_process.cpp
+++ b/engines/ultima/ultima8/audio/u8_music_process.cpp
@@ -173,7 +173,8 @@ void U8MusicProcess::playMusic_internal(int track) {
 		warning("Doing a MIDI transition! trans: %d xmidi: %d speedhack: %d", trans, xmidi_index, speed_hack);
 
 		if (xmidi && xmidi->_data) {
-			_midiPlayer->play(xmidi->_data, xmidi->_size, 1, trans, speed_hack);
+			_midiPlayer->load(xmidi->_data, xmidi->_size, 1, speed_hack);
+			_midiPlayer->play(trans, -1);
 		} else {
 			_midiPlayer->stop();
 		}
@@ -218,24 +219,20 @@ void U8MusicProcess::run() {
 		}
 
 		if (xmidi && xmidi->_data) {
-#ifdef TODO
-			// TODO: support branches in tracks.
-			// Not clear how to do this with the scummvm xmidi parser..
-			if (song_branches[wanted_track] != -1)
-			 {
-				 XMidiEvent *event = list->findBranchEvent(song_branches[wanted_track]);
-				 if (!event) song_branches[wanted_track] = 0;
-			 }
-#endif
 
 			if (_midiPlayer) {
 				// if there's a track queued, only play this one once
 				bool repeat = (_trackState._queued == 0);
-				_midiPlayer->play(xmidi->_data, xmidi->_size, 0, 0, false);
+				_midiPlayer->load(xmidi->_data, xmidi->_size, 0, false);
 				_midiPlayer->setLooping(repeat);
+				if (_songBranches[_trackState._wanted] >= 0 && !_midiPlayer->hasBranchIndex(_songBranches[_trackState._wanted]))
+					// Current branch is past the end of the list of branches. Reset to 0.
+					_songBranches[_trackState._wanted] = 0;
+				_midiPlayer->play(0, _songBranches[_trackState._wanted]);
 			}
 
 			_currentTrack = _trackState._wanted;
+			// Start this track at a different point (branch) next time
 			_songBranches[_trackState._wanted]++;
 		} else {
 			_currentTrack = _trackState._wanted = 0;
diff --git a/engines/ultima/ultima8/audio/u8_music_process.h b/engines/ultima/ultima8/audio/u8_music_process.h
index 1c87cd44ff..5946f0e105 100644
--- a/engines/ultima/ultima8/audio/u8_music_process.h
+++ b/engines/ultima/ultima8/audio/u8_music_process.h
@@ -66,6 +66,7 @@ private:
 
 	MidiPlayer *_midiPlayer;
 	PlaybackStates _state;
+	//! The branch (starting point) to use for each music track
 	int _songBranches[128];
 
 	int _currentTrack;      //! Currently playing track (don't save)


Commit: a24e3b2a4f449d2596d37f42099032f299306c81
    https://github.com/scummvm/scummvm/commit/a24e3b2a4f449d2596d37f42099032f299306c81
Author: NMIError (crampen at gmail.com)
Date: 2020-06-12T13:46:27-05:00

Commit Message:
MIDI: Add constant for number of tracks

Changed paths:
    audio/midiparser.h
    audio/midiparser_xmidi.cpp


diff --git a/audio/midiparser.h b/audio/midiparser.h
index da8e74e3d7..f1542c20e2 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -264,6 +264,8 @@ struct NoteTimer {
  */
 class MidiParser {
 protected:
+	static const uint8 MAXIMUM_TRACKS = 120;
+
 	uint16    _activeNotes[128];   ///< Each uint16 is a bit mask for channels that have that note on.
 	NoteTimer _hangingNotes[32];   ///< Maintains expiration info for up to 32 notes.
 	                                ///< Used for "Smart Jump" and MIDI formats that do not include explicit Note Off events.
@@ -280,7 +282,7 @@ protected:
 	bool   _sendSustainOffOnNotesOff;   ///< Send a sustain off on a notes off event, stopping hanging notes
 	bool   _disableAllNotesOffMidiEvents;   ///< Don't send All Notes Off MIDI messages
 	bool   _doNotAutoStartPlayback;  ///< Do not automatically start playback after parsing MIDI data or setting the track
-	byte  *_tracks[120];    ///< Multi-track MIDI formats are supported, up to 120 tracks.
+	byte  *_tracks[MAXIMUM_TRACKS];    ///< Multi-track MIDI formats are supported, up to 120 tracks.
 	byte   _numTracks;     ///< Count of total tracks for multi-track MIDI formats. 1 for single-track formats.
 	byte   _activeTrack;   ///< Keeps track of the currently active track, in multi-track formats.
 
diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp
index 6c3a479484..3e6f1c6fff 100644
--- a/audio/midiparser_xmidi.cpp
+++ b/audio/midiparser_xmidi.cpp
@@ -55,7 +55,7 @@ protected:
 	 * The sequence branches defined for each track. These point to
 	 * positions in the MIDI data.
 	 */
-	byte *_trackBranches[ARRAYSIZE(_tracks)][MAXIMUM_TRACK_BRANCHES];
+	byte *_trackBranches[MAXIMUM_TRACKS][MAXIMUM_TRACK_BRANCHES];
 
 	XMidiCallbackProc _callbackProc;
 	void *_callbackData;


Commit: ee4de6ebee1818d8c762dee21d99b199d8557af4
    https://github.com/scummvm/scummvm/commit/ee4de6ebee1818d8c762dee21d99b199d8557af4
Author: NMIError (crampen at gmail.com)
Date: 2020-06-12T13:46:27-05:00

Commit Message:
ULTIMA8: Fix warnings when track has no branches

When a MIDI track was played that had no branch index points, the music player
would attempt to start the track at branch index 0 anyway, producing warnings
and then falling back to the start of the track.

This adds a check to see if there are any branches, and start the track at the
beginning if there aren't any. This gets rid of the warnings.

Changed paths:
    engines/ultima/ultima8/audio/u8_music_process.cpp


diff --git a/engines/ultima/ultima8/audio/u8_music_process.cpp b/engines/ultima/ultima8/audio/u8_music_process.cpp
index 2222f92f8c..8b8b4e08c0 100644
--- a/engines/ultima/ultima8/audio/u8_music_process.cpp
+++ b/engines/ultima/ultima8/audio/u8_music_process.cpp
@@ -225,9 +225,15 @@ void U8MusicProcess::run() {
 				bool repeat = (_trackState._queued == 0);
 				_midiPlayer->load(xmidi->_data, xmidi->_size, 0, false);
 				_midiPlayer->setLooping(repeat);
-				if (_songBranches[_trackState._wanted] >= 0 && !_midiPlayer->hasBranchIndex(_songBranches[_trackState._wanted]))
-					// Current branch is past the end of the list of branches. Reset to 0.
-					_songBranches[_trackState._wanted] = 0;
+				if (_songBranches[_trackState._wanted] >= 0 && !_midiPlayer->hasBranchIndex(_songBranches[_trackState._wanted])) {
+					if (_songBranches[_trackState._wanted] == 0) {
+						// This track does not have any branches.
+						_songBranches[_trackState._wanted] = -1;
+					} else {
+						// Current branch is past the end of the list of branches. Reset to 0.
+						_songBranches[_trackState._wanted] = 0;
+					}
+				}
 				_midiPlayer->play(0, _songBranches[_trackState._wanted]);
 			}
 


Commit: 0f297559cd50ec800646cba372229c6dac1a0472
    https://github.com/scummvm/scummvm/commit/0f297559cd50ec800646cba372229c6dac1a0472
Author: NMIError (crampen at gmail.com)
Date: 2020-06-12T13:46:27-05:00

Commit Message:
ULTIMA8/MIDI: Rename doNotAutoStartPlayback

Renamed doNotAutoStartPlayback to disableAutoStartPlayback for more consistency
in property naming.

Changed paths:
    audio/midiparser.cpp
    audio/midiparser.h
    engines/ultima/ultima8/audio/midi_player.cpp


diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index c200eca539..9e8a0105d0 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -43,7 +43,7 @@ _smartJump(false),
 _centerPitchWheelOnUnload(false),
 _sendSustainOffOnNotesOff(false),
 _disableAllNotesOffMidiEvents(false),
-_doNotAutoStartPlayback(false),
+_disableAutoStartPlayback(false),
 _numTracks(0),
 _activeTrack(255),
 _abortParse(false),
@@ -74,8 +74,8 @@ void MidiParser::property(int prop, int value) {
 	case mpDisableAllNotesOffMidiEvents:
 		_disableAllNotesOffMidiEvents = (value != 0);
 		break;
-	case mpDoNotAutoStartPlayback:
-		_doNotAutoStartPlayback = (value != 0);
+	case mpDisableAutoStartPlayback:
+		_disableAutoStartPlayback = (value != 0);
 		break;
 	default:
 		break;
@@ -353,7 +353,7 @@ bool MidiParser::setTrack(int track) {
 
 	resetTracking();
 	memset(_activeNotes, 0, sizeof(_activeNotes));
-	if (_doNotAutoStartPlayback)
+	if (_disableAutoStartPlayback)
 		_doParse = false;
 	_activeTrack = track;
 	_position._playPos = _tracks[track];
diff --git a/audio/midiparser.h b/audio/midiparser.h
index f1542c20e2..11f3a5efdb 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -281,7 +281,7 @@ protected:
 	bool   _centerPitchWheelOnUnload;  ///< Center the pitch wheels when unloading a song
 	bool   _sendSustainOffOnNotesOff;   ///< Send a sustain off on a notes off event, stopping hanging notes
 	bool   _disableAllNotesOffMidiEvents;   ///< Don't send All Notes Off MIDI messages
-	bool   _doNotAutoStartPlayback;  ///< Do not automatically start playback after parsing MIDI data or setting the track
+	bool   _disableAutoStartPlayback;  ///< Do not automatically start playback after parsing MIDI data or setting the track
 	byte  *_tracks[MAXIMUM_TRACKS];    ///< Multi-track MIDI formats are supported, up to 120 tracks.
 	byte   _numTracks;     ///< Count of total tracks for multi-track MIDI formats. 1 for single-track formats.
 	byte   _activeTrack;   ///< Keeps track of the currently active track, in multi-track formats.
@@ -388,7 +388,7 @@ public:
 		  * or setting the track. Use startPlaying to start playback.
 		  * Note that not every parser implementation might support this.
 		  */
-		  mpDoNotAutoStartPlayback = 7
+		  mpDisableAutoStartPlayback = 7
 	};
 
 public:
diff --git a/engines/ultima/ultima8/audio/midi_player.cpp b/engines/ultima/ultima8/audio/midi_player.cpp
index 139bb0578e..b3176c70ec 100644
--- a/engines/ultima/ultima8/audio/midi_player.cpp
+++ b/engines/ultima/ultima8/audio/midi_player.cpp
@@ -76,7 +76,7 @@ void MidiPlayer::load(byte *data, size_t size, int seqNo, bool speedHack) {
 			_parser->setTempo(_driver->getBaseTempo() * 2);
 		_parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
 		_parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
-		_parser->property(MidiParser::mpDoNotAutoStartPlayback, 1);
+		_parser->property(MidiParser::mpDisableAutoStartPlayback, 1);
 
 		int volume = g_engine->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
 		setVolume(volume);




More information about the Scummvm-git-logs mailing list