diff options
-rw-r--r-- | engines/kyra/kyra_v3.cpp | 38 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.h | 51 | ||||
-rw-r--r-- | engines/kyra/scene_v3.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/script_v3.cpp | 92 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 8 | ||||
-rw-r--r-- | engines/kyra/text_v3.cpp | 212 |
6 files changed, 381 insertions, 22 deletions
diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index aafe6fb14e..58c2a66df3 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -112,6 +112,14 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _moveFacingTable = 0; _unkHandleSceneChangeFlag = false; memset(_sceneShapeDescs, 0, sizeof(_sceneShapeDescs)); + _cnvFile = _dlgBuffer = 0; + _curDlgChapter = _curDlgIndex = _curDlgLang = -1; + _isStartupDialog = 0; + _stringBuffer = 0; + _dialogSceneAnim = _dialogSceneScript = -1; + memset(&_dialogScriptData, 0, sizeof(_dialogScriptData)); + memset(&_dialogScriptState, 0, sizeof(_dialogScriptState)); + _dialogScriptFuncStart = _dialogScriptFuncProc = _dialogScriptFuncEnd = 0; } KyraEngine_v3::~KyraEngine_v3() { @@ -160,6 +168,14 @@ KyraEngine_v3::~KyraEngine_v3() { for (Common::Array<const Opcode*>::iterator i = _opcodesTemporary.begin(); i != _opcodesTemporary.end(); ++i) delete *i; _opcodesTemporary.clear(); + + for (Common::Array<const Opcode*>::iterator i = _opcodesDialog.begin(); i != _opcodesDialog.end(); ++i) + delete *i; + _opcodesDialog.clear(); + + delete _cnvFile; + delete _dlgBuffer; + delete [] _stringBuffer; } int KyraEngine_v3::init() { @@ -500,6 +516,7 @@ void KyraEngine_v3::startup() { _screen->setFont(Screen::FID_6_FNT); + _stringBuffer = new char[500]; //XXX musicUpdate(0); _moveFacingTable = new int[600]; @@ -1050,7 +1067,9 @@ void KyraEngine_v3::handleInput(int x, int y) { } else if (_itemInHand >= 0 && _unk3 >= 0) { //XXX return; - } else if (_unk3 != -3) { + } else if (_unk3 == -3) { + return; + } else { if (y > 187 && _unk3 > -4) return; if (_unk5) { @@ -1487,6 +1506,23 @@ uint8 *KyraEngine_v3::getTableEntry(uint8 *buffer, int id) { return buffer + READ_LE_UINT16(offsetTable + num); } +void KyraEngine_v3::getTableEntry(Common::SeekableReadStream *stream, int id, char *dst) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::getTableEntry(%p, %d, %p)", (const void*)stream, id, (const void*)dst); + stream->seek(0, SEEK_SET); + uint16 tableEntries = stream->readUint16LE(); + + int num = 0; + while (id != stream->readUint16LE()) + ++num; + + stream->seek(2+tableEntries*2+num*2, SEEK_SET); + stream->seek(stream->readUint16LE(), SEEK_SET); + char c = 0; + while ((c = stream->readByte()) != 0) + *dst++ = c; + *dst = 0; +} + #pragma mark - Movie *KyraEngine_v3::createWSAMovie() { diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index 1e08016a2a..facab63a20 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -256,6 +256,7 @@ private: uint8 *_sceneStrings; uint8 *getTableEntry(uint8 *buffer, int id); + void getTableEntry(Common::SeekableReadStream *stream, int id, char *dst); // items int8 *_itemBuffer1; @@ -384,6 +385,7 @@ private: WSAMovieV2 *_wsaSlots[10]; bool _specialSceneScriptState[10]; + bool _specialSceneScriptStateBackup[10]; ScriptState _sceneSpecialScripts[10]; uint32 _sceneSpecialScriptsTimer[10]; int _lastProcessedSceneScript; @@ -455,8 +457,8 @@ private: // talk object struct TalkObject { char filename[13]; - int8 unkD; - int8 unkE; + int8 sceneAnim; + int8 sceneScript; int16 x, y; uint8 color; int8 unk14; @@ -487,6 +489,39 @@ private: void badConscienceChat(const char *str, int vocHigh, int vocLow); void badConscienceChatWaitToFinish(); + void malcolmSceneStartupChat(); + + bool _newSceneDlgState[40]; + int8 _conversationState[30][30]; + bool _chatAltFlag; + void setDlgIndex(uint16 index); + + Common::SeekableReadStream *_cnvFile; + Common::SeekableReadStream *_dlgBuffer; + int _curDlgChapter, _curDlgIndex, _curDlgLang; + void updateDlgBuffer(); + void loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2); + + static const uint8 _vocHighTable[]; + bool _isStartupDialog; + void processDialog(int vocHighIndex, int vocHighBase, int funcNum); + + ScriptData _dialogScriptData; + ScriptState _dialogScriptState; + int _dialogSceneAnim; + int _dialogSceneScript; + int _dialogScriptFuncStart, _dialogScriptFuncProc, _dialogScriptFuncEnd; + + void dialogStartScript(int object, int funcNum); + void dialogEndScript(int object); + + void npcChatSequence(const char *str, int object, int vocHigh, int vocLow); + + Common::Array<const Opcode *> _opcodesDialog; + + int o3d_updateAnim(ScriptState *script); + int o3d_delay(ScriptState *script); + // conscience bool _badConscienceShown; int _badConscienceAnim; @@ -505,8 +540,6 @@ private: int o3t_defineNewShapes(ScriptState *script); int o3t_setCurrentFrame(ScriptState *script); - int o3t_playSoundEffect(ScriptState *script); - int o3t_getMalcolmShapes(ScriptState *script); // special shape code char _newShapeFilename[13]; @@ -524,6 +557,8 @@ private: bool _useActorBuffer; int _curChapter; + static const uint8 _chapterLowestScene[]; + int _unk3, _unk4, _unk5; void loadCostPal(); @@ -534,6 +569,8 @@ private: void backUpGfxRect32x32(int x, int y); void restoreGfxRect32x32(int x, int y); + char *_stringBuffer; + // opcodes int o3_getMalcolmShapes(ScriptState *script); int o3_setCharacterPos(ScriptState *script); @@ -550,6 +587,7 @@ private: int o3_objectChat(ScriptState *script); int o3_checkForItem(ScriptState *script); int o3_defineItem(ScriptState *script); + int o3_npcChatSequence(ScriptState *script); int o3_queryGameFlag(ScriptState *script); int o3_resetGameFlag(ScriptState *script); int o3_setGameFlag(ScriptState *script); @@ -566,6 +604,7 @@ private: int o3_setSceneFilename(ScriptState *script); int o3_drawSceneShape(ScriptState *script); int o3_checkInRect(ScriptState *script); + int o3_setSceneDim(ScriptState *script); int o3_update(ScriptState *script); int o3_enterNewScene(ScriptState *script); int o3_setMalcolmPos(ScriptState *script); @@ -578,8 +617,12 @@ private: int o3_defineSceneAnim(ScriptState *script); int o3_updateSceneAnim(ScriptState *script); int o3_runActorScript(ScriptState *script); + int o3_setDlgIndex(ScriptState *script); + int o3_getDlgIndex(ScriptState *script); int o3_defineScene(ScriptState *script); int o3_countItemInstances(ScriptState *script); + int o3_dialogStartScript(ScriptState *script); + int o3_dialogEndScript(ScriptState *script); int o3_setSpecialSceneScriptState(ScriptState *script); int o3_clearSpecialSceneScriptState(ScriptState *script); int o3_querySpecialSceneScriptState(ScriptState *script); diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp index 74beb6ba30..f54706618e 100644 --- a/engines/kyra/scene_v3.cpp +++ b/engines/kyra/scene_v3.cpp @@ -283,7 +283,7 @@ void KyraEngine_v3::enterNewSceneUnk2(int unk1) { if (!unk1) { runSceneScript4(0); - //malcolmSceneStartupChat(); + malcolmSceneStartupChat(); } _unk4 = 0; diff --git a/engines/kyra/script_v3.cpp b/engines/kyra/script_v3.cpp index 3c27152bcf..19ff1c1a8f 100644 --- a/engines/kyra/script_v3.cpp +++ b/engines/kyra/script_v3.cpp @@ -58,8 +58,8 @@ int KyraEngine_v3::o3_defineObject(ScriptState *script) { stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); TalkObject &obj = _talkObjectList[stackPos(0)]; strcpy(obj.filename, stackPosString(1)); - obj.unkD = stackPos(2); - obj.unkE = stackPos(3); + obj.sceneAnim = stackPos(2); + obj.sceneScript = stackPos(3); obj.x = stackPos(4); obj.y = stackPos(5); obj.color = stackPos(6); @@ -173,6 +173,15 @@ int KyraEngine_v3::o3_defineItem(ScriptState *script) { return freeItem; } +int KyraEngine_v3::o3_npcChatSequence(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_npcChatSequence(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + const int id = stackPos(0); + const char *str = (const char*)getTableEntry(_sceneStrings, id); + if (str) + npcChatSequence(str, stackPos(1), _vocHigh, id); + return 0; +} + int KyraEngine_v3::o3_queryGameFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0)); return queryGameFlag(stackPos(0)); @@ -328,6 +337,13 @@ int KyraEngine_v3::o3_checkInRect(ScriptState *script) { } } +int KyraEngine_v3::o3_setSceneDim(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSceneDim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + _sceneMinX = stackPos(0); + _sceneMaxX = stackPos(1); + return 0; +} + int KyraEngine_v3::o3_update(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_update(%p) (%d)", (const void *)script, stackPos(0)); for (int times = stackPos(0); times != 0; --times) { @@ -528,6 +544,17 @@ int KyraEngine_v3::o3_runActorScript(ScriptState *script) { return 0; } +int KyraEngine_v3::o3_setDlgIndex(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); + setDlgIndex(stackPos(0)); + return 0; +} + +int KyraEngine_v3::o3_getDlgIndex(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getDlgIndex(%p) ()", (const void *)script); + return _mainCharacter.dlgIndex; +} + int KyraEngine_v3::o3_defineScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); @@ -575,6 +602,18 @@ int KyraEngine_v3::o3_countItemInstances(ScriptState *script) { return count; } +int KyraEngine_v3::o3_dialogStartScript(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dialogStartScript(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + dialogStartScript(stackPos(0), stackPos(1)); + return 0; +} + +int KyraEngine_v3::o3_dialogEndScript(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_dialogEndScript(%p) (%d)", (const void *)script, stackPos(0)); + dialogEndScript(stackPos(0)); + return 0; +} + int KyraEngine_v3::o3_setSpecialSceneScriptState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0)); _specialSceneScriptState[stackPos(0)] = 1; @@ -663,17 +702,30 @@ int KyraEngine_v3::o3t_setCurrentFrame(ScriptState *script) { return 0; } -int KyraEngine_v3::o3t_playSoundEffect(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3t_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); - playSoundEffect(stackPos(0), 200); +#pragma mark - + +int KyraEngine_v3::o3d_updateAnim(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3d_updateAnim(%p) (%d)", (const void *)script, stackPos(0)); + if (_dialogSceneAnim >= 0) + updateSceneAnim(_dialogSceneAnim, stackPos(0)); return 0; } -int KyraEngine_v3::o3t_getMalcolmShapes(ScriptState *script) { - debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3t_getMalcolmShapes(%p) ()", (const void *)script); - return _malcolmShapes; +int KyraEngine_v3::o3d_delay(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3d_delay(%p) (%d)", (const void *)script, stackPos(0)); + const uint32 endTime = _system->getMillis() + stackPos(0) * _tickLength; + while (_system->getMillis() < endTime) { + if (_chatText) + updateWithText(); + else + update(); + _system->delayMillis(10); + } + return 0; } +#pragma mark - + typedef Common::Functor1Mem<ScriptState*, int, KyraEngine_v3> OpcodeV3; #define SetOpcodeTable(x) table = &x; #define Opcode(x) table->push_back(new OpcodeV3(this, &KyraEngine_v3::x)) @@ -730,7 +782,7 @@ void KyraEngine_v3::setupOpcodeTable() { // 0x24 OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(o3_npcChatSequence); Opcode(o3_queryGameFlag); // 0x28 Opcode(o3_resetGameFlag); @@ -769,7 +821,7 @@ void KyraEngine_v3::setupOpcodeTable() { Opcode(o3_dummy); // 0x44 Opcode(o3_dummy); - OpcodeUnImpl(); + Opcode(o3_setSceneDim); OpcodeUnImpl(); Opcode(o3_dummy); // 0x48 @@ -831,9 +883,9 @@ void KyraEngine_v3::setupOpcodeTable() { Opcode(o3_runActorScript); OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(o3_setDlgIndex); // 0x78 - OpcodeUnImpl(); + Opcode(o3_getDlgIndex); Opcode(o3_defineScene); OpcodeUnImpl(); OpcodeUnImpl(); @@ -855,10 +907,10 @@ void KyraEngine_v3::setupOpcodeTable() { // 0x88 Opcode(o3_countItemInstances); Opcode(o3_dummy); - OpcodeUnImpl(); + Opcode(o3_dialogStartScript); Opcode(o3_dummy); // 0x8c - OpcodeUnImpl(); + Opcode(o3_dialogEndScript); Opcode(o3_dummy); Opcode(o3_dummy); Opcode(o3_setSpecialSceneScriptState); @@ -907,11 +959,21 @@ void KyraEngine_v3::setupOpcodeTable() { // 0x00 Opcode(o3t_defineNewShapes); Opcode(o3t_setCurrentFrame); - Opcode(o3t_playSoundEffect); + Opcode(o3_playSoundEffect); Opcode(o3_dummy); // 0x0a OpcodeUnImpl(); Opcode(o3_getRand); + Opcode(o3_getMalcolmShapes); + Opcode(o3_dummy); + + SetOpcodeTable(_opcodesDialog); + // 0x00 + Opcode(o3d_updateAnim); + Opcode(o3d_delay); + Opcode(o3_getRand); + Opcode(o3_queryGameFlag); + // 0x04 Opcode(o3_dummy); } diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 94bc285302..ba0178e2c6 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -2318,6 +2318,14 @@ const uint8 KyraEngine_v3::_badConscienceFrameTable[] = { 0x24, 0x24, 0x24, 0x24, 0x24, 0x1D, 0x1D, 0x1D }; +const uint8 KyraEngine_v3::_chapterLowestScene[] = { + 0x00, 0x00, 0x19, 0x2B, 0x33, 0x3B +}; + +const uint8 KyraEngine_v3::_vocHighTable[] = { + 0x64, 0x76, 0x82, 0x83, 0x92 +}; + } // End of namespace Kyra diff --git a/engines/kyra/text_v3.cpp b/engines/kyra/text_v3.cpp index 0c252397d2..21f3e5fbca 100644 --- a/engines/kyra/text_v3.cpp +++ b/engines/kyra/text_v3.cpp @@ -24,8 +24,8 @@ */ #include "kyra/text_v3.h" - #include "kyra/screen_v3.h" +#include "kyra/resource.h" namespace Kyra { @@ -438,5 +438,215 @@ void KyraEngine_v3::badConscienceChatWaitToFinish() { } } +void KyraEngine_v3::malcolmSceneStartupChat() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::malcolmSceneStartupChat()"); + + if (_noStartupChat) + return; + + int index = _mainCharacter.sceneId - _chapterLowestScene[_curChapter]; + if (_newSceneDlgState[index]) + return; + + updateDlgBuffer(); + int vocHighBase = 0, vocHighIndex = 0, index1 = 0, index2 = 0; + loadDlgHeader(vocHighBase, vocHighIndex, index1, index2); + + _cnvFile->seek(index1*6, SEEK_CUR); + _cnvFile->seek(index2*4, SEEK_CUR); + _cnvFile->seek(index*2, SEEK_CUR); + _cnvFile->seek(_cnvFile->readUint16LE(), SEEK_SET); + + _isStartupDialog = true; + processDialog(vocHighIndex, vocHighBase, 0); + _isStartupDialog = false; + _newSceneDlgState[index] = true; +} + +void KyraEngine_v3::updateDlgBuffer() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateDlgBuffer()"); + char dlgFile[16]; + char cnvFile[16]; + + if (_cnvFile) + _cnvFile->seek(0, SEEK_SET); + + if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _curChapter && _curDlgLang == _lang) + return; + + snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _curChapter, _mainCharacter.dlgIndex); + appendLanguage(dlgFile, _lang, 16); + snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _curChapter, _mainCharacter.dlgIndex); + + delete _cnvFile; + delete _dlgBuffer; + + _res->exists(cnvFile, true); + _res->exists(dlgFile, true); + _cnvFile = _res->getFileStream(cnvFile); + _dlgBuffer = _res->getFileStream(dlgFile); + assert(_cnvFile); + assert(_dlgBuffer); +} + +void KyraEngine_v3::loadDlgHeader(int &vocHighBase, int &vocHighIndex, int &index1, int &index2) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::loadDlgHeader(-, -, -, -)"); + assert(_cnvFile); + vocHighIndex = _cnvFile->readSint16LE(); + vocHighBase = _cnvFile->readSint16LE(); + index1 = _cnvFile->readSint16LE(); + index2 = _cnvFile->readSint16LE(); +} + +void KyraEngine_v3::setDlgIndex(uint16 index) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::setDlgIndex(%d)", index); + if (_mainCharacter.dlgIndex != index) { + Common::set_to(_newSceneDlgState, _newSceneDlgState+ARRAYSIZE(_newSceneDlgState), false); + memset(_conversationState, -1, sizeof(_conversationState)); + _chatAltFlag = false; + _mainCharacter.dlgIndex = index; + } +} + +void KyraEngine_v3::processDialog(int vocHighIndex, int vocHighBase, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::processDialog(%d, %d, %d)", vocHighIndex, vocHighBase, funcNum); + bool running = true; + int script = -1; + int vocHigh = -1, vocLow = -1; + + while (running) { + uint16 cmd = _cnvFile->readUint16LE(); + int object = cmd - 14; + + if (cmd == 10) { + break; + } else if (cmd == 4) { + vocHighBase = _cnvFile->readUint16LE(); + setDlgIndex(vocHighBase); + } else if (cmd == 11) { + int strSize = _cnvFile->readUint16LE(); + vocLow = _cnvFile->readUint16LE(); + _cnvFile->read(_stringBuffer, strSize); + _stringBuffer[strSize] = 0; + } else { + vocHigh = _vocHighTable[vocHighIndex-1] + vocHighBase; + vocLow = _cnvFile->readUint16LE(); + getTableEntry(_dlgBuffer, vocLow, _stringBuffer); + + if (_isStartupDialog) { + delay(60*_tickLength, true); + _isStartupDialog = false; + } + + if (*_stringBuffer == 0) + continue; + + if (cmd != 12) { + if (object != script) { + if (script >= 0) { + dialogEndScript(script); + script = -1; + } else { + dialogStartScript(object, funcNum); + script = object; + } + } + + npcChatSequence(_stringBuffer, object, vocHigh, vocLow); + } else { + if (script >= 0) { + dialogEndScript(script); + script = -1; + } + + objectChat(_stringBuffer, 0, vocHigh, vocLow); + playStudioSFX(_stringBuffer); + } + } + } + + if (script != -1) + dialogEndScript(script); +} + +void KyraEngine_v3::dialogStartScript(int object, int funcNum) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::dialogStartScript(%d, %d)", object, funcNum); + _dialogSceneAnim = _talkObjectList[object].sceneAnim; + _dialogSceneScript = _talkObjectList[object].sceneScript; + if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { + _specialSceneScriptStateBackup[_dialogSceneScript] = _specialSceneScriptState[_dialogSceneScript]; + _specialSceneScriptState[_dialogSceneScript] = true; + } + + _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); + _scriptInterpreter->loadScript(_talkObjectList[object].filename, &_dialogScriptData, &_opcodesDialog); + + _dialogScriptFuncStart = funcNum * 3 + 0; + _dialogScriptFuncProc = funcNum * 3 + 1; + _dialogScriptFuncEnd = funcNum * 3 + 2; + + _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncStart); + while (_scriptInterpreter->validScript(&_dialogScriptState)) + _scriptInterpreter->runScript(&_dialogScriptState); +} + +void KyraEngine_v3::dialogEndScript(int object) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::dialogEndScript(%d)", object); + + _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); + _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncEnd); + + while (_scriptInterpreter->validScript(&_dialogScriptState)) + _scriptInterpreter->runScript(&_dialogScriptState); + + if (_dialogSceneAnim >= 0 && _dialogSceneScript >= 0) { + _specialSceneScriptState[_dialogSceneScript] = _specialSceneScriptStateBackup[_dialogSceneScript]; + _dialogSceneScript = _dialogSceneAnim = -1; + } + + _scriptInterpreter->unloadScript(&_dialogScriptData); +} + +void KyraEngine_v3::npcChatSequence(const char *str, int object, int vocHigh, int vocLow) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::npcChatSequence('%s', %d, %d, %d)", str, object, vocHigh, vocLow); + + _chatText = str; + _chatObject = object; + _chatVocHigh = _chatVocLow = -1; + + objectChatInit(str, object, vocHigh, vocLow); + + if (_chatVocHigh >= 0 && _chatVocLow >= 0) { + playVoice(_chatVocHigh, _chatVocLow); + _chatVocHigh = _chatVocLow = -1; + } + + _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); + _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncProc); + + resetSkipFlag(); + + uint32 endTime = _chatEndTime; + bool running = true; + while (running) { + if (!_scriptInterpreter->runScript(&_dialogScriptState)) { + _scriptInterpreter->initScript(&_dialogScriptState, &_dialogScriptData); + _scriptInterpreter->startScript(&_dialogScriptState, _dialogScriptFuncProc); + } + + const uint32 curTime = _system->getMillis(); + if ((textEnabled() && !speechEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || skipFlag()) { + snd_stopVoice(); + resetSkipFlag(); + running = false; + } + + delay(10); + } + _text->restoreScreen(); + _chatText = 0; + _chatObject= - 1; +} + } // end of namespace Kyra |