[Scummvm-git-logs] scummvm master -> ed4f414fc139243cffca484113566db8c5a6556f

dreammaster paulfgilbert at gmail.com
Fri Mar 6 05:17:10 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:
ed4f414fc1 ULTIMA8: Fix menu/credits music behavior


Commit: ed4f414fc139243cffca484113566db8c5a6556f
    https://github.com/scummvm/scummvm/commit/ed4f414fc139243cffca484113566db8c5a6556f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-03-05T21:17:06-08:00

Commit Message:
ULTIMA8: Fix menu/credits music behavior

There are 2 problems with the way combat music interacts with the menu (and the
credits you can view from there):

* When the menu is closed, the combat music becomes the "last request", so it
  never stops even if combat finishes.
* If the creidts are viewed, the requested credits music is ignored because
  combat is active, and the music player is checking the actor's status to
  decide whether to change tracks.

This fixes both those problems, and restores the original game behavior of just
turning off the music when the menu is opened.  I also removed the coupling of
actor state from the music process.  I think this now works properly in all
situations.

Changed paths:
    engines/ultima/ultima8/audio/music_process.cpp
    engines/ultima/ultima8/audio/music_process.h
    engines/ultima/ultima8/gumps/menu_gump.cpp
    engines/ultima/ultima8/gumps/menu_gump.h


diff --git a/engines/ultima/ultima8/audio/music_process.cpp b/engines/ultima/ultima8/audio/music_process.cpp
index 59155c27a2..93ef614c1d 100644
--- a/engines/ultima/ultima8/audio/music_process.cpp
+++ b/engines/ultima/ultima8/audio/music_process.cpp
@@ -26,9 +26,6 @@
 #include "ultima/ultima8/audio/music_flex.h"
 #include "ultima/ultima8/audio/midi_player.h"
 #include "ultima/ultima8/audio/audio_mixer.h"
-#include "ultima/ultima8/kernel/object_manager.h"
-#include "ultima/ultima8/world/get_object.h"
-#include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/filesys/idata_source.h"
 #include "ultima/ultima8/filesys/odata_source.h"
 
@@ -40,14 +37,13 @@ DEFINE_RUNTIME_CLASSTYPE_CODE(MusicProcess, Process)
 
 MusicProcess *MusicProcess::_theMusicProcess = 0;
 
