From 9b0bf9e21555fb1760d45792ab4bd6bcb67d08c6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 10 Aug 2015 22:01:02 -0400 Subject: [PATCH] SHERLOCK: RT: Beginnings of speech code --- engines/sherlock/resources.cpp | 8 ++++++ engines/sherlock/sound.cpp | 34 ++++++++++++++++++------- engines/sherlock/sound.h | 17 +++++++++++++ engines/sherlock/talk.cpp | 12 ++++++++- engines/sherlock/talk.h | 2 +- engines/sherlock/tattoo/tattoo_talk.cpp | 8 +++++- 6 files changed, 69 insertions(+), 12 deletions(-) diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 206d7173ac9..8ec2c8c4401 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -116,6 +116,10 @@ Resources::Resources(SherlockEngine *vm) : _vm(vm), _cache(vm) { } void Resources::addToCache(const Common::String &filename) { + // Return immediately if the library has already been loaded + if (_indexes.contains(filename)) + return; + _cache.load(filename); // Check to see if the file is a library @@ -218,6 +222,10 @@ void Resources::loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream, bool isNewStyle) { uint32 offset, nextOffset; + // Return immediately if the library has already been loaded + if (_indexes.contains(libFilename)) + return; + // Create an index entry _indexes[libFilename] = LibraryIndex(); LibraryIndex &index = _indexes[libFilename]; diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index e63efeec244..ffc626c6f8d 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -57,6 +57,7 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _voices = 0; _diskSoundPlaying = false; _soundPlaying = false; + _speechPlaying = false; _soundIsOn = &_soundPlaying; _curPriority = 0; _digiBuf = nullptr; @@ -174,15 +175,6 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit free(data); -#if 0 - // Debug : used to dump files - Common::DumpFile outFile; - outFile.open(filename); - outFile.write(decoded, (size - 2) * 2); - outFile.flush(); - outFile.close(); -#endif - audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); } else { audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); @@ -270,5 +262,29 @@ void Sound::setVolume(int volume) { warning("TODO: setVolume - %d", volume); } +void Sound::playSpeech(const Common::String &name) { + Resources &res = *_vm->_res; + Scene &scene = *_vm->_scene; + stopSpeech(); + + Common::String libraryName = Common::String::format("speech%02d.lib", scene._currentScene); + res.addToCache(libraryName); + + // TODO: Doesn't seem to be WAV files. Need to find out what format it is.. + Common::SeekableReadStream *stream = res.load(name, libraryName); + Audio::AudioStream *audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); + _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume); + _speechPlaying = true; +} + +void Sound::stopSpeech() { + _mixer->stopHandle(_speechHandle); +} + +bool Sound::isSpeechPlaying() { + _speechOn = _mixer->isSoundHandleActive(_speechHandle); + return _speechPlaying; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index d757646770a..a52de1c3393 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -47,6 +47,7 @@ private: Audio::Mixer *_mixer; Audio::SoundHandle _scalpelEffectsHandle; Audio::SoundHandle _tattooEffectsHandle[MAX_MIXER_CHANNELS]; + Audio::SoundHandle _speechHandle; int _curPriority; byte decodeSample(byte sample, byte& reference, int16& scale); @@ -57,6 +58,7 @@ public: bool _speechOn; bool _diskSoundPlaying; bool _soundPlaying; + bool _speechPlaying; bool *_soundIsOn; byte *_digiBuf; int _soundVolume; @@ -101,6 +103,21 @@ public: Audio::SoundHandle getFreeSoundHandle(); void setVolume(int volume); + + /** + * Play a specified voice resource + */ + void playSpeech(const Common::String &name); + + /** + * Stop any currently playing speech + */ + void stopSpeech(); + + /** + * Returns true if speech is currently playing + */ + bool isSpeechPlaying(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 1b12c6afb43..a998c586058 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -571,6 +571,10 @@ void Talk::loadTalkFile(const Common::String &filename) { Common::String talkFile = chP ? Common::String(filename.c_str(), chP) + ".tlk" : Common::String(filename.c_str(), filename.c_str() + 7) + ".tlk"; + // Create the base of the sound filename used for talking in Rose Tattoo + if (IS_ROSE_TATTOO && _scriptMoreFlag != 1) + sound._talkSoundFile = filename + "."; + // Open the talk file for reading Common::SeekableReadStream *talkStream = res.load(talkFile); _converseNum = res.resourceIndex(); @@ -924,8 +928,13 @@ int Talk::waitForMore(int delay) { events.setCursor(ui._lookScriptFlag ? MAGNIFY : ARROW); } + if (sound._speechOn && !sound._talkSoundFile.empty()) { + sound.playSpeech(sound._talkSoundFile); + sound._talkSoundFile.setChar(sound._talkSoundFile.lastChar() + 1, sound._talkSoundFile.size() - 1); + } + do { - if (sound._speechOn && !*sound._soundIsOn) + if (IS_SERRATED_SCALPEL && sound._speechOn && !*sound._soundIsOn) people._portrait._frameNumber = -1; scene.doBgAnim(); @@ -992,6 +1001,7 @@ int Talk::waitForMore(int delay) { break; } + sound._speechOn = false; events.setCursor(_talkToAbort ? ARROW : oldCursor); events._pressed = events._released = false; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 767c7c803cf..87ed547be79 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -185,7 +185,6 @@ protected: Common::Stack _sequenceStack; Common::Stack _scriptStack; Common::Array _talkHistory; - int _speaker; int _talkIndex; int _scriptSelect; int _talkStealth; @@ -276,6 +275,7 @@ public: bool _moreTalkUp, _moreTalkDown; int _converseNum; const byte *_opcodes; + int _speaker; public: static Talk *init(SherlockEngine *vm); virtual ~Talk() {} diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp index ddd863fea40..d16e26fcea4 100644 --- a/engines/sherlock/tattoo/tattoo_talk.cpp +++ b/engines/sherlock/tattoo/tattoo_talk.cpp @@ -25,7 +25,7 @@ #include "sherlock/tattoo/tattoo_people.h" #include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_user_interface.h" -#include "sherlock/sherlock.h" +#include "sherlock/tattoo/tattoo.h" #include "sherlock/screen.h" namespace Sherlock { @@ -184,9 +184,15 @@ TattooTalk::TattooTalk(SherlockEngine *vm) : Talk(vm), _talkWidget(vm), _passwor } void TattooTalk::talkInterface(const byte *&str) { + TattooEngine &vm = *(TattooEngine *)_vm; + Sound &sound = *_vm->_sound; + Talk &talk = *_vm->_talk; TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; const byte *s = str; + if (!vm._textWindowsOn && sound._speechOn && talk._speaker != -1) + return; + // Move to past the end of the text string _charCount = 0; while ((*str < TATTOO_OPCODES[0] || *str == TATTOO_OPCODES[OP_NULL]) && *str) {