[Scummvm-git-logs] scummvm master -> 916221dc562c9062839918d58d1a9968eb8f2b5e

peterkohaut peterkohaut at users.noreply.github.com
Mon Feb 11 22:50:14 CET 2019


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

Summary:
b14fbaa72b BLADERUNNER: Cleanup of audio code
6854ea3ddd BLADERUNNER: Improved time management
916221dc56 BLADERUNNER: Added original logic for speech skipping


Commit: b14fbaa72b3218862a533dd7f7c0e97e1bed4df7
    https://github.com/scummvm/scummvm/commit/b14fbaa72b3218862a533dd7f7c0e97e1bed4df7
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2019-02-11T22:48:07+01:00

Commit Message:
BLADERUNNER: Cleanup of audio code

Separated audio cache.
Fixed bug in the audio cache where still used sound might get freed.
Fixes crashes when engine is unloading which were caused
by a race condition between the timer code and engine teardown code.

Changed paths:
  A engines/bladerunner/audio_cache.cpp
  A engines/bladerunner/audio_cache.h
    engines/bladerunner/aud_stream.cpp
    engines/bladerunner/aud_stream.h
    engines/bladerunner/audio_player.cpp
    engines/bladerunner/audio_player.h
    engines/bladerunner/audio_speech.cpp
    engines/bladerunner/bladerunner.cpp
    engines/bladerunner/bladerunner.h
    engines/bladerunner/module.mk
    engines/bladerunner/music.cpp
    engines/bladerunner/savefile.cpp
    engines/bladerunner/script/script.cpp


diff --git a/engines/bladerunner/aud_stream.cpp b/engines/bladerunner/aud_stream.cpp
index 9cdd35d..bb35702 100644
--- a/engines/bladerunner/aud_stream.cpp
+++ b/engines/bladerunner/aud_stream.cpp
@@ -22,7 +22,7 @@
 
 #include "bladerunner/aud_stream.h"
 
-#include "bladerunner/audio_player.h"
+#include "bladerunner/audio_cache.h"
 
 #include "common/util.h"
 
@@ -36,12 +36,12 @@ AudStream::AudStream(byte *data, int overrideFrequency) {
 	init(data);
 }
 
