[Scummvm-git-logs] scummvm master -> 7cb8dc53d6e687a052c68dbdedaece9621c64542

antoniou79 a.antoniou79 at gmail.com
Sat Jun 12 12:01:39 UTC 2021


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

Summary:
61d66fca74 JANITORIAL: BLADERUNNER: Fix indendation for switch clause
54ecf13bdd BLADERUNNER: Another minor possible optimization
4e32ee564f BLADERUNNER: Rename two flags and add some comments
346fe3722d BLADERUNNER: Fix transition to MA05 for act 5
1a25c2b69a BLADERUNNER: Remove timerprocs for next track and fadeout
5ab6c92f99 BLADERUNNER: Add a reset() method for Music
d11765138c BLADERUNNER: Fix bugs for adjustpan, adjustvolume.
7cb8dc53d6 BLADERUNNER: Fix clearing loop value of queued track


Commit: 61d66fca748beb0682a6b69138f03c8e23b4209b
    https://github.com/scummvm/scummvm/commit/61d66fca748beb0682a6b69138f03c8e23b4209b
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
JANITORIAL: BLADERUNNER: Fix indendation for switch clause

Changed paths:
    engines/bladerunner/bladerunner.h


diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 2c1792fc19..ef8a90dde0 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -367,17 +367,17 @@ static inline const Graphics::PixelFormat screenPixelFormat() {
 
 static inline void drawPixel(Graphics::Surface &surface, void* dst, uint32 value) {
 	switch (surface.format.bytesPerPixel) {
-		case 1:
-			*(uint8*)dst = (uint8)value;
-			break;
-		case 2:
-			*(uint16*)dst = (uint16)value;
-			break;
-		case 4:
-			*(uint32*)dst = (uint32)value;
-			break;
-		default:
-			break;
+	case 1:
+		*(uint8*)dst = (uint8)value;
+		break;
+	case 2:
+		*(uint16*)dst = (uint16)value;
+		break;
+	case 4:
+		*(uint32*)dst = (uint32)value;
+		break;
+	default:
+		break;
 	}
 }
 


Commit: 54ecf13bdd940893ebb6326aa1b6e39d489fc302
    https://github.com/scummvm/scummvm/commit/54ecf13bdd940893ebb6326aa1b6e39d489fc302
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Another minor possible optimization

Really minor, but maybe there's gain in low performing devices since the function is called very often

Changed paths:
    engines/bladerunner/vqa_decoder.cpp


diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp
index a10fdf10d0..6e8706c5b5 100644
--- a/engines/bladerunner/vqa_decoder.cpp
+++ b/engines/bladerunner/vqa_decoder.cpp
@@ -823,14 +823,16 @@ void VQADecoder::VQAVideoTrack::VPTRWriteBlock(Graphics::Surface *surface, unsig
 
 	uint16 blocks_per_line = _width / _blockW;
 
+	uint32 intermDiv = 0;
 	uint32 dst_x = 0;
 	uint32 dst_y = 0;
 	uint16 vqaColor = 0;
 	uint8 a, r, g, b;
 
 	for (uint i = count; i != 0; --i) {
-		dst_x = (dstBlock + count - i) % blocks_per_line * _blockW + _offsetX;
-		dst_y = (dstBlock + count - i) / blocks_per_line * _blockH + _offsetY;
+		intermDiv = (dstBlock + count - i) / blocks_per_line;
+		dst_x = ((dstBlock + count - i) - intermDiv * blocks_per_line) * _blockW + _offsetX;
+		dst_y = intermDiv * _blockH + _offsetY;
 
 		const uint8 *src_p = block_src;
 


Commit: 4e32ee564f3e3eb990625dc458a733a4328e796e
    https://github.com/scummvm/scummvm/commit/4e32ee564f3e3eb990625dc458a733a4328e796e
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Rename two flags and add some comments

Related to Guzza's dialogue in PS4

Changed paths:
    engines/bladerunner/game_constants.h
    engines/bladerunner/script/scene/ps04.cpp


diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index 8835a0ecee..3daa50243d 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -600,8 +600,8 @@ enum Flags {
 	kFlagSergeantWallsBuzzInDone              = 158,
 	kFlagPS04GuzzaTalkZubenRetired            = 159,
 	kFlagPS04GuzzaTalkZubenEscaped            = 160,
-	kFlagPS04GuzzaTalk1                       = 161,
-	kFlagPS04GuzzaTalk2                       = 162,
+	kFlagPS04GuzzaTalkIsFurious               = 161,
+	kFlagPS04GuzzaTalkDumpToMainframe         = 162,
 	kFlagRC01ChromeDebrisTaken                = 163,
 	kFlagIzoArrested                          = 164,
 	kFlagCrazylegsArrested                    = 165,
diff --git a/engines/bladerunner/script/scene/ps04.cpp b/engines/bladerunner/script/scene/ps04.cpp
index 6a2fd8a17b..b22efc1e5b 100644
--- a/engines/bladerunner/script/scene/ps04.cpp
+++ b/engines/bladerunner/script/scene/ps04.cpp
@@ -330,7 +330,7 @@ void SceneScriptPS04::dialogueWithGuzza() {
 		            || Actor_Clue_Query(kActorMcCoy, kClueSushiMenu))
 		           &&  Actor_Clue_Query(kActorMcCoy, kClueRunciterInterviewA)
 		           &&  Actor_Query_Friendliness_To_Other(kActorGuzza, kActorMcCoy) < 50
-		           && !Game_Flag_Query(kFlagPS04GuzzaTalk1)
+		           && !Game_Flag_Query(kFlagPS04GuzzaTalkIsFurious)
 		) {
 			Actor_Says(kActorMcCoy, 3970, 18);
 			Actor_Says(kActorGuzza, 330, 30);
@@ -345,17 +345,20 @@ void SceneScriptPS04::dialogueWithGuzza() {
 			Actor_Says(kActorMcCoy, 3985, 18);
 			Actor_Says(kActorGuzza, 400, 34);
 			Actor_Says(kActorGuzza, 410, 31);
-			Game_Flag_Set(kFlagPS04GuzzaTalk1);
+			Game_Flag_Set(kFlagPS04GuzzaTalkIsFurious);
 		} else if ((Actor_Clue_Query(kActorMcCoy, kClueChopstickWrapper)
 		            || Actor_Clue_Query(kActorMcCoy, kClueSushiMenu))
 		           &&  Actor_Clue_Query(kActorMcCoy, kClueRunciterInterviewA)
-		           && !Game_Flag_Query(kFlagPS04GuzzaTalk2)
+		           && !Game_Flag_Query(kFlagPS04GuzzaTalkDumpToMainframe)
 		) {
+			// McCoy metions Bryant's "vacation",
+			// Guzza says about the procedure via Mainframe
 			Actor_Says(kActorMcCoy, 3920, 13);
 			Actor_Says(kActorGuzza, 570, 32);
 			Actor_Says(kActorMcCoy, 4070, 13);
-			Game_Flag_Set(kFlagPS04GuzzaTalk2);
+			Game_Flag_Set(kFlagPS04GuzzaTalkDumpToMainframe);
 		} else if (Actor_Query_Friendliness_To_Other(kActorGuzza, kActorMcCoy) >= 50) {
+			// Main check-in talk
 			Actor_Says(kActorMcCoy, 4020, 13);
 			Actor_Says(kActorGuzza, 580, 34);
 			Actor_Says(kActorMcCoy, 4075, 16);


Commit: 346fe3722da83c3ef8beb9b9c1ce846e4ac46b8a
    https://github.com/scummvm/scummvm/commit/346fe3722da83c3ef8beb9b9c1ce846e4ac46b8a
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Fix transition to MA05 for act 5

Pending some testing on slow devices

Changed paths:
    engines/bladerunner/vqa_player.cpp


diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index e766fcb3ac..fdf37e27b8 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -53,15 +53,6 @@ bool VQAPlayer::open() {
 		// This has still frames in the end that so it looked as if the smoke was "frozen"
 		_decoder._loopInfo.loops[0].end  = 58; // 59 up to 74 are still frames
 	}
-//	else if (_name.equals("MA05_3.VQA")) {
-//		// loops[1] 60 up to 90 (it will be followed by loops[2] which will play from 30 to 90
-//		// this is to address the issue of non-aligned headlight rotation in the
-//		// InShot transition in Act 5. However, this is still glitchy
-//		// and results in bad z-buffer for the duration of the truncated loop 1
-//		// TODO is there a way to get and use the z-buffering info from start frame without displaying it?
-//		_decoder._loopInfo.loops[1].begin = 60;
-//		_decoder._loopInfo.loops[2].begin = 30;
-//	}
 #endif
 
 	_hasAudio = _decoder.hasAudio();
@@ -79,7 +70,9 @@ bool VQAPlayer::open() {
 	_repeatsCountQueued = -1;
 
 	if (_loopInitial >= 0) {
-		// TODO? When does this happen? _loopInitial seems to be unused
+		// loopInitial is set to the loop Id value that should play,
+		// when the SeekableReadStream (_s) is nullptr
+		// see setLoop()
 		setLoop(_loopInitial, _repeatsCountInitial, kLoopSetModeImmediate, nullptr, nullptr);
 	} else {
 		_frameNext = 0;
@@ -109,6 +102,22 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
 		if (_frameEndQueued != -1) {
 			_frameEnd = _frameEndQueued;
 			_frameEndQueued = -1;
+#if !BLADERUNNER_ORIGINAL_BUGS
+			// Fix glitch in transition from inShot to mainloop
+			// in Act 5 at McCoy's apartment (moving from bedroom to balcony).
+			// This emulates a fast-forward, which is required
+			// in order to have proper z-buffer info,
+			// and display the new first frame of the loop (60) without artifacts.
+			// The code is similar to Scene::advanceFrame()
+			// This will be done once, since this first loop (loopId 1)
+			// is only executed once before moving on to loopId 2
+			if (_name.equals("MA05_3.VQA") && _loop == 1) {
+				while (update(false, true, false) != 59) {
+					updateZBuffer(_vm->_zbuffer);
+				}
+				_frameBegin = 60;
+			}
+#endif
 		}
 		if (_frameNext != _frameBegin) {
 			_frameNext = _frameBegin;


Commit: 1a25c2b69a294273be9955771be0ac87153f6bad
    https://github.com/scummvm/scummvm/commit/1a25c2b69a294273be9955771be0ac87153f6bad
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Remove timerprocs for next track and fadeout

The timers are replaced with "application" timers, which are checked in AudioMixer::tick()

The timerprocs for next and fadeout could potentially cause a game freeze.
This is because they could, under certain race conditions, come to a deadend
while trying to lock the mutexes for access to AudioMixer and Music methods.
The particular use case (non-deterministic) for this was loading a save game
while playing a game that had a music track playing (eg. at MA05, McCoy's balcony).
Here's a rough explanation of a possible lock situation (others could also be possible)
The "Main Thread" and "SDLTimer" threads (as reported from MSVC debug) could become hardlocked.
::Main Thread::
	A. LoadGame() calls _music->stop(0u);
		A1. Locks a Music::_mutex
		A2. Calls vm->_audioMixer->stop()
		A3. AudioMixer::stop() locks AudioMixer::_mutex [THIS DONE]
		A4. calls the endCallback for the music which is Music::ended()
			at Music::ended,
			A41. lock a Music::_mutex (presumably this is ok, even though it's a second lock, because it's the same thread(?))
			A42. call installTimerProc()
				A421. which tries to lock DefaultTimerManager::_mutex from default-timer [THIS FREEZES] - conflict with B11
::SDLTimer::
	B. calls timer_handler,
		B1. calls DefaultTimerManager::handler()
			B11. locks the DefaultTimerManager::_mutex from default-timer [THIS IS DONE]
			B12. we try to service the callbacks from TimerProcs that are currently entered in the TimerSlots queue
				B121. Such a slot is the AudioMixer BladeRunnerAudioMixerTimer, which has the AudioMixer::timerCallback()
				B1211. which calls the at AudioMixer::tick().
						tick() tries to lock the AudioMixer::_mutex [THIS FREEZES] conflict with A3

Changed paths:
    engines/bladerunner/audio_mixer.cpp
    engines/bladerunner/audio_mixer.h
    engines/bladerunner/music.cpp
    engines/bladerunner/music.h


diff --git a/engines/bladerunner/audio_mixer.cpp b/engines/bladerunner/audio_mixer.cpp
index 91076db2c9..8f85b235fc 100644
--- a/engines/bladerunner/audio_mixer.cpp
+++ b/engines/bladerunner/audio_mixer.cpp
@@ -23,6 +23,7 @@
 #include "bladerunner/audio_mixer.h"
 
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/music.h"
 #include "bladerunner/time.h"
 
 #include "audio/audiostream.h"
@@ -37,12 +38,19 @@ AudioMixer::AudioMixer(BladeRunnerEngine *vm) {
 	for (int i = 0; i < kChannels; ++i) {
 		_channels[i].isPresent = false;
 	}
+#if !BLADERUNNER_ORIGINAL_BUGS
+	for (int i = 0; i < kAudioMixerAppTimersNum; ++i) {
+		_audioMixerAppTimers[i].started        = false;
+		_audioMixerAppTimers[i].lastFired      = 0u;
+		_audioMixerAppTimers[i].intervalMillis = 0u;
+	}
+#endif // BLADERUNNER_ORIGINAL_BUGS
 	_vm->getTimerManager()->installTimerProc(timerCallback, (1000 / kUpdatesPerSecond) * 1000, this, "BladeRunnerAudioMixerTimer");
 }
 
 AudioMixer::~AudioMixer() {
 	for (int i = 0; i < kChannels; ++i) {
-		stop(i, 0);
+		stop(i, 0u);
 	}
 	_vm->getTimerManager()->removeTimerProc(timerCallback);
 }
@@ -69,7 +77,7 @@ int AudioMixer::play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream
 			return -1;
 		}
 		//debug("Stopping lowest priority channel %d with lower prio %d!", lowestPriorityChannel, lowestPriority);
-		stop(lowestPriorityChannel, 0);
+		stop(lowestPriorityChannel, 0u);
 		channel = lowestPriorityChannel;
 	}
 
@@ -82,6 +90,7 @@ int AudioMixer::playMusic(Audio::RewindableAudioStream *stream, int volume, void
 	return playInChannel(kMusicChannel, Audio::Mixer::kMusicSoundType, stream, 100, false, volume, 0, endCallback, callbackData, trackDurationMs);
 }
 
+// Note: time tends to be the requested time in seconds multiplied by 60u
 void AudioMixer::stop(int channel, uint32 time) {
 	Common::StackLock lock(_mutex);
 
@@ -93,6 +102,7 @@ void AudioMixer::stop(int channel, uint32 time) {
 			if (_channels[channel].sentToMixer) {
 				_vm->_mixer->stopHandle(_channels[channel].handle);
 			}
+
 			if (_channels[channel].endCallback != nullptr) {
 				_channels[channel].endCallback(channel, _channels[channel].callbackData);
 			}
@@ -151,6 +161,7 @@ void AudioMixer::timerCallback(void *self) {
 	((AudioMixer *)self)->tick();
 }
 
+// Note: time tends to be the requested time in seconds multiplied by 60u
 void AudioMixer::adjustVolume(int channel, int newVolume, uint32 time) {
 	Common::StackLock lock(_mutex);
 
@@ -160,6 +171,7 @@ void AudioMixer::adjustVolume(int channel, int newVolume, uint32 time) {
 	}
 }
 
+// Note: time tends to be the requested time in seconds multiplied by 60u
 void AudioMixer::adjustPan(int channel, int newPan, uint32 time) {
 	Common::StackLock lock(_mutex);
 
@@ -180,9 +192,11 @@ void AudioMixer::tick() {
 		}
 
 		if (channel->volumeDelta != 0.0f) {
+			// apply volumeDelta to volume (common use for adjustVolume or stop playing - ie mainly for fadeIn, fadeOut)
 			channel->volume = CLIP(channel->volume + channel->volumeDelta, 0.0f, 100.0f);
 
-			if ((channel->volumeDelta < 0 && channel->volume <= channel->volumeTarget) || (channel->volumeDelta > 0 && channel->volume >= channel->volumeTarget)) {
+			if ((channel->volumeDelta < 0 && channel->volume <= channel->volumeTarget)
+			    || (channel->volumeDelta > 0 && channel->volume >= channel->volumeTarget)) {
 				channel->volumeDelta = 0.0f;
 			}
 
@@ -191,11 +205,12 @@ void AudioMixer::tick() {
 			}
 
 			if (channel->volume <= 0.0f) {
-				stop(i, 0);
+				stop(i, 0u);
 			}
 		}
 
 		if (channel->panDelta != 0.0) {
+			// apply panDelta to pan (common use for adjusting pan)
 			channel->pan = CLIP(channel->pan + channel->panDelta, -100.0f, 100.0f);
 
 			if ((channel->panDelta < 0 && channel->pan <= channel->panTarget) || (channel->panDelta > 0 && channel->pan >= channel->panTarget)) {
@@ -211,9 +226,57 @@ void AudioMixer::tick() {
 			|| channel->stream->endOfStream()
 			|| (!channel->sentToMixer && !channel->loop && _vm->_time->currentSystem() - channel->timeStarted >= channel->trackDurationMs)
 		) {
-			stop(i, 0);
+			stop(i, 0u);
 		}
 	}
+
+#if !BLADERUNNER_ORIGINAL_BUGS
+	// piggyback the realtime triggered tick() actions, with a check for the virtual timers (app timers)
+	for (int i = 0; i < kAudioMixerAppTimersNum; ++i) {
+		if (_audioMixerAppTimers[i].started
+		    && _vm->_time->currentSystem() - _audioMixerAppTimers[i].lastFired > _audioMixerAppTimers[i].intervalMillis) {
+			// We actually need to have the _vm->_time->currentSystem() check in the if clause
+			// and not use a var that stores the current time before we enter the loop
+			// because the functions for these timers may affect the lastFired, by setting it to the a current system time
+			// and then lastFired would have been greater than our stored system time here.
+			_audioMixerAppTimers[i].lastFired = _vm->_time->currentSystem();
+			switch (i) {
+			case kAudioMixerAppTimerMusicNext:
+				_vm->_music->next();
+				break;
+			case kAudioMixerAppTimerMusicFadeOut:
+				_vm->_music->fadeOut();
+				break;
+			default:
+				// error - but probably won't happen
+				error("Unknown Audio Mixer App Timer Id");
+				break;
+			}
+		}
+	}
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+}
+
+#if !BLADERUNNER_ORIGINAL_BUGS
+void AudioMixer::startAppTimerProc(int audioMixAppTimerId, uint32 intervalMillis) {
+	// Attempt to lock the mutex, since we reach here from another thread (main thread)
+	Common::StackLock lock(_mutex);
+	if (audioMixAppTimerId  < 0 || audioMixAppTimerId >= kAudioMixerAppTimersNum) {
+		return;
+	}
+	_audioMixerAppTimers[audioMixAppTimerId].started        = true;
+	_audioMixerAppTimers[audioMixAppTimerId].intervalMillis = intervalMillis;
+	_audioMixerAppTimers[audioMixAppTimerId].lastFired      = _vm->_time->currentSystem();
+}
+
+void AudioMixer::stopAppTimerProc(int audioMixAppTimerId) {
+	// Attempt to lock the mutex, since we reach here from another thread (main thread)
+	Common::StackLock lock(_mutex);
+	if (audioMixAppTimerId  < 0 || audioMixAppTimerId >= kAudioMixerAppTimersNum) {
+		return;
+	}
+	_audioMixerAppTimers[audioMixAppTimerId].started = false;
 }
+#endif // !BLADERUNNER_ORIGINAL_BUGS
 
 } // End of namespace BladeRunner
diff --git a/engines/bladerunner/audio_mixer.h b/engines/bladerunner/audio_mixer.h
index 6026b318ac..ae192afef8 100644
--- a/engines/bladerunner/audio_mixer.h
+++ b/engines/bladerunner/audio_mixer.h
@@ -32,6 +32,13 @@ namespace BladeRunner {
 
 class BladeRunnerEngine;
 
+#if !BLADERUNNER_ORIGINAL_BUG
+enum audioMixerAppTimers {
+	kAudioMixerAppTimerMusicNext    =  0,
+	kAudioMixerAppTimerMusicFadeOut =  1
+};
+#endif
+
 class AudioMixer {
 #if BLADERUNNER_ORIGINAL_BUGS
 	static const int kChannels         = 9;
@@ -41,6 +48,8 @@ class AudioMixer {
 	static const int kChannels         = 15;
 	static const int kUsableChannels   = 14;
 	static const int kMusicChannel     = 14;
+
+	static const int kAudioMixerAppTimersNum = 2;
 #endif // BLADERUNNER_ORIGINAL_BUGS
 	static const int kUpdatesPerSecond = 40;
 
@@ -68,17 +77,31 @@ class AudioMixer {
 	Channel       _channels[kChannels];
 	Common::Mutex _mutex;
 
+#if !BLADERUNNER_ORIGINAL_BUGS
+	struct audioMixerAppTimer {
+		bool                started;
+		uint32              intervalMillis; // expiration interval in milliseconds
+		uint32              lastFired;      // time of last time the timer expired in milliseconds
+	};
+
+	audioMixerAppTimer      _audioMixerAppTimers[kAudioMixerAppTimersNum];
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+
 public:
 	AudioMixer(BladeRunnerEngine *vm);
 	~AudioMixer();
 
 	int play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void(*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs);
 	int playMusic(Audio::RewindableAudioStream *stream, int volume, void(*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs);
-	void stop(int channel, uint32 delay);
+	void stop(int channel, uint32 time);
 
 	void adjustVolume(int channel, int newVolume, uint32 time);
 	void adjustPan(int channel, int newPan, uint32 time);
 
+#if !BLADERUNNER_ORIGINAL_BUGS
+	void startAppTimerProc(int audioMixAppTimerId, uint32 intervalMillis);
+	void stopAppTimerProc(int audioMixAppTimerId);
+#endif // !BLADERUNNER_ORIGINAL_BUGS
 	// TODO Are these completely unused?
 //	void resume(int channel, uint32 delay);
 //	void pause(int channel, uint32 delay);
diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index e7a62a20e2..307f3c0629 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -45,16 +45,22 @@ Music::Music(BladeRunnerEngine *vm) {
 }
 
 Music::~Music() {
-	stop(0);
+	stop(0u);
 	while (isPlaying()) {
 		// wait for the mixer to finish
 	}
 
+#if BLADERUNNER_ORIGINAL_BUGS
 	_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
 	_vm->getTimerManager()->removeTimerProc(timerCallbackNext);
+#else
+	// probably not really needed, but tidy up anyway
+	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicFadeOut);
+	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicNext);
+#endif
 }
 
-bool Music::play(const Common::String &trackName, int volume, int pan, int32 timeFadeIn, int32 timePlay, int loop, int32 timeFadeOut) {
+bool Music::play(const Common::String &trackName, int volume, int pan, int32 timeFadeInSeconds, int32 timePlaySeconds, int loop, int32 timeFadeOutSeconds) {
 	//Common::StackLock lock(_mutex);
 
 	if (_musicVolume <= 0) {
@@ -63,34 +69,48 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
 
 	int volumeAdjusted = volume * _musicVolume / 100;
 	int volumeStart = volumeAdjusted;
-	if (timeFadeIn > 0) {
+	if (timeFadeInSeconds > 0) {
 		volumeStart = 1;
 	}
 
+	// Queuing mechanism:
+	// if a music track is already playing, then:
+	//    if the requested track is a different track
+	//       queue it as "next", to play after the current one.
+	//       However, if a "next" track already exists,
+	//       then stop the _current track after 2 seconds (force stop current playing track)
+	//       Also the previous "next" track still gets replaced by the new requested one.
+	// 	     This can be best test at Animoid Row, Hawker's Circle moving from Izo's Pawn Shop to the Bar.
+	//    if the requested track is the same as the currently playing,
+	//       update the loop int value of the _current to the new one
+	//       and adjust its fadeIn and balance/pan
+	//    In these both cases above, the _current track is not (yet) changed.
 	if (isPlaying()) {
 		if (!_current.name.equalsIgnoreCase(trackName)) {
 			_next.name = trackName;
-			_next.volume = volume;
-			_next.pan = pan;
-			_next.timeFadeIn = timeFadeIn;
-			_next.timePlay = timePlay;
+			_next.volume = volume; // Don't store the adjustedVolume - This is a "target" value for the volume
+			_next.pan = pan;       // This is a "target" value for the pan (balance)
+			_next.timeFadeInSeconds = timeFadeInSeconds;
+			_next.timePlaySeconds = timePlaySeconds;
 			_next.loop = loop;
-			_next.timeFadeOut = timeFadeOut;
+			_next.timeFadeOutSeconds = timeFadeOutSeconds;
 			if (_isNextPresent) {
-				stop(2);
+				stop(2u);
 			}
 			_isNextPresent = true;
 		} else {
 			_current.loop = loop;
-			if (timeFadeIn < 0) {
-				timeFadeIn = 0;
+			if (timeFadeInSeconds < 0) {
+				timeFadeInSeconds = 0;
 			}
-			adjustVolume(volumeAdjusted, timeFadeIn);
-			adjustPan(volumeAdjusted, timeFadeIn);
+			adjustVolume(volumeAdjusted, timeFadeInSeconds);
+			adjustPan(volumeAdjusted, timeFadeInSeconds);
 		}
 		return true;
 	}
 
+	// If we reach here, there is no music track currently playing
+	// So we load it from the game's resources
 	_data = getData(trackName);
 	if (_data == nullptr) {
 		return false;
@@ -107,28 +127,40 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
 
 		return false;
 	}
-	if (timeFadeIn > 0) {
-		adjustVolume(volumeAdjusted, timeFadeIn);
+	if (timeFadeInSeconds > 0) {
+		adjustVolume(volumeAdjusted, timeFadeInSeconds);
 	}
 	_current.name = trackName;
-	if (timePlay > 0) {
+	if (timePlaySeconds > 0) {
+		// Removes any previous fadeout timer and installs a new one.
+		// Uses the timeFadeOutSeconds value (see Music::fadeOut())
+#if BLADERUNNER_ORIGINAL_BUGS
 		_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
-		_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, timePlay * 1000 * 1000, this, "BladeRunnerMusicFadeoutTimer");
-	} else if (timeFadeOut > 0) {
+		_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, timePlaySeconds * 1000 * 1000, this, "BladeRunnerMusicFadeoutTimer");
+#else
+		_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicFadeOut);
+		_vm->_audioMixer->startAppTimerProc(kAudioMixerAppTimerMusicFadeOut, timePlaySeconds * 1000u);
+#endif //BLADERUNNER_ORIGINAL_BUGS
+	} else if (timeFadeOutSeconds > 0) {
+#if BLADERUNNER_ORIGINAL_BUGS
 		_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
-		_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, (_stream->getLength() - timeFadeOut * 1000) * 1000, this, "BladeRunnerMusicFadeoutTimer");
+		_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, (_stream->getLength() - timeFadeOutSeconds * 1000) * 1000, this, "BladeRunnerMusicFadeoutTimer");
+#else
+		_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicFadeOut);
+		_vm->_audioMixer->startAppTimerProc(kAudioMixerAppTimerMusicFadeOut, (_stream->getLength() - timeFadeOutSeconds * 1000u));
+#endif //BLADERUNNER_ORIGINAL_BUGS
 	}
 	_isPlaying = true;
-	_current.volume = volume;
-	_current.pan = pan;
-	_current.timeFadeIn = timeFadeIn;
-	_current.timePlay = timePlay;
+	_current.volume = volume; // Don't store the adjustedVolume - This is a "target" value for the volume
+	_current.pan = pan;       // This is a "target" value for the pan (balance)
+	_current.timeFadeInSeconds = timeFadeInSeconds;
+	_current.timePlaySeconds = timePlaySeconds;
 	_current.loop = loop;
-	_current.timeFadeOut = timeFadeOut;
+	_current.timeFadeOutSeconds = timeFadeOutSeconds;
 	return true;
 }
 
-void Music::stop(uint32 delay) {
+void Music::stop(uint32 delaySeconds) {
 	Common::StackLock lock(_mutex);
 
 	if (_channel < 0) {
@@ -140,16 +172,17 @@ void Music::stop(uint32 delay) {
 	_isNextPresent = false;
 #endif
 
-	_current.loop = false;
-	_vm->_audioMixer->stop(_channel, 60u * delay);
+	_current.loop = 0;
+	_vm->_audioMixer->stop(_channel, 60u * delaySeconds);
 }
 
-void Music::adjust(int volume, int pan, uint32 delay) {
+void Music::adjust(int volume, int pan, uint32 delaySeconds) {
 	if (volume != -1) {
-		adjustVolume(_musicVolume * volume/ 100, delay);
+		adjustVolume(_musicVolume * volume/ 100, delaySeconds);
 	}
+	// -101 is used as a special value to skip adjusting pan
 	if (pan != -101) {
-		adjustPan(pan, delay);
+		adjustPan(pan, delaySeconds);
 	}
 }
 
@@ -160,9 +193,10 @@ bool Music::isPlaying() {
 void Music::setVolume(int volume) {
 	_musicVolume = volume;
 	if (volume <= 0) {
-		stop(2);
+		stop(2u);
 	} else if (isPlaying()) {
-		_vm->_audioMixer->adjustVolume(_channel, _musicVolume * _current.volume / 100, 120);
+		// delay is 2 seconds (multiplied by 60u as expected by AudioMixer::adjustVolume())
+		_vm->_audioMixer->adjustVolume(_channel, _musicVolume * _current.volume / 100, 120u);
 	}
 }
 
@@ -183,17 +217,17 @@ void Music::save(SaveFileWriteStream &f) {
 	f.writeStringSz(_current.name, 13);
 	f.writeInt(_current.volume);
 	f.writeInt(_current.pan);
-	f.writeInt(_current.timeFadeIn);
-	f.writeInt(_current.timePlay);
+	f.writeInt(_current.timeFadeInSeconds);
+	f.writeInt(_current.timePlaySeconds);
 	f.writeInt(_current.loop);
-	f.writeInt(_current.timeFadeOut);
+	f.writeInt(_current.timeFadeOutSeconds);
 	f.writeStringSz(_next.name, 13);
 	f.writeInt(_next.volume);
 	f.writeInt(_next.pan);
-	f.writeInt(_next.timeFadeIn);
-	f.writeInt(_next.timePlay);
+	f.writeInt(_next.timeFadeInSeconds);
+	f.writeInt(_next.timePlaySeconds);
 	f.writeInt(_next.loop);
-	f.writeInt(_next.timeFadeOut);
+	f.writeInt(_next.timeFadeOutSeconds);
 }
 
 void Music::load(SaveFileReadStream &f) {
@@ -203,50 +237,50 @@ void Music::load(SaveFileReadStream &f) {
 	_current.name = f.readStringSz(13);
 	_current.volume = f.readInt();
 	_current.pan = f.readInt();
-	_current.timeFadeIn = f.readInt();
-	_current.timePlay = f.readInt();
+	_current.timeFadeInSeconds = f.readInt();
+	_current.timePlaySeconds = f.readInt();
 	_current.loop = f.readInt();
-	_current.timeFadeOut = f.readInt();
+	_current.timeFadeOutSeconds = f.readInt();
 	_next.name = f.readStringSz(13);
 	_next.volume = f.readInt();
 	_next.pan = f.readInt();
-	_next.timeFadeIn = f.readInt();
-	_next.timePlay = f.readInt();
+	_next.timeFadeInSeconds = f.readInt();
+	_next.timePlaySeconds = f.readInt();
 	_next.loop = f.readInt();
-	_next.timeFadeOut = f.readInt();
+	_next.timeFadeOutSeconds = f.readInt();
 
-	stop(2);
+	stop(2u);
 	if (_isPlaying) {
 		if (_channel == -1) {
 			play(_current.name,
 				_current.volume,
 				_current.pan,
-				_current.timeFadeIn,
-				_current.timePlay,
+				_current.timeFadeInSeconds,
+				_current.timePlaySeconds,
 				_current.loop,
-				_current.timeFadeOut);
+				_current.timeFadeOutSeconds);
 		} else {
 			_isNextPresent = true;
 			_next.name = _current.name;
 			_next.volume = _current.volume;
 			_next.pan = _current.pan;
-			_next.timeFadeIn = _current.timeFadeIn;
-			_next.timePlay = _current.timePlay;
+			_next.timeFadeInSeconds = _current.timeFadeInSeconds;
+			_next.timePlaySeconds = _current.timePlaySeconds;
 			_next.loop = _current.loop;
-			_next.timeFadeOut = _current.timeFadeOut;
+			_next.timeFadeOutSeconds = _current.timeFadeOutSeconds;
 		}
 	}
 }
 
-void Music::adjustVolume(int volume, uint32 delay) {
+void Music::adjustVolume(int volume, uint32 delaySeconds) {
 	if (_channel >= 0) {
-		_vm->_audioMixer->adjustVolume(_channel, volume, delay);
+		_vm->_audioMixer->adjustVolume(_channel, volume, delaySeconds);
 	}
 }
 
-void Music::adjustPan(int pan, uint32 delay) {
+void Music::adjustPan(int pan, uint32 delaySeconds) {
 	if (_channel >= 0) {
-		_vm->_audioMixer->adjustPan(_channel, pan, delay);
+		_vm->_audioMixer->adjustPan(_channel, pan, delaySeconds);
 	}
 }
 
@@ -259,33 +293,70 @@ void Music::ended() {
 	delete[] _data;
 	_data = nullptr;
 
+	// The timer that checks for a next track is started here.
+	// When it expires, it should check for queued music (_isNextPresent) or looping music (_current.loop)
+#if BLADERUNNER_ORIGINAL_BUGS
 	_vm->getTimerManager()->installTimerProc(timerCallbackNext, 100 * 1000, this, "BladeRunnerMusicNextTimer");
+#else
+	_vm->_audioMixer->startAppTimerProc(kAudioMixerAppTimerMusicNext, 100u);
+#endif // BLADERUNNER_ORIGINAL_BUGS
 }
 
 void Music::fadeOut() {
+#if BLADERUNNER_ORIGINAL_BUGS
 	_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
+#else
+	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicFadeOut);
+#endif // BLADERUNNER_ORIGINAL_BUGS
 	if (_channel >= 0) {
-		if (_current.timeFadeOut < 0) {
-			_current.timeFadeOut = 0;
+		if (_current.timeFadeOutSeconds < 0) {
+			_current.timeFadeOutSeconds = 0;
 		}
-		_vm->_audioMixer->stop(_channel, 60u * _current.timeFadeOut);
+		_vm->_audioMixer->stop(_channel, 60u * _current.timeFadeOutSeconds);
 	}
 }
 
+#if BLADERUNNER_ORIGINAL_BUGS
+void Music::timerCallbackFadeOut(void *refCon) {
+	((Music *)refCon)->fadeOut();
+}
+
+void Music::timerCallbackNext(void *refCon) {
+	((Music *)refCon)->next();
+}
+
 void Music::next() {
 	_vm->getTimerManager()->removeTimerProc(timerCallbackNext);
-
 	if (_isNextPresent) {
 		if (_isPaused) {
+			// postpone loading the next track (re-arm the BladeRunnerMusicNextTimer timer)
 			_vm->getTimerManager()->installTimerProc(timerCallbackNext, 2000 * 1000, this, "BladeRunnerMusicNextTimer");
 		} else {
-			play(_next.name.c_str(), _next.volume, _next.pan, _next.timeFadeIn, _next.timePlay, _next.loop, _next.timeFadeOut);
+			play(_next.name.c_str(), _next.volume, _next.pan, _next.timeFadeInSeconds, _next.timePlaySeconds, _next.loop, _next.timeFadeOutSeconds);
 		}
-		_current.loop = false;
+		// This should not come after a possible call to play() which could swap the "_current" for the new (_next) track
+		// Setting the loop to 0 here, would then make the new track non-looping, even if it is supposed to be looping
+		_current.loop = 0;
 	} else if (_current.loop) {
-		play(_current.name.c_str(), _current.volume, _current.pan, _current.timeFadeIn, _current.timePlay, _current.loop, _current.timeFadeOut);
+		play(_current.name.c_str(), _current.volume, _current.pan, _current.timeFadeInSeconds, _current.timePlaySeconds, _current.loop, _current.timeFadeOutSeconds);
 	}
 }
+#else
+void Music::next() {
+	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicNext);
+	if (_isNextPresent) {
+		if (_isPaused) {
+			// postpone loading the next track (re-arm the BladeRunnerMusicNextTimer timer)
+			_vm->_audioMixer->startAppTimerProc(kAudioMixerAppTimerMusicNext, 2000u);
+		} else {
+			play(_next.name.c_str(), _next.volume, _next.pan, _next.timeFadeInSeconds, _next.timePlaySeconds, _next.loop, _next.timeFadeOutSeconds);
+		}
+		_current.loop = 0;
+	} else if (_current.loop) {
+		play(_current.name.c_str(), _current.volume, _current.pan, _current.timeFadeInSeconds, _current.timePlaySeconds, _current.loop, _current.timeFadeOutSeconds);
+	}
+}
+#endif // BLADERUNNER_ORIGINAL_BUGS
 
 void Music::mixerChannelEnded(int channel, void *data) {
 	if (data != nullptr) {
@@ -293,14 +364,6 @@ void Music::mixerChannelEnded(int channel, void *data) {
 	}
 }
 
-void Music::timerCallbackFadeOut(void *refCon) {
-	((Music *)refCon)->fadeOut();
-}
-
-void Music::timerCallbackNext(void *refCon) {
-	((Music *)refCon)->next();
-}
-
 byte *Music::getData(const Common::String &name) {
 	// NOTE: This is not part original game, loading data is done in the mixer and its using buffering to limit memory usage
 	Common::SeekableReadStream *stream = _vm->getResourceStream(name);
diff --git a/engines/bladerunner/music.h b/engines/bladerunner/music.h
index 306f55147e..a8dcbf29ae 100644
--- a/engines/bladerunner/music.h
+++ b/engines/bladerunner/music.h
@@ -36,12 +36,12 @@ class SaveFileWriteStream;
 class Music {
 	struct Track {
 		Common::String name;
-		int            volume;
-		int            pan;
-		int32          timeFadeIn;
-		int32          timePlay;
-		int            loop;
-		int32          timeFadeOut;
+		int            volume;             // A value between 0 and 100 - It is the set volume for the track regardless of fadeIn and fadeOut transitions
+		int            pan;                // A value between -100  and 100 (right?) (0 is center) - It is the set pan/balance for the track regardless of any ongoing adjustments
+		int32          timeFadeInSeconds;  // how long will it take for the track to reach target volume (in seconds)
+		int32          timePlaySeconds;    // how long the track will play before starting fading out (in seconds) - uses timeFadeOutSeconds for fadeout
+		int            loop;               // 0: do not loop, 1: loop track
+		int32          timeFadeOutSeconds; // how long the fade out will be for the track at its end (in seconds)
 	};
 
 	BladeRunnerEngine *_vm;
@@ -61,9 +61,9 @@ public:
 	Music(BladeRunnerEngine *vm);
 	~Music();
 
-	bool play(const Common::String &trackName, int volume, int pan, int32 timeFadeIn, int32 timePlay, int loop, int32 timeFadeOut);
-	void stop(uint32 delay);
-	void adjust(int volume, int pan, uint32 delay);
+	bool play(const Common::String &trackName, int volume, int pan, int32 timeFadeInSeconds, int32 timePlaySeconds, int loop, int32 timeFadeOutSeconds);
+	void stop(uint32 delaySeconds);
+	void adjust(int volume, int pan, uint32 delaySeconds);
 	bool isPlaying();
 
 	void setVolume(int volume);
@@ -73,17 +73,26 @@ public:
 	void save(SaveFileWriteStream &f);
 	void load(SaveFileReadStream &f);
 
+#if !BLADERUNNER_ORIGINAL_BUGS
+	// moved to public access
+	void fadeOut();
+	void next();
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+
+
 private:
-	void adjustVolume(int volume, uint32 delay);
-	void adjustPan(int pan, uint32 delay);
+	void adjustVolume(int volume, uint32 delaySeconds);
+	void adjustPan(int pan, uint32 delaySeconds);
 
 	void ended();
+#if BLADERUNNER_ORIGINAL_BUGS
 	void fadeOut();
 	void next();
-
-	static void mixerChannelEnded(int channel, void *data);
 	static void timerCallbackFadeOut(void *refCon);
 	static void timerCallbackNext(void *refCon);
+#endif // BLADERUNNER_ORIGINAL_BUGS
+
+	static void mixerChannelEnded(int channel, void *data);
 
 	byte *getData(const Common::String &name);
 };


Commit: 5ab6c92f99c410499b59dc33d05ee8afd17b283f
    https://github.com/scummvm/scummvm/commit/5ab6c92f99c410499b59dc33d05ee8afd17b283f
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Add a reset() method for Music

Similar to the original source code

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


diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index 307f3c0629..f2b0267b4a 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -34,14 +34,9 @@ namespace BladeRunner {
 
 Music::Music(BladeRunnerEngine *vm) {
 	_vm = vm;
-	_channel = -1;
 	_musicVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
-	_isPlaying = false;
-	_isPaused = false;
-	_current.loop = false;
-	_isNextPresent = false;
-	_data = nullptr;
-	_stream = nullptr;
+	reset();
+
 }
 
 Music::~Music() {
@@ -55,11 +50,24 @@ Music::~Music() {
 	_vm->getTimerManager()->removeTimerProc(timerCallbackNext);
 #else
 	// probably not really needed, but tidy up anyway
+	reset();
 	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicFadeOut);
 	_vm->_audioMixer->stopAppTimerProc(kAudioMixerAppTimerMusicNext);
 #endif
 }
 
+void Music::reset() {
+	_current.name = "";
+	_next.name = "";
+	_channel = -1;
+	_isPlaying = false;
+	_isPaused = false;
+	_current.loop = 0;
+	_isNextPresent = false;
+	_data = nullptr;
+	_stream = nullptr;
+}
+
 bool Music::play(const Common::String &trackName, int volume, int pan, int32 timeFadeInSeconds, int32 timePlaySeconds, int loop, int32 timeFadeOutSeconds) {
 	//Common::StackLock lock(_mutex);
 
diff --git a/engines/bladerunner/music.h b/engines/bladerunner/music.h
index a8dcbf29ae..621653bcf7 100644
--- a/engines/bladerunner/music.h
+++ b/engines/bladerunner/music.h
@@ -81,6 +81,7 @@ public:
 
 
 private:
+	void reset();
 	void adjustVolume(int volume, uint32 delaySeconds);
 	void adjustPan(int pan, uint32 delaySeconds);
 


Commit: d11765138cd08be195c7ad2783e665289278c53c
    https://github.com/scummvm/scummvm/commit/d11765138cd08be195c7ad2783e665289278c53c
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Fix bugs for adjustpan, adjustvolume.

This is based in the original code. The bugs were ScummVM Engine specific, probably due to mistyping.

Changed paths:
    engines/bladerunner/music.cpp


diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index f2b0267b4a..127fd66ac3 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -36,7 +36,6 @@ Music::Music(BladeRunnerEngine *vm) {
 	_vm = vm;
 	_musicVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
 	reset();
-
 }
 
 Music::~Music() {
@@ -112,7 +111,7 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
 				timeFadeInSeconds = 0;
 			}
 			adjustVolume(volumeAdjusted, timeFadeInSeconds);
-			adjustPan(volumeAdjusted, timeFadeInSeconds);
+			adjustPan(pan, timeFadeInSeconds);
 		}
 		return true;
 	}
@@ -281,14 +280,17 @@ void Music::load(SaveFileReadStream &f) {
 }
 
 void Music::adjustVolume(int volume, uint32 delaySeconds) {
+	// adjustVolume takes an "adjusted volume" value as an argument
+	// We don't store that as target _current.volume - play() stores the proper value
 	if (_channel >= 0) {
-		_vm->_audioMixer->adjustVolume(_channel, volume, delaySeconds);
+		_vm->_audioMixer->adjustVolume(_channel, volume, 60u * delaySeconds);
 	}
 }
 
 void Music::adjustPan(int pan, uint32 delaySeconds) {
+	_current.pan = pan;
 	if (_channel >= 0) {
-		_vm->_audioMixer->adjustPan(_channel, pan, delaySeconds);
+		_vm->_audioMixer->adjustPan(_channel, pan, 60u * delaySeconds);
 	}
 }
 


Commit: 7cb8dc53d6e687a052c68dbdedaece9621c64542
    https://github.com/scummvm/scummvm/commit/7cb8dc53d6e687a052c68dbdedaece9621c64542
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-06-12T14:58:07+03:00

Commit Message:
BLADERUNNER: Fix clearing loop value of queued track

This is an original bug. The loaded queued track becomes _current.

The new _current's loop value should not be forcedly cleared there.

Changed paths:
    engines/bladerunner/music.cpp


diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index 127fd66ac3..e248618055 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -358,10 +358,11 @@ void Music::next() {
 		if (_isPaused) {
 			// postpone loading the next track (re-arm the BladeRunnerMusicNextTimer timer)
 			_vm->_audioMixer->startAppTimerProc(kAudioMixerAppTimerMusicNext, 2000u);
+			_current.loop = 0;
 		} else {
+			_current.loop = 0;
 			play(_next.name.c_str(), _next.volume, _next.pan, _next.timeFadeInSeconds, _next.timePlaySeconds, _next.loop, _next.timeFadeOutSeconds);
 		}
-		_current.loop = 0;
 	} else if (_current.loop) {
 		play(_current.name.c_str(), _current.volume, _current.pan, _current.timeFadeInSeconds, _current.timePlaySeconds, _current.loop, _current.timeFadeOutSeconds);
 	}




More information about the Scummvm-git-logs mailing list