From f2a25013f1862980107643b2c3d359a817d16e82 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sun, 7 Jun 2015 19:19:04 +0200 Subject: SHERLOCK: 3DO intro: audio implemented --- engines/sherlock/animation.cpp | 46 +++++++++------- engines/sherlock/animation.h | 7 +-- engines/sherlock/scalpel/scalpel.cpp | 69 ++++++++++++------------ engines/sherlock/scalpel/scalpel_talk.cpp | 2 +- engines/sherlock/sound.cpp | 87 ++++++++++++++++--------------- 5 files changed, 114 insertions(+), 97 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index a069abef6f..3bd3137982 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -31,7 +31,7 @@ static const int NO_FRAMES = FRAMES_END; Animation::Animation(SherlockEngine *vm) : _vm(vm) { } -bool Animation::play(const Common::String &filename, int minDelay, int fade, +bool Animation::play(const Common::String &filename, bool intro, int minDelay, int fade, bool setPalette, int speed) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; @@ -39,7 +39,7 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, int soundNumber = 0; // Check for any any sound frames for the given animation - const int *soundFrames = checkForSoundFrames(filename); + const int *soundFrames = checkForSoundFrames(filename, intro); // Add on the VDX extension Common::String vdxName = filename + ".vdx"; @@ -102,12 +102,19 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, if (frameNumber++ == *soundFrames) { ++soundNumber; ++soundFrames; - Common::String fname = _soundLibraryFilename.empty() ? - Common::String::format("%s%01d", filename.c_str(), soundNumber) : - Common::String::format("%s%02d", filename.c_str(), soundNumber); + + Common::String sampleFilename; + + if (!intro) { + // regular animation, append 1-digit number + sampleFilename = Common::String::format("%s%01d", filename.c_str(), soundNumber); + } else { + // intro animation, append 2-digit number + sampleFilename = Common::String::format("%s%02d", filename.c_str(), soundNumber); + } if (sound._voices) - sound.playSound(fname, WAIT_RETURN_IMMEDIATELY, 100, _soundLibraryFilename.c_str()); + sound.playSound(sampleFilename, WAIT_RETURN_IMMEDIATELY, 100, _soundLibraryFilename.c_str()); } events.wait(speed * 3); @@ -133,15 +140,15 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade, return !skipped && !_vm->shouldQuit(); } -bool Animation::play3DO(const Common::String &filename, int minDelay, int fade, +bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay, int fade, int speed) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; - //int soundNumber = 0; + int soundNumber = 0; // Check for any any sound frames for the given animation - //const int *soundFrames = checkForSoundFrames(filename); + const int *soundFrames = checkForSoundFrames(filename, intro); // Add on the VDX extension Common::String indexName = "prologue/" + filename + ".3dx"; @@ -167,7 +174,7 @@ bool Animation::play3DO(const Common::String &filename, int minDelay, int fade, // screen.setPalette(images._palette); // } - //int frameNumber = 0; + int frameNumber = 0; Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { @@ -200,20 +207,21 @@ bool Animation::play3DO(const Common::String &filename, int minDelay, int fade, // if (screen.equalizePalette(images._palette) == 0) // fade = 0; //} +#endif // Check if we've reached a frame with sound if (frameNumber++ == *soundFrames) { ++soundNumber; ++soundFrames; - Common::String fname = _soundLibraryFilename.empty() ? - Common::String::format("%s%01d", filename.c_str(), soundNumber) : - Common::String::format("%s%02d", filename.c_str(), soundNumber); + + Common::String sampleFilename; + + // append 1-digit number + sampleFilename = Common::String::format("prologue/sounds/%s%01d", filename.c_str(), soundNumber); if (sound._voices) - sound.playSound(fname, WAIT_RETURN_IMMEDIATELY, 100, _soundLibraryFilename.c_str()); + sound.playSound(sampleFilename, WAIT_RETURN_IMMEDIATELY, 100); // no sound library } -#endif - events.wait(speed * 3); } @@ -267,10 +275,11 @@ void Animation::setTitleFrames(const int *frames, int count, int maxFrames) { } } -const int *Animation::checkForSoundFrames(const Common::String &filename) { +const int *Animation::checkForSoundFrames(const Common::String &filename, bool intro) { const int *frames = &NO_FRAMES; - if (_soundLibraryFilename.empty()) { + if (!intro) { + // regular animation is playing for (uint idx = 0; idx < _prologueNames.size(); ++idx) { if (filename.equalsIgnoreCase(_prologueNames[idx])) { frames = &_prologueFrames[idx][0]; @@ -278,6 +287,7 @@ const int *Animation::checkForSoundFrames(const Common::String &filename) { } } } else { + // intro-animation is playing for (uint idx = 0; idx < _titleNames.size(); ++idx) { if (filename.equalsIgnoreCase(_titleNames[idx])) { frames = &_titleFrames[idx][0]; diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index 1755edd97b..b6e1337975 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -45,10 +45,11 @@ private: /** * Checks for whether an animation is being played that has associated sound */ - const int *checkForSoundFrames(const Common::String &filename); + const int *checkForSoundFrames(const Common::String &filename, bool intro); public: Common::String _soundLibraryFilename; Common::String _gfxLibraryFilename; + public: Animation(SherlockEngine *vm); @@ -75,9 +76,9 @@ public: /** * Play a full-screen animation */ - bool play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed); + bool play(const Common::String &filename, bool intro, int minDelay, int fade, bool setPalette, int speed); - bool play3DO(const Common::String &filename, int minDelay, int fade, int speed); + bool play3DO(const Common::String &filename, bool intro, int minDelay, int fade, int speed); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index e7d8ef18c3..c349ec9e9b 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -277,7 +277,7 @@ bool ScalpelEngine::showCityCutscene() { _music->playMusic("prolog1.mus"); _animation->_gfxLibraryFilename = "title.lib"; _animation->_soundLibraryFilename = "title.snd"; - bool finished = _animation->play("26open1", 1, 255, true, 2); + bool finished = _animation->play("26open1", true, 1, 255, true, 2); if (finished) { ImageFile titleImages("title2.vgs", true); @@ -302,7 +302,7 @@ bool ScalpelEngine::showCityCutscene() { } if (finished) - finished = _animation->play("26open2", 1, 0, false, 2); + finished = _animation->play("26open2", true, 1, 0, false, 2); if (finished) { ImageFile titleImages("title.vgs", true); @@ -355,7 +355,7 @@ bool ScalpelEngine::showAlleyCutscene() { // Fade "In The Alley..." text to black _screen->fadeToBlack(2); - bool finished = _animation->play("27PRO1", 1, 3, true, 2); + bool finished = _animation->play("27PRO1", true, 1, 3, true, 2); if (finished) { _screen->getPalette(palette); _screen->fadeToBlack(2); @@ -366,7 +366,7 @@ bool ScalpelEngine::showAlleyCutscene() { if (finished) { _screen->setPalette(palette); - finished = _animation->play("27PRO2", 1, 0, false, 2); + finished = _animation->play("27PRO2", true, 1, 0, false, 2); } if (finished) { @@ -385,7 +385,7 @@ bool ScalpelEngine::showAlleyCutscene() { } if (finished) - finished = _animation->play("27PRO3", 1, 0, true, 2); + finished = _animation->play("27PRO3", true, 1, 0, true, 2); if (finished) { _screen->getPalette(palette); @@ -427,12 +427,12 @@ bool ScalpelEngine::showStreetCutscene() { } if (finished) - finished = _animation->play("14KICK", 1, 3, true, 2); + finished = _animation->play("14KICK", true, 1, 3, true, 2); // Constable animation plays slower than speed 2 // If we play it with speed 2, music gets obviously out of sync if (finished) - finished = _animation->play("14NOTE", 1, 0, false, 3); + finished = _animation->play("14NOTE", true, 1, 0, false, 3); // Fade to black if (finished) @@ -484,9 +484,9 @@ bool ScalpelEngine::showOfficeCutscene() { _animation->_gfxLibraryFilename = "TITLE2.LIB"; _animation->_soundLibraryFilename = "TITLE.SND"; - bool finished = _animation->play("COFF1", 1, 3, true, 3); + bool finished = _animation->play("COFF1", true, 1, 3, true, 3); if (finished) - finished = _animation->play("COFF2", 1, 0, false, 3); + finished = _animation->play("COFF2", true, 1, 0, false, 3); if (finished) { showLBV("note.lbv"); @@ -508,10 +508,10 @@ bool ScalpelEngine::showOfficeCutscene() { } if (finished) - finished = _animation->play("COFF3", 1, 0, true, 3); + finished = _animation->play("COFF3", true, 1, 0, true, 3); if (finished) - finished = _animation->play("COFF4", 1, 0, false, 3); + finished = _animation->play("COFF4", true, 1, 0, false, 3); if (finished) finished = scrollCredits(); @@ -526,47 +526,48 @@ bool ScalpelEngine::showOfficeCutscene() { // 3DO variant bool ScalpelEngine::showCityCutscene3DO() { + _animation->_soundLibraryFilename = "TITLE.SND"; - bool finished = _animation->play3DO("26open1", 1, 255, 2); + bool finished = _animation->play3DO("26open1", true, 1, 255, 2); if (finished) - finished = _animation->play3DO("26open2", 1, 0, 2); + finished = _animation->play3DO("26open2", true, 1, 0, 2); return finished; } bool ScalpelEngine::showAlleyCutscene3DO() { - bool finished = _animation->play3DO("27PRO1", 1, 3, 2); + bool finished = _animation->play3DO("27PRO1", true, 1, 3, 2); if (finished) - finished = _animation->play3DO("27PRO2", 1, 0, 2); + finished = _animation->play3DO("27PRO2", true, 1, 0, 2); if (finished) - finished = _animation->play3DO("27PRO3", 1, 0, 2); + finished = _animation->play3DO("27PRO3", true, 1, 0, 2); return finished; } bool ScalpelEngine::showStreetCutscene3DO() { - bool finished = _animation->play3DO("14KICK", 1, 3, 2); + bool finished = _animation->play3DO("14KICK", true, 1, 3, 2); if (finished) - finished = _animation->play3DO("14NOTE", 1, 0, 3); + finished = _animation->play3DO("14NOTE", true, 1, 0, 3); return finished; } bool ScalpelEngine::showOfficeCutscene3DO() { - bool finished = _animation->play3DO("COFF1", 1, 3, 3); + bool finished = _animation->play3DO("COFF1", true, 1, 3, 3); if (finished) - finished = _animation->play3DO("COFF2", 1, 0, 3); + finished = _animation->play3DO("COFF2", true, 1, 0, 3); if (finished) - finished = _animation->play3DO("COFF3", 1, 0, 3); + finished = _animation->play3DO("COFF3", true, 1, 0, 3); if (finished) - finished = _animation->play3DO("COFF4", 1, 0, 3); + finished = _animation->play3DO("COFF4", true, 1, 0, 3); return finished; } @@ -634,8 +635,8 @@ void ScalpelEngine::startScene() { // Blackwood's capture _res->addToCache("final2.vda", "epilogue.lib"); _res->addToCache("final2.vdx", "epilogue.lib"); - _animation->play("final1", 1, 3, true, 4); - _animation->play("final2", 1, 0, false, 4); + _animation->play("final1", false, 1, 3, true, 4); + _animation->play("final2", false, 1, 0, false, 4); break; case RESCUE_ANNA: @@ -651,8 +652,8 @@ void ScalpelEngine::startScene() { _res->addToCache("finale4.vda", "EPILOG2.lib"); _res->addToCache("finale4.vdx", "EPILOG2.lib"); - _animation->play("finalr1", 1, 3, true, 4); - _animation->play("finalr2", 1, 0, false, 4); + _animation->play("finalr1", false, 1, 3, true, 4); + _animation->play("finalr2", false, 1, 0, false, 4); if (!_res->isInCache("finale2.vda")) { // Finale file isn't cached @@ -664,12 +665,12 @@ void ScalpelEngine::startScene() { _res->addToCache("finale4.vdx", "EPILOG2.lib"); } - _animation->play("finale1", 1, 0, false, 4); - _animation->play("finale2", 1, 0, false, 4); - _animation->play("finale3", 1, 0, false, 4); + _animation->play("finale1", false, 1, 0, false, 4); + _animation->play("finale2", false, 1, 0, false, 4); + _animation->play("finale3", false, 1, 0, false, 4); _useEpilogue2 = true; - _animation->play("finale4", 1, 0, false, 4); + _animation->play("finale4", false, 1, 0, false, 4); _useEpilogue2 = false; break; @@ -680,9 +681,9 @@ void ScalpelEngine::startScene() { _res->addToCache("SUBWAY3.vda", "epilogue.lib"); _res->addToCache("SUBWAY3.vdx", "epilogue.lib"); - _animation->play("SUBWAY1", 1, 3, true, 4); - _animation->play("SUBWAY2", 1, 0, false, 4); - _animation->play("SUBWAY3", 1, 0, false, 4); + _animation->play("SUBWAY1", false, 1, 3, true, 4); + _animation->play("SUBWAY2", false, 1, 0, false, 4); + _animation->play("SUBWAY3", false, 1, 0, false, 4); // Set fading to direct fade temporary so the transition goes quickly. _scene->_tempFadeStyle = _screen->_fadeStyle ? 257 : 256; @@ -691,7 +692,7 @@ void ScalpelEngine::startScene() { case BRUMWELL_SUICIDE: // Brumwell suicide - _animation->play("suicid", 1, 3, true, 4); + _animation->play("suicid", false, 1, 3, true, 4); break; default: break; diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp index 89efc70803..b3ac27c137 100644 --- a/engines/sherlock/scalpel/scalpel_talk.cpp +++ b/engines/sherlock/scalpel/scalpel_talk.cpp @@ -397,7 +397,7 @@ OpcodeReturn ScalpelTalk::cmdPlayPrologue(const byte *&str) { for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx) tempString += str[idx]; - anim.play(tempString, 1, 3, true, 4); + anim.play(tempString, false, 1, 3, true, 4); return RET_SUCCESS; } diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index d4edc3095a..bc5f87b48c 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -27,6 +27,7 @@ #include "common/algorithm.h" #include "audio/mixer.h" #include "audio/decoders/raw.h" +#include "audio/decoders/aiff.h" #include "audio/decoders/wave.h" namespace Sherlock { @@ -66,10 +67,7 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _speechOn = true; if (_vm->getPlatform() == Common::kPlatform3DO) { - // 3DO: disable sound for now - // TODO - _soundOn = false; - _speechOn = false; + // 3DO: we don't need to prepare anything for sound return; } @@ -130,58 +128,65 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit Common::String filename = name; if (!filename.contains('.')) { - if (IS_SERRATED_SCALPEL) { - filename += ".SND"; + if (_vm->getPlatform() != Common::kPlatform3DO) { + if (IS_SERRATED_SCALPEL) { + filename += ".SND"; + } else { + filename += ".WAV"; + } } else { - filename += ".WAV"; + // 3DO uses .aiff extension + filename += ".AIFF"; } } Common::String libFilename(libraryFilename); Common::SeekableReadStream *stream = libFilename.empty() ? res.load(filename) : res.load(filename, libFilename); - if (!stream) - error("Unable to find sound file '%s'", filename.c_str()); - Audio::AudioStream *audioStream; - if (IS_SERRATED_SCALPEL) { - stream->skip(2); - int size = stream->readUint32BE(); - int rate = stream->readUint16BE(); - byte *data = (byte *)malloc(size); - byte *ptr = data; - stream->read(ptr, size); - delete stream; - - assert(size > 2); - - byte *decoded = (byte *)malloc((size - 1) * 2); - - // Holmes uses Creative ADPCM 4-bit data - int counter = 0; - byte reference = ptr[0]; - int16 scale = 0; - - for(int i = 1; i < size; i++) { - decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, reference, scale); - decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, reference, scale); - } + if (_vm->getPlatform() != Common::kPlatform3DO) { + if (IS_SERRATED_SCALPEL) { + stream->skip(2); + int size = stream->readUint32BE(); + int rate = stream->readUint16BE(); + byte *data = (byte *)malloc(size); + byte *ptr = data; + stream->read(ptr, size); + delete stream; + + assert(size > 2); + + byte *decoded = (byte *)malloc((size - 1) * 2); + + // Holmes uses Creative ADPCM 4-bit data + int counter = 0; + byte reference = ptr[0]; + int16 scale = 0; + + for(int i = 1; i < size; i++) { + decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, reference, scale); + decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, reference, scale); + } - free(data); + 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(); + // 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); + audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); + } else { + audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); + } } else { - audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); + // 3DO: AIFF file + audioStream = Audio::makeAIFFStream(stream, DisposeAfterUse::YES); } _mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume); -- cgit v1.2.3