aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kyra/animator.cpp525
-rw-r--r--kyra/animator.h105
-rw-r--r--kyra/debugger.cpp2
-rw-r--r--kyra/debugger.h2
-rw-r--r--kyra/gui.cpp293
-rw-r--r--kyra/kyra.cpp1424
-rw-r--r--kyra/kyra.h81
-rw-r--r--kyra/module.mk6
-rw-r--r--kyra/script.cpp267
-rw-r--r--kyra/script_v1.cpp384
-rwxr-xr-xkyra/seqplayer.cpp7
-rw-r--r--kyra/sprites.cpp26
-rw-r--r--kyra/sprites.h1
-rw-r--r--kyra/text.cpp240
-rw-r--r--kyra/text.h67
-rw-r--r--kyra/timer.cpp277
16 files changed, 1988 insertions, 1719 deletions
diff --git a/kyra/animator.cpp b/kyra/animator.cpp
new file mode 100644
index 0000000000..769037f45f
--- /dev/null
+++ b/kyra/animator.cpp
@@ -0,0 +1,525 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/screen.h"
+#include "kyra/animator.h"
+#include "kyra/sprites.h"
+
+namespace Kyra {
+ScreenAnimator::ScreenAnimator(KyraEngine *vm) {
+ _vm = vm;
+ _screen = vm->screen();
+ _initOk = false;
+ _updateScreen = false;
+ _screenObjects = _actors = _items = _sprites = _objectQueue = 0;
+ _noDrawShapesFlag = 0;
+}
+
+ScreenAnimator::~ScreenAnimator() {
+ close();
+}
+
+void ScreenAnimator::init(int actors_, int items_, int sprites_) {
+ debug(9, "ScreenAnimator::init(%d, %d, %d)", actors_, items_, sprites_);
+ _screenObjects = new AnimObject[actors_ + items_ + sprites_];
+ assert(_screenObjects);
+ memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_));
+ _actors = _screenObjects;
+ _sprites = &_screenObjects[actors_];
+ _items = &_screenObjects[actors_ + items_];
+ _initOk = true;
+}
+
+void ScreenAnimator::close() {
+ debug(9, "ScreenAnimator::close()");
+ if (_initOk) {
+ _initOk = false;
+ delete [] _screenObjects;
+ _screenObjects = _actors = _items = _sprites = _objectQueue = 0;
+ }
+}
+
+void ScreenAnimator::preserveAllBackgrounds() {
+ debug(9, "ScreenAnimator::preserveAllBackgrounds()");
+ uint8 curPage = _screen->_curPage;
+ _screen->_curPage = 2;
+
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ if (curObject->active && !curObject->unk1) {
+ preserveOrRestoreBackground(curObject, false);
+ curObject->bkgdChangeFlag = 0;
+ }
+ curObject = curObject->nextAnimObject;
+ }
+ _screen->_curPage = curPage;
+}
+
+void ScreenAnimator::flagAllObjectsForBkgdChange() {
+ debug(9, "ScreenAnimator::flagAllObjectsForBkgdChange()");
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ curObject->bkgdChangeFlag = 1;
+ curObject = curObject->nextAnimObject;
+ }
+}
+
+void ScreenAnimator::flagAllObjectsForRefresh() {
+ debug(9, "ScreenAnimator::flagAllObjectsForRefresh()");
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ curObject->refreshFlag = 1;
+ curObject = curObject->nextAnimObject;
+ }
+}
+
+void ScreenAnimator::restoreAllObjectBackgrounds() {
+ debug(9, "ScreenAnimator::restoreAllObjectBackground()");
+ AnimObject *curObject = _objectQueue;
+ _screen->_curPage = 2;
+
+ while (curObject) {
+ if (curObject->active && !curObject->unk1) {
+ preserveOrRestoreBackground(curObject, true);
+ curObject->x2 = curObject->x1;
+ curObject->y2 = curObject->y1;
+ }
+ curObject = curObject->nextAnimObject;
+ }
+
+ _screen->_curPage = 0;
+}
+
+void ScreenAnimator::preserveAnyChangedBackgrounds() {
+ debug(9, "ScreenAnimator::preserveAnyChangedBackgrounds()");
+ AnimObject *curObject = _objectQueue;
+ _screen->_curPage = 2;
+
+ while (curObject) {
+ if (curObject->active && !curObject->unk1 && curObject->bkgdChangeFlag) {
+ preserveOrRestoreBackground(curObject, false);
+ curObject->bkgdChangeFlag = 0;
+ }
+ curObject = curObject->nextAnimObject;
+ }
+
+ _screen->_curPage = 0;
+}
+
+void ScreenAnimator::preserveOrRestoreBackground(AnimObject *obj, bool restore) {
+ debug(9, "ScreenAnimator::preserveOrRestoreBackground(0x%X, restore)", obj, restore);
+ int x = 0, y = 0, width = obj->width << 3, height = obj->height;
+
+ if (restore) {
+ x = obj->x2;
+ y = obj->y2;
+ } else {
+ x = obj->x1;
+ y = obj->y1;
+ }
+
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+
+ int temp;
+
+ temp = x + width;
+ if (temp >= 319) {
+ x = 319 - width;
+ }
+ temp = y + height;
+ if (temp >= 136) {
+ y = 136 - height;
+ }
+
+ if (restore) {
+ _screen->copyBlockToPage(_screen->_curPage, x, y, width, height, obj->background);
+ } else {
+ _screen->copyRegionToBuffer(_screen->_curPage, x, y, width, height, obj->background);
+ }
+}
+
+void ScreenAnimator::prepDrawAllObjects() {
+ debug(9, "ScreenAnimator::prepDrawAllObjects()");
+ AnimObject *curObject = _objectQueue;
+ int drawPage = 2;
+ int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0;
+ if (_noDrawShapesFlag)
+ return;
+ if (_vm->_brandonStatusBit & 0x20)
+ flagUnk1 = 0x200;
+ if (_vm->_brandonStatusBit & 0x40)
+ flagUnk2 = 0x4000;
+
+ while (curObject) {
+ if (curObject->active) {
+ int xpos = curObject->x1;
+ int ypos = curObject->y1;
+
+ int drawLayer = 0;
+ if (!(curObject->flags & 0x800)) {
+ drawLayer = 7;
+ } else if (curObject->unk1) {
+ drawLayer = 0;
+ } else {
+ drawLayer = _vm->_sprites->getDrawLayer(curObject->drawY);
+ }
+
+ // talking head functionallity
+ if (_vm->_talkingCharNum != -1) {
+ const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 };
+ const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 };
+ const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 };
+ const int8 xOffsetTable2[] = { 6, 4, 8, 3, 6, 0, 0, 0 };
+ const int8 yOffsetTable1[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
+ const int8 yOffsetTable2[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
+ if (curObject->index == 0 || curObject->index <= 4) {
+ int shapesIndex = 0;
+ if (curObject->index == _vm->_charSayUnk3) {
+ shapesIndex = _vm->_currHeadShape + baseAnimFrameTable1[curObject->index];
+ } else {
+ shapesIndex = baseAnimFrameTable2[curObject->index];
+ int temp2 = 0;
+ if (curObject->index == 2) {
+ if (_vm->_characterList[2].sceneId == 0x4D || _vm->_characterList[2].sceneId == 0x56) {
+ temp2 = 1;
+ } else {
+ temp2 = 0;
+ }
+ } else {
+ temp2 = 1;
+ }
+
+ if (!temp2) {
+ shapesIndex = -1;
+ }
+ }
+
+ xpos = curObject->x1;
+ ypos = curObject->y1;
+
+ int tempX = 0, tempY = 0;
+ if (curObject->flags & 0x1) {
+ tempX = (xOffsetTable1[curObject->index] * _vm->_brandonScaleX) >> 8;
+ tempY = yOffsetTable1[curObject->index];
+ } else {
+ tempX = (xOffsetTable2[curObject->index] * _vm->_brandonScaleX) >> 8;
+ tempY = yOffsetTable2[curObject->index];
+ }
+ tempY = (tempY * _vm->_brandonScaleY) >> 8;
+ xpos += tempX;
+ ypos += tempY;
+
+ if (_vm->_scaleMode && _vm->_brandonScaleX != 256) {
+ ++xpos;
+ }
+
+ if (curObject->index == 0) {
+ if (!(_vm->_brandonStatusBit & 2)) {
+ flagUnk3 = 0x100;
+ if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) {
+ flagUnk3 = 0;
+ }
+
+ int tempFlags = 0;
+ if (flagUnk3 & 0x100) {
+ if (curObject->flags & 1) {
+ tempFlags = 1;
+ }
+ tempFlags |= 0x800 | flagUnk1 | 0x100;
+ }
+
+ if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) {
+ tempFlags = 0;
+ if (curObject->flags & 1) {
+ tempFlags = 1;
+ }
+ tempFlags |= 0x900 | flagUnk1 | 0x4000;
+ _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(0)/*XXX*/, drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+ } else {
+ if (!(flagUnk2 & 0x4000)) {
+ tempFlags = 0;
+ if (curObject->flags & 1) {
+ tempFlags = 1;
+ }
+ tempFlags |= 0x900 | flagUnk1;
+ }
+
+ _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+ }
+ }
+ } else {
+ if (shapesIndex != -1) {
+ int tempFlags = 0;
+ if (curObject->flags & 1) {
+ tempFlags = 1;
+ }
+ _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer);
+ }
+ }
+ }
+ }
+
+ xpos = curObject->x1;
+ ypos = curObject->y1;
+
+ curObject->flags |= 0x800;
+ if (curObject->index == 0) {
+ flagUnk3 = 0x100;
+
+ if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) {
+ flagUnk3 = 0;
+ }
+
+ if (_vm->_brandonStatusBit & 2) {
+ curObject->flags &= 0xFFFFFFFE;
+ }
+
+ if (!_vm->_scaleMode) {
+ if (flagUnk3 & 0x100) {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer);
+ } else if (flagUnk3 & 0x4000) {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, _vm->_brandonInvFlag, drawLayer);
+ } else {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer);
+ }
+ } else {
+ if (flagUnk3 & 0x100) {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+ } else if (flagUnk3 & 0x4000) {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(0), drawLayer, _vm->_brandonInvFlag, _vm->_brandonScaleX, _vm->_brandonScaleY);
+ } else {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _vm->_brandonScaleX, _vm->_brandonScaleY);
+ }
+ }
+ } else {
+ if (curObject->index >= 16 && curObject->index <= 27) {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_vm->_scaleTable[curObject->drawY], (int)_vm->_scaleTable[curObject->drawY]);
+ } else {
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer);
+ }
+ }
+ }
+ curObject = curObject->nextAnimObject;
+ }
+}
+
+void ScreenAnimator::copyChangedObjectsForward(int refreshFlag) {
+ debug(9, "ScreenAnimator::copyChangedObjectsForward(%d)", refreshFlag);
+ AnimObject *curObject = _objectQueue;
+
+ while (curObject) {
+ if (curObject->active) {
+ if (curObject->refreshFlag || refreshFlag) {
+ int xpos = 0, ypos = 0, width = 0, height = 0;
+ xpos = curObject->x1 - (curObject->width2+1);
+ ypos = curObject->y1 - curObject->height2;
+ width = (curObject->width + ((curObject->width2)>>3)+2)<<3;
+ height = curObject->height + curObject->height2*2;
+
+ if (xpos < 8) {
+ xpos = 8;
+ } else if (xpos + width > 312) {
+ width = 312 - xpos;
+ }
+
+ if (ypos < 8) {
+ ypos = 8;
+ } else if (ypos + height > 136) {
+ height = 136 - ypos;
+ }
+
+ _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, 2, 0, Screen::CR_CLIPPED);
+ curObject->refreshFlag = 0;
+ _updateScreen = true;
+ }
+ }
+ curObject = curObject->nextAnimObject;
+ }
+ if (_updateScreen) {
+ _screen->updateScreen();
+ _updateScreen = false;
+ }
+}
+
+void ScreenAnimator::updateAllObjectShapes() {
+ debug(9, "ScreenAnimator::updateAllObjectShapes()");
+ restoreAllObjectBackgrounds();
+ preserveAnyChangedBackgrounds();
+ prepDrawAllObjects();
+ copyChangedObjectsForward(0);
+}
+
+void ScreenAnimator::animRemoveGameItem(int index) {
+ debug(9, "ScreenAnimator::animRemoveGameItem(%d)", index);
+ restoreAllObjectBackgrounds();
+
+ AnimObject *animObj = &_items[index];
+ animObj->sceneAnimPtr = 0;
+ animObj->animFrameNumber = -1;
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+ updateAllObjectShapes();
+ animObj->active = 0;
+
+ objectRemoveQueue(_objectQueue, animObj);
+}
+
+void ScreenAnimator::animAddGameItem(int index, uint16 sceneId) {
+ debug(9, "ScreenAnimator::animRemoveGameItem(%d, %d)", index, sceneId);
+ restoreAllObjectBackgrounds();
+ assert(sceneId < _vm->_roomTableSize);
+ Room *currentRoom = &_vm->_roomTable[sceneId];
+ AnimObject *animObj = &_items[index];
+ animObj->active = 1;
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+ animObj->drawY = currentRoom->itemsYPos[index];
+ animObj->sceneAnimPtr = _vm->_shapes[220+currentRoom->itemsTable[index]];
+ animObj->animFrameNumber = -1;
+ animObj->x1 = currentRoom->itemsXPos[index];
+ animObj->y1 = currentRoom->itemsYPos[index];
+ animObj->x1 -= _vm->fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1;
+ animObj->y1 -= _vm->fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]);
+ animObj->x2 = animObj->x1;
+ animObj->y2 = animObj->y1;
+ animObj->width2 = 0;
+ animObj->height2 = 0;
+ _objectQueue = objectQueue(_objectQueue, animObj);
+ preserveAnyChangedBackgrounds();
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+}
+
+void ScreenAnimator::animAddNPC(int character) {
+ debug(9, "ScreenAnimator::animAddNPC(%d)", character);
+ restoreAllObjectBackgrounds();
+ AnimObject *animObj = &_actors[character];
+ const Character *ch = &_vm->_characterList[character];
+
+ animObj->active = 1;
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+ animObj->drawY = ch->y1;
+ animObj->sceneAnimPtr = _vm->_shapes[4+ch->currentAnimFrame];
+ animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset;
+ animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset;
+ if (ch->facing >= 1 && ch->facing <= 3) {
+ animObj->flags |= 1;
+ } else if (ch->facing >= 5 && ch->facing <= 7) {
+ animObj->flags &= 0xFFFFFFFE;
+ }
+ _objectQueue = objectQueue(_objectQueue, animObj);
+ preserveAnyChangedBackgrounds();
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+}
+
+AnimObject *ScreenAnimator::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
+ debug(9, "ScreenAnimator::objectRemoveQueue(0x%X, 0x%X)", queue, rem);
+ AnimObject *cur = queue;
+ AnimObject *prev = queue;
+
+ while (cur != rem && cur) {
+ AnimObject *temp = cur->nextAnimObject;
+ if (!temp)
+ break;
+ prev = cur;
+ cur = temp;
+ }
+
+ if (cur == queue) {
+ if (!cur)
+ return 0;
+ return cur->nextAnimObject;
+ }
+
+ if (!cur->nextAnimObject) {
+ if (cur == rem) {
+ if (!prev) {
+ return 0;
+ } else {
+ prev->nextAnimObject = 0;
+ }
+ }
+ } else {
+ if (cur == rem) {
+ prev->nextAnimObject = rem->nextAnimObject;
+ }
+ }
+
+ return queue;
+}
+
+AnimObject *ScreenAnimator::objectAddHead(AnimObject *queue, AnimObject *head) {
+ debug(9, "ScreenAnimator::objectAddHead(0x%X, 0x%X)", queue, head);
+ head->nextAnimObject = queue;
+ return head;
+}
+
+AnimObject *ScreenAnimator::objectQueue(AnimObject *queue, AnimObject *add) {
+ debug(9, "ScreenAnimator::objectQueue(0x%X, 0x%X)", queue, add);
+ if (add->drawY <= queue->drawY || !queue) {
+ add->nextAnimObject = queue;
+ return add;
+ }
+ AnimObject *cur = queue;
+ AnimObject *prev = queue;
+ while (add->drawY > cur->drawY) {
+ AnimObject *temp = cur->nextAnimObject;
+ if (!temp)
+ break;
+ prev = cur;
+ cur = temp;
+ }
+
+ if (add->drawY <= cur->drawY) {
+ prev->nextAnimObject = add;
+ add->nextAnimObject = cur;
+ } else {
+ cur->nextAnimObject = add;
+ add->nextAnimObject = 0;
+ }
+ return queue;
+}
+
+void ScreenAnimator::addObjectToQueue(AnimObject *object) {
+ debug(9, "ScreenAnimator::addObjectToQueue(0x%X)", object);
+ if (!_objectQueue) {
+ _objectQueue = objectAddHead(0, object);
+ } else {
+ _objectQueue = objectQueue(_objectQueue, object);
+ }
+}
+
+void ScreenAnimator::refreshObject(AnimObject *object) {
+ debug(9, "ScreenAnimator::refreshObject(0x%X)", object);
+ _objectQueue = objectRemoveQueue(_objectQueue, object);
+ if (_objectQueue) {
+ _objectQueue = objectQueue(_objectQueue, object);
+ } else {
+ _objectQueue = objectAddHead(0, object);
+ }
+}
+} // end of namespace Kyra
diff --git a/kyra/animator.h b/kyra/animator.h
new file mode 100644
index 0000000000..a82279aa37
--- /dev/null
+++ b/kyra/animator.h
@@ -0,0 +1,105 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef KYRAANIMATOR_H
+#define KYRAANIMATOR_H
+
+namespace Kyra {
+class KyraEngine;
+class Screen;
+
+struct AnimObject {
+ uint8 index;
+ uint32 active;
+ uint32 refreshFlag;
+ uint32 bkgdChangeFlag;
+ uint32 unk1;
+ uint32 flags;
+ int16 drawY;
+ uint8 *sceneAnimPtr;
+ int16 animFrameNumber;
+ uint8 *background;
+ uint16 rectSize;
+ int16 x1, y1;
+ int16 x2, y2;
+ uint16 width;
+ uint16 height;
+ uint16 width2;
+ uint16 height2;
+ AnimObject *nextAnimObject;
+ };
+
+class ScreenAnimator {
+public:
+ ScreenAnimator(KyraEngine *vm);
+ virtual ~ScreenAnimator();
+
+ operator bool() const { return _initOk; }
+
+ void init(int actors, int items, int sprites);
+ void close();
+
+ AnimObject *objects() { return _screenObjects; }
+ AnimObject *actors() { return _actors; }
+ AnimObject *items() { return _items; }
+ AnimObject *sprites() { return _sprites; }
+
+ void preserveAllBackgrounds();
+ void flagAllObjectsForBkgdChange();
+ void flagAllObjectsForRefresh();
+ void restoreAllObjectBackgrounds();
+ void preserveAnyChangedBackgrounds();
+ virtual void prepDrawAllObjects();
+ void copyChangedObjectsForward(int refreshFlag);
+
+ void updateAllObjectShapes();
+ void animRemoveGameItem(int index);
+ void animAddGameItem(int index, uint16 sceneId);
+ void animAddNPC(int character);
+
+ void clearQueue() { _objectQueue = 0; }
+ void addObjectToQueue(AnimObject *object);
+ void refreshObject(AnimObject *object);
+
+ int _noDrawShapesFlag;
+ bool _updateScreen;
+protected:
+ KyraEngine *_vm;
+ Screen *_screen;
+ bool _initOk;
+
+ AnimObject *_screenObjects;
+
+ AnimObject *_actors;
+ AnimObject *_items;
+ AnimObject *_sprites;
+
+ AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem);
+ AnimObject *objectAddHead(AnimObject *queue, AnimObject *head);
+ AnimObject *objectQueue(AnimObject *queue, AnimObject *add);
+
+ void preserveOrRestoreBackground(AnimObject *obj, bool restore);
+
+ AnimObject *_objectQueue;
+};
+} // end of namespace Kyra
+
+#endif
diff --git a/kyra/debugger.cpp b/kyra/debugger.cpp
index c1bc7fd65e..1384ce5fd8 100644
--- a/kyra/debugger.cpp
+++ b/kyra/debugger.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2005 The ScummVM project
+ * Copyright (C) 2005 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/kyra/debugger.h b/kyra/debugger.h
index ea7f1aba7c..2a15103548 100644
--- a/kyra/debugger.h
+++ b/kyra/debugger.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2005 The ScummVM project
+ * Copyright (C) 2005 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/kyra/gui.cpp b/kyra/gui.cpp
new file mode 100644
index 0000000000..8f3212b2e5
--- /dev/null
+++ b/kyra/gui.cpp
@@ -0,0 +1,293 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/screen.h"
+#include "kyra/script.h"
+
+namespace Kyra {
+Button *KyraEngine::initButton(Button *list, Button *newButton) {
+ if (!newButton)
+ return list;
+ if (!list)
+ return newButton;
+ Button *cur = list;
+ while (true) {
+ if (!cur->nextButton) {
+ break;
+ }
+ cur = cur->nextButton;
+ }
+ cur->nextButton = newButton;
+ return list;
+}
+
+int KyraEngine::buttonInventoryCallback(Button *caller) {
+ int itemOffset = caller->specialValue - 2;
+ uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset];
+ if (_itemInHand == -1) {
+ if (inventoryItem == 0xFF) {
+ // snd_playSoundEffect(0x36);
+ return 0;
+ } else {
+ _screen->hideMouse();
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ // snd_playSoundEffect(0x35);
+ setMouseItem(inventoryItem);
+ updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179);
+ _itemInHand = inventoryItem;
+ _screen->showMouse();
+ _currentCharacter->inventoryItems[itemOffset] = 0xFF;
+ }
+ } else {
+ if (inventoryItem != 0xFF) {
+ // snd_playSoundEffect(0x35);
+ _screen->hideMouse();
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
+ setMouseItem(inventoryItem);
+ updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179);
+ _screen->showMouse();
+ _currentCharacter->inventoryItems[itemOffset] = _itemInHand;
+ _itemInHand = inventoryItem;
+ } else {
+ // snd_playSoundEffect(0x32);
+ _screen->hideMouse();
+ _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
+ _screen->setMouseCursor(1, 1, _shapes[4]);
+ updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179);
+ _screen->showMouse();
+ _currentCharacter->inventoryItems[itemOffset] = _itemInHand;
+ _itemInHand = -1;
+ }
+ }
+ _screen->updateScreen();
+ // XXX clearKyrandiaButtonIO
+ return 0;
+}
+
+int KyraEngine::buttonAmuletCallback(Button *caller) {
+ if (!(_deathHandler & 8))
+ return 1;
+ int jewel = caller->specialValue - 0x14;
+ if (_currentCharacter->sceneId == 210) {
+ //if (_unkSceneVar == 4 || _unkSceneVar == 6)
+ // return 1;
+ }
+ if (!queryGameFlag(0x2D))
+ return 1;
+ if (_itemInHand != -1) {
+ assert(_putDownFirst);
+ characterSays(_putDownFirst[0], 0, -2);
+ return 1;
+ }
+ if (queryGameFlag(0xF1)) {
+ assert(_waitForAmulet);
+ characterSays(_waitForAmulet[0], 0, -2);
+ return 1;
+ }
+ if (!queryGameFlag(0x55+jewel)) {
+ assert(_blackJewel);
+ makeBrandonFaceMouse();
+ drawJewelPress(jewel, 1);
+ characterSays(_blackJewel[0], 0, -2);
+ return 1;
+ }
+ drawJewelPress(jewel, 0);
+ drawJewelsFadeOutStart();
+ drawJewelsFadeOutEnd(jewel);
+
+ _scriptInterpreter->initScript(_scriptClick, _scriptClickData);
+ _scriptClick->variables[3] = 0;
+ _scriptClick->variables[6] = jewel;
+ _scriptInterpreter->startScript(_scriptClick, 4);
+
+ while (_scriptInterpreter->validScript(_scriptClick)) {
+ _scriptInterpreter->runScript(_scriptClick);
+ }
+
+ if (_scriptClick->variables[3])
+ return 1;
+
+ _unkAmuletVar = 1;
+ switch (jewel-1) {
+ case 0:
+ if (_brandonStatusBit & 1) {
+ seq_brandonHealing2();
+ } else if (_brandonStatusBit == 0) {
+ seq_brandonHealing();
+ assert(_healingTip);
+ characterSays(_healingTip[0], 0, -2);
+ }
+ break;
+
+ case 1:
+ seq_makeBrandonInv();
+ break;
+
+ case 2:
+ if (_brandonStatusBit & 1) {
+ assert(_wispJewelStrings);
+ characterSays(_wispJewelStrings[0], 0, -2);
+ } else {
+ if (_brandonStatusBit & 2) {
+ // XXX
+ seq_makeBrandonNormal2();
+ // XXX
+ } else {
+ // do not check for item in hand again as in the original since some strings are missing
+ // in the cd version
+ if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
+ // XXX
+ seq_makeBrandonWisp();
+ // XXX
+ } else {
+ seq_makeBrandonWisp();
+ }
+ setGameFlag(0x9E);
+ }
+ }
+ break;
+
+ case 3:
+ seq_dispelMagicAnimation();
+ assert(_magicJewelString);
+ characterSays(_magicJewelString[0], 0, -2);
+ break;
+
+ default:
+ break;
+ }
+ _unkAmuletVar = 0;
+ // XXX clearKyrandiaButtonIO (!used before every return in this function!)
+ return 1;
+}
+
+void KyraEngine::processButtonList(Button *list) {
+ while (list) {
+ if (list->flags & 8) {
+ list = list->nextButton;
+ continue;
+ }
+
+ int x = list->x;
+ int y = list->y;
+ assert(list->dimTableIndex < _screen->_screenDimTableCount);
+ if (x < 0) {
+ x += _screen->_screenDimTable[list->dimTableIndex].w << 3;
+ }
+ x += _screen->_screenDimTable[list->dimTableIndex].sx << 3;
+
+ if (y < 0) {
+ y += _screen->_screenDimTable[list->dimTableIndex].h;
+ }
+ y += _screen->_screenDimTable[list->dimTableIndex].sy;
+
+ if (_mouseX >= x && _mouseY >= y && x + list->width >= _mouseX && y + list->height >= _mouseY) {
+ int processMouseClick = 0;
+ if (list->flags & 0x400) {
+ if (_mousePressFlag) {
+ if (!(list->flags2 & 1)) {
+ list->flags2 |= 1;
+ processButton(list);
+ }
+ } else {
+ if (list->flags2 & 1) {
+ list->flags2 &= 0xFFFE;
+ processButton(list);
+ processMouseClick = 1;
+ }
+ }
+ } else if (_mousePressFlag) {
+ processMouseClick = 1;
+ }
+
+ if (processMouseClick) {
+ if (list->buttonCallback) {
+ if ((this->*(list->buttonCallback))(list)) {
+ break;
+ }
+ }
+ }
+ } else {
+ if (list->flags2 & 1) {
+ list->flags2 &= 0xFFFE;
+ processButton(list);
+ }
+ list = list->nextButton;
+ continue;
+ }
+
+ list = list->nextButton;
+ }
+}
+
+void KyraEngine::processButton(Button *button) {
+ if (!button)
+ return;
+
+ int processType = 0;
+ uint8 *shape = 0;
+ Button::ButtonCallback callback = 0;
+
+ int flags = (button->flags2 & 5);
+ if (flags == 1) {
+ processType = button->process2;
+ if (processType == 1) {
+ shape = button->process2PtrShape;
+ } else if (processType == 4) {
+ callback = button->process2PtrCallback;
+ }
+ } else if (flags == 4 || flags == 5) {
+ processType = button->process1;
+ if (processType == 1) {
+ shape = button->process1PtrShape;
+ } else if (processType == 4) {
+ callback = button->process1PtrCallback;
+ }
+ } else {
+ processType = button->process0;
+ if (processType == 1) {
+ shape = button->process0PtrShape;
+ } else if (processType == 4) {
+ callback = button->process0PtrCallback;
+ }
+ }
+
+ int x = button->x;
+ int y = button->y;
+ assert(button->dimTableIndex < _screen->_screenDimTableCount);
+ if (x < 0) {
+ x += _screen->_screenDimTable[button->dimTableIndex].w << 3;
+ }
+
+ if (y < 0) {
+ y += _screen->_screenDimTable[button->dimTableIndex].h;
+ }
+
+ if (processType == 1 && shape) {
+ _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10);
+ } else if (processType == 4 && callback) {
+ (this->*callback)(button);
+ }
+}
+} // end of namespace Kyra
+
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index ca90fa940f..422b3da563 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -45,6 +45,8 @@
#include "kyra/sound.h"
#include "kyra/sprites.h"
#include "kyra/wsamovie.h"
+#include "kyra/animator.h"
+#include "kyra/text.h"
#include "kyra/debugger.h"
using namespace Kyra;
@@ -293,6 +295,12 @@ int KyraEngine::init(GameDetector &detector) {
assert(_sprites);
_seq = new SeqPlayer(this, _system);
assert(_seq);
+ _animator = new ScreenAnimator(this);
+ assert(_animator);
+ _animator->init(5, 11, 12);
+ assert(*_animator);
+ _text = new TextDisplayer(_screen);
+ assert(_text);
_paletteChanged = 1;
_currentCharacter = 0;
@@ -307,14 +315,6 @@ int KyraEngine::init(GameDetector &detector) {
_characterList[0].facing = 3;
_characterList[0].currentAnimFrame = 7;
- _objectQueue = 0;
- _animStates = new AnimObject[31];
- assert(_animStates);
- memset(_animStates, 0, sizeof(AnimObject)*31);
- _charactersAnimState = &_animStates[0];
- _sprites->_animObjects = &_animStates[5];
- _animItems = &_animStates[16];
-
_scriptInterpreter = new ScriptHelper(this);
assert(_scriptInterpreter);
@@ -349,19 +349,12 @@ int KyraEngine::init(GameDetector &detector) {
_fastMode = false;
_abortWalkFlag = false;
_abortWalkFlag2 = false;
- _talkCoords.y = 0x88;
- _talkCoords.x = 0;
- _talkCoords.w = 0;
- _talkMessageY = 0xC;
- _talkMessageH = 0;
- _talkMessagePrinted = false;
_talkingCharNum = -1;
_charSayUnk3 = -1;
_mouseX = _mouseY = -1;
memset(_currSentenceColor, 0, 3);
_startSentencePalIndex = -1;
_fadeText = false;
- _noDrawShapesFlag = 0;
_cauldronState = 0;
_crystalState[0] = _crystalState[1] = -1;
@@ -415,12 +408,14 @@ KyraEngine::~KyraEngine() {
delete _debugger;
delete _sprites;
+ delete _animator;
delete _screen;
delete _res;
delete _midi;
delete _saveFileMan;
delete _seq;
delete _scriptInterpreter;
+ delete _text;
delete _npcScriptData;
delete _scriptMain;
@@ -428,7 +423,6 @@ KyraEngine::~KyraEngine() {
delete _scriptClickData;
delete _scriptClick;
- delete [] _animStates;
delete [] _characterList;
delete [] _movFacingTable;
@@ -626,7 +620,7 @@ void KyraEngine::delay(uint32 amount, bool update) {
_sprites->updateSceneAnims();
if (update)
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
if (_currentCharacter->sceneId == 210) {
//XXX
@@ -690,7 +684,7 @@ void KyraEngine::mainLoop() {
updateMousePointer();
updateGameTimers();
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
updateTextFade();
_handleInput = true;
@@ -785,7 +779,7 @@ void KyraEngine::delayWithTicks(int ticks) {
uint32 nextTime = _system->getMillis() + ticks * _tickLength;
while (_system->getMillis() < nextTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
//if (_currentCharacter->sceneId == 210) {
// updateKyragemFading();
// seq_playEnd();
@@ -862,11 +856,11 @@ void KyraEngine::seq_intro() {
_screen->setFont(Screen::FID_8_FNT);
snd_playTheme(MUSIC_INTRO, 2);
snd_setSoundEffectFile(MUSIC_INTRO);
- setTalkCoords(144);
+ _text->setTalkCoords(144);
for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
(this->*introProcTable[i])();
}
- setTalkCoords(136);
+ _text->setTalkCoords(136);
waitTicks(30);
_seq->setCopyViewOffs(false);
_midi->stopMusic();
@@ -1138,10 +1132,10 @@ void KyraEngine::seq_poisonDeathNowAnim() {
resetBrandonAnimSeqSize();
freeShapes123();
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
_currentCharacter->x1 = _currentCharacter->x2 = -1;
_currentCharacter->y1 = _currentCharacter->y2 = -1;
- preserveAllBackgrounds();
+ _animator->preserveAllBackgrounds();
_screen->showMouse();
}
@@ -1227,9 +1221,9 @@ void KyraEngine::seq_winterScroll1() {
if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) {
// snd_playSoundEffect(0x20);
_sprites->_anims[0].play = false;
- _sprites->_animObjects[0].active = 0;
+ _animator->sprites()[0].active = 0;
_sprites->_anims[1].play = true;
- _sprites->_animObjects[1].active = 1;
+ _animator->sprites()[1].active = 1;
}
for (int i = 147; i <= 157; ++i) {
@@ -1241,7 +1235,7 @@ void KyraEngine::seq_winterScroll1() {
if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) {
for (int i = 0; i <= 7; ++i) {
_sprites->_anims[i].play = false;
- _sprites->_animObjects[i].active = 0;
+ _animator->sprites()[i].active = 0;
}
uint8 tmpPal[768];
memcpy(tmpPal, _screen->_currentPalette, 768);
@@ -1392,7 +1386,7 @@ void KyraEngine::seq_makeBrandonWisp() {
_brandonStatusBit0x02Flag = 1;
_currentCharacter->currentAnimFrame = 113;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) {
_screen->fadeSpecialPalette(30, 234, 13, 4);
} else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) {
@@ -2068,7 +2062,7 @@ void KyraEngine::setCharacterPositionWithUpdate(int character) {
setCharacterPosition(character, 0);
_sprites->updateSceneAnims();
updateGameTimers();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
updateTextFade();
if (_currentCharacter->sceneId == 210) {
@@ -2484,55 +2478,56 @@ void KyraEngine::resetBrandonPosionFlags() {
}
void KyraEngine::initAnimStateList() {
- _animStates[0].index = 0;
- _animStates[0].active = 1;
- _animStates[0].flags = 0x800;
- _animStates[0].background = _shapes[2];
- _animStates[0].rectSize = _screen->getRectSize(4, 48);
- _animStates[0].width = 4;
- _animStates[0].height = 48;
- _animStates[0].width2 = 4;
- _animStates[0].height2 = 3;
+ AnimObject *animStates = _animator->objects();
+ animStates[0].index = 0;
+ animStates[0].active = 1;
+ animStates[0].flags = 0x800;
+ animStates[0].background = _shapes[2];
+ animStates[0].rectSize = _screen->getRectSize(4, 48);
+ animStates[0].width = 4;
+ animStates[0].height = 48;
+ animStates[0].width2 = 4;
+ animStates[0].height2 = 3;
for (int i = 1; i <= 4; ++i) {
- _animStates[i].index = i;
- _animStates[i].active = 0;
- _animStates[i].flags = 0x800;
- _animStates[i].background = _shapes[3];
- _animStates[i].rectSize = _screen->getRectSize(4, 64);
- _animStates[i].width = 4;
- _animStates[i].height = 48;
- _animStates[i].width2 = 4;
- _animStates[i].height2 = 3;
+ animStates[i].index = i;
+ animStates[i].active = 0;
+ animStates[i].flags = 0x800;
+ animStates[i].background = _shapes[3];
+ animStates[i].rectSize = _screen->getRectSize(4, 64);
+ animStates[i].width = 4;
+ animStates[i].height = 48;
+ animStates[i].width2 = 4;
+ animStates[i].height2 = 3;
}
for (int i = 5; i < 16; ++i) {
- _animStates[i].index = i;
- _animStates[i].active = 0;
- _animStates[i].flags = 0;
+ animStates[i].index = i;
+ animStates[i].active = 0;
+ animStates[i].flags = 0;
}
for (int i = 16; i < 28; ++i) {
- _animStates[i].index = i;
- _animStates[i].flags = 0;
- _animStates[i].background = _shapes[349+i];
- _animStates[i].rectSize = _screen->getRectSize(3, 24);
- _animStates[i].width = 3;
- _animStates[i].height = 16;
- _animStates[i].width2 = 0;
- _animStates[i].height2 = 0;
+ animStates[i].index = i;
+ animStates[i].flags = 0;
+ animStates[i].background = _shapes[349+i];
+ animStates[i].rectSize = _screen->getRectSize(3, 24);
+ animStates[i].width = 3;
+ animStates[i].height = 16;
+ animStates[i].width2 = 0;
+ animStates[i].height2 = 0;
}
}
void KyraEngine::initSceneObjectList(int brandonAlive) {
debug(9, "initSceneObjectList(%d)", brandonAlive);
for (int i = 0; i < 31; ++i) {
- _charactersAnimState[i].active = 0;
+ _animator->actors()[i].active = 0;
}
int startAnimFrame = 0;
- AnimObject *curAnimState = _charactersAnimState;
+ AnimObject *curAnimState = _animator->actors();
curAnimState->active = 1;
curAnimState->drawY = _currentCharacter->y1;
curAnimState->sceneAnimPtr = _shapes[4+_currentCharacter->currentAnimFrame];
@@ -2557,15 +2552,15 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
curAnimState->y2 = curAnimState->y1;
curAnimState->refreshFlag = 1;
curAnimState->bkgdChangeFlag = 1;
- _objectQueue = 0;
- _objectQueue = objectAddHead(0, curAnimState);
+ _animator->clearQueue();
+ _animator->addObjectToQueue(curAnimState);
int listAdded = 0;
int addedObjects = 1;
for (int i = 1; i < 5; ++i) {
Character *ch = &_characterList[i];
- curAnimState = &_charactersAnimState[addedObjects];
+ curAnimState = &_animator->actors()[addedObjects];
if (ch->sceneId != _currentCharacter->sceneId) {
curAnimState->active = 0;
curAnimState->refreshFlag = 0;
@@ -2605,7 +2600,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
curAnimState->flags &= 0xFFFFFFFE;
}
- _objectQueue = objectQueue(_objectQueue, curAnimState);
+ _animator->addObjectToQueue(curAnimState);
++addedObjects;
++listAdded;
@@ -2614,7 +2609,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
}
for (int i = 0; i < 11; ++i) {
- curAnimState = &_sprites->_animObjects[i];
+ curAnimState = &_animator->sprites()[i];
if (_sprites->_anims[i].play) {
curAnimState->active = 1;
@@ -2644,12 +2639,11 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
if (_sprites->_anims[i].flipX)
curAnimState->flags |= 0x1;
- _objectQueue = objectQueue(_objectQueue, curAnimState);
-
+ _animator->addObjectToQueue(curAnimState);
}
for (int i = 0; i < 12; ++i) {
- curAnimState = &_animItems[i];
+ curAnimState = &_animator->items()[i];
Room *curRoom = &_roomTable[_currentCharacter->sceneId];
byte curItem = curRoom->itemsTable[i];
if (curItem != 0xFF) {
@@ -2669,7 +2663,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
curAnimState->refreshFlag = 1;
curAnimState->bkgdChangeFlag = 1;
- _objectQueue = objectQueue(_objectQueue, curAnimState);
+ _animator->addObjectToQueue(curAnimState);
} else {
curAnimState->active = 0;
curAnimState->refreshFlag = 0;
@@ -2677,22 +2671,22 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
}
}
- preserveAnyChangedBackgrounds();
- curAnimState = _charactersAnimState;
+ _animator->preserveAnyChangedBackgrounds();
+ curAnimState = _animator->actors();
curAnimState->bkgdChangeFlag = 1;
curAnimState->refreshFlag = 1;
for (int i = 1; i < 28; ++i) {
- curAnimState = &_animStates[i];
+ curAnimState = &_animator->objects()[i];
if (curAnimState->active) {
curAnimState->bkgdChangeFlag = 1;
curAnimState->refreshFlag = 1;
}
}
- restoreAllObjectBackgrounds();
- preserveAnyChangedBackgrounds();
- prepDrawAllObjects();
+ _animator->restoreAllObjectBackgrounds();
+ _animator->preserveAnyChangedBackgrounds();
+ _animator->prepDrawAllObjects();
initSceneScreen(brandonAlive);
- copyChangedObjectsForward(0);
+ _animator->copyChangedObjectsForward(0);
}
void KyraEngine::initSceneScreen(int brandonAlive) {
@@ -2731,186 +2725,6 @@ void KyraEngine::initSceneScreen(int brandonAlive) {
#pragma mark - Text handling
#pragma mark -
-void KyraEngine::setTalkCoords(uint16 y) {
- debug(9, "KyraEngine::setTalkCoords(%d)", y);
- _talkCoords.y = y;
-}
-
-int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
- debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
- _screen->_charWidth = -2;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- int strWidth = _screen->getTextWidth(str);
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- int w = x2 - x1 + 1;
- return x1 + (w - strWidth) / 2;
-}
-
-int KyraEngine::getCharLength(const char *str, int len) {
- debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
- int charsCount = 0;
- if (*str) {
- _screen->_charWidth = -2;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- int i = 0;
- while (i <= len && *str) {
- i += _screen->getCharWidth(*str++);
- ++charsCount;
- }
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- }
- return charsCount;
-}
-
-int KyraEngine::dropCRIntoString(char *str, int offs) {
- debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
- int pos = 0;
- str += offs;
- while (*str) {
- if (*str == ' ') {
- *str = '\r';
- return pos;
- }
- ++str;
- ++pos;
- }
- return 0;
-}
-
-char *KyraEngine::preprocessString(const char *str) {
- debug(9, "KyraEngine::preprocessString('%s')", str);
- assert(strlen(str) < sizeof(_talkBuffer) - 1);
- strcpy(_talkBuffer, str);
- char *p = _talkBuffer;
- while (*p) {
- if (*p == '\r') {
- return _talkBuffer;
- }
- ++p;
- }
- p = _talkBuffer;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- int textWidth = _screen->getTextWidth(p);
- _screen->_charWidth = 0;
- if (textWidth > 176) {
- if (textWidth > 352) {
- int count = getCharLength(p, textWidth / 3);
- int offs = dropCRIntoString(p, count);
- p += count + offs;
- _screen->_charWidth = -2;
- textWidth = _screen->getTextWidth(p);
- _screen->_charWidth = 0;
- count = getCharLength(p, textWidth / 2);
- dropCRIntoString(p, count);
- } else {
- int count = getCharLength(p, textWidth / 2);
- dropCRIntoString(p, count);
- }
- }
- _screen->setFont(curFont);
- return _talkBuffer;
-}
-
-int KyraEngine::buildMessageSubstrings(const char *str) {
- debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
- int currentLine = 0;
- int pos = 0;
- while (*str) {
- if (*str == '\r') {
- assert(currentLine < TALK_SUBSTRING_NUM);
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
- ++currentLine;
- pos = 0;
- } else {
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
- ++pos;
- if (pos > TALK_SUBSTRING_LEN - 2) {
- pos = TALK_SUBSTRING_LEN - 2;
- }
- }
- ++str;
- }
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
- return currentLine + 1;
-}
-
-int KyraEngine::getWidestLineWidth(int linesCount) {
- debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
- int maxWidth = 0;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- for (int l = 0; l < linesCount; ++l) {
- int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
- if (maxWidth < w) {
- maxWidth = w;
- }
- }
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- return maxWidth;
-}
-
-void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
- debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
- x1 = cx - w / 2;
- if (x1 + w >= Screen::SCREEN_W - 12) {
- x1 = Screen::SCREEN_W - 12 - w - 1;
- } else if (x1 < 12) {
- x1 = 12;
- }
- x2 = x1 + w + 1;
-}
-
-void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
- debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
- if (_talkMessagePrinted) {
- _talkMessagePrinted = false;
- _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
- }
-}
-
-void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
- debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
- char *str = preprocessString(text);
- int lineCount = buildMessageSubstrings(str);
- int top = y - lineCount * 10;
- if (top < 0) {
- top = 0;
- }
- _talkMessageY = top;
- _talkMessageH = lineCount * 10;
- int w = getWidestLineWidth(lineCount);
- int x1, x2;
- 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);
- int curPage = _screen->_curPage;
- _screen->_curPage = srcPage;
- for (int i = 0; i < lineCount; ++i) {
- top = i * 10 + _talkMessageY;
- char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
- int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, color, 0xC, 0);
- }
- _screen->_curPage = curPage;
- _talkMessagePrinted = true;
-}
-
-void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
- uint8 colorMap[] = { 0, 15, 12, 12 };
- colorMap[3] = c1;
- _screen->setTextColor(colorMap, 0, 3);
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- _screen->printText(str, x, y, c0, c2);
- _screen->_charWidth = 0;
- _screen->setFont(curFont);
-}
-
void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 charNum) {
debug(9, "KyraEngine::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum);
bool hasUpdatedNPCs = false;
@@ -2959,7 +2773,7 @@ void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 ch
animRefreshNPC(_talkingCharNum);
if (_charSayUnk2 != -1) {
- _sprites->_animObjects[_charSayUnk2].active = 0;
+ _animator->sprites()[_charSayUnk2].active = 0;
_sprites->_anims[_charSayUnk2].play = false;
_charSayUnk2 = -1;
}
@@ -2967,16 +2781,16 @@ void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 ch
updateGameTimers();
_sprites->updateSceneAnims();
- restoreAllObjectBackgrounds();
- preserveAnyChangedBackgrounds();
- prepDrawAllObjects();
+ _animator->restoreAllObjectBackgrounds();
+ _animator->preserveAnyChangedBackgrounds();
+ _animator->prepDrawAllObjects();
currPage = _screen->_curPage;
_screen->_curPage = 2;
- printCharacterText(chatStr, charNum);
+ _text->printCharacterText(chatStr, charNum, _characterList[charNum].x1);
_screen->_curPage = currPage;
- copyChangedObjectsForward(0);
+ _animator->copyChangedObjectsForward(0);
updateTextFade();
if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
@@ -3025,7 +2839,7 @@ void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
_talkingCharNum = -1;
_currentCharacter->currentAnimFrame = 7;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
}
@@ -3039,7 +2853,7 @@ void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
_currentCharacter->currentAnimFrame = 7;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
@@ -3054,7 +2868,7 @@ void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
_currentCharacter->currentAnimFrame = _currentCharAnimFrame;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
int8 KyraEngine::getChatPartnerNum() {
@@ -3089,46 +2903,26 @@ int KyraEngine::initCharacterChat(int8 charNum) {
_currentCharacter->currentAnimFrame = 16;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
_charSayUnk2 = -1;
- flagAllObjectsForBkgdChange();
- restoreAllObjectBackgrounds();
+ _animator->flagAllObjectsForBkgdChange();
+ _animator->restoreAllObjectBackgrounds();
if (charNum > 4 && charNum < 11) {
// TODO: Fill in weird _game_inventory stuff here
warning("STUB: initCharacterChat() for high charnums");
}
- flagAllObjectsForRefresh();
- flagAllObjectsForBkgdChange();
- preserveAnyChangedBackgrounds();
+ _animator->flagAllObjectsForRefresh();
+ _animator->flagAllObjectsForBkgdChange();
+ _animator->preserveAnyChangedBackgrounds();
_charSayUnk3 = charNum;
return 1;
}
-void KyraEngine::printCharacterText(char *text, int8 charNum) {
- uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
- int top, left, x1, x2, w, x;
- char *msg;
-
- uint8 color = colorTable[charNum];
- text = preprocessString(text);
- int lineCount = buildMessageSubstrings(text);
- w = getWidestLineWidth(lineCount);
- x = _characterList[charNum].x1;
- calcWidestLineBounds(x1, x2, w, x);
-
- for (int i = 0; i < lineCount; ++i) {
- top = i * 10 + _talkMessageY;
- msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
- left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, color, 0xC, 0);
- }
-}
-
void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
debug(9, "KyraEngine::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
@@ -3153,8 +2947,8 @@ void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
animRefreshNPC(charNum);
}
- char *processedString = preprocessString(chatStr);
- int lineNum = buildMessageSubstrings(processedString);
+ char *processedString = _text->preprocessString(chatStr);
+ int lineNum = _text->buildMessageSubstrings(processedString);
int16 yPos = _characterList[charNum].y1;
yPos -= _scaleTable[charNum] * _characterList[charNum].height;
@@ -3167,14 +2961,14 @@ void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
if (yPos > 100)
yPos = 100;
- _talkMessageY = yPos;
- _talkMessageH = lineNum * 10;
- restoreAllObjectBackgrounds();
+ _text->_talkMessageY = yPos;
+ _text->_talkMessageH = lineNum * 10;
+ _animator->restoreAllObjectBackgrounds();
- _screen->copyRegion(1, _talkMessageY, 1, 136, 319, _talkMessageH, 2, 2);
+ _screen->copyRegion(1, _text->_talkMessageY, 1, 136, 319, _text->_talkMessageH, 2, 2);
_screen->hideMouse();
- printCharacterText(processedString, charNum);
+ _text->printCharacterText(processedString, charNum, _characterList[charNum].x1);
_screen->showMouse();
if (chatDuration == -2)
@@ -3184,17 +2978,17 @@ void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
waitForChatToFinish(chatTicks, chatStr, charNum);
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
- _screen->copyRegion(1, 136, 1, _talkMessageY, 319, _talkMessageH, 2, 2);
- preserveAllBackgrounds();
- prepDrawAllObjects();
+ _screen->copyRegion(1, 136, 1, _text->_talkMessageY, 319, _text->_talkMessageH, 2, 2);
+ _animator->preserveAllBackgrounds();
+ _animator->prepDrawAllObjects();
_screen->hideMouse();
- _screen->copyRegion(1, _talkMessageY, 1, _talkMessageY, 319, _talkMessageH, 2, 0);
+ _screen->copyRegion(1, _text->_talkMessageY, 1, _text->_talkMessageY, 319, _text->_talkMessageH, 2, 0);
_screen->showMouse();
- flagAllObjectsForRefresh();
- copyChangedObjectsForward(0);
+ _animator->flagAllObjectsForRefresh();
+ _animator->copyChangedObjectsForward(0);
if (chatPartnerNum != -1 && chatPartnerNum < 5)
restoreChatPartnerAnimFrame(chatPartnerNum);
@@ -3216,7 +3010,7 @@ void KyraEngine::drawSentenceCommand(char *sentence, int color) {
_startSentencePalIndex = 0;
}
- printText(sentence, 8, 143, 0xFF, 12, 0);
+ _text->printText(sentence, 8, 143, 0xFF, 12, 0);
_screen->showMouse();
setTextFadeTimerCountdown(15);
_fadeText = false;
@@ -3257,10 +3051,8 @@ void KyraEngine::updateTextFade() {
_fadeText = false;
_startSentencePalIndex = -1;
}
-
}
-
#pragma mark -
#pragma mark - Item handling
#pragma mark -
@@ -3663,14 +3455,14 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un
void KyraEngine::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
debug(9, "exchangeItemWithMouseItem(%d, %d)", sceneId, itemIndex);
_screen->hideMouse();
- animRemoveGameItem(itemIndex);
+ _animator->animRemoveGameItem(itemIndex);
assert(sceneId < _roomTableSize);
Room *currentRoom = &_roomTable[sceneId];
int item = currentRoom->itemsTable[itemIndex];
currentRoom->itemsTable[itemIndex] = _itemInHand;
_itemInHand = item;
- animAddGameItem(itemIndex, sceneId);
+ _animator->animAddGameItem(itemIndex, sceneId);
// XXX snd_kyraPlaySound 53
setMouseItem(_itemInHand);
@@ -3749,7 +3541,7 @@ void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem,
currentRoom->itemsYPos[freeItem] = destY;
currentRoom->itemsTable[freeItem] = item;
// call kyraPlaySound(0x32)
- animAddGameItem(freeItem, _currentCharacter->sceneId);
+ _animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
return;
}
_screen->hideMouse();
@@ -3830,7 +3622,7 @@ void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem,
currentRoom->itemsYPos[freeItem] = destY;
currentRoom->itemsTable[freeItem] = item;
// call kyraPlaySound(0x32)
- animAddGameItem(freeItem, _currentCharacter->sceneId);
+ _animator->animAddGameItem(freeItem, _currentCharacter->sceneId);
_screen->showMouse();
}
@@ -4196,319 +3988,9 @@ void KyraEngine::redrawInventory(int page) {
#pragma mark - Animation/shape specific code
#pragma mark -
-void KyraEngine::preserveAllBackgrounds() {
- uint8 currPage = _screen->_curPage;
- _screen->_curPage = 2;
-
- AnimObject *curObject = _objectQueue;
- while (curObject) {
- if (curObject->active && !curObject->unk1) {
- preserveOrRestoreBackground(curObject, false);
- curObject->bkgdChangeFlag = 0;
- }
- curObject = curObject->nextAnimObject;
- }
- _screen->_curPage = currPage;
-}
-
-void KyraEngine::flagAllObjectsForBkgdChange() {
- AnimObject *curObject = _objectQueue;
- while (curObject) {
- curObject->bkgdChangeFlag = 1;
- curObject = curObject->nextAnimObject;
- }
-}
-
-void KyraEngine::flagAllObjectsForRefresh() {
- AnimObject *curObject = _objectQueue;
- while (curObject) {
- curObject->refreshFlag = 1;
- curObject = curObject->nextAnimObject;
- }
-}
-
-void KyraEngine::restoreAllObjectBackgrounds() {
- debug(9, "restoreAllObjectBackground()");
- AnimObject *curObject = _objectQueue;
- _screen->_curPage = 2;
-
- while (curObject) {
- if (curObject->active && !curObject->unk1) {
- preserveOrRestoreBackground(curObject, true);
- curObject->x2 = curObject->x1;
- curObject->y2 = curObject->y1;
- }
- curObject = curObject->nextAnimObject;
- }
-
- _screen->_curPage = 0;
-}
-
-void KyraEngine::preserveAnyChangedBackgrounds() {
- debug(9, "preserveAnyChangedBackgrounds()");
- AnimObject *curObject = _objectQueue;
- _screen->_curPage = 2;
-
- while (curObject) {
- if (curObject->active && !curObject->unk1 && curObject->bkgdChangeFlag) {
- preserveOrRestoreBackground(curObject, false);
- curObject->bkgdChangeFlag = 0;
- }
- curObject = curObject->nextAnimObject;
- }
-
- _screen->_curPage = 0;
-}
-
-void KyraEngine::preserveOrRestoreBackground(AnimObject *obj, bool restore) {
- debug(9, "preserveOrRestoreBackground(0x%X, restore)", obj, restore);
- int x = 0, y = 0, width = obj->width << 3, height = obj->height;
-
- if (restore) {
- x = obj->x2;
- y = obj->y2;
- } else {
- x = obj->x1;
- y = obj->y1;
- }
-
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
-
- int temp;
-
- temp = x + width;
- if (temp >= 319) {
- x = 319 - width;
- }
- temp = y + height;
- if (temp >= 136) {
- y = 136 - height;
- }
-
- if (restore) {
- _screen->copyBlockToPage(_screen->_curPage, x, y, width, height, obj->background);
- } else {
- _screen->copyRegionToBuffer(_screen->_curPage, x, y, width, height, obj->background);
- }
-}
-
-void KyraEngine::prepDrawAllObjects() {
- debug(9, "prepDrawAllObjects()");
- AnimObject *curObject = _objectQueue;
- int drawPage = 2;
- int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0;
- if (_noDrawShapesFlag)
- return;
- if (_brandonStatusBit & 0x20)
- flagUnk1 = 0x200;
- if (_brandonStatusBit & 0x40)
- flagUnk2 = 0x4000;
-
- while (curObject) {
- if (curObject->active) {
- int xpos = curObject->x1;
- int ypos = curObject->y1;
-
- int drawLayer = 0;
- if (!(curObject->flags & 0x800)) {
- drawLayer = 7;
- } else if (curObject->unk1) {
- drawLayer = 0;
- } else {
- drawLayer = _sprites->getDrawLayer(curObject->drawY);
- }
-
- // talking head functionallity
- if (_talkingCharNum != -1) {
- const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 };
- const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 };
- const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 };
- const int8 xOffsetTable2[] = { 6, 4, 8, 3, 6, 0, 0, 0 };
- const int8 yOffsetTable1[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
- const int8 yOffsetTable2[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
- if (curObject->index == 0 || curObject->index <= 4) {
- int shapesIndex = 0;
- if (curObject->index == _charSayUnk3) {
- shapesIndex = _currHeadShape + baseAnimFrameTable1[curObject->index];
- } else {
- shapesIndex = baseAnimFrameTable2[curObject->index];
- int temp2 = 0;
- if (curObject->index == 2) {
- if (_characterList[2].sceneId == 0x4D || _characterList[2].sceneId == 0x56) {
- temp2 = 1;
- } else {
- temp2 = 0;
- }
- } else {
- temp2 = 1;
- }
-
- if (!temp2) {
- shapesIndex = -1;
- }
- }
-
- xpos = curObject->x1;
- ypos = curObject->y1;
-
- int tempX = 0, tempY = 0;
- if (curObject->flags & 0x1) {
- tempX = (xOffsetTable1[curObject->index] * _brandonScaleX) >> 8;
- tempY = yOffsetTable1[curObject->index];
- } else {
- tempX = (xOffsetTable2[curObject->index] * _brandonScaleX) >> 8;
- tempY = yOffsetTable2[curObject->index];
- }
- tempY = (tempY * _brandonScaleY) >> 8;
- xpos += tempX;
- ypos += tempY;
-
- if (_scaleMode && _brandonScaleX != 256) {
- ++xpos;
- }
-
- if (curObject->index == 0) {
- if (!(_brandonStatusBit & 2)) {
- flagUnk3 = 0x100;
- if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) {
- flagUnk3 = 0;
- }
-
- int tempFlags = 0;
- if (flagUnk3 & 0x100) {
- if (curObject->flags & 1) {
- tempFlags = 1;
- }
- tempFlags |= 0x800 | flagUnk1 | 0x100;
- }
-
- if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) {
- tempFlags = 0;
- if (curObject->flags & 1) {
- tempFlags = 1;
- }
- tempFlags |= 0x900 | flagUnk1 | 0x4000;
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _brandonPoisonFlagsGFX, int(1), int(0)/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);
- } else {
- if (!(flagUnk2 & 0x4000)) {
- tempFlags = 0;
- if (curObject->flags & 1) {
- tempFlags = 1;
- }
- tempFlags |= 0x900 | flagUnk1;
- }
-
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
- }
- }
- } else {
- if (shapesIndex != -1) {
- int tempFlags = 0;
- if (curObject->flags & 1) {
- tempFlags = 1;
- }
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer);
- }
- }
- }
- }
-
- xpos = curObject->x1;
- ypos = curObject->y1;
-
- curObject->flags |= 0x800;
- if (curObject->index == 0) {
- flagUnk3 = 0x100;
-
- if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) {
- flagUnk3 = 0;
- }
-
- if (_brandonStatusBit & 2) {
- curObject->flags &= 0xFFFFFFFE;
- }
-
- if (!_scaleMode) {
- if (flagUnk3 & 0x100) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_brandonPoisonFlagsGFX, int(1), drawLayer);
- } else if (flagUnk3 & 0x4000) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, _brandonInvFlag, drawLayer);
- } else {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer);
- }
- } else {
- if (flagUnk3 & 0x100) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
- } else if (flagUnk3 & 0x4000) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(0), drawLayer, _brandonInvFlag, _brandonScaleX, _brandonScaleY);
- } else {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY);
- }
- }
- } else {
- if (curObject->index >= 16 && curObject->index <= 27) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_scaleTable[curObject->drawY], (int)_scaleTable[curObject->drawY]);
- } else {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer);
- }
- }
- }
- curObject = curObject->nextAnimObject;
- }
-}
-
-void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
- debug(9, "copyChangedObjectsForward(%d)", refreshFlag);
- AnimObject *curObject = _objectQueue;
-
- while (curObject) {
- if (curObject->active) {
- if (curObject->refreshFlag || refreshFlag) {
- int xpos = 0, ypos = 0, width = 0, height = 0;
- xpos = curObject->x1 - (curObject->width2+1);
- ypos = curObject->y1 - curObject->height2;
- width = (curObject->width + ((curObject->width2)>>3)+2)<<3;
- height = curObject->height + curObject->height2*2;
-
- if (xpos < 8) {
- xpos = 8;
- } else if (xpos + width > 312) {
- width = 312 - xpos;
- }
-
- if (ypos < 8) {
- ypos = 8;
- } else if (ypos + height > 136) {
- height = 136 - ypos;
- }
-
- _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, 2, 0, Screen::CR_CLIPPED);
- curObject->refreshFlag = 0;
- _updateScreen = true;
- }
- }
- curObject = curObject->nextAnimObject;
- }
- if (_updateScreen) {
- _screen->updateScreen();
- _updateScreen = false;
- }
-}
-
-void KyraEngine::updateAllObjectShapes() {
- debug(9, "updateAllObjectShapes()");
- restoreAllObjectBackgrounds();
- preserveAnyChangedBackgrounds();
- prepDrawAllObjects();
- copyChangedObjectsForward(0);
-}
-
void KyraEngine::animRefreshNPC(int character) {
debug(9, "animRefreshNPC(%d)", character);
- AnimObject *animObj = &_charactersAnimState[character];
+ AnimObject *animObj = &_animator->actors()[character];
Character *ch = &_characterList[character];
animObj->refreshFlag = 1;
@@ -4560,77 +4042,7 @@ void KyraEngine::animRefreshNPC(int character) {
animObj->width2 = 4;
animObj->height2 = 3;
- _objectQueue = objectRemoveQueue(_objectQueue, animObj);
- if (_objectQueue) {
- _objectQueue = objectQueue(_objectQueue, animObj);
- } else {
- _objectQueue = objectAddHead(0, animObj);
- }
-}
-
-void KyraEngine::animRemoveGameItem(int index) {
- debug(9, "animRemoveGameItem(%d)", index);
- restoreAllObjectBackgrounds();
-
- AnimObject *animObj = &_animItems[index];
- animObj->sceneAnimPtr = 0;
- animObj->animFrameNumber = -1;
- animObj->refreshFlag = 1;
- animObj->bkgdChangeFlag = 1;
- updateAllObjectShapes();
- animObj->active = 0;
-
- objectRemoveQueue(_objectQueue, animObj);
-}
-
-void KyraEngine::animAddGameItem(int index, uint16 sceneId) {
- debug(9, "animRemoveGameItem(%d, %d)", index, sceneId);
- restoreAllObjectBackgrounds();
- assert(sceneId < _roomTableSize);
- Room *currentRoom = &_roomTable[sceneId];
- AnimObject *animObj = &_animItems[index];
- animObj->active = 1;
- animObj->refreshFlag = 1;
- animObj->bkgdChangeFlag = 1;
- animObj->drawY = currentRoom->itemsYPos[index];
- animObj->sceneAnimPtr = _shapes[220+currentRoom->itemsTable[index]];
- animObj->animFrameNumber = -1;
- animObj->x1 = currentRoom->itemsXPos[index];
- animObj->y1 = currentRoom->itemsYPos[index];
- animObj->x1 -= fetchAnimWidth(animObj->sceneAnimPtr, _scaleTable[animObj->drawY]) >> 1;
- animObj->y1 -= fetchAnimHeight(animObj->sceneAnimPtr, _scaleTable[animObj->drawY]);
- animObj->x2 = animObj->x1;
- animObj->y2 = animObj->y1;
- animObj->width2 = 0;
- animObj->height2 = 0;
- _objectQueue = objectQueue(_objectQueue, animObj);
- preserveAnyChangedBackgrounds();
- animObj->refreshFlag = 1;
- animObj->bkgdChangeFlag = 1;
-}
-
-void KyraEngine::animAddNPC(int character) {
- debug(9, "animAddNPC(%d)", character);
- restoreAllObjectBackgrounds();
- AnimObject *animObj = &_charactersAnimState[character];
- const Character *ch = &_characterList[character];
-
- animObj->active = 1;
- animObj->refreshFlag = 1;
- animObj->bkgdChangeFlag = 1;
- animObj->drawY = ch->y1;
- animObj->sceneAnimPtr = _shapes[4+ch->currentAnimFrame];
- animObj->x1 = animObj->x2 = ch->x1 + _defaultShapeTable[ch->currentAnimFrame-7].xOffset;
- animObj->y1 = animObj->y2 = ch->y1 + _defaultShapeTable[ch->currentAnimFrame-7].yOffset;
- if (ch->facing >= 1 && ch->facing <= 3) {
- animObj->flags |= 1;
- } else if (ch->facing >= 5 && ch->facing <= 7) {
- animObj->flags &= 0xFFFFFFFE;
- }
- _objectQueue = objectQueue(_objectQueue, animObj);
- preserveAnyChangedBackgrounds();
- animObj->refreshFlag = 1;
- animObj->bkgdChangeFlag = 1;
+ _animator->refreshObject(animObj);
}
void KyraEngine::drawJewelPress(int jewel, int drawSpecial) {
@@ -4758,88 +4170,19 @@ void KyraEngine::freeShapes123() {
void KyraEngine::setBrandonAnimSeqSize(int width, int height) {
debug(9, "setBrandonAnimSeqSize(%d, %d)", width, height);
- restoreAllObjectBackgrounds();
- _brandonAnimSeqSizeWidth = _charactersAnimState[0].width;
- _brandonAnimSeqSizeHeight = _charactersAnimState[0].height;
- _charactersAnimState[0].width = width + 1;
- _charactersAnimState[0].height = height;
- preserveAllBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
+ _brandonAnimSeqSizeWidth = _animator->actors()[0].width;
+ _brandonAnimSeqSizeHeight = _animator->actors()[0].height;
+ _animator->actors()[0].width = width + 1;
+ _animator->actors()[0].height = height;
+ _animator->preserveAllBackgrounds();
}
void KyraEngine::resetBrandonAnimSeqSize() {
- restoreAllObjectBackgrounds();
- _charactersAnimState[0].width = _brandonAnimSeqSizeWidth;
- _charactersAnimState[0].height = _brandonAnimSeqSizeHeight;
- preserveAllBackgrounds();
-}
-
-#pragma mark -
-#pragma mark - Queue handling
-#pragma mark -
-
-AnimObject *KyraEngine::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
- AnimObject *cur = queue;
- AnimObject *prev = queue;
-
- while (cur != rem && cur) {
- AnimObject *temp = cur->nextAnimObject;
- if (!temp)
- break;
- prev = cur;
- cur = temp;
- }
-
- if (cur == queue) {
- if (!cur)
- return 0;
- return cur->nextAnimObject;
- }
-
- if (!cur->nextAnimObject) {
- if (cur == rem) {
- if (!prev) {
- return 0;
- } else {
- prev->nextAnimObject = 0;
- }
- }
- } else {
- if (cur == rem) {
- prev->nextAnimObject = rem->nextAnimObject;
- }
- }
-
- return queue;
-}
-
-AnimObject *KyraEngine::objectAddHead(AnimObject *queue, AnimObject *head) {
- head->nextAnimObject = queue;
- return head;
-}
-
-AnimObject *KyraEngine::objectQueue(AnimObject *queue, AnimObject *add) {
- if (add->drawY <= queue->drawY || !queue) {
- add->nextAnimObject = queue;
- return add;
- }
- AnimObject *cur = queue;
- AnimObject *prev = queue;
- while (add->drawY > cur->drawY) {
- AnimObject *temp = cur->nextAnimObject;
- if (!temp)
- break;
- prev = cur;
- cur = temp;
- }
-
- if (add->drawY <= cur->drawY) {
- prev->nextAnimObject = add;
- add->nextAnimObject = cur;
- } else {
- cur->nextAnimObject = add;
- add->nextAnimObject = 0;
- }
- return queue;
+ _animator->restoreAllObjectBackgrounds();
+ _animator->actors()[0].width = _brandonAnimSeqSizeWidth;
+ _animator->actors()[0].height = _brandonAnimSeqSizeHeight;
+ _animator->preserveAllBackgrounds();
}
#pragma mark -
@@ -4993,7 +4336,7 @@ void KyraEngine::makeBrandonFaceMouse() {
_currentCharacter->facing = 5;
}
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
void KyraEngine::setBrandonPoisonFlags(int reset) {
@@ -5491,7 +4834,7 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
*table = 8;
_currentCharacter->currentAnimFrame = 7;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
processInput(_mouseX, _mouseY);
return 0;
}
@@ -5546,7 +4889,7 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
_sprites->updateSceneAnims();
updateMousePointer();
updateGameTimers();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
updateTextFade();
if (_currentCharacter->sceneId == 210) {
// XXX updateKyragemFading
@@ -5562,7 +4905,7 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
_currentCharacter->currentAnimFrame = 7;
}
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
return returnValue;
}
@@ -5624,7 +4967,7 @@ int KyraEngine::changeScene(int facing) {
_currentCharacter->facing = facing;
animRefreshNPC(0);
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
enterNewScene(sceneId, facing, unk1, unk2, 0);
resetGameFlag(0xEE);
return 1;
@@ -5684,260 +5027,6 @@ int KyraEngine::changeScene(int facing) {
}
#pragma mark -
-#pragma mark - Timer handling
-#pragma mark -
-
-void KyraEngine::setupTimers() {
- debug(9, "setupTimers()");
- memset(_timers, 0, sizeof(_timers));
-
- for (int i = 0; i < 34; i++)
- _timers[i].active = 1;
-
- _timers[0].func = _timers[1].func = _timers[2].func = _timers[3].func = _timers[4].func = 0; //Unused.
- _timers[5].func = _timers[6].func = _timers[7].func = _timers[8].func = _timers[9].func = 0; //_nullsub51;
- _timers[10].func = _timers[11].func = _timers[12].func = _timers[13].func = 0; //_nullsub50;
- _timers[14].func = &KyraEngine::timerCheckAnimFlag2; //_nullsub52;
- _timers[15].func = &KyraEngine::timerUpdateHeadAnims; //_nullsub48;
- _timers[16].func = &KyraEngine::timerSetFlags1; //_nullsub47;
- _timers[17].func = 0; //sub_15120;
- _timers[18].func = &KyraEngine::timerCheckAnimFlag1; //_nullsub53;
- _timers[19].func = &KyraEngine::timerRedrawAmulet; //_nullsub54;
- _timers[20].func = 0; //offset _timerDummy1
- _timers[21].func = 0; //sub_1517C;
- _timers[22].func = 0; //offset _timerDummy2
- _timers[23].func = 0; //offset _timerDummy3,
- _timers[24].func = 0; //_nullsub45;
- _timers[25].func = 0; //offset _timerDummy4
- _timers[26].func = 0; //_nullsub46;
- _timers[27].func = 0; //offset _timerDummy5,
- _timers[28].func = 0; //offset _timerDummy6
- _timers[29].func = 0; //offset _timerDummy7,
- _timers[30].func = 0; //offset _timerDummy8,
- _timers[31].func = &KyraEngine::timerFadeText; //sub_151F8;
- _timers[32].func = &KyraEngine::updateAnimFlag1; //_nullsub61;
- _timers[33].func = &KyraEngine::updateAnimFlag2; //_nullsub62;
-
- _timers[0].countdown = _timers[1].countdown = _timers[2].countdown = _timers[3].countdown = _timers[4].countdown = -1;
- _timers[5].countdown = 5;
- _timers[6].countdown = 7;
- _timers[7].countdown = 8;
- _timers[8].countdown = 9;
- _timers[9].countdown = 7;
- _timers[10].countdown = _timers[11].countdown = _timers[12].countdown = _timers[13].countdown = 420;
- _timers[14].countdown = 600;
- _timers[15].countdown = 11;
- _timers[16].countdown = _timers[17].countdown = 7200;
- _timers[18].countdown = _timers[19].countdown = 600;
- _timers[20].countdown = 7200;
- _timers[21].countdown = 18000;
- _timers[22].countdown = 7200;
- _timers[23].countdown = _timers[24].countdown = _timers[25].countdown = _timers[26].countdown = _timers[27].countdown = 10800;
- _timers[28].countdown = 21600;
- _timers[29].countdown = 7200;
- _timers[30].countdown = 10800;
- _timers[31].countdown = -1;
- _timers[32].countdown = 9;
- _timers[33].countdown = 3;
-}
-
-void KyraEngine::updateGameTimers() {
- debug(9, "updateGameTimers()");
-
- if (_system->getMillis() < _timerNextRun)
- return;
-
- _timerNextRun += 99999;
-
- for (int i = 0; i < 34; i++) {
- if (_timers[i].active && _timers[i].countdown > -1) {
- if (_timers[i].nextRun <=_system->getMillis()) {
- if (i > 4 && _timers[i].func)
- (*this.*_timers[i].func)(i);
-
- _timers[i].nextRun = _system->getMillis() + _timers[i].countdown * _tickLength;
-
- }
- }
- if (_timers[i].nextRun < _timerNextRun)
- _timerNextRun = _timers[i].nextRun;
- }
-}
-
-void KyraEngine::clearNextEventTickCount() {
- debug(9, "clearNextEventTickCount()");
- _timerNextRun = 0;
-}
-
-void KyraEngine::setTimerDelay(uint8 timer, int32 countdown) {
- debug(9, "setTimerDelay(%i, %d)", timer, countdown);
- _timers[timer].countdown = countdown;
-}
-
-int16 KyraEngine::getTimerDelay(uint8 timer) {
- debug(9, "getTimerDelay(%i)", timer);
- return _timers[timer].countdown;
-}
-
-void KyraEngine::setTimerCountdown(uint8 timer, int32 countdown) {
- debug(9, "setTimerCountdown(%i, %i)", timer, countdown);
- _timers[timer].countdown = countdown;
-
- uint32 nextRun = _system->getMillis() + countdown;
- if (nextRun < _timerNextRun)
- _timerNextRun = nextRun;
-}
-
-void KyraEngine::enableTimer(uint8 timer) {
- debug(9, "enableTimer(%i)", timer);
- _timers[timer].active = 1;
-}
-
-void KyraEngine::disableTimer(uint8 timer) {
- debug(9, "disableTimer(%i)", timer);
- _timers[timer].active = 0;
-}
-
-void KyraEngine::timerUpdateHeadAnims(int timerNum) {
- debug(9, "timerUpdateHeadAnims(%i)", timerNum);
- static int8 currentFrame = 0;
- static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5,
- 4, 4, 6, 4, 8, 1, 9, 4, -1};
-
- if (_talkingCharNum < 0)
- return;
-
- _currHeadShape = frameTable[currentFrame];
- currentFrame++;
-
- if (frameTable[currentFrame] == -1)
- currentFrame = 0;
-
- animRefreshNPC(0);
- animRefreshNPC(_talkingCharNum);
-}
-
-void KyraEngine::timerSetFlags1(int timerNum) {
- debug(9, "timerSetFlags(%i)", timerNum);
- if (_currentCharacter->sceneId == 0x1C)
- return;
-
- int rndNr = _rnd.getRandomNumberRng(0, 3);
-
- for (int i = 0; i < 4; i++) {
- if (!queryGameFlag(rndNr + 17)) {
- setGameFlag(rndNr + 17);
- break;
- } else {
- rndNr++;
- if (rndNr > 3)
- rndNr = 0;
- }
- }
-}
-
-void KyraEngine::timerFadeText(int timerNum) {
- debug(9, "timerFadeText(%i)", timerNum);
- _fadeText = true;
-}
-
-void KyraEngine::updateAnimFlag1(int timerNum) {
- debug(9, "updateAnimFlag1(%d)", timerNum);
- if (_brandonStatusBit & 2) {
- _brandonStatusBit0x02Flag = 1;
- }
-}
-
-void KyraEngine::updateAnimFlag2(int timerNum) {
- debug(9, "updateAnimFlag2(%d)", timerNum);
- if (_brandonStatusBit & 0x20) {
- _brandonStatusBit0x20Flag = 1;
- }
-}
-
-void KyraEngine::setTextFadeTimerCountdown(int16 countdown) {
- debug(9, "setTextFadeTimerCountdown(%i)", countdown);
- //if (countdown == -1)
- //countdown = 32000;
-
- setTimerCountdown(31, countdown*60);
-}
-
-void KyraEngine::timerSetFlags2(int timerNum) {
- debug(9, "timerSetFlags2(%i)", timerNum);
- if (!((uint32*)(_flagsTable+0x2D))[timerNum])
- ((uint32*)(_flagsTable+0x2D))[timerNum] = 1;
-}
-
-void KyraEngine::timerCheckAnimFlag1(int timerNum) {
- debug(9, "timerCheckAnimFlag1(%i)", timerNum);
- if (_brandonStatusBit & 0x20) {
- checkAmuletAnimFlags();
- setTimerCountdown(18, -1);
- }
-}
-
-void KyraEngine::timerCheckAnimFlag2(int timerNum) {
- debug(9, "timerCheckAnimFlag1(%i)", timerNum);
- if (_brandonStatusBit & 0x2) {
- checkAmuletAnimFlags();
- setTimerCountdown(14, -1);
- }
-}
-
-void KyraEngine::checkAmuletAnimFlags() {
- debug(9, "checkSpecialAnimFlags()");
- if (_brandonStatusBit & 2) {
- seq_makeBrandonNormal2();
- setTimerCountdown(19, 300);
- }
-
- if (_brandonStatusBit & 0x20) {
- seq_makeBrandonNormal();
- setTimerCountdown(19, 300);
- }
-}
-
-void KyraEngine::timerRedrawAmulet(int timerNum) {
- debug(9, "timerRedrawAmulet(%i)", timerNum);
- if (queryGameFlag(0xF1)) {
- drawAmulet();
- setTimerCountdown(19, -1);
- }
-}
-
-void KyraEngine::drawAmulet() {
- debug(9, "drawAmulet()");
- static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1};
- static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1};
- static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1};
- static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1};
-
- resetGameFlag(0xF1);
- _screen->hideMouse();
-
- int i = 0;
- while (amuletTable1[i] != -1) {
- if (queryGameFlag(87))
- _screen->drawShape(0, _shapes[4+amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0);
-
- if (queryGameFlag(89))
- _screen->drawShape(0, _shapes[4+amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0);
-
- if (queryGameFlag(86))
- _screen->drawShape(0, _shapes[4+amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0);
-
- if (queryGameFlag(88))
- _screen->drawShape(0, _shapes[4+amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0);
-
- _screen->updateScreen();
- delayWithTicks(3);
- i++;
- }
- _screen->showMouse();
-}
-
-#pragma mark -
#pragma mark - Input
#pragma mark -
@@ -6007,7 +5096,7 @@ int KyraEngine::processInputHelper(int xpos, int ypos) {
if (item != 0xFF) {
if (_itemInHand == -1) {
_screen->hideMouse();
- animRemoveGameItem(item);
+ _animator->animRemoveGameItem(item);
// XXX call kyraPlaySound(53)
assert(_currentCharacter->sceneId < _roomTableSize);
Room *currentRoom = &_roomTable[_currentCharacter->sceneId];
@@ -6401,275 +5490,4 @@ void KyraEngine::saveGame(const char *fileName, const char *saveName) {
delete out;
}
-
-#pragma mark -
-#pragma mark - Button handling
-#pragma mark -
-
-Button *KyraEngine::initButton(Button *list, Button *newButton) {
- if (!newButton)
- return list;
- if (!list)
- return newButton;
- Button *cur = list;
- while (true) {
- if (!cur->nextButton) {
- break;
- }
- cur = cur->nextButton;
- }
- cur->nextButton = newButton;
- return list;
-}
-
-int KyraEngine::buttonInventoryCallback(Button *caller) {
- int itemOffset = caller->specialValue - 2;
- uint8 inventoryItem = _currentCharacter->inventoryItems[itemOffset];
- if (_itemInHand == -1) {
- if (inventoryItem == 0xFF) {
- // snd_playSoundEffect(0x36);
- return 0;
- } else {
- _screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
- // snd_playSoundEffect(0x35);
- setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179);
- _itemInHand = inventoryItem;
- _screen->showMouse();
- _currentCharacter->inventoryItems[itemOffset] = 0xFF;
- }
- } else {
- if (inventoryItem != 0xFF) {
- // snd_playSoundEffect(0x35);
- _screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
- _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
- setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179);
- _screen->showMouse();
- _currentCharacter->inventoryItems[itemOffset] = _itemInHand;
- _itemInHand = inventoryItem;
- } else {
- // snd_playSoundEffect(0x32);
- _screen->hideMouse();
- _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
- _screen->setMouseCursor(1, 1, _shapes[4]);
- updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179);
- _screen->showMouse();
- _currentCharacter->inventoryItems[itemOffset] = _itemInHand;
- _itemInHand = -1;
- }
- }
- _screen->updateScreen();
- // XXX clearKyrandiaButtonIO
- return 0;
-}
-
-int KyraEngine::buttonAmuletCallback(Button *caller) {
- if (!(_deathHandler & 8))
- return 1;
- int jewel = caller->specialValue - 0x14;
- if (_currentCharacter->sceneId == 210) {
- //if (_unkSceneVar == 4 || _unkSceneVar == 6)
- // return 1;
- }
- if (!queryGameFlag(0x2D))
- return 1;
- if (_itemInHand != -1) {
- assert(_putDownFirst);
- characterSays(_putDownFirst[0], 0, -2);
- return 1;
- }
- if (queryGameFlag(0xF1)) {
- assert(_waitForAmulet);
- characterSays(_waitForAmulet[0], 0, -2);
- return 1;
- }
- if (!queryGameFlag(0x55+jewel)) {
- assert(_blackJewel);
- makeBrandonFaceMouse();
- drawJewelPress(jewel, 1);
- characterSays(_blackJewel[0], 0, -2);
- return 1;
- }
- drawJewelPress(jewel, 0);
- drawJewelsFadeOutStart();
- drawJewelsFadeOutEnd(jewel);
-
- _scriptInterpreter->initScript(_scriptClick, _scriptClickData);
- _scriptClick->variables[3] = 0;
- _scriptClick->variables[6] = jewel;
- _scriptInterpreter->startScript(_scriptClick, 4);
-
- while (_scriptInterpreter->validScript(_scriptClick)) {
- _scriptInterpreter->runScript(_scriptClick);
- }
-
- if (_scriptClick->variables[3])
- return 1;
-
- _unkAmuletVar = 1;
- switch (jewel-1) {
- case 0:
- if (_brandonStatusBit & 1) {
- seq_brandonHealing2();
- } else if (_brandonStatusBit == 0) {
- seq_brandonHealing();
- assert(_healingTip);
- characterSays(_healingTip[0], 0, -2);
- }
- break;
-
- case 1:
- seq_makeBrandonInv();
- break;
-
- case 2:
- if (_brandonStatusBit & 1) {
- assert(_wispJewelStrings);
- characterSays(_wispJewelStrings[0], 0, -2);
- } else {
- if (_brandonStatusBit & 2) {
- // XXX
- seq_makeBrandonNormal2();
- // XXX
- } else {
- // do not check for item in hand again as in the original since some strings are missing
- // in the cd version
- if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
- // XXX
- seq_makeBrandonWisp();
- // XXX
- } else {
- seq_makeBrandonWisp();
- }
- setGameFlag(0x9E);
- }
- }
- break;
-
- case 3:
- seq_dispelMagicAnimation();
- assert(_magicJewelString);
- characterSays(_magicJewelString[0], 0, -2);
- break;
-
- default:
- break;
- }
- _unkAmuletVar = 0;
- // XXX clearKyrandiaButtonIO (!used before every return in this function!)
- return 1;
-}
-
-void KyraEngine::processButtonList(Button *list) {
- while (list) {
- if (list->flags & 8) {
- list = list->nextButton;
- continue;
- }
-
- int x = list->x;
- int y = list->y;
- assert(list->dimTableIndex < _screen->_screenDimTableCount);
- if (x < 0) {
- x += _screen->_screenDimTable[list->dimTableIndex].w << 3;
- }
- x += _screen->_screenDimTable[list->dimTableIndex].sx << 3;
-
- if (y < 0) {
- y += _screen->_screenDimTable[list->dimTableIndex].h;
- }
- y += _screen->_screenDimTable[list->dimTableIndex].sy;
-
- if (_mouseX >= x && _mouseY >= y && x + list->width >= _mouseX && y + list->height >= _mouseY) {
- int processMouseClick = 0;
- if (list->flags & 0x400) {
- if (_mousePressFlag) {
- if (!(list->flags2 & 1)) {
- list->flags2 |= 1;
- processButton(list);
- }
- } else {
- if (list->flags2 & 1) {
- list->flags2 &= 0xFFFE;
- processButton(list);
- processMouseClick = 1;
- }
- }
- } else if (_mousePressFlag) {
- processMouseClick = 1;
- }
-
- if (processMouseClick) {
- if (list->buttonCallback) {
- if ((this->*(list->buttonCallback))(list)) {
- break;
- }
- }
- }
- } else {
- if (list->flags2 & 1) {
- list->flags2 &= 0xFFFE;
- processButton(list);
- }
- list = list->nextButton;
- continue;
- }
-
- list = list->nextButton;
- }
-}
-
-void KyraEngine::processButton(Button *button) {
- if (!button)
- return;
-
- int processType = 0;
- uint8 *shape = 0;
- Button::ButtonCallback callback = 0;
-
- int flags = (button->flags2 & 5);
- if (flags == 1) {
- processType = button->process2;
- if (processType == 1) {
- shape = button->process2PtrShape;
- } else if (processType == 4) {
- callback = button->process2PtrCallback;
- }
- } else if (flags == 4 || flags == 5) {
- processType = button->process1;
- if (processType == 1) {
- shape = button->process1PtrShape;
- } else if (processType == 4) {
- callback = button->process1PtrCallback;
- }
- } else {
- processType = button->process0;
- if (processType == 1) {
- shape = button->process0PtrShape;
- } else if (processType == 4) {
- callback = button->process0PtrCallback;
- }
- }
-
- int x = button->x;
- int y = button->y;
- assert(button->dimTableIndex < _screen->_screenDimTableCount);
- if (x < 0) {
- x += _screen->_screenDimTable[button->dimTableIndex].w << 3;
- }
-
- if (y < 0) {
- y += _screen->_screenDimTable[button->dimTableIndex].h;
- }
-
- if (processType == 1 && shape) {
- _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10);
- } else if (processType == 4 && callback) {
- (this->*callback)(button);
- }
-}
-
} // End of namespace Kyra
diff --git a/kyra/kyra.h b/kyra/kyra.h
index 6cdf4a1116..1b41ccb3d5 100644
--- a/kyra/kyra.h
+++ b/kyra/kyra.h
@@ -78,36 +78,11 @@ struct Room {
uint32 unkField3[12];
};
-struct AnimObject {
- uint8 index;
- uint32 active;
- uint32 refreshFlag;
- uint32 bkgdChangeFlag;
- uint32 unk1;
- uint32 flags;
- int16 drawY;
- uint8 *sceneAnimPtr;
- int16 animFrameNumber;
- uint8 *background;
- uint16 rectSize;
- int16 x1, y1;
- int16 x2, y2;
- uint16 width;
- uint16 height;
- uint16 width2;
- uint16 height2;
- AnimObject *nextAnimObject;
-};
-
struct Rect {
int x, y;
int x2, y2;
};
-struct TalkCoords {
- uint16 y, x, w;
-};
-
struct Item {
uint8 unk1;
uint8 height;
@@ -143,6 +118,8 @@ struct ScriptState;
struct ScriptData;
class ScriptHelper;
class Debugger;
+class ScreenAnimator;
+class TextDisplayer;
class KyraEngine;
struct Timer {
@@ -183,14 +160,10 @@ struct Button {
class KyraEngine : public Engine {
friend class MusicPlayer;
friend class Debugger;
+ friend class ScreenAnimator;
public:
enum {
- TALK_SUBSTRING_LEN = 80,
- TALK_SUBSTRING_NUM = 3
- };
-
- enum {
MUSIC_INTRO = 0
};
@@ -201,6 +174,8 @@ public:
Resource *resource() { return _res; }
Screen *screen() { return _screen; }
+ ScreenAnimator *animator() { return _animator; }
+ TextDisplayer *text() { return _text; }
MusicPlayer *midi() { return _midi; }
Movie *createWSAMovie();
@@ -234,8 +209,6 @@ public:
bool snd_voicePlaying();
void snd_playSoundEffect(int track);
- void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
- void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
void drawSentenceCommand(char *sentence, int unk1);
void updateSentenceCommand(char *str1, char *str2, int unk1);
void updateTextFade();
@@ -250,8 +223,6 @@ public:
void waitTicks(int ticks);
void delayWithTicks(int ticks);
- void updateAllObjectShapes();
- void flagAllObjectsForRefresh();
void animRefreshNPC(int character);
int16 fetchAnimWidth(const uint8 *shape, int16 mult);
int16 fetchAnimHeight(const uint8 *shape, int16 mult);
@@ -426,23 +397,13 @@ protected:
void startup();
void mainLoop();
- void setTalkCoords(uint16 y);
- int getCenterStringX(const char *str, int x1, int x2);
- int getCharLength(const char *str, int len);
- int dropCRIntoString(char *str, int offs);
- char *preprocessString(const char *str);
- int buildMessageSubstrings(const char *str);
- int getWidestLineWidth(int linesCount);
- void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
- void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
- void characterSays(char *msg, int8 charNum, int8 chatDuration);
int initCharacterChat(int8 charNum);
int8 getChatPartnerNum();
void backupChatPartnerAnimFrame(int8 charNum);
void restoreChatPartnerAnimFrame(int8 charNum);
void endCharacterChat(int8 charNum, int16 arg_4);
void waitForChatToFinish(int16 chatDuration, char *str, uint8 charNum);
- void printCharacterText(char *text, int8 charNum);
+ void characterSays(char *chatStr, int8 charNum, int8 chatDuration);
void setCharacterDefaultFrame(int character);
void setCharactersPositions(int character);
@@ -472,13 +433,6 @@ protected:
void placeItemInGenericMapScene(int item, int index);
void initSceneObjectList(int brandonAlive);
void initSceneScreen(int brandonAlive);
- void preserveAllBackgrounds();
- void flagAllObjectsForBkgdChange();
- void restoreAllObjectBackgrounds();
- void preserveAnyChangedBackgrounds();
- void preserveOrRestoreBackground(AnimObject *obj, bool restore);
- void prepDrawAllObjects();
- void copyChangedObjectsForward(int refreshFlag);
int findDuplicateItemShape(int shape);
int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize);
int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end);
@@ -533,9 +487,6 @@ protected:
void updatePlayerItemsForScene();
void redrawInventory(int page);
- void animRemoveGameItem(int index);
- void animAddGameItem(int index, uint16 sceneId);
- void animAddNPC(int character);
void drawJewelPress(int jewel, int drawSpecial);
void drawJewelsFadeOutStart();
void drawJewelsFadeOutEnd(int jewel);
@@ -544,11 +495,6 @@ protected:
void setBrandonAnimSeqSize(int width, int height);
void resetBrandonAnimSeqSize();
- AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem);
- AnimObject *objectAddHead(AnimObject *queue, AnimObject *head);
- AnimObject *objectQueue(AnimObject *queue, AnimObject *add);
- AnimObject *_animStates;
-
void seq_demo();
void seq_intro();
void seq_introLogos();
@@ -637,12 +583,6 @@ protected:
bool _abortWalkFlag;
bool _abortWalkFlag2;
bool _mousePressFlag;
- char _talkBuffer[300];
- char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM];
- TalkCoords _talkCoords;
- uint16 _talkMessageY;
- uint16 _talkMessageH;
- bool _talkMessagePrinted;
uint8 _flagsTable[53];
uint8 *_unkPtr1, *_unkPtr2;
uint8 *_hidPage, *_screenPage;
@@ -654,10 +594,8 @@ protected:
int8 _itemInHand;
int _mouseState;
bool _handleInput;
- bool _updateScreen;
bool _changedScene;
int _unkScreenVar1, _unkScreenVar2, _unkScreenVar3;
- int _noDrawShapesFlag;
int _unkAmuletVar;
int _brandonAnimSeqSizeWidth;
@@ -688,7 +626,7 @@ protected:
uint16 _brandonStatusBit;
int _brandonStatusBit0x02Flag;
int _brandonStatusBit0x20Flag;
- uint8 _brandonPoisonFlagsGFX[256]; // this seem not to be posion flags, it is used for drawing once
+ uint8 _brandonPoisonFlagsGFX[256];
uint8 _deathHandler;
int _brandonInvFlag;
int8 _poisonDeathCounter;
@@ -731,9 +669,6 @@ protected:
bool _fadeText;
uint8 _configTalkspeed;
- AnimObject *_objectQueue;
- AnimObject *_charactersAnimState;
- AnimObject *_animItems;
int _curMusicTheme;
int _newMusicTheme;
@@ -742,9 +677,11 @@ protected:
Resource *_res;
Screen *_screen;
+ ScreenAnimator *_animator;
MusicPlayer *_midi;
SeqPlayer *_seq;
Sprites *_sprites;
+ TextDisplayer *_text;
ScriptHelper *_scriptInterpreter;
Debugger *_debugger;
Common::SaveFileManager *_saveFileMan;
diff --git a/kyra/module.mk b/kyra/module.mk
index ed33f27ba6..75568213eb 100644
--- a/kyra/module.mk
+++ b/kyra/module.mk
@@ -11,7 +11,11 @@ MODULE_OBJS := \
kyra/staticres.o \
kyra/sprites.o \
kyra/wsamovie.o \
- kyra/debugger.o
+ kyra/debugger.o \
+ kyra/animator.o \
+ kyra/gui.o \
+ kyra/text.o \
+ kyra/timer.o
MODULE_DIRS += \
kyra
diff --git a/kyra/script.cpp b/kyra/script.cpp
index ad9d853eed..c374b007ee 100644
--- a/kyra/script.cpp
+++ b/kyra/script.cpp
@@ -294,4 +294,271 @@ bool ScriptHelper::loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const
}
return false;
}
+
+#pragma mark -
+#pragma mark - Command implementations
+#pragma mark -
+
+void ScriptHelper::c1_jmpTo() {
+ _curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
+}
+
+void ScriptHelper::c1_setRetValue() {
+ _curScript->retValue = _parameter;
+}
+
+void ScriptHelper::c1_pushRetOrPos() {
+ switch (_parameter) {
+ case 0:
+ _curScript->stack[--_curScript->sp] = _curScript->retValue;
+ break;
+
+ case 1:
+ _curScript->stack[--_curScript->sp] = (_curScript->ip - _curScript->dataPtr->data) / 2 + 1;
+ _curScript->stack[--_curScript->sp] = _curScript->bp;
+ _curScript->bp = _curScript->sp + 2;
+ break;
+
+ default:
+ _continue = false;
+ _curScript->ip = 0;
+ break;
+ }
+}
+
+void ScriptHelper::c1_push() {
+ _curScript->stack[--_curScript->sp] = _parameter;
+}
+
+void ScriptHelper::c1_pushVar() {
+ _curScript->stack[--_curScript->sp] = _curScript->variables[_parameter];
+}
+
+void ScriptHelper::c1_pushBPNeg() {
+ _curScript->stack[--_curScript->sp] = _curScript->stack[(-(int32)(_parameter + 2)) + _curScript->bp];
+}
+
+void ScriptHelper::c1_pushBPAdd() {
+ _curScript->stack[--_curScript->sp] = _curScript->stack[(_parameter - 1) + _curScript->bp];
+}
+
+void ScriptHelper::c1_popRetOrPos() {
+ switch (_parameter) {
+ case 0:
+ _curScript->retValue = _curScript->stack[_curScript->sp++];
+ break;
+
+ case 1:
+ if (_curScript->sp >= 60) {
+ _continue = false;
+ _curScript->ip = 0;
+ } else {
+ _curScript->bp = _curScript->stack[_curScript->sp++];
+ _curScript->ip = _curScript->dataPtr->data + (_curScript->stack[_curScript->sp++] << 1);
+ }
+ break;
+
+ default:
+ _continue = false;
+ _curScript->ip = 0;
+ break;
+ }
+}
+
+void ScriptHelper::c1_popVar() {
+ _curScript->variables[_parameter] = _curScript->stack[_curScript->sp++];
+}
+
+void ScriptHelper::c1_popBPNeg() {
+ _curScript->stack[(-(int32)(_parameter + 2)) + _curScript->bp] = _curScript->stack[_curScript->sp++];
+}
+
+void ScriptHelper::c1_popBPAdd() {
+ _curScript->stack[(_parameter - 1) + _curScript->bp] = _curScript->stack[_curScript->sp++];
+}
+
+void ScriptHelper::c1_addSP() {
+ _curScript->sp += _parameter;
+}
+
+void ScriptHelper::c1_subSP() {
+ _curScript->sp -= _parameter;
+}
+
+void ScriptHelper::c1_execOpcode() {
+ assert((uint8)_parameter < _curScript->dataPtr->opcodeSize);
+ if (_curScript->dataPtr->opcodes[(uint8)_parameter] == &KyraEngine::cmd_dummy)
+ debug("calling unimplemented opcode(0x%.02X)", (uint8)_parameter);
+ _curScript->retValue = (_vm->*_curScript->dataPtr->opcodes[(uint8)_parameter])(_curScript);
+}
+
+void ScriptHelper::c1_ifNotJmp() {
+ if (!_curScript->stack[_curScript->sp++]) {
+ _parameter &= 0x7FFF;
+ _curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
+ }
+}
+
+void ScriptHelper::c1_negate() {
+ int16 value = _curScript->stack[_curScript->sp];
+ switch (_parameter) {
+ case 0:
+ if (!value) {
+ _curScript->stack[_curScript->sp] = 1;
+ } else {
+ _curScript->stack[_curScript->sp] = 0;
+ }
+ break;
+
+ case 1:
+ _curScript->stack[_curScript->sp] = -value;
+ break;
+
+ case 2:
+ _curScript->stack[_curScript->sp] = ~value;
+ break;
+
+ default:
+ _continue = false;
+ break;
+ }
+}
+
+void ScriptHelper::c1_eval() {
+ int16 ret = 0;
+ bool error = false;
+
+ int16 val1 = _curScript->stack[_curScript->sp++];
+ int16 val2 = _curScript->stack[_curScript->sp++];
+
+ switch (_parameter) {
+ case 0:
+ if (!val2 || !val1) {
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+ break;
+
+ case 1:
+ if (val2 || val1) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 2:
+ if (val1 == val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 3:
+ if (val1 != val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 4:
+ if (val1 > val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 5:
+ if (val1 >= val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 6:
+ if (val1 < val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 7:
+ if (val1 <= val2) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ break;
+
+ case 8:
+ ret = val1 + val2;
+ break;
+
+ case 9:
+ ret = val2 - val1;
+ break;
+
+ case 10:
+ ret = val1 * val2;
+ break;
+
+ case 11:
+ ret = val2 / val1;
+ break;
+
+ case 12:
+ ret = val2 >> val1;
+ break;
+
+ case 13:
+ ret = val2 << val1;
+ break;
+
+ case 14:
+ ret = val1 & val2;
+ break;
+
+ case 15:
+ ret = val1 | val2;
+ break;
+
+ case 16:
+ ret = val2 % val1;
+ break;
+
+ case 17:
+ ret = val1 ^ val2;
+ break;
+
+ default:
+ warning("Unknown evaluate func: %d", _parameter);
+ error = true;
+ break;
+ }
+
+ if (error) {
+ _curScript->ip = 0;
+ _continue = false;
+ } else {
+ _curScript->stack[--_curScript->sp] = ret;
+ }
+}
+
+void ScriptHelper::c1_setRetAndJmp() {
+ if (_curScript->sp >= 60) {
+ _continue = false;
+ _curScript->ip = 0;
+ } else {
+ _curScript->retValue = _curScript->stack[_curScript->sp++];
+ uint16 temp = _curScript->stack[_curScript->sp++];
+ _curScript->stack[60] = 0;
+ _curScript->ip = &_curScript->dataPtr->data[temp*2];
+ }
+}
} // end of namespace Kyra
diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp
index e8c078faf0..d3aa3a8d8c 100644
--- a/kyra/script_v1.cpp
+++ b/kyra/script_v1.cpp
@@ -25,277 +25,11 @@
#include "kyra/screen.h"
#include "kyra/sprites.h"
#include "kyra/wsamovie.h"
+#include "kyra/animator.h"
+#include "kyra/text.h"
#include "common/system.h"
namespace Kyra {
-
-void ScriptHelper::c1_jmpTo() {
- _curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
-}
-
-void ScriptHelper::c1_setRetValue() {
- _curScript->retValue = _parameter;
-}
-
-void ScriptHelper::c1_pushRetOrPos() {
- switch (_parameter) {
- case 0:
- _curScript->stack[--_curScript->sp] = _curScript->retValue;
- break;
-
- case 1:
- _curScript->stack[--_curScript->sp] = (_curScript->ip - _curScript->dataPtr->data) / 2 + 1;
- _curScript->stack[--_curScript->sp] = _curScript->bp;
- _curScript->bp = _curScript->sp + 2;
- break;
-
- default:
- _continue = false;
- _curScript->ip = 0;
- break;
- }
-}
-
-void ScriptHelper::c1_push() {
- _curScript->stack[--_curScript->sp] = _parameter;
-}
-
-void ScriptHelper::c1_pushVar() {
- _curScript->stack[--_curScript->sp] = _curScript->variables[_parameter];
-}
-
-void ScriptHelper::c1_pushBPNeg() {
- _curScript->stack[--_curScript->sp] = _curScript->stack[(-(int32)(_parameter + 2)) + _curScript->bp];
-}
-
-void ScriptHelper::c1_pushBPAdd() {
- _curScript->stack[--_curScript->sp] = _curScript->stack[(_parameter - 1) + _curScript->bp];
-}
-
-void ScriptHelper::c1_popRetOrPos() {
- switch (_parameter) {
- case 0:
- _curScript->retValue = _curScript->stack[_curScript->sp++];
- break;
-
- case 1:
- if (_curScript->sp >= 60) {
- _continue = false;
- _curScript->ip = 0;
- } else {
- _curScript->bp = _curScript->stack[_curScript->sp++];
- _curScript->ip = _curScript->dataPtr->data + (_curScript->stack[_curScript->sp++] << 1);
- }
- break;
-
- default:
- _continue = false;
- _curScript->ip = 0;
- break;
- }
-}
-
-void ScriptHelper::c1_popVar() {
- _curScript->variables[_parameter] = _curScript->stack[_curScript->sp++];
-}
-
-void ScriptHelper::c1_popBPNeg() {
- _curScript->stack[(-(int32)(_parameter + 2)) + _curScript->bp] = _curScript->stack[_curScript->sp++];
-}
-
-void ScriptHelper::c1_popBPAdd() {
- _curScript->stack[(_parameter - 1) + _curScript->bp] = _curScript->stack[_curScript->sp++];
-}
-
-void ScriptHelper::c1_addSP() {
- _curScript->sp += _parameter;
-}
-
-void ScriptHelper::c1_subSP() {
- _curScript->sp -= _parameter;
-}
-
-void ScriptHelper::c1_execOpcode() {
- assert((uint8)_parameter < _curScript->dataPtr->opcodeSize);
- if (_curScript->dataPtr->opcodes[(uint8)_parameter] == &KyraEngine::cmd_dummy)
- debug("calling unimplemented opcode(0x%.02X)", (uint8)_parameter);
- _curScript->retValue = (_vm->*_curScript->dataPtr->opcodes[(uint8)_parameter])(_curScript);
-}
-
-void ScriptHelper::c1_ifNotJmp() {
- if (!_curScript->stack[_curScript->sp++]) {
- _parameter &= 0x7FFF;
- _curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
- }
-}
-
-void ScriptHelper::c1_negate() {
- int16 value = _curScript->stack[_curScript->sp];
- switch (_parameter) {
- case 0:
- if (!value) {
- _curScript->stack[_curScript->sp] = 1;
- } else {
- _curScript->stack[_curScript->sp] = 0;
- }
- break;
-
- case 1:
- _curScript->stack[_curScript->sp] = -value;
- break;
-
- case 2:
- _curScript->stack[_curScript->sp] = ~value;
- break;
-
- default:
- _continue = false;
- break;
- }
-}
-
-void ScriptHelper::c1_eval() {
- int16 ret = 0;
- bool error = false;
-
- int16 val1 = _curScript->stack[_curScript->sp++];
- int16 val2 = _curScript->stack[_curScript->sp++];
-
- switch (_parameter) {
- case 0:
- if (!val2 || !val1) {
- ret = 0;
- } else {
- ret = 1;
- }
- break;
-
- case 1:
- if (val2 || val1) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 2:
- if (val1 == val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 3:
- if (val1 != val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 4:
- if (val1 > val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 5:
- if (val1 >= val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 6:
- if (val1 < val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 7:
- if (val1 <= val2) {
- ret = 1;
- } else {
- ret = 0;
- }
- break;
-
- case 8:
- ret = val1 + val2;
- break;
-
- case 9:
- ret = val2 - val1;
- break;
-
- case 10:
- ret = val1 * val2;
- break;
-
- case 11:
- ret = val2 / val1;
- break;
-
- case 12:
- ret = val2 >> val1;
- break;
-
- case 13:
- ret = val2 << val1;
- break;
-
- case 14:
- ret = val1 & val2;
- break;
-
- case 15:
- ret = val1 | val2;
- break;
-
- case 16:
- ret = val2 % val1;
- break;
-
- case 17:
- ret = val1 ^ val2;
- break;
-
- default:
- warning("Unknown evaluate func: %d", _parameter);
- error = true;
- break;
- }
-
- if (error) {
- _curScript->ip = 0;
- _continue = false;
- } else {
- _curScript->stack[--_curScript->sp] = ret;
- }
-}
-
-void ScriptHelper::c1_setRetAndJmp() {
- if (_curScript->sp >= 60) {
- _continue = false;
- _curScript->ip = 0;
- } else {
- _curScript->retValue = _curScript->stack[_curScript->sp++];
- uint16 temp = _curScript->stack[_curScript->sp++];
- _curScript->stack[60] = 0;
- _curScript->ip = &_curScript->dataPtr->data[temp*2];
- }
-}
-
-#pragma mark -
-#pragma mark - Opcode implementations
-#pragma mark -
-
#define stackPos(x) script->stack[script->sp+x]
#define stackPosString(x) (char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])]
@@ -431,8 +165,8 @@ int KyraEngine::cmd_dropItemInScene(ScriptState *script) {
room->itemsYPos[freeItem] = ypos;
room->itemsTable[freeItem] = item;
- animAddGameItem(freeItem, sceneId);
- updateAllObjectShapes();
+ _animator->animAddGameItem(freeItem, sceneId);
+ _animator->updateAllObjectShapes();
} else {
if (item == 43) {
placeItemInGenericMapScene(item, 0);
@@ -446,17 +180,17 @@ int KyraEngine::cmd_dropItemInScene(ScriptState *script) {
int KyraEngine::cmd_drawAnimShapeIntoScene(ScriptState *script) {
debug(3, "cmd_drawAnimShapeIntoScene(0x%X) (%d, %d, %d, %d)", stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_screen->hideMouse();
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
int shape = stackPos(0);
int xpos = stackPos(1);
int ypos = stackPos(2);
int flags = (stackPos(3) != 0) ? 1 : 0;
_screen->drawShape(2, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags);
_screen->drawShape(0, _sprites->_sceneShapes[shape], xpos, ypos, 0, flags);
- flagAllObjectsForBkgdChange();
- preserveAnyChangedBackgrounds();
- flagAllObjectsForRefresh();
- updateAllObjectShapes();
+ _animator->flagAllObjectsForBkgdChange();
+ _animator->preserveAnyChangedBackgrounds();
+ _animator->flagAllObjectsForRefresh();
+ _animator->updateAllObjectShapes();
_screen->showMouse();
return 0;
}
@@ -506,16 +240,16 @@ int KyraEngine::cmd_destroyMouseItem(ScriptState *script) {
int KyraEngine::cmd_runSceneAnimUntilDone(ScriptState *script) {
debug(3, "cmd_runSceneAnimUntilDone(0x%X) (%d)", script, stackPos(0));
_sprites->_anims[stackPos(0)].play = true;
- _sprites->_animObjects[stackPos(0)].active = 1;
+ _animator->sprites()[stackPos(0)].active = 1;
_screen->hideMouse();
- restoreAllObjectBackgrounds();
- flagAllObjectsForBkgdChange();
- preserveAnyChangedBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
+ _animator->flagAllObjectsForBkgdChange();
+ _animator->preserveAnyChangedBackgrounds();
while (_sprites->_anims[stackPos(0)].play) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
_screen->showMouse();
return 0;
}
@@ -636,7 +370,7 @@ int KyraEngine::cmd_magicOutMouseItem(ScriptState *script) {
int KyraEngine::cmd_internalAnimOn(ScriptState *script) {
debug(3, "cmd_internalAnimOn(0x%X) (%d)", script, stackPos(0));
- _sprites->_animObjects[stackPos(0)].active = 1;
+ _animator->sprites()[stackPos(0)].active = 1;
return 0;
}
@@ -715,7 +449,7 @@ int KyraEngine::cmd_runWSAFromBeginningToEnd(ScriptState *script) {
_movieObjects[wsaIndex]->_drawPage = 0;
while (running) {
_movieObjects[wsaIndex]->displayFrame(wsaFrame++);
- _updateScreen = true;
+ _animator->_updateScreen = true;
if (wsaFrame >= _movieObjects[wsaIndex]->frames())
running = false;
@@ -723,7 +457,7 @@ int KyraEngine::cmd_runWSAFromBeginningToEnd(ScriptState *script) {
while (_system->getMillis() < continueTime) {
if (worldUpdate) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
} else {
_screen->updateScreen();
}
@@ -751,10 +485,10 @@ int KyraEngine::cmd_displayWSAFrame(ScriptState *script) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
delay(10);
}
- _updateScreen = true;
+ _animator->_updateScreen = true;
_screen->showMouse();
return 0;
}
@@ -793,7 +527,7 @@ int KyraEngine::cmd_popBrandonIntoScene(ScriptState *script) {
int yOffset = _defaultShapeTable[0].yOffset;
int width = _defaultShapeTable[0].w << 3;
int height = _defaultShapeTable[0].h;
- AnimObject *curAnim = _charactersAnimState;
+ AnimObject *curAnim = _animator->actors();
if (changeScaleMode) {
curAnim->x1 = _currentCharacter->x1;
@@ -820,9 +554,9 @@ int KyraEngine::cmd_popBrandonIntoScene(ScriptState *script) {
}
animRefreshNPC(0);
- preserveAllBackgrounds();
- prepDrawAllObjects();
- copyChangedObjectsForward(0);
+ _animator->preserveAllBackgrounds();
+ _animator->prepDrawAllObjects();
+ _animator->copyChangedObjectsForward(0);
_scaleMode = scaleModeBackup;
@@ -831,7 +565,7 @@ int KyraEngine::cmd_popBrandonIntoScene(ScriptState *script) {
int KyraEngine::cmd_restoreAllObjectBackgrounds(ScriptState *script) {
debug(3, "cmd_restoreAllObjectBackgrounds(0x%X) ()", script);
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
return 0;
}
@@ -855,18 +589,18 @@ int KyraEngine::cmd_customPrintTalkString(ScriptState *script) {
delay(10);
}
snd_playVoiceFile(stackPos(0));
- printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
+ _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
} else {
debug(3, "cmd_customPrintTalkString(0x%X) ('%s', %d, %d, %d)", script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF);
- printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2);
+ _text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2);
}
- _updateScreen = true;
+ _animator->_updateScreen = true;
return 0;
}
int KyraEngine::cmd_restoreCustomPrintBackground(ScriptState *script) {
debug(3, "cmd_restoreCustomPrintBackground(0x%X) ()", script);
- restoreTalkTextMessageBkgd(2, 0);
+ _text->restoreTalkTextMessageBkgd(2, 0);
return 0;
}
@@ -898,15 +632,15 @@ int KyraEngine::cmd_changeCharactersFacing(ScriptState *script) {
int facing = stackPos(1);
int newAnimFrame = stackPos(2);
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
if (newAnimFrame != -1) {
_characterList[character].currentAnimFrame = newAnimFrame;
}
_characterList[character].facing = facing;
animRefreshNPC(character);
- preserveAllBackgrounds();
- prepDrawAllObjects();
- copyChangedObjectsForward(0);
+ _animator->preserveAllBackgrounds();
+ _animator->prepDrawAllObjects();
+ _animator->copyChangedObjectsForward(0);
return 0;
}
@@ -957,7 +691,7 @@ int KyraEngine::cmd_displayWSAFrameOnHidPage(ScriptState *script) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
delay(10);
}
_screen->showMouse();
@@ -988,11 +722,11 @@ int KyraEngine::cmd_displayWSASequentialFrames(ScriptState *script) {
int frame = startFrame;
while (endFrame >= frame) {
_movieObjects[wsaIndex]->displayFrame(frame);
- _updateScreen = true;
+ _animator->_updateScreen = true;
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
if (continueTime - _system->getMillis() >= 10)
delay(10);
}
@@ -1002,11 +736,11 @@ int KyraEngine::cmd_displayWSASequentialFrames(ScriptState *script) {
int frame = startFrame;
while (endFrame <= frame) {
_movieObjects[wsaIndex]->displayFrame(frame);
- _updateScreen = true;
+ _animator->_updateScreen = true;
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
if (continueTime - _system->getMillis() >= 10)
delay(10);
}
@@ -1032,14 +766,14 @@ int KyraEngine::cmd_drawCharacterStanding(ScriptState *script) {
}
animRefreshNPC(character);
if (updateShapes) {
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
return 0;
}
int KyraEngine::cmd_internalAnimOff(ScriptState *script) {
debug(3, "cmd_internalAnimOff(0x%X) (%d)", script, stackPos(0));
- _sprites->_animObjects[stackPos(0)].active = 0;
+ _animator->sprites()[stackPos(0)].active = 0;
return 0;
}
@@ -1052,10 +786,10 @@ int KyraEngine::cmd_changeCharactersXAndY(ScriptState *script) {
x &= 0xFFFC;
y &= 0xFFFE;
}
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
ch->x1 = ch->x2 = x;
ch->y1 = ch->y2 = y;
- preserveAllBackgrounds();
+ _animator->preserveAllBackgrounds();
return 0;
}
@@ -1073,7 +807,7 @@ int KyraEngine::cmd_querySceneAnimatorBeacon(ScriptState *script) {
int KyraEngine::cmd_refreshSceneAnimator(ScriptState *script) {
debug(3, "cmd_refreshSceneAnimator(0x%X) ()", script);
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
return 0;
}
@@ -1149,8 +883,8 @@ int KyraEngine::cmd_popMobileNPCIntoScene(ScriptState *script) {
curChar->x1 = curChar->x2 = xpos;
curChar->y1 = curChar->y2 = ypos;
- animAddNPC(character);
- updateAllObjectShapes();
+ _animator->animAddNPC(character);
+ _animator->updateAllObjectShapes();
return 0;
}
@@ -1172,7 +906,7 @@ int KyraEngine::cmd_unhideMobileCharacter(ScriptState *script) {
int KyraEngine::cmd_setCharactersLocation(ScriptState *script) {
debug(3, "cmd_setCharactersLocation(0x%X) (%d, %d)", script, stackPos(0), stackPos(1));
Character *ch = &_characterList[stackPos(0)];
- AnimObject *animObj = &_charactersAnimState[stackPos(0)];
+ AnimObject *animObj = &_animator->actors()[stackPos(0)];
int newScene = stackPos(1);
if (_currentCharacter->sceneId == ch->sceneId) {
if (_currentCharacter->sceneId != newScene)
@@ -1260,7 +994,7 @@ int KyraEngine::cmd_walkCharacterToPoint(ScriptState *script) {
_sprites->updateSceneAnims();
updateMousePointer();
updateGameTimers();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
updateTextFade();
if ((nextFrame - _system->getMillis()) >= 10)
delay(10);
@@ -1317,13 +1051,13 @@ int KyraEngine::cmd_setLogicPage(ScriptState *script) {
int KyraEngine::cmd_fatPrint(ScriptState *script) {
debug(3, "cmd_fatPrint(0x%X) ('%s', %d, %d, %d, %d, %d)", script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
- printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
return 0;
}
int KyraEngine::cmd_preserveAllObjectBackgrounds(ScriptState *script) {
debug(3, "cmd_preserveAllObjectBackgrounds(0x%X) ()", script);
- preserveAllBackgrounds();
+ _animator->preserveAllBackgrounds();
return 0;
}
@@ -1331,7 +1065,7 @@ int KyraEngine::cmd_updateSceneAnimations(ScriptState *script) {
debug(3, "cmd_updateSceneAnimations(0x%X) (%d)", script, stackPos(0));
if (stackPos(0)) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
return 0;
}
@@ -1489,11 +1223,11 @@ int KyraEngine::cmd_makeAmuletAppear(ScriptState *script) {
amulet.displayFrame(code);
- _updateScreen = true;
+ _animator->_updateScreen = true;
while (_system->getMillis() < nextTime) {
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
}
}
_screen->showMouse();
@@ -1515,12 +1249,12 @@ int KyraEngine::cmd_drawItemShapeIntoScene(ScriptState *script) {
_screen->drawShape(2, _shapes[220+item], x, y, 0, flags);
} else {
_screen->hideMouse();
- restoreAllObjectBackgrounds();
+ _animator->restoreAllObjectBackgrounds();
_screen->drawShape(2, _shapes[220+item], x, y, 0, flags);
_screen->drawShape(0, _shapes[220+item], x, y, 0, flags);
- flagAllObjectsForBkgdChange();
- flagAllObjectsForRefresh();
- updateAllObjectShapes();
+ _animator->flagAllObjectsForBkgdChange();
+ _animator->flagAllObjectsForRefresh();
+ _animator->updateAllObjectShapes();
_screen->showMouse();
}
return 0;
@@ -1538,14 +1272,14 @@ int KyraEngine::cmd_waitForConfirmationMouseClick(ScriptState *script) {
while (!_mousePressFlag) {
updateMousePointer();
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
delay(10);
}
while (_mousePressFlag) {
updateMousePointer();
_sprites->updateSceneAnims();
- updateAllObjectShapes();
+ _animator->updateAllObjectShapes();
delay(10);
}
// }
@@ -1706,7 +1440,7 @@ int KyraEngine::cmd_itemAppearsOnGround(ScriptState *script) {
int KyraEngine::cmd_setNoDrawShapesFlag(ScriptState *script) {
debug(3, "cmd_setNoDrawShapesFlag(0x%X) (%d)", script, stackPos(0));
- _noDrawShapesFlag = stackPos(0);
+ _animator->_noDrawShapesFlag = stackPos(0);
return 0;
}
diff --git a/kyra/seqplayer.cpp b/kyra/seqplayer.cpp
index 6cd2b97aae..71be508b91 100755
--- a/kyra/seqplayer.cpp
+++ b/kyra/seqplayer.cpp
@@ -29,6 +29,7 @@
#include "kyra/screen.h"
#include "kyra/sound.h"
#include "kyra/wsamovie.h"
+#include "kyra/text.h"
#include "kyra/seqplayer.h"
@@ -266,7 +267,7 @@ void SeqPlayer::s1_printTalkText() {
} else {
b = 0;
}
- _vm->restoreTalkTextMessageBkgd(2, b);
+ _vm->text()->restoreTalkTextMessageBkgd(2, b);
}
_seqTalkTextPrinted = true;
_seqTalkTextRestored = false;
@@ -275,7 +276,7 @@ void SeqPlayer::s1_printTalkText() {
} else {
b = 0;
}
- _vm->printTalkTextMessage(_vm->seqTextsTable()[txt], x, y, fillColor, b, 2);
+ _vm->text()->printTalkTextMessage(_vm->seqTextsTable()[txt], x, y, fillColor, b, 2);
}
void SeqPlayer::s1_restoreTalkText() {
@@ -286,7 +287,7 @@ void SeqPlayer::s1_restoreTalkText() {
} else {
b = 0;
}
- _vm->restoreTalkTextMessageBkgd(2, b);
+ _vm->text()->restoreTalkTextMessageBkgd(2, b);
_seqTalkTextRestored = true;
}
}
diff --git a/kyra/sprites.cpp b/kyra/sprites.cpp
index 6115c18c08..f83b53d083 100644
--- a/kyra/sprites.cpp
+++ b/kyra/sprites.cpp
@@ -27,6 +27,7 @@
#include "kyra/kyra.h"
#include "kyra/sprites.h"
#include "kyra/resource.h"
+#include "kyra/animator.h"
namespace Kyra {
@@ -339,8 +340,8 @@ void Sprites::updateSceneAnims() {
data += 2;
debug(6, "func: Update Brandon's sprite");
_engine->animRefreshNPC(0);
- _engine->flagAllObjectsForRefresh();
- _engine->updateAllObjectShapes();
+ _engine->animator()->flagAllObjectsForRefresh();
+ _engine->animator()->updateAllObjectShapes();
break;
case 0xFFB0:
data += 2;
@@ -524,23 +525,24 @@ void Sprites::loadSceneShapes() {
void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) {
debug(9, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag);
- _animObjects[animNum].refreshFlag = 1;
- _animObjects[animNum].bkgdChangeFlag = 1;
+ AnimObject &anim = _engine->animator()->sprites()[animNum];
+ anim.refreshFlag = 1;
+ anim.bkgdChangeFlag = 1;
if (unkFlag)
- _animObjects[animNum].flags |= 0x0200;
+ anim.flags |= 0x0200;
else
- _animObjects[animNum].flags &= 0xFD00;
+ anim.flags &= 0xFD00;
if (flipX)
- _animObjects[animNum].flags |= 1;
+ anim.flags |= 1;
else
- _animObjects[animNum].flags &= 0xFE;
+ anim.flags &= 0xFE;
- _animObjects[animNum].sceneAnimPtr = _sceneShapes[shapeNum];
- _animObjects[animNum].animFrameNumber = -1;
- _animObjects[animNum].x1 = x;
- _animObjects[animNum].y1 = y;
+ anim.sceneAnimPtr = _sceneShapes[shapeNum];
+ anim.animFrameNumber = -1;
+ anim.x1 = x;
+ anim.y1 = y;
}
int Sprites::getDrawLayer(int y) {
diff --git a/kyra/sprites.h b/kyra/sprites.h
index 81405e7cee..87a7427b1a 100644
--- a/kyra/sprites.h
+++ b/kyra/sprites.h
@@ -67,7 +67,6 @@ public:
void loadSceneShapes();
Anim _anims[MAX_NUM_ANIMS];
- AnimObject *_animObjects;
uint8 *_sceneShapes[50];
void refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag);
diff --git a/kyra/text.cpp b/kyra/text.cpp
new file mode 100644
index 0000000000..c9feadbb49
--- /dev/null
+++ b/kyra/text.cpp
@@ -0,0 +1,240 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "kyra/screen.h"
+#include "kyra/text.h"
+
+namespace Kyra {
+TextDisplayer::TextDisplayer(Screen *screen) {
+ _screen = screen;
+
+ _talkCoords.y = 0x88;
+ _talkCoords.x = 0;
+ _talkCoords.w = 0;
+ _talkMessageY = 0xC;
+ _talkMessageH = 0;
+ _talkMessagePrinted = false;
+}
+
+void TextDisplayer::setTalkCoords(uint16 y) {
+ debug(9, "TextDisplayer::setTalkCoords(%d)", y);
+ _talkCoords.y = y;
+}
+
+int TextDisplayer::getCenterStringX(const char *str, int x1, int x2) {
+ debug(9, "TextDisplayer::getCenterStringX('%s', %d, %d)", str, x1, x2);
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int strWidth = _screen->getTextWidth(str);
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ int w = x2 - x1 + 1;
+ return x1 + (w - strWidth) / 2;
+}
+
+int TextDisplayer::getCharLength(const char *str, int len) {
+ debug(9, "TextDisplayer::getCharLength('%s', %d)", str, len);
+ int charsCount = 0;
+ if (*str) {
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int i = 0;
+ while (i <= len && *str) {
+ i += _screen->getCharWidth(*str++);
+ ++charsCount;
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ }
+ return charsCount;
+}
+
+int TextDisplayer::dropCRIntoString(char *str, int offs) {
+ debug(9, "TextDisplayer::dropCRIntoString('%s', %d)", str, offs);
+ int pos = 0;
+ str += offs;
+ while (*str) {
+ if (*str == ' ') {
+ *str = '\r';
+ return pos;
+ }
+ ++str;
+ ++pos;
+ }
+ return 0;
+}
+
+char *TextDisplayer::preprocessString(const char *str) {
+ debug(9, "TextDisplayer::preprocessString('%s')", str);
+ assert(strlen(str) < sizeof(_talkBuffer) - 1);
+ strcpy(_talkBuffer, str);
+ char *p = _talkBuffer;
+ while (*p) {
+ if (*p == '\r') {
+ return _talkBuffer;
+ }
+ ++p;
+ }
+ p = _talkBuffer;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ int textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ if (textWidth > 176) {
+ if (textWidth > 352) {
+ int count = getCharLength(p, textWidth / 3);
+ int offs = dropCRIntoString(p, count);
+ p += count + offs;
+ _screen->_charWidth = -2;
+ textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ } else {
+ int count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ }
+ }
+ _screen->setFont(curFont);
+ return _talkBuffer;
+}
+
+int TextDisplayer::buildMessageSubstrings(const char *str) {
+ debug(9, "TextDisplayer::buildMessageSubstrings('%s')", str);
+ int currentLine = 0;
+ int pos = 0;
+ while (*str) {
+ if (*str == '\r') {
+ assert(currentLine < TALK_SUBSTRING_NUM);
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
+ ++currentLine;
+ pos = 0;
+ } else {
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
+ ++pos;
+ if (pos > TALK_SUBSTRING_LEN - 2) {
+ pos = TALK_SUBSTRING_LEN - 2;
+ }
+ }
+ ++str;
+ }
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
+ return currentLine + 1;
+}
+
+int TextDisplayer::getWidestLineWidth(int linesCount) {
+ debug(9, "TextDisplayer::getWidestLineWidth(%d)", linesCount);
+ int maxWidth = 0;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ for (int l = 0; l < linesCount; ++l) {
+ int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
+ if (maxWidth < w) {
+ maxWidth = w;
+ }
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ return maxWidth;
+}
+
+void TextDisplayer::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
+ debug(9, "TextDisplayer::calcWidestLineBounds(%d, %d)", w, cx);
+ x1 = cx - w / 2;
+ if (x1 + w >= Screen::SCREEN_W - 12) {
+ x1 = Screen::SCREEN_W - 12 - w - 1;
+ } else if (x1 < 12) {
+ x1 = 12;
+ }
+ x2 = x1 + w + 1;
+}
+
+void TextDisplayer::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
+ debug(9, "TextDisplayer::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
+ if (_talkMessagePrinted) {
+ _talkMessagePrinted = false;
+ _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ }
+}
+
+void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
+ debug(9, "TextDisplayer::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
+ char *str = preprocessString(text);
+ int lineCount = buildMessageSubstrings(str);
+ int top = y - lineCount * 10;
+ if (top < 0) {
+ top = 0;
+ }
+ _talkMessageY = top;
+ _talkMessageH = lineCount * 10;
+ int w = getWidestLineWidth(lineCount);
+ int x1, x2;
+ 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);
+ int curPage = _screen->_curPage;
+ _screen->_curPage = srcPage;
+ for (int i = 0; i < lineCount; ++i) {
+ top = i * 10 + _talkMessageY;
+ char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
+ int left = getCenterStringX(msg, x1, x2);
+ printText(msg, left, top, color, 0xC, 0);
+ }
+ _screen->_curPage = curPage;
+ _talkMessagePrinted = true;
+}
+
+void TextDisplayer::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
+ debug(9, "TextDisplayer::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2);
+ uint8 colorMap[] = { 0, 15, 12, 12 };
+ colorMap[3] = c1;
+ _screen->setTextColor(colorMap, 0, 3);
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ _screen->printText(str, x, y, c0, c2);
+ _screen->_charWidth = 0;
+ _screen->setFont(curFont);
+}
+
+void TextDisplayer::printCharacterText(char *text, int8 charNum, int charX) {
+ debug(9, "TextDisplayer::printCharacterText('%s', %d, %d)", text, charNum, charX);
+ uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
+ int top, left, x1, x2, w, x;
+ char *msg;
+
+ uint8 color = colorTable[charNum];
+ text = preprocessString(text);
+ int lineCount = buildMessageSubstrings(text);
+ w = getWidestLineWidth(lineCount);
+ x = charX;
+ calcWidestLineBounds(x1, x2, w, x);
+
+ for (int i = 0; i < lineCount; ++i) {
+ top = i * 10 + _talkMessageY;
+ msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
+ left = getCenterStringX(msg, x1, x2);
+ printText(msg, left, top, color, 0xC, 0);
+ }
+}
+} // end of namespace Kyra
diff --git a/kyra/text.h b/kyra/text.h
new file mode 100644
index 0000000000..7f0a10df34
--- /dev/null
+++ b/kyra/text.h
@@ -0,0 +1,67 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef KYRATEXT_H
+#define KYRATEXT_H
+
+namespace Kyra {
+class Screen;
+
+class TextDisplayer {
+ struct TalkCoords {
+ uint16 y, x, w;
+ };
+
+ enum {
+ TALK_SUBSTRING_LEN = 80,
+ TALK_SUBSTRING_NUM = 3
+ };
+public:
+ TextDisplayer(Screen *screen);
+ ~TextDisplayer() {}
+
+ void setTalkCoords(uint16 y);
+ int getCenterStringX(const char *str, int x1, int x2);
+ int getCharLength(const char *str, int len);
+ int dropCRIntoString(char *str, int offs);
+ char *preprocessString(const char *str);
+ int buildMessageSubstrings(const char *str);
+ int getWidestLineWidth(int linesCount);
+ void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
+ void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
+ void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
+ void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
+ void printCharacterText(char *text, int8 charNum, int charX);
+
+ uint16 _talkMessageY;
+ uint16 _talkMessageH;
+private:
+ Screen *_screen;
+
+ char _talkBuffer[300];
+ char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM];
+ TalkCoords _talkCoords;
+ bool _talkMessagePrinted;
+};
+} // end of namespace Kyra
+
+#endif
+
diff --git a/kyra/timer.cpp b/kyra/timer.cpp
new file mode 100644
index 0000000000..9760ec5287
--- /dev/null
+++ b/kyra/timer.cpp
@@ -0,0 +1,277 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/screen.h"
+#include "common/system.h"
+
+namespace Kyra {
+void KyraEngine::setupTimers() {
+ debug(9, "setupTimers()");
+ memset(_timers, 0, sizeof(_timers));
+
+ for (int i = 0; i < 34; i++)
+ _timers[i].active = 1;
+
+ _timers[0].func = _timers[1].func = _timers[2].func = _timers[3].func = _timers[4].func = 0; //Unused.
+ _timers[5].func = _timers[6].func = _timers[7].func = _timers[8].func = _timers[9].func = 0; //_nullsub51;
+ _timers[10].func = _timers[11].func = _timers[12].func = _timers[13].func = 0; //_nullsub50;
+ _timers[14].func = &KyraEngine::timerCheckAnimFlag2; //_nullsub52;
+ _timers[15].func = &KyraEngine::timerUpdateHeadAnims; //_nullsub48;
+ _timers[16].func = &KyraEngine::timerSetFlags1; //_nullsub47;
+ _timers[17].func = 0; //sub_15120;
+ _timers[18].func = &KyraEngine::timerCheckAnimFlag1; //_nullsub53;
+ _timers[19].func = &KyraEngine::timerRedrawAmulet; //_nullsub54;
+ _timers[20].func = 0; //offset _timerDummy1
+ _timers[21].func = 0; //sub_1517C;
+ _timers[22].func = 0; //offset _timerDummy2
+ _timers[23].func = 0; //offset _timerDummy3,
+ _timers[24].func = 0; //_nullsub45;
+ _timers[25].func = 0; //offset _timerDummy4
+ _timers[26].func = 0; //_nullsub46;
+ _timers[27].func = 0; //offset _timerDummy5,
+ _timers[28].func = 0; //offset _timerDummy6
+ _timers[29].func = 0; //offset _timerDummy7,
+ _timers[30].func = 0; //offset _timerDummy8,
+ _timers[31].func = &KyraEngine::timerFadeText; //sub_151F8;
+ _timers[32].func = &KyraEngine::updateAnimFlag1; //_nullsub61;
+ _timers[33].func = &KyraEngine::updateAnimFlag2; //_nullsub62;
+
+ _timers[0].countdown = _timers[1].countdown = _timers[2].countdown = _timers[3].countdown = _timers[4].countdown = -1;
+ _timers[5].countdown = 5;
+ _timers[6].countdown = 7;
+ _timers[7].countdown = 8;
+ _timers[8].countdown = 9;
+ _timers[9].countdown = 7;
+ _timers[10].countdown = _timers[11].countdown = _timers[12].countdown = _timers[13].countdown = 420;
+ _timers[14].countdown = 600;
+ _timers[15].countdown = 11;
+ _timers[16].countdown = _timers[17].countdown = 7200;
+ _timers[18].countdown = _timers[19].countdown = 600;
+ _timers[20].countdown = 7200;
+ _timers[21].countdown = 18000;
+ _timers[22].countdown = 7200;
+ _timers[23].countdown = _timers[24].countdown = _timers[25].countdown = _timers[26].countdown = _timers[27].countdown = 10800;
+ _timers[28].countdown = 21600;
+ _timers[29].countdown = 7200;
+ _timers[30].countdown = 10800;
+ _timers[31].countdown = -1;
+ _timers[32].countdown = 9;
+ _timers[33].countdown = 3;
+}
+
+void KyraEngine::updateGameTimers() {
+ debug(9, "updateGameTimers()");
+
+ if (_system->getMillis() < _timerNextRun)
+ return;
+
+ _timerNextRun += 99999;
+
+ for (int i = 0; i < 34; i++) {
+ if (_timers[i].active && _timers[i].countdown > -1) {
+ if (_timers[i].nextRun <=_system->getMillis()) {
+ if (i > 4 && _timers[i].func)
+ (*this.*_timers[i].func)(i);
+
+ _timers[i].nextRun = _system->getMillis() + _timers[i].countdown * _tickLength;
+
+ }
+ }
+ if (_timers[i].nextRun < _timerNextRun)
+ _timerNextRun = _timers[i].nextRun;
+ }
+}
+
+void KyraEngine::clearNextEventTickCount() {
+ debug(9, "clearNextEventTickCount()");
+ _timerNextRun = 0;
+}
+
+void KyraEngine::setTimerDelay(uint8 timer, int32 countdown) {
+ debug(9, "setTimerDelay(%i, %d)", timer, countdown);
+ _timers[timer].countdown = countdown;
+}
+
+int16 KyraEngine::getTimerDelay(uint8 timer) {
+ debug(9, "getTimerDelay(%i)", timer);
+ return _timers[timer].countdown;
+}
+
+void KyraEngine::setTimerCountdown(uint8 timer, int32 countdown) {
+ debug(9, "setTimerCountdown(%i, %i)", timer, countdown);
+ _timers[timer].countdown = countdown;
+
+ uint32 nextRun = _system->getMillis() + countdown;
+ if (nextRun < _timerNextRun)
+ _timerNextRun = nextRun;
+}
+
+void KyraEngine::enableTimer(uint8 timer) {
+ debug(9, "enableTimer(%i)", timer);
+ _timers[timer].active = 1;
+}
+
+void KyraEngine::disableTimer(uint8 timer) {
+ debug(9, "disableTimer(%i)", timer);
+ _timers[timer].active = 0;
+}
+
+void KyraEngine::timerUpdateHeadAnims(int timerNum) {
+ debug(9, "timerUpdateHeadAnims(%i)", timerNum);
+ static int8 currentFrame = 0;
+ static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5,
+ 4, 4, 6, 4, 8, 1, 9, 4, -1};
+
+ if (_talkingCharNum < 0)
+ return;
+
+ _currHeadShape = frameTable[currentFrame];
+ currentFrame++;
+
+ if (frameTable[currentFrame] == -1)
+ currentFrame = 0;
+
+ animRefreshNPC(0);
+ animRefreshNPC(_talkingCharNum);
+}
+
+void KyraEngine::timerSetFlags1(int timerNum) {
+ debug(9, "timerSetFlags(%i)", timerNum);
+ if (_currentCharacter->sceneId == 0x1C)
+ return;
+
+ int rndNr = _rnd.getRandomNumberRng(0, 3);
+
+ for (int i = 0; i < 4; i++) {
+ if (!queryGameFlag(rndNr + 17)) {
+ setGameFlag(rndNr + 17);
+ break;
+ } else {
+ rndNr++;
+ if (rndNr > 3)
+ rndNr = 0;
+ }
+ }
+}
+
+void KyraEngine::timerFadeText(int timerNum) {
+ debug(9, "timerFadeText(%i)", timerNum);
+ _fadeText = true;
+}
+
+void KyraEngine::updateAnimFlag1(int timerNum) {
+ debug(9, "updateAnimFlag1(%d)", timerNum);
+ if (_brandonStatusBit & 2) {
+ _brandonStatusBit0x02Flag = 1;
+ }
+}
+
+void KyraEngine::updateAnimFlag2(int timerNum) {
+ debug(9, "updateAnimFlag2(%d)", timerNum);
+ if (_brandonStatusBit & 0x20) {
+ _brandonStatusBit0x20Flag = 1;
+ }
+}
+
+void KyraEngine::setTextFadeTimerCountdown(int16 countdown) {
+ debug(9, "setTextFadeTimerCountdown(%i)", countdown);
+ //if (countdown == -1)
+ //countdown = 32000;
+
+ setTimerCountdown(31, countdown*60);
+}
+
+void KyraEngine::timerSetFlags2(int timerNum) {
+ debug(9, "timerSetFlags2(%i)", timerNum);
+ if (!((uint32*)(_flagsTable+0x2D))[timerNum])
+ ((uint32*)(_flagsTable+0x2D))[timerNum] = 1;
+}
+
+void KyraEngine::timerCheckAnimFlag1(int timerNum) {
+ debug(9, "timerCheckAnimFlag1(%i)", timerNum);
+ if (_brandonStatusBit & 0x20) {
+ checkAmuletAnimFlags();
+ setTimerCountdown(18, -1);
+ }
+}
+
+void KyraEngine::timerCheckAnimFlag2(int timerNum) {
+ debug(9, "timerCheckAnimFlag1(%i)", timerNum);
+ if (_brandonStatusBit & 0x2) {
+ checkAmuletAnimFlags();
+ setTimerCountdown(14, -1);
+ }
+}
+
+void KyraEngine::checkAmuletAnimFlags() {
+ debug(9, "checkSpecialAnimFlags()");
+ if (_brandonStatusBit & 2) {
+ seq_makeBrandonNormal2();
+ setTimerCountdown(19, 300);
+ }
+
+ if (_brandonStatusBit & 0x20) {
+ seq_makeBrandonNormal();
+ setTimerCountdown(19, 300);
+ }
+}
+
+void KyraEngine::timerRedrawAmulet(int timerNum) {
+ debug(9, "timerRedrawAmulet(%i)", timerNum);
+ if (queryGameFlag(0xF1)) {
+ drawAmulet();
+ setTimerCountdown(19, -1);
+ }
+}
+
+void KyraEngine::drawAmulet() {
+ debug(9, "drawAmulet()");
+ static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1};
+ static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1};
+ static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1};
+ static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1};
+
+ resetGameFlag(0xF1);
+ _screen->hideMouse();
+
+ int i = 0;
+ while (amuletTable1[i] != -1) {
+ if (queryGameFlag(87))
+ _screen->drawShape(0, _shapes[4+amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0);
+
+ if (queryGameFlag(89))
+ _screen->drawShape(0, _shapes[4+amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0);
+
+ if (queryGameFlag(86))
+ _screen->drawShape(0, _shapes[4+amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0);
+
+ if (queryGameFlag(88))
+ _screen->drawShape(0, _shapes[4+amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0);
+
+ _screen->updateScreen();
+ delayWithTicks(3);
+ i++;
+ }
+ _screen->showMouse();
+}
+} // end of namespace Kyra
+