diff options
-rw-r--r-- | engines/kyra/kyra_v2.h | 4 | ||||
-rw-r--r-- | engines/kyra/script_v2.cpp | 99 | ||||
-rw-r--r-- | engines/kyra/text.h | 17 | ||||
-rw-r--r-- | engines/kyra/text_v2.cpp | 36 | ||||
-rw-r--r-- | engines/kyra/text_v2.h | 3 |
5 files changed, 147 insertions, 12 deletions
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index 9365d3b8be..382ef91388 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -959,7 +959,9 @@ protected: int o2_setSceneComment(ScriptState *script); int o2_setCharacterAnimFrame(ScriptState *script); int o2_trySceneChange(ScriptState *script); + int o2_customCharacterChat(ScriptState *script); int o2_showChapterMessage(ScriptState *script); + int o2_restoreTalkTextMessageBkgd(ScriptState *script); int o2_wsaClose(ScriptState *script); int o2_displayWsaFrame(ScriptState *script); int o2_displayWsaSequentialFramesLooping(ScriptState *script); @@ -1002,6 +1004,7 @@ protected: int o2_loadMusicTrack(ScriptState *script); int o2_playWanderScoreViaMap(ScriptState *script); int o2_playSoundEffect(ScriptState *script); + int o2_setCauldronState(ScriptState *script); int o2_getRand(ScriptState *script); int o2_setDrawNoShapeFlag(ScriptState *script); int o2_showLetter(ScriptState *script); @@ -1046,6 +1049,7 @@ protected: int o2_mushroomEffect(ScriptState *script); int o2_customChat(ScriptState *script); int o2_customChatFinish(ScriptState *script); + int o2_setupSceneAnimation(ScriptState *script); int o2_stopSceneAnimation(ScriptState *script); int o2_processPaletteIndex(ScriptState *script); int o2_getBoolFromStack(ScriptState *script); diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp index 3fb62b84d8..5f9a62d678 100644 --- a/engines/kyra/script_v2.cpp +++ b/engines/kyra/script_v2.cpp @@ -142,12 +142,25 @@ int KyraEngine_v2::o2_trySceneChange(ScriptState *script) { } } +int KyraEngine_v2::o2_customCharacterChat(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_customCharacterChat(%p) ('%s', %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + playVoice(_vocHigh, stackPos(4)); + _text->printCustomCharacterText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), 0, 2); + return 0; +} + int KyraEngine_v2::o2_showChapterMessage(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); showChapterMessage(stackPos(0), stackPos(1)); return 0; } +int KyraEngine_v2::o2_restoreTalkTextMessageBkgd(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_restoreTalkTextMessageBkgd(%p) ()", (const void *)script); + _text->restoreTalkTextMessageBkgd(2, 0); + return 0; +} + int KyraEngine_v2::o2_wsaClose(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots)); @@ -638,6 +651,13 @@ int KyraEngine_v2::o2_playSoundEffect(ScriptState *script) { return 0; } +int KyraEngine_v2::o2_setCauldronState(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setCauldronState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + setCauldronState(stackPos(0), stackPos(1) != 0); + clearCauldronTable(); + return 0; +} + int KyraEngine_v2::o2_getRand(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o2_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < stackPos(1)); @@ -1122,6 +1142,77 @@ int KyraEngine_v2::o2_customChatFinish(ScriptState *script) { return 0; } +int KyraEngine_v2::o2_setupSceneAnimation(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "o2_setupSceneAnimation(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, + stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12)); + const int index = stackPos(0); + const uint16 flags = stackPos(1); + + SceneAnim &anim = _sceneAnims[index]; + anim.x = stackPos(2); + anim.y = stackPos(3); + anim.x2 = stackPos(4); + anim.y2 = stackPos(5); + anim.width = stackPos(6); + anim.height = stackPos(7); + anim.unkE = stackPos(8); + anim.specialSize = stackPos(9); + anim.unk12 = stackPos(10); + anim.shapeIndex = stackPos(11); + if (stackPosString(12)) + strcpy(anim.filename, stackPosString(12)); + + if (flags & 0x40) { + _sceneAnimMovie[index]->open(stackPosString(12), 0, 0); + if (_sceneAnimMovie[index]->xAdd() || _sceneAnimMovie[index]->yAdd()) + anim.wsaFlag = 1; + else + anim.wsaFlag = 0; + } + + AnimObj *obj = &_animObjects[1+index]; + obj->enabled = 1; + obj->needRefresh = 1; + obj->unk8 = 1; + obj->animFlags = anim.flags & 8; + + if (anim.flags & 2) + obj->flags = 0x800; + else + obj->flags = 0; + + if (anim.flags & 4) + obj->flags |= 1; + + obj->xPos1 = anim.x; + obj->yPos1 = anim.y; + + if ((anim.flags & 0x20) && anim.shapeIndex >= 0) + obj->shapePtr = _sceneShapeTable[anim.shapeIndex]; + else + obj->shapePtr = 0; + + if (anim.flags & 0x40) { + obj->shapeIndex3 = anim.shapeIndex; + obj->animNum = index; + } else { + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + } + + obj->shapeIndex2 = 0xFFFF; + obj->xPos2 = obj->xPos3 = anim.x2; + obj->yPos2 = obj->yPos3 = anim.y2; + obj->width = anim.width; + obj->height = anim.height; + obj->width2 = obj->height2 = anim.specialSize; + + _animList = addToAnimListSorted(_animList, obj); + obj->needRefresh = 1; + obj->unk8 = 1; + return 0; +} + int KyraEngine_v2::o2_stopSceneAnimation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o2_stopSceneAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); const int index = 1+stackPos(0); @@ -1278,11 +1369,11 @@ void KyraEngine_v2::setupOpcodeTable() { OpcodeUnImpl(), Opcode(o2_trySceneChange), OpcodeUnImpl(), - OpcodeUnImpl(), + Opcode(o2_customCharacterChat), // 0x10 OpcodeUnImpl(), Opcode(o2_showChapterMessage), - OpcodeUnImpl(), + Opcode(o2_restoreTalkTextMessageBkgd), OpcodeUnImpl(), // 0x14 Opcode(o2_wsaClose), @@ -1377,7 +1468,7 @@ void KyraEngine_v2::setupOpcodeTable() { // 0x5c OpcodeUnImpl(), OpcodeUnImpl(), - OpcodeUnImpl(), + Opcode(o2_setCauldronState), OpcodeUnImpl(), // 0x60 Opcode(o2_getRand), @@ -1452,7 +1543,7 @@ void KyraEngine_v2::setupOpcodeTable() { // 0x98 Opcode(o2_customChat), Opcode(o2_customChatFinish), - OpcodeUnImpl(), + Opcode(o2_setupSceneAnimation), Opcode(o2_stopSceneAnimation), // 0x9c OpcodeUnImpl(), diff --git a/engines/kyra/text.h b/engines/kyra/text.h index 07bc0605dd..5d9179b1ee 100644 --- a/engines/kyra/text.h +++ b/engines/kyra/text.h @@ -34,14 +34,6 @@ namespace Kyra { class KyraEngine; class TextDisplayer { - struct TalkCoords { - uint16 y, x, w; - }; - - enum { - TALK_SUBSTRING_LEN = 80, - TALK_SUBSTRING_NUM = 5 - }; public: TextDisplayer(KyraEngine *vm, Screen *screen); virtual ~TextDisplayer() {} @@ -70,6 +62,15 @@ protected: Screen *_screen; KyraEngine *_vm; + struct TalkCoords { + uint16 y, x, w; + }; + + enum { + TALK_SUBSTRING_LEN = 80, + TALK_SUBSTRING_NUM = 5 + }; + char _talkBuffer[1040]; char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM]; TalkCoords _talkCoords; diff --git a/engines/kyra/text_v2.cpp b/engines/kyra/text_v2.cpp index bd05672fc0..adcaacbd15 100644 --- a/engines/kyra/text_v2.cpp +++ b/engines/kyra/text_v2.cpp @@ -39,6 +39,10 @@ void TextDisplayer_v2::backupTalkTextMessageBkgd(int srcPage, int dstPage) { _screen->copyRegion(_talkCoords.x, _talkMessageY, 0, 144, _talkCoords.w, _talkMessageH, srcPage, dstPage); } +void TextDisplayer_v2::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { + _screen->copyRegion(0, 144, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); +} + void TextDisplayer_v2::restoreScreen() { _vm->restorePage3(); _vm->drawAnimObjects(); @@ -49,6 +53,38 @@ void TextDisplayer_v2::restoreScreen() { _vm->refreshAnimObjects(0); } +void TextDisplayer_v2::printCustomCharacterText(const char *text, int x, int y, uint8 c1, int srcPage, int dstPage) { + text = preprocessString(text); + int lineCount = buildMessageSubstrings(text); + int w = getWidestLineWidth(lineCount); + int h = lineCount * 10; + y = MAX(0, y - (lineCount * 10)); + int x1 = 0, x2 = 0; + calcWidestLineBounds(x1, x2, w, x); + + _screen->hideMouse(); + + _talkCoords.x = x1; + _talkCoords.w = w+2; + _talkCoords.y = y; + _talkMessageY = y; + _talkMessageH = h; + + backupTalkTextMessageBkgd(srcPage, dstPage); + int curPageBackUp = _screen->_curPage; + _screen->_curPage = srcPage; + + if (_vm->textEnabled()) { + for (int i = 0; i < lineCount; ++i) { + const char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; + printText(msg, getCenterStringX(msg, x1, x2), i * 10 + _talkMessageY, c1, 0xCF, 0); + } + } + + _screen->_curPage = curPageBackUp; + _screen->showMouse(); +} + char *TextDisplayer_v2::preprocessString(const char *str) { debugC(9, kDebugLevelMain, "TextDisplayer_v2::preprocessString('%s')", str); diff --git a/engines/kyra/text_v2.h b/engines/kyra/text_v2.h index affbbc2be2..6b8cf5d38e 100644 --- a/engines/kyra/text_v2.h +++ b/engines/kyra/text_v2.h @@ -39,8 +39,11 @@ public: TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen); void backupTalkTextMessageBkgd(int srcPage, int dstPage); + void restoreTalkTextMessageBkgd(int srcPage, int dstPage); void restoreScreen(); + void printCustomCharacterText(const char *src, int x, int y, uint8 c1, int srcPage, int dstPage); + char *preprocessString(const char *str); void calcWidestLineBounds(int &x1, int &x2, int w, int x); private: |