[Scummvm-git-logs] scummvm master -> c1021785d6094a6867d9bce38a7af2d8047255aa
csnover
csnover at users.noreply.github.com
Sat Jun 10 06:47:34 CEST 2017
This automated email contains information about 13 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
06e82211ee SCI: Implement Serializable for Object
b73906feb7 SCI: Get LRU from list directly, instead of from a reverse iterator
a2ead7c4a4 SCI32: Fix include path
cf98e16d90 SCI: Add serialization for ResourceId
ddc00e4211 SCI: Remove unhelpful comment
f48fc02a9b SCI: Fix typo in comment
f0d00caf93 SCI: Remove unnecessary condition
095226a614 SCI: Lock Audio resource types when digital SFX is enabled
4311d1b182 SCI: Do not lock Audio36/Sync36 in kLock for SCI1.1
85e35943fe SCI32: Implement kLock & kDoAudio(1) for SCI32
57d257b36a SCI32: Fix audio sync recursion
40566820a7 SCI: Return the original master sound volume when mute is on
c1021785d6 SCI: Remove some unused #includes
Commit: 06e82211ee38b0e63d81befed6b2cde9be4beba3
https://github.com/scummvm/scummvm/commit/06e82211ee38b0e63d81befed6b2cde9be4beba3
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:47:54-05:00
Commit Message:
SCI: Implement Serializable for Object
Changed paths:
engines/sci/engine/object.h
engines/sci/engine/savegame.cpp
diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h
index 12387bc..8b597b4 100644
--- a/engines/sci/engine/object.h
+++ b/engines/sci/engine/object.h
@@ -67,7 +67,7 @@ enum ObjectOffsets {
kOffsetNamePointerSci11 = 16
};
-class Object {
+class Object : public Common::Serializable {
public:
Object() :
_name(NULL_REG),
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index a59b240..de891b5 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -71,12 +71,6 @@ void syncWithSerializer(Common::Serializer &s, Common::Serializable &obj) {
obj.saveLoadWithSerializer(s);
}
-// FIXME: Object could implement Serializable to make use of the function
-// above.
-void syncWithSerializer(Common::Serializer &s, Object &obj) {
- obj.saveLoadWithSerializer(s);
-}
-
void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
// Segment and offset are accessed directly here
s.syncAsUint16LE(obj._segment);
Commit: b73906feb7b5aabf0e0efb5a0040c3dac94656a9
https://github.com/scummvm/scummvm/commit/b73906feb7b5aabf0e0efb5a0040c3dac94656a9
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:47:54-05:00
Commit Message:
SCI: Get LRU from list directly, instead of from a reverse iterator
Changed paths:
engines/sci/resource.cpp
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index a931d87..a465dd0 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1098,7 +1098,7 @@ void ResourceManager::printLRU() {
void ResourceManager::freeOldResources() {
while (_maxMemoryLRU < _memoryLRU) {
assert(!_LRU.empty());
- Resource *goner = *_LRU.reverse_begin();
+ Resource *goner = _LRU.back();
removeFromLRU(goner);
goner->unalloc();
#ifdef SCI_VERBOSE_RESMAN
Commit: a2ead7c4a423fed5c53a785356b99ecd26d80732
https://github.com/scummvm/scummvm/commit/a2ead7c4a423fed5c53a785356b99ecd26d80732
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:14-05:00
Commit Message:
SCI32: Fix include path
Changed paths:
engines/sci/sound/audio32.h
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index f77f676..dd48b39 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -28,7 +28,7 @@
#include "common/array.h" // for Array
#include "common/mutex.h" // for StackLock, Mutex
#include "common/scummsys.h" // for int16, uint8, uint32, uint16
-#include "engines/sci/resource.h" // for ResourceId
+#include "sci/resource.h" // for ResourceId
#include "sci/engine/vm_types.h" // for reg_t, NULL_REG
#include "sci/video/robot_decoder.h" // for RobotAudioStream
Commit: cf98e16d902bcfb50910fe8e196991e5f2f48e1a
https://github.com/scummvm/scummvm/commit/cf98e16d902bcfb50910fe8e196991e5f2f48e1a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:14-05:00
Commit Message:
SCI: Add serialization for ResourceId
Changed paths:
engines/sci/engine/savegame.cpp
engines/sci/resource.h
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index de891b5..bfd4957 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -71,6 +71,12 @@ void syncWithSerializer(Common::Serializer &s, Common::Serializable &obj) {
obj.saveLoadWithSerializer(s);
}
+void syncWithSerializer(Common::Serializer &s, ResourceId &obj) {
+ s.syncAsByte(obj._type);
+ s.syncAsUint16LE(obj._number);
+ s.syncAsUint32LE(obj._tuple);
+}
+
void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
// Segment and offset are accessed directly here
s.syncAsUint16LE(obj._segment);
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 3239a16..878e2ac 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -164,6 +164,8 @@ class ResourceId {
return string;
}
+ friend void syncWithSerializer(Common::Serializer &s, ResourceId &obj);
+
public:
ResourceId() : _type(kResourceTypeInvalid), _number(0), _tuple(0) { }
Commit: ddc00e421104bb7fe2806a29fcadcf68f2badb61
https://github.com/scummvm/scummvm/commit/ddc00e421104bb7fe2806a29fcadcf68f2badb61
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:14-05:00
Commit Message:
SCI: Remove unhelpful comment
Changed paths:
engines/sci/engine/savegame.cpp
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index bfd4957..c8e8813 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -78,7 +78,6 @@ void syncWithSerializer(Common::Serializer &s, ResourceId &obj) {
}
void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
- // Segment and offset are accessed directly here
s.syncAsUint16LE(obj._segment);
s.syncAsUint16LE(obj._offset);
}
Commit: f48fc02a9ba42ceba608e8a5eef785f3b3abeed6
https://github.com/scummvm/scummvm/commit/f48fc02a9ba42ceba608e8a5eef785f3b3abeed6
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:15-05:00
Commit Message:
SCI: Fix typo in comment
Changed paths:
engines/sci/engine/kscripts.cpp
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 75f905e..015daf2 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -45,7 +45,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, ((restype << 11) | resnr)); // Return the resource identifier as handle
}
-// Unloads an arbitrary resource of type 'restype' with resource numbber 'resnr'
+// Unloads an arbitrary resource of type 'restype' with resource number 'resnr'
// behavior of this call didn't change between sci0->sci1.1 parameter wise, which means getting called with
// 1 or 3+ parameters is not right according to sierra sci
reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
Commit: f0d00caf93b4d329fa39d66740906c317317780c
https://github.com/scummvm/scummvm/commit/f0d00caf93b4d329fa39d66740906c317317780c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:15-05:00
Commit Message:
SCI: Remove unnecessary condition
Argument count validation for kernel calls is performed through the
kernel table signature, so checking here is not necessary.
Changed paths:
engines/sci/engine/kscripts.cpp
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 015daf2..c04de52 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -49,13 +49,11 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
// behavior of this call didn't change between sci0->sci1.1 parameter wise, which means getting called with
// 1 or 3+ parameters is not right according to sierra sci
reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
- if (argc >= 2) {
- ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16());
- reg_t resnr = argv[1];
+ ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16());
+ reg_t resnr = argv[1];
- if (restype == kResourceTypeMemory)
- s->_segMan->freeHunkEntry(resnr);
- }
+ if (restype == kResourceTypeMemory)
+ s->_segMan->freeHunkEntry(resnr);
return s->r_acc;
}
Commit: 095226a614be5f1d4d3d8b9b5b03c4127fdb33e2
https://github.com/scummvm/scummvm/commit/095226a614be5f1d4d3d8b9b5b03c4127fdb33e2
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:15-05:00
Commit Message:
SCI: Lock Audio resource types when digital SFX is enabled
This seems to have been added in SCI1.1 and continued through
SCI32; older games with digital SFX (like KQ5CD) did not convert
the resource type in kLock.
This is not known to fix any problem, but was a noted difference
in the implementation between ScummVM and SSCI.
Changed paths:
engines/sci/engine/kscripts.cpp
engines/sci/sound/soundcmd.h
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index c04de52..3dba4b1 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -61,7 +61,11 @@ reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
reg_t kLock(EngineState *s, int argc, reg_t *argv) {
int state = argc > 2 ? argv[2].toUint16() : 1;
ResourceType type = g_sci->getResMan()->convertResType(argv[0].toUint16());
- ResourceId id = ResourceId(type, argv[1].toUint16());
+ if (type == kResourceTypeSound && getSciVersion() >= SCI_VERSION_1_1) {
+ type = g_sci->_soundCmd->getSoundResourceType(argv[1].toUint16());
+ }
+
+ const ResourceId id(type, argv[1].toUint16());
Resource *which;
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index 928c9b1..cac3ff7 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -72,6 +72,13 @@ public:
MusicType getMusicType() const;
+ ResourceType getSoundResourceType(const uint16 resourceNo) const {
+ if (_useDigitalSFX && _resMan->testResource(ResourceId(kResourceTypeAudio, resourceNo)))
+ return kResourceTypeAudio;
+ else
+ return kResourceTypeSound;
+ }
+
/**
* Synchronizes the current state of the music list to the rest of the engine, so that
* the changes that the sound thread makes to the music are registered with the engine
Commit: 4311d1b18274d25384c5492c27f0611db28d6c4a
https://github.com/scummvm/scummvm/commit/4311d1b18274d25384c5492c27f0611db28d6c4a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T22:48:15-05:00
Commit Message:
SCI: Do not lock Audio36/Sync36 in kLock for SCI1.1
This is not known to fix any problem, but was a noted difference
in the implementation between ScummVM and SSCI.
Changed paths:
engines/sci/engine/kscripts.cpp
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 3dba4b1..7bcbd0e 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -67,6 +67,11 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) {
const ResourceId id(type, argv[1].toUint16());
+ if (getSciVersion() == SCI_VERSION_1_1 &&
+ (type == kResourceTypeAudio36 || type == kResourceTypeSync36)) {
+ return s->r_acc;
+ }
+
Resource *which;
switch (state) {
Commit: 85e35943fe27b99a91d97eace3072117c2073f69
https://github.com/scummvm/scummvm/commit/85e35943fe27b99a91d97eace3072117c2073f69
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T23:00:14-05:00
Commit Message:
SCI32: Implement kLock & kDoAudio(1) for SCI32
1. Unlocking all resources of a type using a resource ID of -1 is
gone in SCI32;
2. Audio locks need to be serialized starting in GK2 for the game's
modified kDoAudio(1) call;
3. Audio locks in SCI3 must work more like SSCI, since at least
Lighthouse's `BackMusic::fade` method will attempt to unlock
audio that was never locked by a script. In SSCI (and now in
ScummVM too) this is a no-op; previously in ScummVM, it would
remove Audio32's own lock on the audio resource, resulting in a
use-after-free;
4. kDoAudio(1) starting in GK2 returns the number of active
*not-in-memory* channels being played, not the total number of
active channels.
Fixes Trac#9675.
Changed paths:
engines/sci/engine/features.h
engines/sci/engine/kscripts.cpp
engines/sci/engine/ksound.cpp
engines/sci/engine/savegame.cpp
engines/sci/engine/savegame.h
engines/sci/sound/audio32.cpp
engines/sci/sound/audio32.h
diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h
index 6d9460d..0861198 100644
--- a/engines/sci/engine/features.h
+++ b/engines/sci/engine/features.h
@@ -113,6 +113,10 @@ public:
}
}
+ inline bool hasSci3Audio() const {
+ return getSciVersion() == SCI_VERSION_3 || g_sci->getGameId() == GID_GK2;
+ }
+
inline bool hasTransparentPicturePlanes() const {
const SciGameId &gid = g_sci->getGameId();
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 7bcbd0e..5a33023 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -27,6 +27,10 @@
#include "sci/engine/state.h"
#include "sci/engine/selector.h"
#include "sci/engine/kernel.h"
+#ifdef ENABLE_SCI32
+#include "sci/engine/features.h"
+#include "sci/sound/audio32.h"
+#endif
#include "common/file.h"
@@ -49,6 +53,11 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
// behavior of this call didn't change between sci0->sci1.1 parameter wise, which means getting called with
// 1 or 3+ parameters is not right according to sierra sci
reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
+ // NOTE: Locked resources in SSCI could be disposed by kUnLoad regardless
+ // of lock state. With this ScummVM implementation of kUnLoad, game scripts
+ // that dispose locked resources via kUnLoad without unlocking them with
+ // kLock will leak the resource until the engine is restarted.
+
ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16());
reg_t resnr = argv[1];
@@ -59,27 +68,48 @@ reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
}
reg_t kLock(EngineState *s, int argc, reg_t *argv) {
- int state = argc > 2 ? argv[2].toUint16() : 1;
+ // NOTE: In SSCI, kLock uses a boolean lock flag, not a lock counter.
+ // ScummVM's current counter-based implementation should be better than SSCI
+ // at dealing with game scripts that unintentionally lock & unlock the same
+ // resource multiple times (e.g. through recursion), but it will introduce
+ // memory bugs (resource leaks lasting until the engine is restarted, or
+ // destruction of kernel locks that lead to a use-after-free) that are
+ // masked by ResourceManager's LRU cache if scripts rely on kLock being
+ // idempotent like it was in SSCI.
+ //
+ // Like SSCI, resource locks are not persisted in save games in ScummVM
+ // until GK2, so it is also possible that kLock bugs will appear only after
+ // restoring a save game.
+ //
+ // See also kUnLoad.
+
ResourceType type = g_sci->getResMan()->convertResType(argv[0].toUint16());
if (type == kResourceTypeSound && getSciVersion() >= SCI_VERSION_1_1) {
type = g_sci->_soundCmd->getSoundResourceType(argv[1].toUint16());
}
const ResourceId id(type, argv[1].toUint16());
+ const bool lock = argc > 2 ? argv[2].toUint16() : true;
+
+#ifdef ENABLE_SCI32
+ // SSCI GK2+SCI3 also saves lock states for View, Pic, and Sync resources,
+ // but so far it seems like audio resources are the only ones that actually
+ // need to be handled
+ if (g_sci->_features->hasSci3Audio() && type == kResourceTypeAudio) {
+ g_sci->_audio32->lockResource(id, lock);
+ return s->r_acc;
+ }
+#endif
if (getSciVersion() == SCI_VERSION_1_1 &&
(type == kResourceTypeAudio36 || type == kResourceTypeSync36)) {
return s->r_acc;
}
- Resource *which;
-
- switch (state) {
- case 1 :
- g_sci->getResMan()->findResource(id, 1);
- break;
- case 0 :
- if (id.getNumber() == 0xFFFF) {
+ if (lock) {
+ g_sci->getResMan()->findResource(id, true);
+ } else {
+ if (getSciVersion() < SCI_VERSION_2 && id.getNumber() == 0xFFFF) {
// Unlock all resources of the requested type
Common::List<ResourceId> resources = g_sci->getResMan()->listResources(type);
Common::List<ResourceId>::iterator itr;
@@ -89,7 +119,7 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) {
g_sci->getResMan()->unlockResource(res);
}
} else {
- which = g_sci->getResMan()->findResource(id, 0);
+ Resource *which = g_sci->getResMan()->findResource(id, false);
if (which)
g_sci->getResMan()->unlockResource(which);
@@ -103,7 +133,6 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) {
debugC(kDebugLevelResMan, "[resMan] Attempt to unlock non-existent resource %s", id.toString().c_str());
}
}
- break;
}
return s->r_acc;
}
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index ad0d836..ad13756 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -348,10 +348,22 @@ reg_t kDoAudioInit(EngineState *s, int argc, reg_t *argv) {
}
reg_t kDoAudioWaitForPlay(EngineState *s, int argc, reg_t *argv) {
+ if (argc == 0) {
+ if (g_sci->_features->hasSci3Audio()) {
+ return make_reg(0, g_sci->_audio32->getNumUnlockedChannels());
+ } else {
+ return make_reg(0, g_sci->_audio32->getNumActiveChannels());
+ }
+ }
+
return g_sci->_audio32->kernelPlay(false, argc, argv);
}
reg_t kDoAudioPlay(EngineState *s, int argc, reg_t *argv) {
+ if (argc == 0) {
+ return make_reg(0, g_sci->_audio32->getNumActiveChannels());
+ }
+
return g_sci->_audio32->kernelPlay(true, argc, argv);
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index c8e8813..e0f9ec3 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -435,6 +435,10 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
g_sci->_gfxPalette32->saveLoadWithSerializer(s);
g_sci->_gfxRemap32->saveLoadWithSerializer(s);
g_sci->_gfxCursor32->saveLoadWithSerializer(s);
+ // TODO: SCI2 should be using Audio32 too, but is not yet.
+ if (g_sci->_audio32) {
+ g_sci->_audio32->saveLoadWithSerializer(s);
+ }
g_sci->_video32->saveLoadWithSerializer(s);
} else
#endif
@@ -1017,6 +1021,14 @@ void GfxCursor32::saveLoadWithSerializer(Common::Serializer &s) {
}
}
+void Audio32::saveLoadWithSerializer(Common::Serializer &s) {
+ if (!g_sci->_features->hasSci3Audio() || s.getVersion() < 44) {
+ return;
+ }
+
+ syncArray(s, _lockedResourceIds);
+}
+
void Video32::beforeSaveLoadWithSerializer(Common::Serializer &s) {
if (getSciVersion() < SCI_VERSION_3 || s.isSaving()) {
return;
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 151585a..2993024 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 44 - GK2+SCI3 audio resource locks
* 43 - stop saving SCI3 mustSetViewVisible array
* 42 - SCI3 robots and VM objects
* 41 - palette support for newer SCI2.1 games; stable SCI2/2.1 save games
@@ -68,7 +69,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 43,
+ CURRENT_SAVEGAME_VERSION = 44,
MINIMUM_SAVEGAME_VERSION = 14
#ifdef ENABLE_SCI32
,
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index b61bbd9..f47002b 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -354,6 +354,20 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
#pragma mark -
#pragma mark Channel management
+uint8 Audio32::getNumUnlockedChannels() const {
+ Common::StackLock lock(_mutex);
+
+ uint8 numChannels = 0;
+ for (uint i = 0; i < _numActiveChannels; ++i) {
+ const AudioChannel &channel = getChannel(i);
+ if (!channel.robot && Common::find(_lockedResourceIds.begin(), _lockedResourceIds.end(), channel.id) == _lockedResourceIds.end()) {
+ ++numChannels;
+ }
+ }
+
+ return numChannels;
+}
+
int16 Audio32::findChannelByArgs(int argc, const reg_t *argv, const int startIndex, const reg_t soundNode) const {
// NOTE: argc/argv are already reduced by one in our engine because
// this call is always made from a subop, so no reduction for the
@@ -420,6 +434,21 @@ int16 Audio32::findChannelById(const ResourceId resourceId, const reg_t soundNod
return kNoExistingChannel;
}
+void Audio32::lockResource(const ResourceId resourceId, const bool lock) {
+ Common::StackLock slock(_mutex);
+
+ LockList::iterator it = Common::find(_lockedResourceIds.begin(), _lockedResourceIds.end(), resourceId);
+ if (it != _lockedResourceIds.end()) {
+ if (!lock) {
+ _lockedResourceIds.erase(it);
+ }
+ } else {
+ if (lock) {
+ _lockedResourceIds.push_back(resourceId);
+ }
+ }
+}
+
void Audio32::freeUnusedChannels() {
Common::StackLock lock(_mutex);
for (int channelIndex = 0; channelIndex < _numActiveChannels; ++channelIndex) {
@@ -1037,10 +1066,6 @@ bool Audio32::hasSignal() const {
reg_t Audio32::kernelPlay(const bool autoPlay, const int argc, const reg_t *const argv) {
Common::StackLock lock(_mutex);
- if (argc == 0) {
- return make_reg(0, _numActiveChannels);
- }
-
const int16 channelIndex = findChannelByArgs(argc, argv, 0, NULL_REG);
ResourceId resourceId;
bool loop;
@@ -1214,6 +1239,20 @@ void Audio32::printAudioList(Console *con) const {
channel.stopChannelOnFade ? ", stopping" : "");
}
}
+
+ if (g_sci->_features->hasSci3Audio()) {
+ con->debugPrintf("\nLocks: ");
+ if (_lockedResourceIds.size()) {
+ const char *separator = "";
+ for (LockList::const_iterator it = _lockedResourceIds.begin(); it != _lockedResourceIds.end(); ++it) {
+ con->debugPrintf("%s%s", separator, it->toString().c_str());
+ separator = ", ";
+ }
+ } else {
+ con->debugPrintf("none");
+ }
+ con->debugPrintf("\n");
+ }
}
} // End of namespace Sci
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index dd48b39..27f7e8f 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -157,11 +157,13 @@ enum AudioChannelIndex {
* engine, since the system mixer does not support all the
* features of SCI.
*/
-class Audio32 : public Audio::AudioStream {
+class Audio32 : public Audio::AudioStream, public Common::Serializable {
public:
Audio32(ResourceManager *resMan);
~Audio32();
+ virtual void saveLoadWithSerializer(Common::Serializer &s);
+
enum {
/**
* The maximum channel volume.
@@ -205,6 +207,19 @@ public:
}
/**
+ * Gets the number of currently active channels that are playing from
+ * unlocked resources.
+ *
+ * @note In SSCI, this function would actually return the number of channels
+ * whose audio data were not loaded into memory. In practice, the signal for
+ * placing audio data into memory was a call to kLock, so since we do not
+ * follow how SSCI works when it comes to resource management, the lock
+ * state is used as an (apparently) successful proxy for this information
+ * instead.
+ */
+ uint8 getNumUnlockedChannels() const;
+
+ /**
* Finds a channel that is already configured for the
* given audio sample.
*
@@ -219,7 +234,13 @@ public:
*/
int16 findChannelById(const ResourceId resourceId, const reg_t soundNode = NULL_REG) const;
+ /**
+ * Sets or clears a lock on the given resource ID.
+ */
+ void lockResource(const ResourceId resourceId, const bool lock);
+
private:
+ typedef Common::Array<ResourceId> LockList;
typedef Common::Array<Resource *> UnlockList;
/**
@@ -252,6 +273,11 @@ private:
UnlockList _resourcesToUnlock;
/**
+ * The list of resource IDs that have been locked by game scripts.
+ */
+ LockList _lockedResourceIds;
+
+ /**
* Gets the audio channel at the given index.
*/
inline AudioChannel &getChannel(const int16 channelIndex) {
Commit: 57d257b36a1a4c9657dff360cca4d1d58bb880e0
https://github.com/scummvm/scummvm/commit/57d257b36a1a4c9657dff360cca4d1d58bb880e0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T23:30:10-05:00
Commit Message:
SCI32: Fix audio sync recursion
Calling to SciEngine::syncSoundSettings from GuestAdditions
recurses back into GuestAdditions, which is obviously not
desirable. Even when it didn't manage to cause infinite recursion
(as in SQ6 demo), it would make the UI behave in broken ways (e.g.
the +/- buttons on the music slider in SQ6 would not work because
the UI would just get updated immediately back to the closest
rounded value).
Changed paths:
engines/sci/engine/guest_additions.cpp
engines/sci/engine/guest_additions.h
engines/sci/sci.cpp
engines/sci/sci.h
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index 23f600f..6d9bb20 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -68,7 +68,7 @@ GuestAdditions::GuestAdditions(EngineState *state, GameFeatures *features, Kerne
#pragma mark -
-void GuestAdditions::syncSoundSettings() const {
+void GuestAdditions::syncSoundSettingsFromScummVM() const {
#ifdef ENABLE_SCI32
if (_features->audioVolumeSyncUsesGlobals())
syncAudioVolumeGlobalsFromScummVM();
@@ -94,7 +94,7 @@ void GuestAdditions::invokeSelector(const reg_t objId, const Selector selector,
::Sci::invokeSelector(_state, objId, selector, 0, _state->_executionStack.back().sp, argc, argv);
}
-bool GuestAdditions::shouldSyncAudio() const {
+bool GuestAdditions::shouldSyncAudioToScummVM() const {
const SciGameId gameId = g_sci->getGameId();
Common::List<ExecStack>::const_iterator it;
for (it = _state->_executionStack.begin(); it != _state->_executionStack.end(); ++it) {
@@ -163,7 +163,7 @@ void GuestAdditions::writeVarHook(const int type, const int index, const reg_t v
if (type == VAR_GLOBAL) {
#ifdef ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2) {
- if (_features->audioVolumeSyncUsesGlobals() && shouldSyncAudio()) {
+ if (_features->audioVolumeSyncUsesGlobals() && shouldSyncAudioToScummVM()) {
syncAudioVolumeGlobalsToScummVM(index, value);
} else if (g_sci->getGameId() == GID_GK1) {
syncGK1StartupVolumeFromScummVM(index, value);
@@ -179,7 +179,7 @@ void GuestAdditions::writeVarHook(const int type, const int index, const reg_t v
}
bool GuestAdditions::kDoSoundMasterVolumeHook(const int volume) const {
- if (!_features->audioVolumeSyncUsesGlobals() && shouldSyncAudio()) {
+ if (!_features->audioVolumeSyncUsesGlobals() && shouldSyncAudioToScummVM()) {
syncMasterVolumeToScummVM(volume);
return true;
}
@@ -194,14 +194,14 @@ void GuestAdditions::sendSelectorHook(const reg_t sendObj, Selector &selector, r
}
bool GuestAdditions::audio32SetVolumeHook(const int16 channelIndex, int16 volume) const {
- if (!_features->audioVolumeSyncUsesGlobals() && shouldSyncAudio()) {
+ if (!_features->audioVolumeSyncUsesGlobals() && shouldSyncAudioToScummVM()) {
volume = volume * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume;
if (Common::checkGameGUIOption(GUIO_LINKMUSICTOSFX, ConfMan.get("guioptions"))) {
ConfMan.setInt("music_volume", volume);
}
ConfMan.setInt("sfx_volume", volume);
ConfMan.setInt("speech_volume", volume);
- g_engine->syncSoundSettings();
+ g_sci->updateSoundMixerVolumes();
return true;
}
@@ -209,7 +209,7 @@ bool GuestAdditions::audio32SetVolumeHook(const int16 channelIndex, int16 volume
}
void GuestAdditions::kDoSoundSetVolumeHook(const reg_t soundObj, const int16 volume) const {
- if (g_sci->getGameId() == GID_GK1 && shouldSyncAudio()) {
+ if (g_sci->getGameId() == GID_GK1 && shouldSyncAudioToScummVM()) {
syncGK1AudioVolumeToScummVM(soundObj, volume);
}
}
@@ -727,17 +727,8 @@ void GuestAdditions::syncMessageTypeToScummVMUsingLSL6HiresStrategy(const reg_t
#pragma mark Master volume sync
void GuestAdditions::syncMasterVolumeFromScummVM() const {
- const int16 musicVolume = (ConfMan.getInt("music_volume") + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
-
- // When the volume changes from the ScummVM launcher, ScummVM automatically
- // adjusts the software mixer in Engine::syncSoundSettings, but MIDI may not
- // run through the ScummVM mixer so its master volume must be adjusted
- // explicitly
- if (g_sci->_soundCmd) {
- g_sci->_soundCmd->setMasterVolume(ConfMan.getBool("mute") ? 0 : musicVolume);
- }
-
#ifdef ENABLE_SCI32
+ const int16 musicVolume = (ConfMan.getInt("music_volume") + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
const int16 sfxVolume = (ConfMan.getInt("sfx_volume") + 1) * Audio32::kMaxVolume / Audio::Mixer::kMaxMixerVolume;
// Volume was changed from ScummVM during the game, so resync the
@@ -765,7 +756,7 @@ void GuestAdditions::syncMasterVolumeToScummVM(const int16 masterVolume) const {
ConfMan.setInt("sfx_volume", scummVMVolume);
ConfMan.setInt("speech_volume", scummVMVolume);
}
- g_engine->syncSoundSettings();
+ g_sci->updateSoundMixerVolumes();
}
#ifdef ENABLE_SCI32
@@ -1003,11 +994,11 @@ void GuestAdditions::syncGK1AudioVolumeToScummVM(const reg_t soundObj, int16 vol
// have been set by the volume slider
if (objName == "gkMusic2") {
ConfMan.setInt("music_volume", volume);
- g_engine->syncSoundSettings();
+ g_sci->updateSoundMixerVolumes();
} else if (objName == "gkSound3") {
ConfMan.setInt("sfx_volume", volume);
ConfMan.setInt("speech_volume", volume);
- g_engine->syncSoundSettings();
+ g_sci->updateSoundMixerVolumes();
}
}
diff --git a/engines/sci/engine/guest_additions.h b/engines/sci/engine/guest_additions.h
index 9e5100d..c920fa7 100644
--- a/engines/sci/engine/guest_additions.h
+++ b/engines/sci/engine/guest_additions.h
@@ -55,7 +55,7 @@ public:
* Synchronises audio volume settings from ScummVM to the game. Called
* whenever the ScummVM global menu is dismissed.
*/
- void syncSoundSettings() const;
+ void syncSoundSettingsFromScummVM() const;
/**
* Synchronises all audio settings from ScummVM to the game. Called when the
@@ -84,7 +84,7 @@ private:
* Determines whether the current stack contains calls from audio controls
* that indicate a user-initiated change of audio settings.
*/
- bool shouldSyncAudio() const;
+ bool shouldSyncAudioToScummVM() const;
#pragma mark -
#pragma mark Hooks
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 59f1b35..655721d 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -879,8 +879,21 @@ void SciEngine::pauseEngineIntern(bool pause) {
}
void SciEngine::syncSoundSettings() {
+ updateSoundMixerVolumes();
+ _guestAdditions->syncSoundSettingsFromScummVM();
+}
+
+void SciEngine::updateSoundMixerVolumes() {
Engine::syncSoundSettings();
- _guestAdditions->syncSoundSettings();
+
+ // ScummVM adjusts the software mixer volume in Engine::syncSoundSettings,
+ // but MIDI either does not run through the ScummVM mixer (e.g. hardware
+ // synth) or it uses a kPlainSoundType channel type, so the master MIDI
+ // volume must be adjusted here for MIDI playback volume to be correct
+ if (_soundCmd) {
+ const int16 musicVolume = (ConfMan.getInt("music_volume") + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
+ _soundCmd->setMasterVolume(ConfMan.getBool("mute") ? 0 : musicVolume);
+ }
}
void SciEngine::loadMacExecutable() {
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index ef2fb3b..3139f15 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -260,7 +260,8 @@ public:
Common::Error saveGameState(int slot, const Common::String &desc);
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
- void syncSoundSettings();
+ void syncSoundSettings(); ///< from ScummVM to the game
+ void updateSoundMixerVolumes();
uint32 getTickCount();
void setTickCount(const uint32 ticks);
Commit: 40566820a71adb63d34a7831c85efacc430f3481
https://github.com/scummvm/scummvm/commit/40566820a71adb63d34a7831c85efacc430f3481
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T23:30:10-05:00
Commit Message:
SCI: Return the original master sound volume when mute is on
Changed paths:
engines/sci/sound/music.cpp
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index ca5644d..987983a 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -739,6 +739,14 @@ void SciMusic::soundToggle(MusicEntry *pSnd, bool pause) {
}
uint16 SciMusic::soundGetMasterVolume() {
+ if (ConfMan.getBool("mute")) {
+ // When a game is muted, the master volume is set to zero so that
+ // mute applies to external MIDI devices, but this should not be
+ // communicated to the game as it will cause the UI to be drawn with
+ // the wrong (zero) volume for music
+ return (ConfMan.getInt("music_volume") + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
+ }
+
return _masterVolume;
}
Commit: c1021785d6094a6867d9bce38a7af2d8047255aa
https://github.com/scummvm/scummvm/commit/c1021785d6094a6867d9bce38a7af2d8047255aa
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-06-09T23:30:11-05:00
Commit Message:
SCI: Remove some unused #includes
Changed paths:
engines/sci/engine/vm.cpp
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index f4071a4..12a9c3b 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -26,12 +26,6 @@
#include "sci/sci.h"
#include "sci/console.h"
-#include "sci/resource.h"
-#ifdef ENABLE_SCI32
-#include "audio/mixer.h"
-#include "sci/sound/audio32.h"
-#include "sci/sound/music.h"
-#endif
#include "sci/engine/features.h"
#include "sci/engine/guest_additions.h"
#include "sci/engine/state.h"
More information about the Scummvm-git-logs
mailing list