aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound/audio32.cpp
diff options
context:
space:
mode:
authorColin Snover2017-06-07 20:59:34 -0500
committerColin Snover2017-06-09 23:00:14 -0500
commit85e35943fe27b99a91d97eace3072117c2073f69 (patch)
treeb298ba66c3cdafde9d48f9d8b6690fb19cec3eef /engines/sci/sound/audio32.cpp
parent4311d1b18274d25384c5492c27f0611db28d6c4a (diff)
downloadscummvm-rg350-85e35943fe27b99a91d97eace3072117c2073f69.tar.gz
scummvm-rg350-85e35943fe27b99a91d97eace3072117c2073f69.tar.bz2
scummvm-rg350-85e35943fe27b99a91d97eace3072117c2073f69.zip
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.
Diffstat (limited to 'engines/sci/sound/audio32.cpp')
-rw-r--r--engines/sci/sound/audio32.cpp47
1 files changed, 43 insertions, 4 deletions
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index b61bbd9a4e..f47002bb59 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