aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/kyra_v2.h4
-rw-r--r--engines/kyra/script_v2.cpp99
-rw-r--r--engines/kyra/text.h17
-rw-r--r--engines/kyra/text_v2.cpp36
-rw-r--r--engines/kyra/text_v2.h3
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: