aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2008-05-24 22:47:08 +0000
committerJohannes Schickel2008-05-24 22:47:08 +0000
commit335eb1bf0853dbdede70fc4366fd1ff166715198 (patch)
tree40077f06fc91cef4b7937a1af17edfca1f981a87
parent6866a4e133f2ae505bc142bc4b35e79d48f5191a (diff)
downloadscummvm-rg350-335eb1bf0853dbdede70fc4366fd1ff166715198.tar.gz
scummvm-rg350-335eb1bf0853dbdede70fc4366fd1ff166715198.tar.bz2
scummvm-rg350-335eb1bf0853dbdede70fc4366fd1ff166715198.zip
Committed my fix for bug #1497437 "KYRA1: Subtitles glitch during 'Speech of the Land'".
svn-id: r32260
-rw-r--r--engines/kyra/kyra_lok.cpp1
-rw-r--r--engines/kyra/kyra_lok.h2
-rw-r--r--engines/kyra/script_lok.cpp68
-rw-r--r--engines/kyra/sound.cpp18
-rw-r--r--engines/kyra/sound.h13
-rw-r--r--engines/kyra/sound_lok.cpp2
-rw-r--r--engines/kyra/sound_towns.cpp6
-rw-r--r--engines/kyra/text.cpp2
-rw-r--r--engines/kyra/text_lok.cpp6
9 files changed, 97 insertions, 21 deletions
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index 0668cc7202..c852f6e3ee 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -91,6 +91,7 @@ KyraEngine_LoK::KyraEngine_LoK(OSystem *system, const GameFlags &flags)
memset(_panPagesTable, 0, sizeof(_panPagesTable));
memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable));
_currHeadShape = 0;
+ _speechPlayTime = 0;
memset(&_itemBkgBackUp, 0, sizeof(_itemBkgBackUp));
}
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index 6bae169a77..fa884750e5 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -211,6 +211,8 @@ public:
void snd_voiceWaitForFinish(bool ingame = true);
protected:
+ int32 _speechPlayTime;
+
void saveGame(const char *fileName, const char *saveName);
void loadGame(const char *fileName);
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 670c7282e3..d4825387d9 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -35,6 +35,7 @@
#include "kyra/animator_lok.h"
#include "kyra/text.h"
#include "kyra/timer.h"
+#include "kyra/sound.h"
namespace Kyra {
int KyraEngine_LoK::o1_magicInMouseItem(EMCState *script) {
@@ -320,9 +321,20 @@ int KyraEngine_LoK::o1_setBrandonStatusBit(EMCState *script) {
}
int KyraEngine_LoK::o1_delaySecs(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_delaySecs(%p) (%d)", (const void *)script, stackPos(0));
- if (stackPos(0) > 0 && !_skipFlag)
- delay(stackPos(0)*1000, true);
+ if (_flags.isTalkie && speechEnabled()) {
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_voiceDelay(%p) (%d)", (const void *)script, stackPos(0));
+ if (stackPos(0) == 0) {
+ snd_voiceWaitForFinish(true);
+ } else if (stackPos(0) < 0) {
+ uint32 time = ABS(stackPos(0)) * _tickLength;
+ delay(time, true);
+ }
+ } else {
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_delaySecs(%p) (%d)", (const void *)script, stackPos(0));
+ if (stackPos(0) >= 0 && !_skipFlag)
+ delay(stackPos(0)*1000, true);
+ }
+
_skipFlag = false;
return 0;
}
@@ -700,7 +712,10 @@ int KyraEngine_LoK::o1_displayWSAFrameOnHidPage(EMCState *script) {
}
int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6));
+ if (_flags.isTalkie)
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ else
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6));
int startFrame = stackPos(0);
int endFrame = stackPos(1);
int xpos = stackPos(2);
@@ -708,6 +723,43 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
int waitTime = stackPos(4);
int wsaIndex = stackPos(5);
int maxTime = stackPos(6);
+
+ if (_flags.isTalkie) {
+ int specialTime = stackPos(7);
+ if (specialTime) {
+ int32 voiceTime = _speechPlayTime;
+ if (voiceTime && voiceTime != -1) {
+ int displayFrames = ABS(endFrame-startFrame)+1;
+ displayFrames *= maxTime;
+ assert(displayFrames != 0);
+
+ bool voiceSync = false;
+
+ if (specialTime < 0) {
+ voiceSync = true;
+ specialTime = ABS(specialTime);
+ }
+
+ voiceTime *= specialTime;
+ voiceTime /= 100;
+
+ if (voiceSync) {
+ uint32 voicePlayedTime = _sound->voicePlayedTime(_speechFile.c_str());
+ if (voicePlayedTime >= (uint32)voiceTime)
+ voiceTime = 0;
+ else
+ voiceTime -= voicePlayedTime;
+
+ if (!snd_voiceIsPlaying())
+ voiceTime = 0;
+ }
+
+ waitTime = voiceTime / displayFrames;
+ waitTime /= _tickLength;
+ }
+ }
+ }
+
if (maxTime - 1 <= 0)
maxTime = 1;
@@ -734,7 +786,8 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
while (endFrame >= frame) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
_movieObjects[wsaIndex]->displayFrame(frame);
- _animator->_updateScreen = true;
+ if (waitTime)
+ _animator->_updateScreen = true;
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
_animator->updateAllObjectShapes();
@@ -751,7 +804,8 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
while (endFrame <= frame) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
_movieObjects[wsaIndex]->displayFrame(frame);
- _animator->_updateScreen = true;
+ if (waitTime)
+ _animator->_updateScreen = true;
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
_animator->updateAllObjectShapes();
@@ -1691,7 +1745,7 @@ int KyraEngine_LoK::o1_pauseMusicSeconds(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseMusicSeconds(%p) ()", (const void *)script);
// if music disabled
// return
- o1_delaySecs(script);
+ delay(stackPos(0)*1000, true);
return 0;
}
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 854e2de41f..137956196f 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -66,14 +66,14 @@ bool Sound::voiceFileIsPresent(const char *file) {
return false;
}
-bool Sound::voicePlay(const char *file, bool isSfx) {
+int32 Sound::voicePlay(const char *file, bool isSfx) {
char filenamebuffer[25];
int h = 0;
while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)
h++;
if (h >= kNumChannelHandles)
- return false;
+ return 0;
Audio::AudioStream *audioStream = 0;
@@ -107,7 +107,7 @@ bool Sound::voicePlay(const char *file, bool isSfx) {
_soundChannels[h].file = file;
_mixer->playInputStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, audioStream);
- return true;
+ return audioStream->getTotalPlayTime();
}
void Sound::voiceStop(const char *file) {
@@ -140,6 +140,18 @@ bool Sound::voiceIsPlaying(const char *file) {
return res;
}
+uint32 Sound::voicePlayedTime(const char *file) {
+ if (!file)
+ return 0;
+
+ for (int i = 0; i < kNumChannelHandles; ++i) {
+ if (_soundChannels[i].file == file)
+ return _mixer->getSoundElapsedTime(_soundChannels[i].channelHandle);
+ }
+
+ return 0;
+}
+
#pragma mark -
SoundMidiPC::SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver) : Sound(vm, mixer) {
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index 595619c7e9..2427a6cdde 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -174,9 +174,9 @@ public:
*
* @param file file to be played
* @param isSfx marks file as sfx instead of voice
- * @return channel the voice file is played on
+ * @return playtime of the voice file (-1 marks unknown playtime)
*/
- virtual bool voicePlay(const char *file, bool isSfx = false);
+ virtual int32 voicePlay(const char *file, bool isSfx = false);
/**
* Checks if a voice is being played.
@@ -186,6 +186,13 @@ public:
bool voiceIsPlaying(const char *file = 0);
/**
+ * Checks how long a voice has been playing
+ *
+ * @return time in milliseconds
+ */
+ uint32 voicePlayedTime(const char *file);
+
+ /**
* Stops playback of the current voice.
*/
void voiceStop(const char *file = 0);
@@ -449,7 +456,7 @@ public:
void haltTrack();
void beginFadeOut();
- bool voicePlay(const char *file, bool isSfx = false);
+ int32 voicePlay(const char *file, bool isSfx = false);
void playSoundEffect(uint8) {}
private:
diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp
index 728013cdaa..b12b1fa800 100644
--- a/engines/kyra/sound_lok.cpp
+++ b/engines/kyra/sound_lok.cpp
@@ -67,7 +67,7 @@ void KyraEngine_LoK::snd_playVoiceFile(int id) {
assert(id >= 0 && id < 9999);
sprintf(vocFile, "%03d", id);
_speechFile = vocFile;
- _sound->voicePlay(vocFile);
+ _speechPlayTime = _sound->voicePlay(vocFile);
}
void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) {
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index 5a1801b803..4265533507 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1432,7 +1432,7 @@ void SoundTowns_v2::haltTrack() {
//_driver->reset();
}
-bool SoundTowns_v2::voicePlay(const char *file, bool) {
+int32 SoundTowns_v2::voicePlay(const char *file, bool) {
static const uint16 rates[] = { 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 };
int h = 0;
@@ -1440,7 +1440,7 @@ bool SoundTowns_v2::voicePlay(const char *file, bool) {
while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)
h++;
if (h >= kNumChannelHandles)
- return false;
+ return 0;
}
char filename [13];
@@ -1497,7 +1497,7 @@ bool SoundTowns_v2::voicePlay(const char *file, bool) {
_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundChannels[h].channelHandle, _currentSFX);
delete[] data;
- return true;
+ return 1;
}
void SoundTowns_v2::beginFadeOut() {
diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp
index 931c5fe1c9..f8eb10a85e 100644
--- a/engines/kyra/text.cpp
+++ b/engines/kyra/text.cpp
@@ -210,7 +210,7 @@ void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 c
calcWidestLineBounds(x1, x2, w, x);
_talkCoords.x = x1;
_talkCoords.w = w + 2;
- _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK);
int curPage = _screen->_curPage;
_screen->_curPage = srcPage;
for (int i = 0; i < lineCount; ++i) {
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index ccca079e32..f6b0407a75 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -62,10 +62,8 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const
if (chatDuration != -1)
chatDuration *= _tickLength;
- if (vocFile != -1) {
- snd_voiceWaitForFinish();
+ if (vocFile != -1)
snd_playVoiceFile(vocFile);
- }
_timer->disable(14);
_timer->disable(18);
@@ -269,6 +267,8 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
if (_currentCharacter->sceneId == 210)
return;
+ snd_voiceWaitForFinish(true);
+
convoInitialized = initCharacterChat(charNum);
chatPartnerNum = getChatPartnerNum();