-MusicProcess::MusicProcess() : _midiPlayer(0), _state(MUSIC_NORMAL),
-		_currentTrack(0), _wantedTrack(0), _lastRequest(0), _queuedTrack(0) {
+MusicProcess::MusicProcess() : _midiPlayer(0), _state(PLAYBACK_NORMAL),
+		_currentTrack(0), _combatMusicActive(false) {
 	Std::memset(_songBranches, (byte)-1, 128 * sizeof(int));
 }
 
 MusicProcess::MusicProcess(MidiPlayer *player) : _midiPlayer(player),
-		_state(MUSIC_NORMAL), _currentTrack(0), _wantedTrack(0),
-		_lastRequest(0), _queuedTrack(0) {
+		_state(PLAYBACK_NORMAL), _currentTrack(0), _combatMusicActive(false)  {
 	Std::memset(_songBranches, (byte)-1, 128 * sizeof(int));
 
 	_theMusicProcess = this;
@@ -61,19 +57,13 @@ MusicProcess::~MusicProcess() {
 }
 
 void MusicProcess::playMusic(int track) {
-	_lastRequest = track;
+	_trackState._lastRequest = track;
 
-	ObjectManager *om = ObjectManager::get_instance();
-	if (om && getMainActor()) {
-		MainActor *av = getMainActor();
-		if (av->isInCombat() || (av->getActorFlags() & Actor::ACT_COMBATRUN)) {
-			// combat music active
-			return;
-		}
-	}
+	if (_combatMusicActive)
+		return;
 
-	if (_queuedTrack) {
-		_queuedTrack = track;
+	if (_trackState._queued) {
+		_trackState._queued = track;
 		return;
 	}
 
@@ -81,22 +71,33 @@ void MusicProcess::playMusic(int track) {
 }
 
 void MusicProcess::playCombatMusic(int track) {
+	_combatMusicActive = (track != 0);
 	playMusic_internal(track);
 }
 
 void MusicProcess::queueMusic(int track) {
-	if (_wantedTrack != track) {
-		_queuedTrack = track;
+	if (_trackState._wanted != track) {
+		_trackState._queued = track;
 	}
 }
 
 void MusicProcess::unqueueMusic() {
-	_queuedTrack = 0;
+	_trackState._queued = 0;
 }
 
 void MusicProcess::restoreMusic() {
-	_queuedTrack = 0;
-	playMusic_internal(_lastRequest);
+	_trackState._queued = 0;
+	_combatMusicActive = false;
+	playMusic_internal(_trackState._lastRequest);
+}
+
+void MusicProcess::getTrackState(TrackState &trackState) const {
+	trackState = _trackState;
+}
+
+void MusicProcess::setTrackState(const TrackState &trackState) {
+	_trackState = trackState;
+	_state = PLAYBACK_PLAY_WANTED;
 }
 
 void MusicProcess::playMusic_internal(int track) {
@@ -107,14 +108,14 @@ void MusicProcess::playMusic_internal(int track) {
 
 	// No current track if not playing
 	if (_midiPlayer && !_midiPlayer->isPlaying())
-		_wantedTrack = _currentTrack = 0;
+		_trackState._wanted = _currentTrack = 0;
 
 	// It's already playing and we are not transitioning
-	if (_currentTrack == track && _state == MUSIC_NORMAL) {
+	if (_currentTrack == track && _state == PLAYBACK_NORMAL) {
 		return;
-	} else if (_currentTrack == 0 || _state != MUSIC_NORMAL || !_midiPlayer) {
-		_wantedTrack = track;
-		_state = MUSIC_PLAY_WANTED;
+	} else if (_currentTrack == 0 || _state != PLAYBACK_NORMAL || !_midiPlayer) {
+		_trackState._wanted = track;
+		_state = PLAYBACK_PLAY_WANTED;
 
 	} else {
 		// We want to do a transition
@@ -129,7 +130,7 @@ void MusicProcess::playMusic_internal(int track) {
 		        !info->transitions[track] || !info->transitions[track][measure]) {
 			_currentTrack = 0;
 			if (track == 0) {
-				_wantedTrack = 0;
+				_trackState._wanted = 0;
 				_state = MUSIC_PLAY_WANTED;
 			} else {
 				playMusic_internal(track);
@@ -154,48 +155,53 @@ void MusicProcess::playMusic_internal(int track) {
 		XMidiFile *xmidi = GameData::get_instance()->getMusic()->getXMidi(xmidi_index);
 		XMidiEventList *list;
 
-		if (xmidi) list = xmidi->GetEventList(trans);
-		else list = 0;
+		if (xmidi)
+			list = xmidi->GetEventList(trans);
+		else
+			list = 0;
 
 		if (list) {
 			_midiPlayer->startSequence(1, list, false, 255, _songBranches[track]);
-			if (speed_hack) _midiPlayer->setSequenceSpeed(1, 200);
-		} else _midiPlayer->finishSequence(1);
+			if (speed_hack)
+				_midiPlayer->setSequenceSpeed(1, 200);
+		} else {
+			_midiPlayer->finishSequence(1);
+		}
 #endif
-		_wantedTrack = track;
-		_state = MUSIC_TRANSITION;
+		_trackState._wanted = track;
+		_state = PLAYBACK_TRANSITION;
 	}
 }
 
 void MusicProcess::run() {
 	switch (_state) {
-	case MUSIC_NORMAL:
-		if (_midiPlayer && !_midiPlayer->isPlaying() && _queuedTrack) {
-			_wantedTrack = _queuedTrack;
-			_state = MUSIC_PLAY_WANTED;
-			_queuedTrack = 0;
+	case PLAYBACK_NORMAL:
+		if (_midiPlayer && !_midiPlayer->isPlaying() && _trackState._queued) {
+			_trackState._wanted = _trackState._queued;
+			_state = PLAYBACK_PLAY_WANTED;
+			_trackState._queued = 0;
 		}
 
 		break;
 
-	case MUSIC_TRANSITION:
+	case PLAYBACK_TRANSITION:
 		if (!_midiPlayer) {
-			_state = MUSIC_PLAY_WANTED;
+			_state = PLAYBACK_PLAY_WANTED;
 		} else {
-			_state = MUSIC_PLAY_WANTED;
+			_state = PLAYBACK_PLAY_WANTED;
 			_midiPlayer->stop();
 		}
 		break;
 
-	case MUSIC_PLAY_WANTED: {
+	case PLAYBACK_PLAY_WANTED: {
 		if (_midiPlayer)
 			_midiPlayer->stop();
 
 		byte *data = nullptr;
 		uint32 size = 0;
 
-		if (_wantedTrack) {
-			int xmidi_index = _wantedTrack;
+		if (_trackState._wanted) {
+			int xmidi_index = _trackState._wanted;
 			if (_midiPlayer && _midiPlayer->isFMSynth())
 				xmidi_index += 128;
 
@@ -205,17 +211,17 @@ void MusicProcess::run() {
 		if (data) {
 			if (_midiPlayer) {
 				// if there's a track queued, only play this one once
-				bool repeat = (_queuedTrack == 0);
+				bool repeat = (_trackState._queued == 0);
 				_midiPlayer->play(data, size);
 				_midiPlayer->setLooping(repeat);
 			}
 
-			_currentTrack = _wantedTrack;
-			_songBranches[_wantedTrack]++;
+			_currentTrack = _trackState._wanted;
+			_songBranches[_trackState._wanted]++;
 		} else {
-			_currentTrack = _wantedTrack = 0;
+			_currentTrack = _trackState._wanted = 0;
 		}
-		_state = MUSIC_NORMAL;
+		_state = PLAYBACK_NORMAL;
 	}
 	break;
 	}
@@ -224,25 +230,25 @@ void MusicProcess::run() {
 void MusicProcess::saveData(ODataSource *ods) {
 	Process::saveData(ods);
 
-	ods->write4(static_cast<uint32>(_wantedTrack));
-	ods->write4(static_cast<uint32>(_lastRequest));
-	ods->write4(static_cast<uint32>(_queuedTrack));
+	ods->write4(static_cast<uint32>(_trackState._wanted));
+	ods->write4(static_cast<uint32>(_trackState._lastRequest));
+	ods->write4(static_cast<uint32>(_trackState._queued));
 }
 
 bool MusicProcess::loadData(IDataSource *ids, uint32 version) {
 	if (!Process::loadData(ids, version)) return false;
 
-	_wantedTrack = static_cast<int32>(ids->read4());
+	_trackState._wanted = static_cast<int32>(ids->read4());
 
 	if (version >= 4) {
-		_lastRequest = static_cast<int32>(ids->read4());
-		_queuedTrack = static_cast<int32>(ids->read4());
+		_trackState._lastRequest = static_cast<int32>(ids->read4());
+		_trackState._queued = static_cast<int32>(ids->read4());
 	} else {
-		_lastRequest = _wantedTrack;
-		_queuedTrack = 0;
+		_trackState._lastRequest = _trackState._wanted;
+		_trackState._queued = 0;
 	}
 
-	_state = MUSIC_PLAY_WANTED;
+	_state = PLAYBACK_PLAY_WANTED;
 
 	_theMusicProcess = this;
 
diff --git a/engines/ultima/ultima8/audio/music_process.h b/engines/ultima/ultima8/audio/music_process.h
index afb87328ff..e86c9ec948 100644
--- a/engines/ultima/ultima8/audio/music_process.h
+++ b/engines/ultima/ultima8/audio/music_process.h
@@ -37,11 +37,27 @@ class MidiPlayer;
 class MusicProcess : public Process {
 	friend class Debugger;
 
-	enum MusicStates {
-		MUSIC_NORMAL = 1,
-		MUSIC_TRANSITION = 2,
-		MUSIC_PLAY_WANTED = 3
+	enum PlaybackStates {
+		PLAYBACK_NORMAL = 1,
+		PLAYBACK_TRANSITION = 2,
+		PLAYBACK_PLAY_WANTED = 3
 	};
+
+public:
+	//! The saveable part of track state
+	struct TrackState {
+		//! Track we want to play
+		int _wanted;
+		//! Last requested track that was not a temporary (ie, combat) track
+		int _lastRequest;
+		//! Track queued to start after current
+		int _queued;
+
+		TrackState() : _wanted(0), _lastRequest(0), _queued(0) { }
+		TrackState(int wanted, int lastRequest, int queued) :
+			_wanted(wanted), _lastRequest(lastRequest), _queued(queued) { }
+	};
+
 private:
 	void saveData(ODataSource *ods) override;
 
@@ -52,13 +68,16 @@ private:
 	static MusicProcess *_theMusicProcess;
 
 	MidiPlayer *_midiPlayer;
-	MusicStates _state;
-	int _currentTrack;      // Currently playing track (don't save)
-	int _wantedTrack;       // Track we want to play (save this)
+	PlaybackStates _state;
 	int _songBranches[128];
 
-	int _lastRequest;       // Last requested track
-	int _queuedTrack;       // Track queued to start after current
+	int _currentTrack;      //! Currently playing track (don't save)
+
+	TrackState _trackState;
+
+	//! Is the current music "combat" music
+	bool _combatMusicActive;
+
 public:
 	MusicProcess();
 	MusicProcess(MidiPlayer *player); // Note that this does NOT delete the driver
@@ -72,20 +91,25 @@ public:
 		return _theMusicProcess;
 	}
 
+	//! Play some background music. Does not change the current track if combat music is active.  If another track is currently queued, just queues this track for play.
 	void playMusic(int track);
+	//! Play some combat music - the last played track will be remembered
 	void playCombatMusic(int track);
+	//! Queue a track to start once the current one finishes
 	void queueMusic(int track);
+	//! Clear any queued track (does not affect currently playing track)
 	void unqueueMusic();
+	//! Restore the last requested non-combat track (eg, at the end of combat)
 	void restoreMusic();
 
 	INTRINSIC(I_playMusic);
 	INTRINSIC(I_musicStop);
 
 
-	//! Get the number of the current or wanted track
-	int getTrack() const {
-		return _wantedTrack;
-	}
+	//! Get the state of tracks (wanted, requested, queued)
+	void getTrackState(TrackState &trackState) const;
+
+	void setTrackState(const TrackState &state);
 
 	void run() override;
 
diff --git a/engines/ultima/ultima8/gumps/menu_gump.cpp b/engines/ultima/ultima8/gumps/menu_gump.cpp
index 975c20a78f..b5bb8aaa8c 100644
--- a/engines/ultima/ultima8/gumps/menu_gump.cpp
+++ b/engines/ultima/ultima8/gumps/menu_gump.cpp
@@ -68,8 +68,13 @@ MenuGump::MenuGump(bool nameEntryMode_)
 
 	// Save old music state
 	MusicProcess *musicprocess = MusicProcess::get_instance();
-	if (musicprocess) _oldMusicTrack = musicprocess->getTrack();
-	else _oldMusicTrack = 0;
+	if (musicprocess) {
+		musicprocess->getTrackState(_oldMusicTrackState);
+		// Stop any playing music.
+		musicprocess->playCombatMusic(0);
+	} else {
+		_oldMusicTrackState = MusicProcess::TrackState();
+	}
 	// Save old palette transform
 	PaletteManager *palman = PaletteManager::get_instance();
 	palman->getTransformMatrix(_oldPalTransform, PaletteManager::Pal_Game);
@@ -80,9 +85,10 @@ MenuGump::~MenuGump() {
 }
 
 void MenuGump::Close(bool no_del) {
-	// Restore old music state and palette
+	// Restore old music state and palette.
+	// Music state can be changed by the Intro and Credits
 	MusicProcess *musicprocess = MusicProcess::get_instance();
-	if (musicprocess) musicprocess->playMusic(_oldMusicTrack);
+	if (musicprocess) musicprocess->setTrackState(_oldMusicTrackState);
 	PaletteManager *palman = PaletteManager::get_instance();
 	palman->transformPalette(PaletteManager::Pal_Game, _oldPalTransform);
 
diff --git a/engines/ultima/ultima8/gumps/menu_gump.h b/engines/ultima/ultima8/gumps/menu_gump.h
index 199458edfc..e46fb0333c 100644
--- a/engines/ultima/ultima8/gumps/menu_gump.h
+++ b/engines/ultima/ultima8/gumps/menu_gump.h
@@ -24,6 +24,7 @@
 #define ULTIMA8_GUMPS_MENUGUMP_H
 
 #include "ultima/ultima8/gumps/modal_gump.h"
+#include "ultima/ultima8/audio/music_process.h"
 #include "ultima/ultima8/misc/p_dynamic_cast.h"
 
 namespace Ultima {
@@ -55,7 +56,7 @@ public:
 
 protected:
 	bool _nameEntryMode;
-	int _oldMusicTrack;
+	MusicProcess::TrackState _oldMusicTrackState;
 	int16 _oldPalTransform[12];
 
 	virtual void selectEntry(int entry);




More information about the Scummvm-git-logs mailing list