aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/kyra_v3.cpp38
-rw-r--r--engines/kyra/kyra_v3.h51
-rw-r--r--engines/kyra/scene_v3.cpp2
-rw-r--r--engines/kyra/script_v3.cpp92
-rw-r--r--engines/kyra/staticres.cpp8
-rw-r--r--engines/kyra/text_v3.cpp212
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