aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Bouclet2010-12-18 13:12:56 +0000
committerBastien Bouclet2010-12-18 13:12:56 +0000
commitc870bf22d1f4bd154267a31b6a24eeb6e85c34d7 (patch)
treee07244845d270d76151bd84aaefca77cbc98d7fb
parent41acf18a5376f47c9965263ad5fdc8cc2b3a8005 (diff)
downloadscummvm-rg350-c870bf22d1f4bd154267a31b6a24eeb6e85c34d7.tar.gz
scummvm-rg350-c870bf22d1f4bd154267a31b6a24eeb6e85c34d7.tar.bz2
scummvm-rg350-c870bf22d1f4bd154267a31b6a24eeb6e85c34d7.zip
MOHAWK: Separate background sound handling from other sounds for Myst. Allow the scripts to change the background sound volume.
svn-id: r54953
-rw-r--r--engines/mohawk/console.cpp3
-rw-r--r--engines/mohawk/myst.cpp17
-rw-r--r--engines/mohawk/myst_areas.cpp12
-rw-r--r--engines/mohawk/myst_areas.h4
-rw-r--r--engines/mohawk/myst_scripts.cpp37
-rw-r--r--engines/mohawk/myst_scripts.h2
-rw-r--r--engines/mohawk/sound.cpp83
-rw-r--r--engines/mohawk/sound.h14
8 files changed, 116 insertions, 56 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index d406d7575c..bf1d9b02ce 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -215,8 +215,7 @@ bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
return true;
}
- _vm->_sound->stopSound();
- _vm->_sound->playSound((uint16)atoi(argv[1]));
+ _vm->_sound->replaceSound((uint16)atoi(argv[1]));
return false;
}
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 15232966dd..be3a776b60 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -453,6 +453,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack) {
// Clear the resource cache and the image cache
_cache.clear();
_gfx->clearCache();
+ _sound->stopBackground();
}
uint16 MohawkEngine_Myst::getCardBackgroundId() {
@@ -521,27 +522,17 @@ void MohawkEngine_Myst::changeToCard(uint16 card, bool updateScreen) {
soundActionVolume = _view.soundVolume;
}
- // NOTE: Mixer only has 8-bit channel volume granularity,
- // Myst uses 16-bit? Or is part of this balance?
- soundActionVolume = (byte)(soundActionVolume / 255);
-
if (soundAction == kMystSoundActionContinue)
debug(2, "Continuing with current sound");
else if (soundAction == kMystSoundActionChangeVolume) {
debug(2, "Continuing with current sound, changing volume");
- // TODO: Implement Volume Control..
+ _sound->changeBackgroundVolume(soundActionVolume);
} else if (soundAction == kMystSoundActionStop) {
debug(2, "Stopping sound");
- _sound->stopSound();
+ _sound->stopBackground();
} else if (soundAction > 0) {
debug(2, "Playing new sound %d", soundAction);
- _sound->stopSound();
- // TODO: Need to keep sound handle and add function to change volume of
- // looped running sound for kMystSoundActionChangeVolume type
-
- // NOTE: All sounds are looped when played via the sound section of the
- // VIEW resources.
- _sound->playSound(soundAction, soundActionVolume, true);
+ _sound->replaceBackground(soundAction, soundActionVolume);
} else {
error("Unknown sound action %d", soundAction);
}
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 5b27a69ab9..6377f3255c 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -171,14 +171,20 @@ MystResourceType6::MystResourceType6(MohawkEngine_Myst *vm, Common::SeekableRead
_videoFile = convertMystVideoName(_videoFile);
// Position values require modulus 10000 to keep in sane range.
- _left = rlstStream->readUint16LE() % 10000;
- _top = rlstStream->readUint16LE() % 10000;
+ _left = rlstStream->readSint16LE() % 10000;
+ _top = rlstStream->readSint16LE() % 10000;
_playOnCardChange = rlstStream->readUint16LE();
_direction = rlstStream->readUint16LE();
_playBlocking = rlstStream->readUint16LE();
_loop = rlstStream->readUint16LE();
_u3 = rlstStream->readUint16LE();
+ // TODO: Out of bound values should clip the movie
+ if (_left < 0)
+ _left = 0;
+ if (_top < 0)
+ _top = 0;
+
if (_direction != 1)
warning("Type 6 _u0 != 1");
if (_u3 != 0)
@@ -648,7 +654,7 @@ void MystResourceType10::updatePosition(const Common::Point &mouse) {
}
if (positionChanged && _dragSound) {
- _vm->_sound->playSound(_dragSound);
+ _vm->_sound->replaceSound(_dragSound);
}
}
diff --git a/engines/mohawk/myst_areas.h b/engines/mohawk/myst_areas.h
index 0aa5f082f6..6e84747fe4 100644
--- a/engines/mohawk/myst_areas.h
+++ b/engines/mohawk/myst_areas.h
@@ -112,8 +112,8 @@ public:
protected:
static Common::String convertMystVideoName(Common::String name);
Common::String _videoFile;
- uint16 _left;
- uint16 _top;
+ int16 _left;
+ int16 _top;
uint16 _loop;
uint16 _direction; // 1 => forward, -1 => backwards
uint16 _playBlocking;
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 279de90226..bf1aadcea0 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -128,7 +128,7 @@ void MystScriptParser::setupCommonOpcodes() {
OPCODE(27, o_playSoundBlocking);
OPCODE(28, o_copyBackBufferToScreen);
OPCODE(29, o_copyImageToBackBuffer);
- OPCODE(30, o_changeSound);
+ OPCODE(30, o_changeBackgroundSound);
OPCODE(31, o_soundPlaySwitch);
OPCODE(32, o_soundResumeBackground);
OPCODE(33, o_copyImageToScreen);
@@ -558,14 +558,14 @@ void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *a
debugC(kDebugScript, "Opcode %d: playSound", op);
debugC(kDebugScript, "\tsoundId: %d", soundId);
- _vm->_sound->playSound(soundId);
+ _vm->_sound->replaceSound(soundId);
} else
unknown(op, var, argc, argv);
}
void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: stopSoundBackground", op);
- //_vm->_sound->stopBackground();
+ _vm->_sound->stopBackground();
}
void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -636,7 +636,7 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 arg
// Current behaviour here and with VIEW sound block is not right as demonstrated
// by Channelwood Card 3280 (Tank Valve) and water flow sound behaviour in pipe
// on cards leading from shed...
-void MystScriptParser::o_changeSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
int16 *soundList = NULL;
@@ -682,27 +682,20 @@ void MystScriptParser::o_changeSound(uint16 op, uint16 var, uint16 argc, uint16
}
}
- // NOTE: Mixer only has 8-bit channel volume granularity,
- // Myst uses 16-bit? Or is part of this balance?
- soundVolume = (byte)(soundVolume / 255);
-
if (soundAction == kMystSoundActionContinue)
debugC(kDebugScript, "Continue current sound");
else if (soundAction == kMystSoundActionChangeVolume) {
debugC(kDebugScript, "Continue current sound, change volume");
debugC(kDebugScript, "\tVolume: %d", soundVolume);
- // TODO: Implement Volume Control..
+ _vm->_sound->changeBackgroundVolume(soundVolume);
} else if (soundAction == kMystSoundActionStop) {
debugC(kDebugScript, "Stop sound");
- _vm->_sound->stopSound();
+ _vm->_sound->stopBackground();
} else if (soundAction > 0) {
debugC(kDebugScript, "Play new Sound, change volume");
debugC(kDebugScript, "\tSound: %d", soundAction);
debugC(kDebugScript, "\tVolume: %d", soundVolume);
- _vm->_sound->stopSound();
- // TODO: Need to keep sound handle and add function to change volume of
- // looped running sound for kMystSoundActionChangeVolume type
- _vm->_sound->playSound(soundAction, soundVolume);
+ _vm->_sound->replaceBackground(soundAction, soundVolume);
} else {
debugC(kDebugScript, "Unknown");
warning("Unknown sound control value in opcode %d", op);
@@ -726,13 +719,13 @@ void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, uint16 argc, uin
debugC(kDebugScript, "\tsoundId: %d", soundId);
if (soundId)
- _vm->_sound->playSound(soundId);
+ _vm->_sound->replaceSound(soundId);
}
}
void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: soundResumeBackground", op);
- //_vm->_sound->resumeBackground();
+ _vm->_sound->resumeBackground();
}
void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -857,7 +850,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
// wrong as you're not actually linking when using this opcode. The sounds are only
// played for the full game linking.
if (!_vm->_tweaksEnabled) {
- handle= _vm->_sound->playSound(soundIdLinkSrc);
+ handle= _vm->_sound->replaceSound(soundIdLinkSrc);
while (_vm->_mixer->isSoundHandleActive(*handle))
_vm->_system->delayMillis(10);
}
@@ -872,12 +865,12 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
}
if (!_vm->_tweaksEnabled) {
- handle = _vm->_sound->playSound(soundIdLinkDst);
+ handle = _vm->_sound->replaceSound(soundIdLinkDst);
while (_vm->_mixer->isSoundHandleActive(*handle))
_vm->_system->delayMillis(10);
}
} else {
- handle = _vm->_sound->playSound(soundIdLinkSrc);
+ handle = _vm->_sound->replaceSound(soundIdLinkSrc);
while (_vm->_mixer->isSoundHandleActive(*handle))
_vm->_system->delayMillis(10);
@@ -886,7 +879,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
_vm->changeToStack(_stackMap[targetStack]);
_vm->changeToCard(_startCard[targetStack], true);
- handle = _vm->_sound->playSound(soundIdLinkDst);
+ handle = _vm->_sound->replaceSound(soundIdLinkDst);
while (_vm->_mixer->isSoundHandleActive(*handle))
_vm->_system->delayMillis(10);
}
@@ -908,7 +901,7 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, u
debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
if (soundId)
- _vm->_sound->playSound(soundId);
+ _vm->_sound->replaceSound(soundId);
_vm->changeToCard(cardId, false);
@@ -927,7 +920,7 @@ void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, uint1
debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
if (soundId)
- _vm->_sound->playSound(soundId);
+ _vm->_sound->replaceSound(soundId);
animatedUpdate(dataSize, &argv[3], delayBetweenSteps);
}
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index f455daf66d..f16c4fcbd9 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -103,7 +103,7 @@ public:
DECLARE_OPCODE(o_playSoundBlocking);
DECLARE_OPCODE(o_copyBackBufferToScreen);
DECLARE_OPCODE(o_copyImageToBackBuffer);
- DECLARE_OPCODE(o_changeSound);
+ DECLARE_OPCODE(o_changeBackgroundSound);
DECLARE_OPCODE(o_soundPlaySwitch);
DECLARE_OPCODE(o_copyImageToScreen);
DECLARE_OPCODE(o_soundResumeBackground);
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index 29a097e591..aec01dcdd5 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -70,9 +70,7 @@ void Sound::initMidi() {
_midiParser->setTimerRate(_midiDriver->getBaseTempo());
}
-Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
- debug (0, "Playing sound %d", id);
-
+Audio::AudioStream *Sound::makeAudioStream(uint16 id) {
Audio::AudioStream *audStream = NULL;
switch (_vm->getGameType()) {
@@ -103,6 +101,14 @@ Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
audStream = makeMohawkWaveStream(_vm->getResource(ID_TWAV, id));
}
+ return audStream;
+}
+
+Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
+ debug (0, "Playing sound %d", id);
+
+ Audio::AudioStream *audStream = makeAudioStream(id);
+
if (audStream) {
SndHandle *handle = getHandle();
handle->type = kUsedHandle;
@@ -127,12 +133,11 @@ Audio::SoundHandle *Sound::replaceSound(uint16 id, byte volume, bool loop) {
Common::String name = _vm->getResourceName(ID_MSND, id);
// Check if sound is already playing
- for (uint32 i = 0; i < _handles.size(); i++) {
- if (_vm->_mixer->isSoundHandleActive(_handles[i].handle)
- && name.equals(_vm->getResourceName(ID_MSND, _handles[i].id))) {
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kUsedHandle
+ && _vm->_mixer->isSoundHandleActive(_handles[i].handle)
+ && name.equals(_vm->getResourceName(ID_MSND, _handles[i].id)))
return &_handles[i].handle;
- }
- }
stopSound();
return playSound(id, volume, loop);
@@ -552,4 +557,66 @@ bool Sound::isPlaying(uint16 id) {
return false;
}
+Audio::SoundHandle *Sound::replaceBackground(uint16 id, uint16 volume) {
+ debug (0, "Replacing background %d", id);
+
+ //TODO: The original engine does fading
+
+ Common::String name = _vm->getResourceName(ID_MSND, id);
+
+ // Check if sound is already playing
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kBackgroundHandle
+ && _vm->_mixer->isSoundHandleActive(_handles[i].handle)
+ && name.equals(_vm->getResourceName(ID_MSND, _handles[i].id)))
+ return &_handles[i].handle;
+
+ // Stop old background sound
+ stopBackground();
+
+ // Play new sound
+ Audio::AudioStream *audStream = makeAudioStream(id);
+
+ if (audStream) {
+ SndHandle *handle = getHandle();
+ handle->type = kBackgroundHandle;
+ handle->id = id;
+
+ // Set the stream to loop
+ audStream = Audio::makeLoopingAudioStream((Audio::RewindableAudioStream *)audStream, 0);
+
+ _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle->handle, audStream, -1, volume >> 8);
+ return &handle->handle;
+ }
+
+ return NULL;
+}
+
+void Sound::stopBackground() {
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kBackgroundHandle) {
+ _vm->_mixer->stopHandle(_handles[i].handle);
+ _handles[i].type = kFreeHandle;
+ _handles[i].id = 0;
+ }
+}
+
+void Sound::pauseBackground() {
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kBackgroundHandle)
+ _vm->_mixer->pauseHandle(_handles[i].handle, true);
+}
+
+void Sound::resumeBackground() {
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kBackgroundHandle)
+ _vm->_mixer->pauseHandle(_handles[i].handle, false);
+}
+
+void Sound::changeBackgroundVolume(uint16 vol) {
+ for (uint32 i = 0; i < _handles.size(); i++)
+ if (_handles[i].type == kBackgroundHandle)
+ _vm->_mixer->setChannelVolume(_handles[i].handle, vol >> 8);
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h
index 2d3edad557..daadd765eb 100644
--- a/engines/mohawk/sound.h
+++ b/engines/mohawk/sound.h
@@ -59,7 +59,8 @@ struct SLSTRecord {
enum SndHandleType {
kFreeHandle,
- kUsedHandle
+ kUsedHandle,
+ kBackgroundHandle
};
struct SndHandle {
@@ -129,10 +130,12 @@ public:
void resumeSound();
bool isPlaying(uint16 id);
- void pauseBackground() {} //TODO: implement
- void replaceBackground(uint16 id, uint16 volume) {}
- void resumeBackground() {}
- void stopBackground() {}
+ // Myst background sound functions
+ Audio::SoundHandle *replaceBackground(uint16 id, uint16 volume = 0xFFFF);
+ void pauseBackground();
+ void resumeBackground();
+ void stopBackground();
+ void changeBackgroundVolume(uint16 vol);
// Riven-specific
void playSLST(uint16 index, uint16 card);
@@ -153,6 +156,7 @@ private:
Common::Array<SndHandle> _handles;
SndHandle *getHandle();
+ Audio::AudioStream *makeAudioStream(uint16 id);
// Riven-specific
void playSLSTSound(uint16 index, bool fade, bool loop, uint16 volume, int16 balance);