SHERLOCK: RT: Beginnings of speech code

This commit is contained in:
Paul Gilbert 2015-08-10 22:01:02 -04:00
parent 60759cfb5d
commit 9b0bf9e215
6 changed files with 69 additions and 12 deletions

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -185,7 +185,6 @@ protected:
Common::Stack<SequenceEntry> _sequenceStack;
Common::Stack<ScriptStackEntry> _scriptStack;
Common::Array<TalkHistoryEntry> _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() {}

View File

@ -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) {