-AudStream::AudStream(AudioCache *cache, int32 hash) {
+AudStream::AudStream(AudioCache *cache, int32 hash, int overrideFrequency) {
 	assert(cache != nullptr);
 
 	_cache = cache;
 	_hash  = hash;
-	_overrideFrequency = -1;
+	_overrideFrequency = overrideFrequency;
 
 	_cache->incRef(_hash);
 
@@ -128,7 +128,7 @@ bool AudStream::rewind() {
 }
 
 int AudStream::getLength() const {
-	int bytesPerSecond = _frequency;
+	int bytesPerSecond = _overrideFrequency > 0 ? _overrideFrequency : _frequency;
 	if (_flags & 1) { // 16 bit
 		bytesPerSecond *= 2;
 	}
diff --git a/engines/bladerunner/aud_stream.h b/engines/bladerunner/aud_stream.h
index 0316e25..1d65022 100644
--- a/engines/bladerunner/aud_stream.h
+++ b/engines/bladerunner/aud_stream.h
@@ -53,7 +53,7 @@ class AudStream : public Audio::RewindableAudioStream {
 
 public:
 	AudStream(byte *data, int overrideFrequency = -1);
-	AudStream(AudioCache *cache, int32 hash);
+	AudStream(AudioCache *cache, int32 hash, int overrideFrequency = -1);
 	~AudStream();
 
 	int readBuffer(int16 *buffer, const int numSamples);
diff --git a/engines/bladerunner/audio_cache.cpp b/engines/bladerunner/audio_cache.cpp
new file mode 100644
index 0000000..734eeae
--- /dev/null
+++ b/engines/bladerunner/audio_cache.cpp
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "bladerunner/audio_cache.h"
+
+#include "bladerunner/bladerunner.h"
+
+namespace BladeRunner {
+
+AudioCache::AudioCache(BladeRunnerEngine *vm) :
+	_vm(vm),
+	_totalSize(0),
+	_maxSize(2457600),
+	_accessCounter(0) {}
+
+AudioCache::~AudioCache() {
+	for (uint i = 0; i != _cacheItems.size(); ++i) {
+		free(_cacheItems[i].data);
+	}
+}
+
+bool AudioCache::canAllocate(uint32 size) const {
+	Common::StackLock lock(_mutex);
+
+	return _maxSize - _totalSize >= size;
+}
+
+bool AudioCache::dropOldest() {
+	Common::StackLock lock(_mutex);
+
+	if (_cacheItems.size() == 0)
+		return false;
+
+	int oldest = -1;
+	for (uint i = 1; i != _cacheItems.size(); ++i) {
+		if (_cacheItems[i].refs == 0) {
+			if (oldest == -1 || _cacheItems[i].lastAccess < _cacheItems[oldest].lastAccess) {
+				oldest = i;
+			}
+		}
+	}
+
+	if (oldest == -1) {
+		return false;
+	}
+
+	memset(_cacheItems[oldest].data, 0x00, _cacheItems[oldest].size);
+	free(_cacheItems[oldest].data);
+	_totalSize -= _cacheItems[oldest].size;
+	_cacheItems.remove_at(oldest);
+	return true;
+}
+
+byte *AudioCache::findByHash(int32 hash) {
+	Common::StackLock lock(_mutex);
+
+	for (uint i = 0; i != _cacheItems.size(); ++i) {
+		if (_cacheItems[i].hash == hash) {
+			_cacheItems[i].lastAccess = _accessCounter++;
+			return _cacheItems[i].data;
+		}
+	}
+
+	return nullptr;
+}
+
+void  AudioCache::storeByHash(int32 hash, Common::SeekableReadStream *stream) {
+	Common::StackLock lock(_mutex);
+
+	uint32 size = stream->size();
+	byte *data = (byte *)malloc(size);
+	stream->read(data, size);
+
+	cacheItem item = {
+		hash,
+		0,
+		_accessCounter++,
+		data,
+		size
+	};
+
+	_cacheItems.push_back(item);
+	_totalSize += size;
+}
+
+void AudioCache::incRef(int32 hash) {
+	Common::StackLock lock(_mutex);
+
+	for (uint i = 0; i != _cacheItems.size(); ++i) {
+		if (_cacheItems[i].hash == hash) {
+			_cacheItems[i].refs++;
+			return;
+		}
+	}
+	assert(false && "AudioCache::incRef: hash not found");
+}
+
+void AudioCache::decRef(int32 hash) {
+	Common::StackLock lock(_mutex);
+
+	for (uint i = 0; i != _cacheItems.size(); ++i) {
+		if (_cacheItems[i].hash == hash) {
+			assert(_cacheItems[i].refs > 0);
+			_cacheItems[i].refs--;
+			return;
+		}
+	}
+	assert(false && "AudioCache::decRef: hash not found");
+}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/audio_cache.h b/engines/bladerunner/audio_cache.h
new file mode 100644
index 0000000..8357689
--- /dev/null
+++ b/engines/bladerunner/audio_cache.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLADERUNNER_AUDIO_CACHE_H
+#define BLADERUNNER_AUDIO_CACHE_H
+
+#include "common/array.h"
+#include "common/mutex.h"
+
+namespace BladeRunner {
+
+class BladeRunnerEngine;
+class AudioCache;
+
+/*
+ * This is a poor imitation of Bladerunner's resource cache
+ */
+class AudioCache {
+	struct cacheItem {
+		int32   hash;
+		int     refs;
+		uint    lastAccess;
+		byte   *data;
+		uint32  size;
+	};
+
+	BladeRunnerEngine *_vm;
+
+	Common::Mutex            _mutex;
+	Common::Array<cacheItem> _cacheItems;
+
+	uint32 _totalSize;
+	uint32 _maxSize;
+	uint32 _accessCounter;
+
+public:
+	AudioCache(BladeRunnerEngine *vm);
+	~AudioCache();
+
+	bool  canAllocate(uint32 size) const;
+	bool  dropOldest();
+	byte *findByHash(int32 hash);
+	void  storeByHash(int32 hash, Common::SeekableReadStream *stream);
+
+	void  incRef(int32 hash);
+	void  decRef(int32 hash);
+};
+
+} // End of namespace BladeRunner
+
+#endif
diff --git a/engines/bladerunner/audio_player.cpp b/engines/bladerunner/audio_player.cpp
index 4493a02..df92be2 100644
--- a/engines/bladerunner/audio_player.cpp
+++ b/engines/bladerunner/audio_player.cpp
@@ -24,6 +24,7 @@
 
 #include "bladerunner/archive.h"
 #include "bladerunner/aud_stream.h"
+#include "bladerunner/audio_cache.h"
 #include "bladerunner/audio_mixer.h"
 #include "bladerunner/bladerunner.h"
 
@@ -37,99 +38,10 @@ namespace Common {
 
 namespace BladeRunner {
 
-AudioCache::~AudioCache() {
-	for (uint i = 0; i != _cacheItems.size(); ++i) {
-		free(_cacheItems[i].data);
-	}
-}
-
-bool AudioCache::canAllocate(uint32 size) const {
-	Common::StackLock lock(_mutex);
-
-	return _maxSize - _totalSize >= size;
-}
-
-bool AudioCache::dropOldest() {
-	Common::StackLock lock(_mutex);
-
-	if (_cacheItems.size() == 0)
-		return false;
-
-	uint oldest = 0;
-	for (uint i = 1; i != _cacheItems.size(); ++i) {
-		if (_cacheItems[i].refs == 0 && _cacheItems[i].lastAccess < _cacheItems[oldest].lastAccess)
-			oldest = i;
-	}
-
-	free(_cacheItems[oldest].data);
-	_totalSize -= _cacheItems[oldest].size;
-	_cacheItems.remove_at(oldest);
-	return true;
-}
-
-byte *AudioCache::findByHash(int32 hash) {
-	Common::StackLock lock(_mutex);
-
-	for (uint i = 0; i != _cacheItems.size(); ++i) {
-		if (_cacheItems[i].hash == hash) {
-			_cacheItems[i].lastAccess = _accessCounter++;
-			return _cacheItems[i].data;
-		}
-	}
-
-	return nullptr;
-}
-
-void AudioCache::storeByHash(int32 hash, Common::SeekableReadStream *stream) {
-	Common::StackLock lock(_mutex);
-
-	uint32 size = stream->size();
-	byte *data = (byte *)malloc(size);
-	stream->read(data, size);
-
-	cacheItem item = {
-		hash,
-		0,
-		_accessCounter++,
-		data,
-		size
-	};
-
-	_cacheItems.push_back(item);
-	_totalSize += size;
-}
-
-void AudioCache::incRef(int32 hash) {
-	Common::StackLock lock(_mutex);
-
-	for (uint i = 0; i != _cacheItems.size(); ++i) {
-		if (_cacheItems[i].hash == hash) {
-			_cacheItems[i].refs++;
-			return;
-		}
-	}
-	assert(false && "AudioCache::incRef: hash not found");
-}
-
-void AudioCache::decRef(int32 hash) {
-	Common::StackLock lock(_mutex);
-
-	for (uint i = 0; i != _cacheItems.size(); ++i) {
-		if (_cacheItems[i].hash == hash) {
-			assert(_cacheItems[i].refs > 0);
-			_cacheItems[i].refs--;
-			return;
-		}
-	}
-	assert(false && "AudioCache::decRef: hash not found");
-}
-
 AudioPlayer::AudioPlayer(BladeRunnerEngine *vm) {
 	_vm = vm;
-	_cache = new AudioCache();
 
 	for (int i = 0; i != 6; ++i) {
-		_tracks[i].hash = 0;
 		_tracks[i].priority = 0;
 		_tracks[i].isActive = false;
 		_tracks[i].channel = -1;
@@ -141,12 +53,11 @@ AudioPlayer::AudioPlayer(BladeRunnerEngine *vm) {
 
 AudioPlayer::~AudioPlayer() {
 	stopAll();
-	delete _cache;
 }
 
 void AudioPlayer::stopAll() {
 	for (int i = 0; i != kTracks; ++i) {
-		stop(i, false);
+		stop(i, true);
 	}
 	for (int i = 0; i != kTracks; ++i) {
 		while (isActive(i)) {
@@ -254,24 +165,24 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panFrom, in
 
 	/* Load audio resource and store in cache. Playback will happen directly from there. */
 	int32 hash = MIXArchive::getHash(name);
-	if (!_cache->findByHash(hash)) {
+	if (!_vm->_audioCache->findByHash(hash)) {
 		Common::SeekableReadStream *r = _vm->getResourceStream(name);
 		if (!r) {
 			return -1;
 		}
 
 		int32 size = r->size();
-		while (!_cache->canAllocate(size)) {
-			if (!_cache->dropOldest()) {
+		while (!_vm->_audioCache->canAllocate(size)) {
+			if (!_vm->_audioCache->dropOldest()) {
 				delete r;
 				return -1;
 			}
 		}
-		_cache->storeByHash(hash, r);
+		_vm->_audioCache->storeByHash(hash, r);
 		delete r;
 	}
 
-	AudStream *audioStream = new AudStream(_cache, hash);
+	AudStream *audioStream = new AudStream(_vm->_audioCache, hash);
 
 	int actualVolume = volume;
 	if (!(flags & kAudioPlayerOverrideVolume)) {
@@ -290,7 +201,6 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panFrom, in
 
 	if (channel == -1) {
 		delete audioStream;
-		_cache->decRef(hash);
 		return -1;
 	}
 
@@ -301,7 +211,6 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panFrom, in
 	_tracks[track].isActive = true;
 	_tracks[track].channel  = channel;
 	_tracks[track].priority = priority;
-	_tracks[track].hash     = hash;
 	_tracks[track].volume   = actualVolume;
 	_tracks[track].stream   = audioStream;
 
diff --git a/engines/bladerunner/audio_player.h b/engines/bladerunner/audio_player.h
index 34059e3..580bdbc 100644
--- a/engines/bladerunner/audio_player.h
+++ b/engines/bladerunner/audio_player.h
@@ -35,43 +35,6 @@ namespace BladeRunner {
 class BladeRunnerEngine;
 class AudioCache;
 
-/*
- * This is a poor imitation of Bladerunner's resource cache
- */
-class AudioCache {
-	struct cacheItem {
-		int32   hash;
-		int     refs;
-		uint    lastAccess;
-		byte   *data;
-		uint32  size;
-	};
-
-	Common::Mutex            _mutex;
-	Common::Array<cacheItem> _cacheItems;
-
-	uint32 _totalSize;
-	uint32 _maxSize;
-	uint32 _accessCounter;
-
-public:
-	AudioCache() :
-		_totalSize(0),
-		_maxSize(2457600),
-		_accessCounter(0) {
-	}
-	~AudioCache();
-
-	bool  canAllocate(uint32 size) const;
-	bool  dropOldest();
-	byte *findByHash(int32 hash);
-	void  storeByHash(int32 hash, Common::SeekableReadStream *stream);
-
-	void  incRef(int32 hash);
-	void  decRef(int32 hash);
-};
-
-
 enum AudioPlayerFlags {
 	kAudioPlayerLoop = 1,
 	kAudioPlayerOverrideVolume = 2
@@ -84,7 +47,6 @@ class AudioPlayer {
 		bool                isActive;
 		int                 channel;
 		int                 priority;
-		int32               hash;
 		int                 volume;
 		int                 pan;
 		Audio::AudioStream *stream;
@@ -93,7 +55,6 @@ class AudioPlayer {
 	BladeRunnerEngine *_vm;
 
 	Common::Mutex _mutex;
-	AudioCache   *_cache;
 	Track         _tracks[kTracks];
 	int           _sfxVolume;
 
diff --git a/engines/bladerunner/audio_speech.cpp b/engines/bladerunner/audio_speech.cpp
index 6963b70..aa8b0f4 100644
--- a/engines/bladerunner/audio_speech.cpp
+++ b/engines/bladerunner/audio_speech.cpp
@@ -28,7 +28,6 @@
 #include "bladerunner/audio_player.h"
 #include "bladerunner/bladerunner.h"
 
-#include "common/debug.h"
 #include "common/str.h"
 
 namespace BladeRunner {
@@ -55,10 +54,22 @@ AudioSpeech::AudioSpeech(BladeRunnerEngine *vm) {
 }
 
 AudioSpeech::~AudioSpeech() {
+	stopSpeech();
+	while (isPlaying()) {
+		// wait for the mixer to finish
+	}
+
 	delete[] _data;
 }
 
 bool AudioSpeech::playSpeech(const Common::String &name, int pan) {
+	if (isPlaying()) {
+		stopSpeech();
+	}
+
+	// Audio cache is not usable as hash function is producing collision for speech lines.
+	// It was not used in the original game either
+
 	Common::ScopedPtr<Common::SeekableReadStream> r(_vm->getResourceStream(name));
 
 	if (!r) {
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index a12e375..5c49281 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -25,6 +25,7 @@
 #include "bladerunner/actor.h"
 #include "bladerunner/actor_dialogue_queue.h"
 #include "bladerunner/ambient_sounds.h"
+#include "bladerunner/audio_cache.h"
 #include "bladerunner/audio_mixer.h"
 #include "bladerunner/audio_player.h"
 #include "bladerunner/audio_speech.h"
@@ -156,7 +157,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
 	_lights                  = nullptr;
 	_obstacles               = nullptr;
 	_sceneScript             = nullptr;
-	_time                = nullptr;
+	_time                    = nullptr;
 	_gameInfo                = nullptr;
 	_waypoints               = nullptr;
 	_gameVars                = nullptr;
@@ -164,6 +165,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
 	_sceneObjects            = nullptr;
 	_gameFlags               = nullptr;
 	_items                   = nullptr;
+	_audioCache              = nullptr;
 	_audioMixer              = nullptr;
 	_audioPlayer             = nullptr;
 	_music                   = nullptr;
@@ -379,7 +381,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 		return false;
 	}
 
-	// TODO: Allocate audio cache
+	_audioCache = new AudioCache(this);
 
 	if (hasSavegames) {
 		if (!loadSplash()) {
@@ -664,6 +666,9 @@ void BladeRunnerEngine::shutdown() {
 	delete _audioMixer;
 	_audioMixer = nullptr;
 
+	delete _audioCache;
+	_audioCache = nullptr;
+
 	if (isArchiveOpen("MUSIC.MIX")) {
 		closeArchive("MUSIC.MIX");
 	}
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index f52f808..e1469db 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -60,6 +60,7 @@ class ActorDialogueQueue;
 class ScreenEffects;
 class AIScripts;
 class AmbientSounds;
+class AudioCache;
 class AudioMixer;
 class AudioPlayer;
 class AudioSpeech;
@@ -118,6 +119,7 @@ public:
 	ScreenEffects      *_screenEffects;
 	AIScripts          *_aiScripts;
 	AmbientSounds      *_ambientSounds;
+	AudioCache         *_audioCache;
 	AudioMixer         *_audioMixer;
 	AudioPlayer        *_audioPlayer;
 	AudioSpeech        *_audioSpeech;
@@ -277,7 +279,6 @@ public:
 	bool isSubtitlesEnabled();
 	void setSubtitlesEnabled(bool newVal);
 
-
 	Common::SeekableReadStream *getResourceStream(const Common::String &name);
 
 	bool playerHasControl();
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index 7f800e5..e52f8e5 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS = \
 	ambient_sounds.o \
 	archive.o \
 	aud_stream.o \
+	audio_cache.o \
 	audio_mixer.o \
 	audio_player.o \
 	audio_speech.o \
diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index 61326b6..42c0b62 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -45,7 +45,7 @@ Music::Music(BladeRunnerEngine *vm) {
 }
 
 Music::~Music() {
-	stop(1);
+	stop(0);
 	while (isPlaying()) {
 		// wait for the mixer to finish
 	}
diff --git a/engines/bladerunner/savefile.cpp b/engines/bladerunner/savefile.cpp
index 33a91b8..929bd8b 100644
--- a/engines/bladerunner/savefile.cpp
+++ b/engines/bladerunner/savefile.cpp
@@ -31,9 +31,6 @@
 
 #include "graphics/thumbnail.h"
 
-
-
-#include "common/debug.h"
 namespace BladeRunner {
 
 SaveStateList SaveFileManager::list(const Common::String &target) {
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 4c205d5..14f34c4 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -335,9 +335,11 @@ void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause,
 			Sound_Play(Random_Query(319, 327), 40, 0, 0, 50);
 		}
 	}
-	if(pause > 0.0f && !_vm->_speechSkipped) {
+
+	if (pause > 0.0f && !_vm->_speechSkipped) {
 		Delay(pause * 1000);
 	}
+
 	Player_Gains_Control();
 }
 


Commit: 6854ea3ddd83798a9045307763bbb346d8a1736b
    https://github.com/scummvm/scummvm/commit/6854ea3ddd83798a9045307763bbb346d8a1736b
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2019-02-11T22:48:55+01:00

Commit Message:
BLADERUNNER: Improved time management

This should fix thi issue with freezing actors after loading save game,
but works on new saves only. Game was not paused before saving
and wrong timer value got saved.

Changed paths:
    engines/bladerunner/bladerunner.cpp
    engines/bladerunner/bladerunner.h
    engines/bladerunner/debugger.cpp
    engines/bladerunner/item_pickup.cpp
    engines/bladerunner/slice_animations.cpp
    engines/bladerunner/time.cpp
    engines/bladerunner/time.h
    engines/bladerunner/ui/end_credits.cpp
    engines/bladerunner/ui/kia.cpp
    engines/bladerunner/ui/kia_section_diagnostic.cpp
    engines/bladerunner/ui/kia_section_load.cpp
    engines/bladerunner/ui/kia_section_pogo.cpp
    engines/bladerunner/ui/kia_section_save.cpp
    engines/bladerunner/ui/ui_check_box.cpp
    engines/bladerunner/ui/ui_input_box.cpp
    engines/bladerunner/ui/ui_scroll_box.cpp
    engines/bladerunner/vqa_player.cpp


diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 5c49281..5aef48c 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -274,7 +274,9 @@ Common::Error BladeRunnerEngine::saveGameState(int slot, const Common::String &d
 
 	BladeRunner::SaveFileManager::writeHeader(*saveFile, header);
 
+	_time->pause();
 	saveGame(*saveFile, thumbnail);
+	_time->resume();
 
 	saveFile->finalize();
 
@@ -285,6 +287,10 @@ Common::Error BladeRunnerEngine::saveGameState(int slot, const Common::String &d
 	return Common::kNoError;
 }
 
+void BladeRunnerEngine::pauseEngineIntern(bool pause) {
+	_mixer->pauseAll(pause);
+}
+
 Common::Error BladeRunnerEngine::run() {
 	Graphics::PixelFormat format = createRGB555();
 	initGraphics(640, 480, &format);
@@ -1113,7 +1119,7 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
 			_kia->open(kKIASectionSettings);
 			break;
 		case Common::KEYCODE_SPACE:
-			// TODO: combat::switchCombatMode(&Combat);
+			_combat->change();
 			break;
 		default:
 			break;
@@ -1122,16 +1128,8 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
 
 void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
 	if ((event.kbd.keycode == Common::KEYCODE_d) && (event.kbd.flags & Common::KBD_CTRL)) {
-		_time->pause();
 		getDebugger()->attach();
 		getDebugger()->onFrame();
-
-		_time->resume();
-
-		if (!_kia->isOpen() && !_spinner->isOpen() && !_elevator->isOpen() && !_esper->isOpen() && !_dialogueMenu->isOpen() && !_scores->isOpen()) {
-			_scene->resume();
-		}
-
 		return;
 	}
 
@@ -1968,32 +1966,12 @@ void BladeRunnerEngine::autoSaveGame(int textId, bool endgame) {
 	if (slot == -1) {
 		slot = maxSlot + 1;
 	}
-
-	Common::OutSaveFile *saveFile = BladeRunner::SaveFileManager::openForSaving(getTargetName(), slot);
-	if (saveFile == nullptr || saveFile->err()) {
-		delete saveFile;
-	}
-
-	BladeRunner::SaveFileHeader header;
 	if (endgame) {
-		header._name = "END_GAME_STATE";
+		saveGameState(slot, "END_GAME_STATE");
 	} else {
-		header._name = textAutoSave.getText(textId);
+		saveGameState(slot,  textAutoSave.getText(textId));
 	}
 
-	BladeRunner::SaveFileManager::writeHeader(*saveFile, header);
-
-	Graphics::Surface thumbnail = generateThumbnail();
-
-	_time->pause();
-	saveGame(*saveFile, thumbnail);
-	_time->resume();
-
-	saveFile->finalize();
-
-	thumbnail.free();
-
-	delete saveFile;
 }
 
 void BladeRunnerEngine::ISez(const Common::String &str) {
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index e1469db..74387b1 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -236,8 +236,9 @@ public:
 	Common::Error loadGameState(int slot) override;
 	bool canSaveGameStateCurrently() override;
 	Common::Error saveGameState(int slot, const Common::String &desc) override;
+	void pauseEngineIntern(bool pause) override;
 
-	Common::Error run();
+	Common::Error run() override;
 
 	bool startup(bool hasSavegames = false);
 	void initChapterAndScene();
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 49abdfc..fae61d0 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -42,6 +42,7 @@
 #include "bladerunner/set.h"
 #include "bladerunner/set_effects.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 #include "bladerunner/vector.h"
 #include "bladerunner/view.h"
 #include "bladerunner/vqa_decoder.h"
@@ -706,7 +707,9 @@ bool Debugger::cmdSave(int argc, const char **argv) {
 
 	Graphics::Surface thumbnail = _vm->generateThumbnail();
 
+	_vm->_time->pause();
 	_vm->saveGame(*saveFile, thumbnail);
+	_vm->_time->resume();
 
 	saveFile->finalize();
 
@@ -714,7 +717,7 @@ bool Debugger::cmdSave(int argc, const char **argv) {
 
 	delete saveFile;
 
-	return true;
+	return false;
 }
 
 void Debugger::drawDebuggerOverlay() {
diff --git a/engines/bladerunner/item_pickup.cpp b/engines/bladerunner/item_pickup.cpp
index 1bed3bb..4991828 100644
--- a/engines/bladerunner/item_pickup.cpp
+++ b/engines/bladerunner/item_pickup.cpp
@@ -27,6 +27,7 @@
 #include "bladerunner/game_info.h"
 #include "bladerunner/slice_animations.h"
 #include "bladerunner/slice_renderer.h"
+#include "bladerunner/time.h"
 #include "bladerunner/zbuffer.h"
 
 namespace BladeRunner {
@@ -56,7 +57,7 @@ void ItemPickup::setup(int animationId, int screenX, int screenY) {
 	int pan = (150 * _screenX - 48000) / 640;
 	_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(335), 80, pan, pan, 50, 0);
 
-	_timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	_timeLast = _vm->_time->currentSystem();
 }
 
 void ItemPickup::reset() {
@@ -75,7 +76,7 @@ void ItemPickup::tick() {
 		return;
 	}
 
-	int timeNow = _vm->getTotalPlayTime(); // Original game is using system timer
+	int timeNow = _vm->_time->currentSystem();
 	int timeDiff = timeNow - _timeLast;
 	_timeLast = timeNow;
 	timeDiff = MIN(MIN(timeDiff, 67), _timeLeft);
diff --git a/engines/bladerunner/slice_animations.cpp b/engines/bladerunner/slice_animations.cpp
index 274d39f..b180e84 100644
--- a/engines/bladerunner/slice_animations.cpp
+++ b/engines/bladerunner/slice_animations.cpp
@@ -23,6 +23,7 @@
 #include "bladerunner/slice_animations.h"
 
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/time.h"
 
 #include "common/debug.h"
 #include "common/file.h"
@@ -182,7 +183,7 @@ void *SliceAnimations::getFramePtr(uint32 animation, uint32 frame) {
 	if (!_pages[page]._data)
 		error("Unable to locate page %d for animation %d frame %d", page, animation, frame);
 
-	_pages[page]._lastAccess = _vm->_system->getMillis();
+	_pages[page]._lastAccess = _vm->_time->currentSystem();
 
 	return (byte *)_pages[page]._data + pageOffset;
 }
diff --git a/engines/bladerunner/time.cpp b/engines/bladerunner/time.cpp
index 2e41282..5d82a0c 100644
--- a/engines/bladerunner/time.cpp
+++ b/engines/bladerunner/time.cpp
@@ -25,20 +25,25 @@
 #include "bladerunner/bladerunner.h"
 
 #include "common/timer.h"
+#include "common/system.h"
 
 namespace BladeRunner {
 
 Time::Time(BladeRunnerEngine *vm) {
 	_vm = vm;
 
-	_start = _vm->getTotalPlayTime();
+	_start = currentSystem();
 	_pauseCount = 0;
 	_offset = 0;
 	_pauseStart = 0;
 }
 
+int Time::currentSystem() {
+	return _vm->getTotalPlayTime();
+}
+
 int Time::current() {
-	int time = _vm->getTotalPlayTime() - _offset;
+	int time = currentSystem() - _offset;
 	return time - _start;
 }
 
diff --git a/engines/bladerunner/time.h b/engines/bladerunner/time.h
index 11f96ed..4e372ea 100644
--- a/engines/bladerunner/time.h
+++ b/engines/bladerunner/time.h
@@ -38,6 +38,7 @@ class Time {
 public:
 	Time(BladeRunnerEngine *vm);
 
+	int  currentSystem();
 	int  current();
 	int  pause();
 	int  getPauseStart();
diff --git a/engines/bladerunner/ui/end_credits.cpp b/engines/bladerunner/ui/end_credits.cpp
index 0fc97d0..1e9a3ac 100644
--- a/engines/bladerunner/ui/end_credits.cpp
+++ b/engines/bladerunner/ui/end_credits.cpp
@@ -33,6 +33,7 @@
 #include "bladerunner/mouse.h"
 #include "bladerunner/music.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/end_credits.h"
 
 namespace BladeRunner {
@@ -95,7 +96,7 @@ void EndCredits::show() {
 	_vm->_vqaStopIsRequested = false;
 
 	double position = 0.0;
-	uint32 timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	uint32 timeLast = _vm->_time->currentSystem();
 
 	while (!_vm->_vqaStopIsRequested && !_vm->shouldQuit()) {
 		if (position >= textPositions[textCount - 1]) {
@@ -106,12 +107,12 @@ void EndCredits::show() {
 		_vm->handleEvents();
 
 		if (!_vm->_windowIsActive) {
-			timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+			timeLast = _vm->_time->currentSystem();
 
 			continue;
 		}
 
-		uint32 timeNow = _vm->getTotalPlayTime(); // Original game is using system timer
+		uint32 timeNow = _vm->_time->currentSystem();
 		position += (double)(timeNow - timeLast) * 0.05f;
 		timeLast = timeNow;
 
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index d54133a..42aaf3c 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -73,14 +73,14 @@ KIA::KIA(BladeRunnerEngine *vm) {
 	_currentSectionId = kKIASectionNone;
 	_lastSectionIdKIA = kKIASectionCrimes;
 	_lastSectionIdOptions = kKIASectionSettings;
-	_playerVqaTimeLast = _vm->getTotalPlayTime();
+	_playerVqaTimeLast = _vm->_time->currentSystem();
 	_playerVqaFrame = 0;
 	_playerVisualizerState = 0;
 	_playerPhotographId = -1;
 	_playerPhotograph = nullptr;
 	_playerSliceModelId = -1;
 	_playerSliceModelAngle = 0.0f;
-	_timeLast = _vm->getTotalPlayTime();
+	_timeLast = _vm->_time->currentSystem();
 	_playerActorDialogueQueuePosition = 0;
 	_playerActorDialogueQueueSize = 0;
 	_playerActorDialogueState = 0;
@@ -223,7 +223,7 @@ void KIA::tick() {
 		return;
 	}
 
-	int timeNow = _vm->getTotalPlayTime();
+	int timeNow = _vm->_time->currentSystem();
 	int timeDiff = timeNow - _timeLast;
 
 	if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition) {
@@ -650,8 +650,8 @@ void KIA::init() {
 
 	playerReset();
 	_playerVqaFrame = 0;
-	_playerVqaTimeLast = _vm->getTotalPlayTime();
-	_timeLast = _vm->getTotalPlayTime();
+	_playerVqaTimeLast = _vm->_time->currentSystem();
+	_timeLast = _vm->_time->currentSystem();
 
 	if (_vm->_gameFlags->query(kFlagKIAPrivacyAddon) && !_vm->_gameFlags->query(kFlagKIAPrivacyAddonIntro)) {
 		_vm->_gameFlags->set(kFlagKIAPrivacyAddonIntro);
diff --git a/engines/bladerunner/ui/kia_section_diagnostic.cpp b/engines/bladerunner/ui/kia_section_diagnostic.cpp
index 55672cd..333cf63 100644
--- a/engines/bladerunner/ui/kia_section_diagnostic.cpp
+++ b/engines/bladerunner/ui/kia_section_diagnostic.cpp
@@ -26,6 +26,7 @@
 #include "bladerunner/font.h"
 #include "bladerunner/game_constants.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/kia.h"
 
 namespace BladeRunner {
@@ -45,7 +46,7 @@ void KIASectionDiagnostic::open() {
 	}
 	_vm->_kia->playActorDialogue(kActorRunciter, 140);
 	_offset = 0;
-	_timeLast = _vm->getTotalPlayTime();
+	_timeLast = _vm->_time->currentSystem();
 }
 
 void KIASectionDiagnostic::close() {
@@ -53,7 +54,7 @@ void KIASectionDiagnostic::close() {
 }
 
 void KIASectionDiagnostic::draw(Graphics::Surface &surface) {
-	int timeNow = _vm->getTotalPlayTime();
+	int timeNow = _vm->_time->currentSystem();
 
 	for (int i = 0; i < _text->getCount(); ++i) {
 		int y = kLineHeight * i + 366 - _offset;
diff --git a/engines/bladerunner/ui/kia_section_load.cpp b/engines/bladerunner/ui/kia_section_load.cpp
index 9b37f5e..a512188 100644
--- a/engines/bladerunner/ui/kia_section_load.cpp
+++ b/engines/bladerunner/ui/kia_section_load.cpp
@@ -27,6 +27,7 @@
 #include "bladerunner/game_info.h"
 #include "bladerunner/savefile.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
@@ -74,7 +75,7 @@ void KIASectionLoad::open() {
 	_scrollBox->addLine(_vm->_textOptions->getText(29), _newGameHardLineId, 0); // Hard
 
 	_hoveredLineId = -1;
-	_timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	_timeLast = _vm->_time->currentSystem();
 	_timeLeft = 800;
 }
 
@@ -108,7 +109,7 @@ void KIASectionLoad::draw(Graphics::Surface &surface){
 		_hoveredLineId = selectedLineId;
 	}
 
-	uint32 now = _vm->getTotalPlayTime(); // Original game is using system timer
+	uint32 now = _vm->_time->currentSystem();
 	if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) {
 		if (_timeLeft) {
 			uint32 timeDiff = now - _timeLast;
diff --git a/engines/bladerunner/ui/kia_section_pogo.cpp b/engines/bladerunner/ui/kia_section_pogo.cpp
index a0c5ac6..037cea9 100644
--- a/engines/bladerunner/ui/kia_section_pogo.cpp
+++ b/engines/bladerunner/ui/kia_section_pogo.cpp
@@ -27,6 +27,7 @@
 #include "bladerunner/font.h"
 #include "bladerunner/game_info.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 
 namespace BladeRunner {
 
@@ -225,14 +226,14 @@ void KIASectionPogo::open() {
 		_lineOffsets[i] = 0;
 	}
 
-	_timeLast = _vm->getTotalPlayTime();
+	_timeLast = _vm->_time->currentSystem();
 
 	_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(319), 100, 0, 0, 50, 0);
 }
 
 void KIASectionPogo::draw(Graphics::Surface &surface) {
 	// Timing fixed for 60Hz by ScummVM team
-	int timeNow = _vm->getTotalPlayTime();
+	int timeNow = _vm->_time->currentSystem();
 	bool updateTimeout = false;
 	if (timeNow - _timeLast > 1000 / 60) {
 		updateTimeout = true;
diff --git a/engines/bladerunner/ui/kia_section_save.cpp b/engines/bladerunner/ui/kia_section_save.cpp
index 6bdcec9..07873e3 100644
--- a/engines/bladerunner/ui/kia_section_save.cpp
+++ b/engines/bladerunner/ui/kia_section_save.cpp
@@ -28,6 +28,7 @@
 #include "bladerunner/game_info.h"
 #include "bladerunner/savefile.h"
 #include "bladerunner/text_resource.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_shapes.h"
 #include "bladerunner/ui/ui_container.h"
@@ -121,7 +122,7 @@ void KIASectionSave::open() {
 	}
 
 	_hoveredLineId = -1;
-	_timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	_timeLast = _vm->_time->currentSystem();
 	_timeLeft = 800;
 }
 
@@ -191,7 +192,7 @@ void KIASectionSave::draw(Graphics::Surface &surface){
 		_hoveredLineId = selectedLineId;
 	}
 
-	uint32 now = _vm->getTotalPlayTime(); // Original game is using system timer
+	uint32 now = _vm->_time->currentSystem();
 	if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) {
 		if (_timeLeft) {
 			uint32 timeDiff = now - _timeLast;
diff --git a/engines/bladerunner/ui/ui_check_box.cpp b/engines/bladerunner/ui/ui_check_box.cpp
index 631b9ba..510d6e6 100644
--- a/engines/bladerunner/ui/ui_check_box.cpp
+++ b/engines/bladerunner/ui/ui_check_box.cpp
@@ -25,6 +25,7 @@
 #include "bladerunner/audio_player.h"
 #include "bladerunner/bladerunner.h"
 #include "bladerunner/game_info.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_shapes.h"
 
@@ -47,7 +48,7 @@ UICheckBox::UICheckBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedC
 		_frame = 0;
 	}
 
-	_timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	_timeLast = _vm->_time->currentSystem();
 	_rect = rect;
 	_isChecked = isChecked;
 }
@@ -56,7 +57,7 @@ UICheckBox::UICheckBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedC
 void UICheckBox::draw(Graphics::Surface &surface) {
 	int shapeId;
 	if (_rect.right > _rect.left && _rect.bottom > _rect.top) {
-		uint timeNow = _vm->getTotalPlayTime(); // Original game is using system timer
+		uint timeNow = _vm->_time->currentSystem();
 		if (timeNow - _timeLast > 67) {
 			int frameDelta = (timeNow - _timeLast) / 67u;
 			_timeLast = timeNow;
diff --git a/engines/bladerunner/ui/ui_input_box.cpp b/engines/bladerunner/ui/ui_input_box.cpp
index 6b9388c..6ad2db2 100644
--- a/engines/bladerunner/ui/ui_input_box.cpp
+++ b/engines/bladerunner/ui/ui_input_box.cpp
@@ -24,6 +24,7 @@
 
 #include "bladerunner/bladerunner.h"
 #include "bladerunner/font.h"
+#include "bladerunner/time.h"
 
 #include "common/keyboard.h"
 
@@ -43,7 +44,7 @@ UIInputBox::UIInputBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedC
 	setText(text);
 
 	_cursorIsVisible = false;
-	_timeLast = _vm->getTotalPlayTime(); // Original game is using system timer
+	_timeLast = _vm->_time->currentSystem();
 }
 
 void UIInputBox::draw(Graphics::Surface &surface) {
@@ -60,8 +61,8 @@ void UIInputBox::draw(Graphics::Surface &surface) {
 		surface.vLine(textHalfWidth + rectHalfWidth + 2, _rect.top, _rect.bottom - 1, 0x7FDD); // 11111 11110 11101
 	}
 
-	if (_vm->getTotalPlayTime() - _timeLast > 500) { // Original game is using system timer
-		_timeLast = _vm->getTotalPlayTime();
+	if (_vm->_time->currentSystem() - _timeLast > 500) {
+		_timeLast = _vm->_time->currentSystem();
 		_cursorIsVisible = !_cursorIsVisible;
 	}
 }
diff --git a/engines/bladerunner/ui/ui_scroll_box.cpp b/engines/bladerunner/ui/ui_scroll_box.cpp
index d39e580..39e4174 100644
--- a/engines/bladerunner/ui/ui_scroll_box.cpp
+++ b/engines/bladerunner/ui/ui_scroll_box.cpp
@@ -27,6 +27,7 @@
 #include "bladerunner/font.h"
 #include "bladerunner/game_info.h"
 #include "bladerunner/shape.h"
+#include "bladerunner/time.h"
 #include "bladerunner/ui/kia.h"
 #include "bladerunner/ui/kia_shapes.h"
 
@@ -62,9 +63,9 @@ UIScrollBox::UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelecte
 	_isVisible  = false;
 	_style      = style;
 	_center     = center;
-	_timeLastScroll    = _vm->getTotalPlayTime(); // Original game is using system timer
-	_timeLastCheckbox  = _vm->getTotalPlayTime();
-	_timeLastHighlight = _vm->getTotalPlayTime();
+	_timeLastScroll    = _vm->_time->currentSystem();
+	_timeLastCheckbox  = _vm->_time->currentSystem();
+	_timeLastHighlight = _vm->_time->currentSystem();
 
 	_highlightFrame = 0;
 
@@ -113,9 +114,9 @@ void UIScrollBox::show() {
 	_scrollAreaDownHover   = false;
 	_scrollBarHover        = false;
 
-	_timeLastScroll    = _vm->getTotalPlayTime(); // Original game is using system timer
-	_timeLastCheckbox  = _vm->getTotalPlayTime();
-	_timeLastHighlight = _vm->getTotalPlayTime();
+	_timeLastScroll    = _vm->_time->currentSystem();
+	_timeLastCheckbox  = _vm->_time->currentSystem();
+	_timeLastHighlight = _vm->_time->currentSystem();
 
 	_highlightFrame = 0;
 	_isVisible = true;
@@ -267,7 +268,7 @@ void UIScrollBox::handleMouseDown(bool alternateButton) {
 	if (!alternateButton) {
 		if (_scrollUpButtonHover) {
 			_scrollUpButtonState = 2;
-			_timeLastScroll = _vm->getTotalPlayTime() - 160; // Original game is using system timer
+			_timeLastScroll = _vm->_time->currentSystem() - 160;
 		} else {
 			_scrollUpButtonState = 1;
 		}
@@ -283,13 +284,13 @@ void UIScrollBox::handleMouseDown(bool alternateButton) {
 		}
 		if (_scrollAreaUpHover) {
 			_scrollAreaUpState = 2;
-			_timeLastScroll = _vm->getTotalPlayTime() - 160; // Original game is using system timer
+			_timeLastScroll = _vm->_time->currentSystem() - 160;
 		} else {
 			_scrollAreaUpState = 1;
 		}
 		if (_scrollAreaDownHover) {
 			_scrollAreaDownState = 2;
-			_timeLastScroll = _vm->getTotalPlayTime() - 160; // Original game is using system timer
+			_timeLastScroll = _vm->_time->currentSystem() - 160;
 		} else {
 			_scrollAreaDownState = 1;
 		}
@@ -321,7 +322,7 @@ int UIScrollBox::getSelectedLineData() {
 }
 
 void UIScrollBox::draw(Graphics::Surface &surface) {
-	int timeNow = _vm->getTotalPlayTime(); // Original game is using system timer
+	int timeNow = _vm->_time->currentSystem();
 
 	// update scrolling
 	if (_scrollUpButtonState == 2 && _scrollUpButtonHover) {
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index 0d83237..f073895 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -23,6 +23,7 @@
 #include "bladerunner/vqa_player.h"
 
 #include "bladerunner/bladerunner.h"
+#include "bladerunner/time.h"
 
 #include "audio/decoders/raw.h"
 
@@ -72,7 +73,7 @@ void VQAPlayer::close() {
 }
 
 int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics::Surface *customSurface) {
-	uint32 now = 60 * _vm->_system->getMillis();
+	uint32 now = 60 * _vm->_time->currentSystem();
 	int result = -1;
 
 	if (_frameNext < 0) {
@@ -216,7 +217,7 @@ bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int lo
 
 bool VQAPlayer::seekToFrame(int frame) {
 	_frameNext = frame;
-	_frameNextTime = 60 * _vm->_system->getMillis();
+	_frameNextTime = 60 * _vm->_time->currentSystem();
 	return true;
 }
 


Commit: 916221dc562c9062839918d58d1a9968eb8f2b5e
    https://github.com/scummvm/scummvm/commit/916221dc562c9062839918d58d1a9968eb8f2b5e
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2019-02-11T22:49:18+01:00

Commit Message:
BLADERUNNER: Added original logic for speech skipping

And some small cleanup of unnecessary comments.

Changed paths:
    engines/bladerunner/bladerunner.cpp
    engines/bladerunner/bladerunner.h
    engines/bladerunner/script/script.cpp
    engines/bladerunner/ui/vk.cpp


diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 5aef48c..035ab22 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -103,14 +103,18 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
 	_vqaIsPlaying       = false;
 	_vqaStopIsRequested = false;
 
+	_actorIsSpeaking           = false;
+	_actorSpeakStopIsRequested = false;
+
 	_subtitlesEnabled = false;
-	_sitcomMode       = true;
+	_sitcomMode       = false;
+	_shortyMode       = false;
 
 	_playerLosesControlCounter = 0;
 
 	_playerActorIdle = false;
 	_playerDead      = false;
-	_speechSkipped   = false;
+
 	_gameOver        = false;
 	_gameAutoSave    = -1;
 	_gameIsLoading   = false;
@@ -401,11 +405,8 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 
 	_gameVars = new int[_gameInfo->getGlobalVarCount()]();
 
-	// TODO: Init Actor AI Update counter
-
 	// Seed rand
 
-	// TODO: Sine and cosine lookup tables for intervals of 1.0, 4.0, and 12.0
 	_cosTable1024 = new Common::CosineTable(1024); // 10-bits = 1024 points for 2*PI;
 	_sinTable1024 = new Common::SineTable(1024);
 
@@ -469,8 +470,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 	_playerActor->setFPS(15);
 	_playerActor->timerStart(6, 200);
 
-	// TODO: Set actor ids (redundant?)
-
 	_policeMaze = new PoliceMaze(this);
 
 	_textActorNames = new TextResource(this);
@@ -563,7 +562,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
 }
 
 void BladeRunnerEngine::initChapterAndScene() {
-	// TODO: Init actors...
 	for (int i = 0, end = _gameInfo->getActorCount(); i != end; ++i) {
 		_aiScripts->initialize(i);
 	}
@@ -611,8 +609,8 @@ void BladeRunnerEngine::shutdown() {
 	}
 	_shapes.clear();
 
-	// TODO: Shutdown Scene
 	delete _scene;
+	_scene = nullptr;
 
 	if (_chapters) {
 		if (_chapters->hasOpenResources())
@@ -693,7 +691,7 @@ void BladeRunnerEngine::shutdown() {
 		_mainFont = nullptr;
 	}
 
-	if(isArchiveOpen("SUBTITLES.MIX")) {
+	if (isArchiveOpen("SUBTITLES.MIX")) {
 		closeArchive("SUBTITLES.MIX");
 	}
 	if (_subtitles) {
@@ -756,7 +754,6 @@ void BladeRunnerEngine::shutdown() {
 	delete _gameInfo;
 	_gameInfo = nullptr;
 
-	// TODO: Delete graphics surfaces here
 	_surface4.free();
 	_surfaceBack.free();
 	_surfaceFront.free();
@@ -765,8 +762,6 @@ void BladeRunnerEngine::shutdown() {
 		closeArchive("STARTUP.MIX");
 	}
 
-	// TODO: Delete MIXArchives here
-
 	delete _time;
 	_time = nullptr;
 
@@ -908,7 +903,6 @@ void BladeRunnerEngine::gameTick() {
 
 	_policeMaze->tick();
 
-	// TODO: Gun range announcements
 	_zbuffer->clean();
 
 	_ambientSounds->tick();
@@ -963,8 +957,6 @@ void BladeRunnerEngine::gameTick() {
 	_mouse->tick(p.x, p.y);
 	_mouse->draw(_surfaceFront, p.x, p.y);
 
-	// TODO: Process AUD
-
 	if (_walkSoundId >= 0) {
 		_audioPlayer->playAud(_gameInfo->getSfxTrack(_walkSoundId), _walkSoundVolume, _walkSoundBalance, _walkSoundBalance, 50, 0);
 		_walkSoundId = -1;
@@ -1066,8 +1058,11 @@ void BladeRunnerEngine::handleEvents() {
 }
 
 void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
-	if (event.kbd.keycode == Common::KEYCODE_RETURN) {
-		_speechSkipped = true;
+	if (_actorIsSpeaking && event.kbd.keycode == Common::KEYCODE_RETURN) {
+		_actorSpeakStopIsRequested = true;
+		_actorIsSpeaking = false;
+
+		return;
 	}
 
 	if (_vqaIsPlaying) {
@@ -1077,8 +1072,7 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
 		return;
 	}
 
-	// TODO:
-	if (!playerHasControl() /*|| ActorInWalkingLoop*/) {
+	if (!playerHasControl() || _isWalkingInterruptible) {
 		return;
 	}
 
@@ -1133,8 +1127,7 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
 		return;
 	}
 
-	//TODO:
-	if (!playerHasControl() /* || ActorWalkingLoop || ActorSpeaking || VqaIsPlaying */) {
+	if (!playerHasControl() || _isWalkingInterruptible || _actorIsSpeaking || _vqaIsPlaying) {
 		return;
 	}
 
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 74387b1..deaf4fa 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -188,7 +188,8 @@ public:
 	bool _interruptWalking;
 	bool _playerActorIdle;
 	bool _playerDead;
-	bool _speechSkipped;
+	bool _actorIsSpeaking;
+	bool _actorSpeakStopIsRequested;
 	bool _gameOver;
 	int  _gameAutoSave;
 	bool _gameIsLoading;
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 14f34c4..9e2097b2 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -318,9 +318,11 @@ void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause,
 	}
 	Player_Loses_Control();
 	while (_vm->_gameIsRunning) {
-		_vm->_speechSkipped = false;
+		_vm->_actorIsSpeaking = true;
+		_vm->_actorSpeakStopIsRequested = false;
 		_vm->gameTick();
-		if (_vm->_speechSkipped || !actor->isSpeeching()) {
+		_vm->_actorIsSpeaking = false;
+		if (_vm->_actorSpeakStopIsRequested || !actor->isSpeeching()) {
 			actor->speechStop();
 			break;
 		}
@@ -336,7 +338,7 @@ void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause,
 		}
 	}
 
-	if (pause > 0.0f && !_vm->_speechSkipped) {
+	if (pause > 0.0f && !_vm->_actorSpeakStopIsRequested) {
 		Delay(pause * 1000);
 	}
 
@@ -355,10 +357,12 @@ void ScriptBase::Actor_Voice_Over(int sentenceId, int actorId) {
 
 	actor->speechPlay(sentenceId, true);
 	Player_Loses_Control();
-	while(_vm->_gameIsRunning) {
-		_vm->_speechSkipped = false;
+	while (_vm->_gameIsRunning) {
+		_vm->_actorIsSpeaking = true;
+		_vm->_actorSpeakStopIsRequested = false;
 		_vm->gameTick();
-		if(_vm->_speechSkipped || !actor->isSpeeching()) {
+		_vm->_actorIsSpeaking = false;
+		if (_vm->_actorSpeakStopIsRequested || !actor->isSpeeching()) {
 			actor->speechStop();
 			break;
 		}
diff --git a/engines/bladerunner/ui/vk.cpp b/engines/bladerunner/ui/vk.cpp
index ab2b5de..6186452 100644
--- a/engines/bladerunner/ui/vk.cpp
+++ b/engines/bladerunner/ui/vk.cpp
@@ -243,24 +243,24 @@ void VK::playSpeechLine(int actorId, int sentenceId, float duration) {
 	actor->speechPlay(sentenceId, true);
 
 	while (_vm->_gameIsRunning) {
-		// ActorSpeaking = 1;
-		_vm->_speechSkipped = false;
+		_vm->_actorIsSpeaking = true;
+		_vm->_actorSpeakStopIsRequested = false;
 		_vm->gameTick();
-		// ActorSpeaking = 0;
-		if (_vm->_speechSkipped || !actor->isSpeeching()) {
+		_vm->_actorIsSpeaking = false;
+		if (_vm->_actorSpeakStopIsRequested || !actor->isSpeeching()) {
 			actor->speechStop();
 			break;
 		}
 	}
 
-	if (duration > 0.0f && !_vm->_speechSkipped) {
+	if (duration > 0.0f && !_vm->_actorSpeakStopIsRequested) {
 		int timeEnd = duration * 1000.0f + _vm->_time->current();
 		while ((timeEnd > _vm->_time->current()) && _vm->_gameIsRunning) {
 			_vm->gameTick();
 		}
 	}
 
-	_vm->_speechSkipped = false;
+	_vm->_actorSpeakStopIsRequested = false;
 
 	_vm->_mouse->enable();
 }





More information about the Scummvm-git-logs mailing list