mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 20:59:00 +00:00
SHERLOCK: 3DO intro: audio implemented
This commit is contained in:
parent
a07cfe1eb0
commit
f2a25013f1
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
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);
|
||||
assert(size > 2);
|
||||
|
||||
byte *decoded = (byte *)malloc((size - 1) * 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;
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user