aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorJohannes Schickel2007-07-29 16:33:11 +0000
committerJohannes Schickel2007-07-29 16:33:11 +0000
commit1140fca82e79121ad2a154dc98b1637c8d56d55d (patch)
tree409ae64e02fef57ada9489f652c6e6f40762102a /engines
parent076d6b1bc1c4f62732ff46a0931c6bc28ef9a08f (diff)
downloadscummvm-rg350-1140fca82e79121ad2a154dc98b1637c8d56d55d.tar.gz
scummvm-rg350-1140fca82e79121ad2a154dc98b1637c8d56d55d.tar.bz2
scummvm-rg350-1140fca82e79121ad2a154dc98b1637c8d56d55d.zip
- Kyrandia 1 works again
- Added timer class for timer handling - Little bit more resturcturing - A little bit (almost nothing but a start!) Kyrandia 2 support svn-id: r28297
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/animator_v2.cpp313
-rw-r--r--engines/kyra/debugger.cpp9
-rw-r--r--engines/kyra/gui_v1.cpp33
-rw-r--r--engines/kyra/gui_v2.cpp7
-rw-r--r--engines/kyra/items_v2.cpp56
-rw-r--r--engines/kyra/kyra.cpp20
-rw-r--r--engines/kyra/kyra.h30
-rw-r--r--engines/kyra/kyra_v1.cpp40
-rw-r--r--engines/kyra/kyra_v1.h31
-rw-r--r--engines/kyra/kyra_v2.cpp1179
-rw-r--r--engines/kyra/kyra_v2.h352
-rw-r--r--engines/kyra/kyra_v3.cpp10
-rw-r--r--engines/kyra/module.mk7
-rw-r--r--engines/kyra/resource.cpp4
-rw-r--r--engines/kyra/resource.h5
-rw-r--r--engines/kyra/saveload_v1.cpp23
-rw-r--r--engines/kyra/scene.cpp383
-rw-r--r--engines/kyra/scene_v1.cpp374
-rw-r--r--engines/kyra/scene_v2.cpp865
-rw-r--r--engines/kyra/screen.cpp68
-rw-r--r--engines/kyra/screen.h18
-rw-r--r--engines/kyra/screen_v2.cpp522
-rw-r--r--engines/kyra/screen_v2.h41
-rw-r--r--engines/kyra/script.cpp209
-rw-r--r--engines/kyra/script.h94
-rw-r--r--engines/kyra/script_v1.cpp325
-rw-r--r--engines/kyra/script_v2.cpp430
-rw-r--r--engines/kyra/sequences_v1.cpp9
-rw-r--r--engines/kyra/sequences_v2.cpp1
-rw-r--r--engines/kyra/staticres.cpp67
-rw-r--r--engines/kyra/text_v1.cpp24
-rw-r--r--engines/kyra/timer.cpp251
-rw-r--r--engines/kyra/timer.h93
-rw-r--r--engines/kyra/timer_v1.cpp222
-rw-r--r--engines/kyra/timer_v2.cpp80
-rw-r--r--engines/kyra/util.h61
-rw-r--r--engines/kyra/wsamovie.cpp101
-rw-r--r--engines/kyra/wsamovie.h18
38 files changed, 5312 insertions, 1063 deletions
diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp
new file mode 100644
index 0000000000..179bdd140d
--- /dev/null
+++ b/engines/kyra/animator_v2.cpp
@@ -0,0 +1,313 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra_v2.h"
+#include "kyra/wsamovie.h"
+
+namespace Kyra {
+
+void KyraEngine_v2::clearAnimObjects() {
+ memset(_animObjects, 0, sizeof(_animObjects));
+
+ _animObjects[0].index = 0;
+ _animObjects[0].type = 0;
+ _animObjects[0].enabled = 1;
+ _animObjects[0].flags = 0x800;
+ _animObjects[0].width = 32;
+ _animObjects[0].height = 49;
+ _animObjects[0].width2 = 4;
+ _animObjects[0].height2 = 10;
+
+ for (int i = 1; i < 11; ++i) {
+ _animObjects[i].index = i;
+ _animObjects[i].type = 2;
+ }
+
+ for (int i = 11; i <= 40; ++i) {
+ _animObjects[i].index = i;
+ _animObjects[i].type = 1;
+ _animObjects[i].flags = 0x800;
+ _animObjects[i].width = 16;
+ _animObjects[i].height = 16;
+ }
+}
+
+KyraEngine_v2::AnimObj *KyraEngine_v2::initAnimList(AnimObj *list, AnimObj *entry) {
+ entry->nextObject = list;
+ return entry;
+}
+
+KyraEngine_v2::AnimObj *KyraEngine_v2::addToAnimListSorted(AnimObj *list, AnimObj *add) {
+ if (add->yPos1 <= list->yPos1) {
+ add->nextObject = list;
+ return add;
+ }
+
+ AnimObj *cur = list;
+ AnimObj *prev = list;
+ while (add->yPos1 > cur->yPos1) {
+ AnimObj *temp = cur->nextObject;
+ if (!temp)
+ break;
+ prev = cur;
+ cur = temp;
+ }
+
+ if (add->yPos1 <= cur->yPos1) {
+ prev->nextObject = add;
+ add->nextObject = cur;
+ } else {
+ cur->nextObject = add;
+ add->nextObject = 0;
+ }
+ return list;
+}
+
+KyraEngine_v2::AnimObj *KyraEngine_v2::deleteAnimListEntry(AnimObj *list, AnimObj *entry) {
+ if (!list)
+ return 0;
+
+ AnimObj *old = 0;
+ AnimObj *cur = list;
+
+ while (true) {
+ if (cur == entry)
+ break;
+ if (!cur->nextObject)
+ break;
+ old = cur;
+ cur = cur->nextObject;
+ }
+
+ if (cur == list) {
+ if (!cur->nextObject)
+ return 0;
+ cur = cur->nextObject;
+ return cur;
+ }
+
+ if (!cur->nextObject) {
+ if (!old)
+ return 0;
+ old->nextObject = 0;
+ return list;
+ }
+
+ if (cur != entry)
+ return list;
+
+ old->nextObject = entry->nextObject;
+ return list;
+}
+
+void KyraEngine_v2::drawAnimObjects() {
+ for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) {
+ if (!curObject->enabled)
+ continue;
+
+ int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3);
+ int y = curObject->yPos2 - _screen->getScreenDim(2)->sy;
+ int layer = 7;
+
+ if (curObject->flags & 0x800) {
+ if (curObject->animFlags)
+ layer = 0;
+ else
+ layer = getDrawLayer(curObject->xPos1, curObject->yPos1);
+ }
+ curObject->flags |= 0x800;
+
+ if (curObject->index)
+ drawSceneAnimObject(curObject, x, y, layer);
+ else
+ drawCharacterAnimObject(curObject, x, y, layer);
+ }
+}
+
+void KyraEngine_v2::refreshAnimObjects(int force) {
+ for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) {
+ if (!curObject->enabled)
+ continue;
+ if (!curObject->needRefresh && !force)
+ continue;
+
+ int x = curObject->xPos2 - curObject->width2;
+ if (x < 0)
+ x = 0;
+ if (x >= 320)
+ x = 319;
+ int y = curObject->yPos2 - curObject->height2;
+ if (y < 0)
+ y = 0;
+ if (y >= 143)
+ y = 142;
+
+ int width = curObject->width + curObject->width2 + 8;
+ int height = curObject->height + curObject->height2*2;
+ if (width + x > 320)
+ width -= width + x - 322;
+ if (height + y > 143)
+ height -= height + y - 144;
+
+ _screen->hideMouse();
+ _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_CLIPPED);
+ _screen->showMouse();
+
+ curObject->needRefresh = false;
+ }
+}
+
+void KyraEngine_v2::refreshAnimObjectsIfNeed() {
+ for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) {
+ if (curEntry->enabled && curEntry->needRefresh) {
+ restorePage3();
+ drawAnimObjects();
+ refreshAnimObjects(0);
+ _screen->updateScreen();
+ return;
+ }
+ }
+}
+
+void KyraEngine_v2::updateCharacterAnim(int) {
+ Character *c = &_mainCharacter;
+ AnimObj *animState = _animObjects;
+
+ animState->needRefresh = 1;
+ animState->unk8 = 1;
+
+ if (c->facing >= 1 && c->facing <= 3)
+ animState->flags |= 1;
+ else if (c->facing >= 5 && c->facing <= 7)
+ animState->flags &= ~1;
+
+ animState->xPos2 = animState->xPos1 = c->x1;
+ animState->yPos2 = animState->yPos1 = c->y1;
+ animState->shapePtr = _defaultShapeTable[c->animFrame];
+ animState->shapeIndex1 = animState->shapeIndex2 = c->animFrame;
+
+ int xAdd = _shapeDescTable[c->animFrame-9].xAdd;
+ int yAdd = _shapeDescTable[c->animFrame-9].yAdd;
+
+ _charScaleX = _charScaleY = getScale(c->x1, c->y1);
+
+ animState->xPos2 += (xAdd * _charScaleX) >> 8;
+ animState->yPos2 += (yAdd * _charScaleY) >> 8;
+ animState->width2 = 8;
+ animState->height2 = 10;
+
+ _animList = deleteAnimListEntry(_animList, animState);
+ if (_animList)
+ _animList = addToAnimListSorted(_animList, animState);
+ else
+ _animList = initAnimList(_animList, animState);
+
+ updateCharPal(1);
+}
+
+void KyraEngine_v2::updateSceneAnim(int anim, int newFrame) {
+ AnimObj *animObject = &_animObjects[1+anim];
+ if (!animObject->enabled)
+ return;
+
+ animObject->needRefresh = 1;
+ animObject->unk8 = 1;
+ animObject->flags = 0;
+
+ if (_sceneAnims[anim].flags & 2)
+ animObject->flags |= 0x800;
+ else
+ animObject->flags &= ~0x800;
+
+ if (_sceneAnims[anim].flags & 4)
+ animObject->flags |= 1;
+ else
+ animObject->flags &= ~1;
+
+ if (_sceneAnims[anim].flags & 0x20) {
+ animObject->shapePtr = _sceneShapeTable[newFrame];
+ animObject->shapeIndex2 = 0xFFFF;
+ animObject->shapeIndex3 = 0xFFFF;
+ animObject->animNum = 0xFFFF;
+ } else {
+ animObject->shapePtr = 0;
+ animObject->shapeIndex3 = newFrame;
+ animObject->animNum = anim;
+ }
+
+ animObject->xPos1 = _sceneAnims[anim].x;
+ animObject->yPos1 = _sceneAnims[anim].y;
+ animObject->xPos2 = _sceneAnims[anim].x2;
+ animObject->yPos2 = _sceneAnims[anim].y2;
+
+ if (_sceneAnims[anim].flags & 2) {
+ _animList = deleteAnimListEntry(_animList, animObject);
+ if (!_animList)
+ _animList = initAnimList(_animList, animObject);
+ else
+ _animList = addToAnimListSorted(_animList, animObject);
+ }
+}
+
+void KyraEngine_v2::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) {
+ if (obj->type == 1) {
+ if (obj->shapeIndex1 == 0xFFFF)
+ return;
+ int scale = getScale(obj->xPos1, obj->yPos1);
+ _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, scale, scale);
+ return;
+ }
+
+ if (obj->shapePtr) {
+ _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, layer);
+ } else {
+ if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF)
+ return;
+
+ int flags = 0x4000;
+ if (obj->flags & 0x800)
+ flags |= 0x8000;
+
+ if (_sceneAnims[obj->animNum].wsaFlag) {
+ x = y = 0;
+ } else {
+ x = obj->xPos2;
+ y = obj->yPos2;
+ }
+
+ _sceneAnimMovie[obj->animNum]->setX(x);
+ _sceneAnimMovie[obj->animNum]->setY(y);
+ _sceneAnimMovie[obj->animNum]->setDrawPage(2);
+ _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, int(flags | layer), 0, 0);
+ }
+}
+
+void KyraEngine_v2::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) {
+ if (_drawNoShapeFlag || obj->shapeIndex1 == 0xFFFF)
+ return;
+ _screen->drawShape(2, getShapePtr(obj->shapeIndex1), x, y, 2, obj->flags | 4, layer, _charScaleX, _charScaleY);
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index 0a1974c3f4..152dc21c61 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -29,6 +29,7 @@
#include "kyra/debugger.h"
#include "kyra/kyra_v1.h"
#include "kyra/screen.h"
+#include "kyra/timer.h"
namespace Kyra {
@@ -141,8 +142,8 @@ bool Debugger_v1::cmd_queryFlag(int argc, const char **argv) {
}
bool Debugger_v1::cmd_listTimers(int argc, const char **argv) {
- for (int i = 0; i < ARRAYSIZE(_vm->_timers); i++)
- DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i\n", i, _vm->_timers[i].active ? "Yes" : "No", _vm->_timers[i].countdown);
+ for (int i = 0; i < _vm->timer()->count(); i++)
+ DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i\n", i, _vm->timer()->isEnabled(i) ? "Yes" : "No", _vm->timer()->getDelay(i));
return true;
}
@@ -151,8 +152,8 @@ bool Debugger_v1::cmd_setTimerCountdown(int argc, const char **argv) {
if (argc > 2) {
uint timer = atoi(argv[1]);
uint countdown = atoi(argv[2]);
- _vm->setTimerCountdown(timer, countdown);
- DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->_timers[timer].countdown);
+ _vm->timer()->setCountdown(timer, countdown);
+ DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->timer()->getDelay(timer));
} else {
DebugPrintf("Syntax: settimercountdown <timer> <countdown>\n");
}
diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp
index 2452185c24..b7692cc97d 100644
--- a/engines/kyra/gui_v1.cpp
+++ b/engines/kyra/gui_v1.cpp
@@ -1469,5 +1469,38 @@ void KyraEngine_v1::gui_restorePalette() {
_screen->fadePalette(_screen->_currentPalette, 2);
}
+#pragma mark -
+
+void KyraEngine_v1::drawAmulet() {
+ debugC(9, kDebugLevelMain, "KyraEngine_v1::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[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0);
+
+ if (queryGameFlag(89))
+ _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0);
+
+ if (queryGameFlag(86))
+ _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0);
+
+ if (queryGameFlag(88))
+ _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0);
+
+ _screen->updateScreen();
+ delayWithTicks(3);
+ i++;
+ }
+ _screen->showMouse();
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index f24bf295a8..838d347f8f 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -11,7 +11,7 @@
* 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
+ * 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
@@ -63,7 +63,10 @@ int KyraEngine_v2::gui_handleMainMenu() {
int charWidthBackUp = _screen->_charWidth;
_screen->_charWidth = -2;
- _screen->setScreenDim(3);
+ if (_flags.gameID == GI_KYRA2)
+ _screen->setScreenDim(11);
+ else
+ _screen->setScreenDim(3);
int backUpX = _screen->_curDim->sx;
int backUpY = _screen->_curDim->sy;
int backUpWidth = _screen->_curDim->w;
diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp
new file mode 100644
index 0000000000..fd4c7a5fab
--- /dev/null
+++ b/engines/kyra/items_v2.cpp
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra_v2.h"
+
+namespace Kyra {
+
+int KyraEngine_v2::findFreeItem() {
+ for (int i = 0; i < 30; ++i) {
+ if (_itemList[i].id == 0xFFFF)
+ return i;
+ }
+ return -1;
+}
+
+int KyraEngine_v2::findItem(uint16 sceneId, int id) {
+ for (int i = 0; i < 30; ++i) {
+ if (_itemList[i].id == id && _itemList[i].sceneId == sceneId)
+ return i;
+ }
+ return -1;
+}
+
+void KyraEngine_v2::resetItemList() {
+ for (int i = 0; i < 30; ++i) {
+ _itemList[i].id = 0xFFFF;
+ _itemList[i].sceneId = 0xFFFF;
+ _itemList[i].x = 0;
+ _itemList[i].y = 0;
+ _itemList[i].unk7 = 0;
+ }
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp
index c7e167f600..1d8d7440f0 100644
--- a/engines/kyra/kyra.cpp
+++ b/engines/kyra/kyra.cpp
@@ -35,16 +35,23 @@
#include "kyra/resource.h"
#include "kyra/screen.h"
#include "kyra/text.h"
+#include "kyra/timer.h"
+#include "kyra/script.h"
namespace Kyra {
KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags)
: Engine(system) {
- _screen = 0;
_res = 0;
_sound = 0;
_text = 0;
_staticres = 0;
+ _timer = 0;
+ _scriptInterpreter = 0;
+
+ _flags = flags;
+ _gameSpeed = 60;
+ _tickLength = (uint8)(1000.0 / _gameSpeed);
_quitFlag = false;
@@ -63,6 +70,7 @@ KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags)
Common::addSpecialDebugLevel(kDebugLevelGUI, "GUI", "GUI debug level");
Common::addSpecialDebugLevel(kDebugLevelSequence, "Sequence", "Sequence debug level");
Common::addSpecialDebugLevel(kDebugLevelMovie, "Movie", "Movie debug level");
+ Common::addSpecialDebugLevel(kDebugLevelTimer, "Timer", "Timer debug level");
}
int KyraEngine::init() {
@@ -115,12 +123,18 @@ int KyraEngine::init() {
_res = new Resource(this);
assert(_res);
- _text = new TextDisplayer(this, _screen);
+ _text = new TextDisplayer(this, this->screen());
assert(_text);
_staticres = new StaticResource(this);
assert(_staticres);
if (!_staticres->init())
error("_staticres->init() failed");
+ _timer = new TimerManager(this, _system);
+ assert(_timer);
+ _scriptInterpreter = new ScriptHelper(this);
+ assert(_scriptInterpreter);
+
+ setupOpcodeTable();
_lang = 0;
Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
@@ -155,6 +169,8 @@ KyraEngine::~KyraEngine() {
delete _res;
delete _sound;
delete _text;
+ delete _timer;
+ delete _scriptInterpreter;
}
void KyraEngine::quitGame() {
diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h
index 7d795abd7c..8ed546d1ce 100644
--- a/engines/kyra/kyra.h
+++ b/engines/kyra/kyra.h
@@ -31,9 +31,9 @@
#include "common/array.h"
#include "common/events.h"
-namespace Kyra {
+#include "kyra/util.h"
-struct Opcode;
+namespace Kyra {
struct GameFlags {
Common::Language lang;
@@ -59,16 +59,17 @@ enum {
// TODO: this is just the start of makeing the debug output of the kyra engine a bit more useable
// in the future we maybe merge some flags and/or create new ones
enum kDebugLevels {
- kDebugLevelScriptFuncs = 1 << 0, // prints debug output of o1_* functions
+ kDebugLevelScriptFuncs = 1 << 0, // prints debug output of o#_* functions
kDebugLevelScript = 1 << 1, // prints debug output of "ScriptHelper" functions
kDebugLevelSprites = 1 << 2, // prints debug output of "Sprites" functions
kDebugLevelScreen = 1 << 3, // prints debug output of "Screen" functions
kDebugLevelSound = 1 << 4, // prints debug output of "Sound" functions
kDebugLevelAnimator = 1 << 5, // prints debug output of "ScreenAnimator" functions
- kDebugLevelMain = 1 << 6, // prints debug output of common "KyraEngine*" functions && "TextDisplayer" functions
+ kDebugLevelMain = 1 << 6, // prints debug output of common "KyraEngine(_v#)" functions && "TextDisplayer" functions
kDebugLevelGUI = 1 << 7, // prints debug output of "KyraEngine*" gui functions
kDebugLevelSequence = 1 << 8, // prints debug output of "SeqPlayer" functions
- kDebugLevelMovie = 1 << 9 // prints debug output of movie specific funtions
+ kDebugLevelMovie = 1 << 9, // prints debug output of movie specific funtions
+ kDebugLevelTimer = 1 << 10 // prints debug output of "TimerManager" functions
};
class Screen;
@@ -77,6 +78,8 @@ class Sound;
class Movie;
class TextDisplayer;
class StaticResource;
+class TimerManager;
+class ScriptHelper;
class KyraEngine : public Engine {
public:
@@ -94,6 +97,7 @@ public:
TextDisplayer *text() { return _text; }
Sound *sound() { return _sound; }
StaticResource *staticres() { return _staticres; }
+ TimerManager *timer() { return _timer; }
uint32 tickLength() const { return _tickLength; }
@@ -123,14 +127,16 @@ protected:
// intern
Resource *_res;
- Screen *_screen;
Sound *_sound;
TextDisplayer *_text;
StaticResource *_staticres;
+ TimerManager *_timer;
+ ScriptHelper *_scriptInterpreter;
// game speed
bool _skipFlag;
uint16 _tickLength;
+ uint16 _gameSpeed;
// detection
GameFlags _flags;
@@ -145,6 +151,18 @@ protected:
// input
Common::Point getMousePos() const;
+
+ // pathfinder
+ virtual 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);
+ int getFacingFromPointToPoint(int x, int y, int toX, int toY);
+ int getOppositeFacingDirection(int dir);
+ void changePosTowardsFacing(int &x, int &y, int facing);
+ int getMoveTableSize(int *moveTable);
+ virtual bool lineIsPassable(int x, int y) = 0;
+
+ static const int8 _addXPosTable[];
+ static const int8 _addYPosTable[];
};
} // End of namespace Kyra
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index 404e62403a..45ee42b0d3 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -42,6 +42,7 @@
#include "kyra/animator_v1.h"
#include "kyra/text.h"
#include "kyra/debugger.h"
+#include "kyra/timer.h"
namespace Kyra {
@@ -80,7 +81,6 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
_sprites = 0;
_animator = 0;
_seq = 0;
- _scriptInterpreter = 0;
_npcScriptData = 0;
_scriptMain = 0;
_scriptClickData = 0;
@@ -124,8 +124,7 @@ KyraEngine_v1::~KyraEngine_v1() {
delete _sprites;
delete _animator;
delete _seq;
- delete _scriptInterpreter;
-
+
delete _npcScriptData;
delete _scriptMain;
@@ -181,18 +180,18 @@ int KyraEngine_v1::init() {
initStaticResource();
- if (!_sound->init())
- error("Couldn't init sound");
-
if (_flags.platform == Common::kPlatformFMTowns)
_sound->setSoundFileList(_soundFilesTowns, _soundFilesTownsCount);
else
_sound->setSoundFileList(_soundFiles, _soundFilesCount);
+
+ if (!_sound->init())
+ error("Couldn't init sound");
_sound->setVolume(255);
_sound->loadSoundFile(0);
- setupOpcodeTable();
+ setupTimers();
setupButtonData();
setupMenu();
@@ -210,9 +209,6 @@ int KyraEngine_v1::init() {
_characterList[0].facing = 3;
_characterList[0].currentAnimFrame = 7;
- _scriptInterpreter = new ScriptHelper(this);
- assert(_scriptInterpreter);
-
_npcScriptData = new ScriptData;
memset(_npcScriptData, 0, sizeof(ScriptData));
assert(_npcScriptData);
@@ -263,7 +259,6 @@ int KyraEngine_v1::init() {
_pathfinderFlag = _pathfinderFlag2 = 0;
_lastFindWayRet = 0;
_sceneChangeState = _loopFlag2 = 0;
- _timerNextRun = 0;
_movFacingTable = new int[150];
assert(_movFacingTable);
@@ -309,9 +304,6 @@ int KyraEngine_v1::init() {
_menuDirectlyToLoad = false;
_lastMusicCommand = 0;
-
- _gameSpeed = 60;
- _tickLength = (uint8)(1000.0 / _gameSpeed);
return 0;
}
@@ -456,7 +448,7 @@ void KyraEngine_v1::mainLoop() {
processButtonList(_buttonList);
updateMousePointer();
- updateGameTimers();
+ _timer->update();
updateTextFade();
_handleInput = true;
@@ -470,7 +462,7 @@ void KyraEngine_v1::mainLoop() {
void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) {
while (_system->getMillis() < timestamp && !_quitFlag) {
if (updateTimers)
- updateGameTimers();
+ _timer->update();
if (timestamp - _system->getMillis() >= 10)
delay(10, update, isMainLoop);
@@ -1003,6 +995,21 @@ void KyraEngine_v1::runNpcScript(int func) {
_scriptInterpreter->runScript(_npcScript);
}
+void KyraEngine_v1::checkAmuletAnimFlags() {
+ debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()");
+
+ if (_brandonStatusBit & 2) {
+ seq_makeBrandonNormal2();
+ _timer->setCountdown(19, 300);
+ }
+
+ if (_brandonStatusBit & 0x20) {
+ seq_makeBrandonNormal();
+ _timer->setCountdown(19, 300);
+ }
+}
+
+typedef Functor1Mem<ScriptState*, int, KyraEngine_v1> OpcodeV1;
#define Opcode(x) OpcodeV1(this, &KyraEngine_v1::x)
void KyraEngine_v1::setupOpcodeTable() {
static const OpcodeV1 opcodeTable[] = {
@@ -1201,6 +1208,7 @@ void KyraEngine_v1::setupOpcodeTable() {
Opcode(o1_fillRect),
Opcode(o1_vocUnload),
Opcode(o1_vocLoad),
+ // 0x9c
Opcode(o1_dummy)
};
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 1bd8f48971..6e5ba98d3c 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -36,7 +36,6 @@ class Movie;
class SoundDigital;
class SeqPlayer;
class Sprites;
-class ScriptHelper;
class Debugger;
class ScreenAnimator;
class TextDisplayer;
@@ -105,13 +104,6 @@ struct BeadState {
int16 tableIndex;
};
-struct Timer {
- uint8 active;
- int32 countdown;
- uint32 nextRun;
- void (KyraEngine_v1::*func)(int timerNum);
-};
-
struct Button {
Button *nextButton;
uint16 specialValue;
@@ -294,14 +286,6 @@ public:
bool speechEnabled();
bool textEnabled();
- void updateGameTimers();
- void clearNextEventTickCount();
- void setTimerCountdown(uint8 timer, int32 countdown);
- void setTimerDelay(uint8 timer, int32 countdown);
- int16 getTimerDelay(uint8 timer);
- void enableTimer(uint8 timer);
- void disableTimer(uint8 timer);
-
void saveGame(const char *fileName, const char *saveName);
void loadGame(const char *fileName);
@@ -336,11 +320,7 @@ protected:
// -> pathfinder
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);
- int getFacingFromPointToPoint(int x, int y, int toX, int toY);
- void changePosTowardsFacing(int &x, int &y, int facing);
bool lineIsPassable(int x, int y);
- int getMoveTableSize(int *moveTable);
// -> item handling
// --> misc
@@ -397,7 +377,6 @@ protected:
void setCharacterPositionWithUpdate(int character);
int setCharacterPosition(int character, int *facingTable);
void setCharacterPositionHelper(int character, int *facingTable);
- int getOppositeFacingDirection(int dir);
void setCharactersPositions(int character);
// -> brandon
@@ -459,7 +438,7 @@ protected:
void freePanPages();
void closeFinalWsa();
- void setTimer19();
+ //void setTimer19();
void setupTimers();
void timerUpdateHeadAnims(int timerNum);
void timerSetFlags1(int timerNum);
@@ -535,7 +514,6 @@ protected:
int8 _mouseWheel;
uint8 *_itemBkgBackUp[2];
uint8 *_shapes[373];
- uint16 _gameSpeed;
int8 _itemInHand;
int _mouseState;
bool _handleInput;
@@ -632,7 +610,6 @@ protected:
SeqPlayer *_seq;
Sprites *_sprites;
Screen_v1 *_screen;
- ScriptHelper *_scriptInterpreter;
Debugger *_debugger;
ScriptState *_scriptMain;
@@ -790,18 +767,13 @@ protected:
const uint8 * const*_specialPalettes;
- Timer _timers[34];
- uint32 _timerNextRun;
-
static const char *_soundFiles[];
static const int _soundFilesCount;
static const char *_soundFilesTowns[];
static const int _soundFilesTownsCount;
static const int8 _charXPosTable[];
- static const int8 _addXPosTable[];
static const int8 _charYPosTable[];
- static const int8 _addYPosTable[];
// positions of the inventory
static const uint16 _itemPosX[];
@@ -829,7 +801,6 @@ protected:
static const uint16 _amuletX2[];
static const uint16 _amuletY2[];
protected:
- typedef OpcodeImpl<KyraEngine_v1> OpcodeV1;
void setupOpcodeTable();
// Opcodes
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 2f52d8919d..7a9d631c25 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -29,14 +29,38 @@
#include "kyra/resource.h"
#include "kyra/wsamovie.h"
#include "kyra/sound.h"
+#include "kyra/script.h"
+#include "kyra/text.h"
+#include "kyra/timer.h"
#include "common/system.h"
namespace Kyra {
KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) {
- memset(_gameShapes, 0, sizeof(_gameShapes));
+ memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable));
_mouseSHPBuf = 0;
+
+ _gamePlayBuffer = 0;
+ _cCodeBuffer = _optionsBuffer = _chapterBuffer = 0;
+
+ _overwriteSceneFacing = false;
+ _mainCharX = _mainCharY = -1;
+ _drawNoShapeFlag = false;
+ _charPalEntry = 0;
+ _itemInHand = -1;
+ _unkSceneScreenFlag1 = false;
+ _noScriptEnter = true;
+ _currentChapter = 0;
+ _newChapterFile = 1;
+ _handItemSet = -1;
+ _lastProcessedSceneScript = 0;
+ _specialSceneScriptRunFlag = false;
+ memset(_animObjects, 0, sizeof(_animObjects));
+ _unkHandleSceneChangeFlag = false;
+ _pathfinderFlag = 0;
+
+ memset(&_sceneScriptData, 0, sizeof(_sceneScriptData));
}
KyraEngine_v2::~KyraEngine_v2() {
@@ -55,13 +79,14 @@ int KyraEngine_v2::init() {
error("_screen->init() failed");
KyraEngine::init();
+
+ setupTimers();
- if (_res->getFileSize("6.FNT"))
- _screen->loadFont(Screen::FID_6_FNT, "6.FNT");
- if (_res->getFileSize("8FAT.FNT"))
- _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT");
- _screen->loadFont(Screen::FID_GOLDFONT_FNT, "GOLDFONT.FNT");
- _screen->setAnimBlockPtr(3500);
+ _screen->loadFont(_screen->FID_6_FNT, "6.FNT");
+ _screen->loadFont(_screen->FID_8_FNT, "8FAT.FNT");
+ _screen->loadFont(_screen->FID_GOLDFONT_FNT, "GOLDFONT.FNT");
+ _screen->loadFont(_screen->FID_BOOKFONT_FNT, "BOOKFONT.FNT");
+ _screen->setAnimBlockPtr(3504);
_screen->setScreenDim(0);
assert(_introStringsSize == 21);
@@ -76,11 +101,11 @@ int KyraEngine_v2::init() {
assert(_mouseSHPBuf);
for (int i = 0; i < 2; i++) {
- _gameShapes[i] = _screen->getPtrToShape(_mouseSHPBuf, i);
- assert(_gameShapes[i]);
+ _defaultShapeTable[i] = _screen->getPtrToShape(_mouseSHPBuf, i);
+ assert(_defaultShapeTable[i]);
}
- _screen->setMouseCursor(0, 0, _gameShapes[0]);
+ _screen->setMouseCursor(0, 0, _defaultShapeTable[0]);
return 0;
}
@@ -105,14 +130,14 @@ int KyraEngine_v2::go() {
_res->unloadPakFile("OUTFARM.PAK");
_res->unloadPakFile("FLYTRAP.PAK");
- seq_playSequences(kSequenceVirgin, kSequenceWestwood);
+ //seq_playSequences(kSequenceVirgin, kSequenceWestwood);
mainMenu();
return 0;
}
void KyraEngine_v2::mainMenu() {
- bool running = true;
+ /*bool running = true;
while (running && !_quitFlag) {
seq_playSequences(kSequenceTitle);
@@ -120,6 +145,11 @@ void KyraEngine_v2::mainMenu() {
switch (gui_handleMainMenu()) {
case 0:
+ _screen->showMouse();*/
+ startup();
+ runLoop();
+ cleanup();
+ /*running = false;
break;
case 1:
seq_playSequences(kSequenceOverview, kSequenceZanFaun);
@@ -133,7 +163,1130 @@ void KyraEngine_v2::mainMenu() {
break;
}
_screen->hideMouse();
- }
+ }*/
+}
+
+void KyraEngine_v2::startup() {
+ _screen->_curPage = 0;
+ delete [] _mouseSHPBuf;
+ _mouseSHPBuf = 0;
+
+ memset(_defaultShapeTable, 0, sizeof(_defaultShapeTable));
+ memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable));
+ _gamePlayBuffer = new uint8[46080];
+ _unkBuf500Bytes = new uint8[500];
+
+ loadMouseShapes();
+ loadItemShapes();
+
+ _screen->setMouseCursor(0, 0, getShapePtr(0));
+
+ _screenBuffer = new uint8[64000];
+
+ loadCCodeBuffer("C_CODE.XXX");
+ loadOptionsBuffer("OPTIONS.XXX");
+ loadChapterBuffer(_newChapterFile);
+
+ _unkBuf200kByte = new uint8[200000];
+
+ showMessageFromCCode(265, 150, 0);
+
+ // XXX
+
+ showMessageFromCCode(0, 0, 207);
+
+ // XXX
+
+ _screen->setShapePages(5, 3);
+
+ memset(&_mainCharacter, 0, sizeof(_mainCharacter));
+ _mainCharacter.height = 0x30;
+ _mainCharacter.facing = 4;
+ _mainCharacter.animFrame = 0x12;
+ memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory));
+
+ memset(_sceneAnims, 0, sizeof(_sceneAnims));
+ for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i)
+ _sceneAnimMovie[i] = new WSAMovieV2(this);
+ memset(_wsaSlots, 0, sizeof(_wsaSlots));
+ for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i)
+ _wsaSlots[i] = new WSAMovieV2(this);
+
+ _maskPage = 0;//_screen->getPagePtr(5);
+ _screen->_curPage = 0;
+
+ _objectList = new Object[72];
+ memset(_objectList, 0, sizeof(Object)*72);
+ _shapeDescTable = new ShapeDesc[55];
+ memset(_shapeDescTable, 0, sizeof(ShapeDesc)*55);
+
+ for (int i = 9; i <= 32; ++i) {
+ _shapeDescTable[i-9].unk5 = 30;
+ _shapeDescTable[i-9].unk7 = 55;
+ _shapeDescTable[i-9].xAdd = -15;
+ _shapeDescTable[i-9].yAdd = -50;
+ }
+
+ for (int i = 19; i <= 24; ++i) {
+ _shapeDescTable[i-9].unk7 = 53;
+ _shapeDescTable[i-9].yAdd = -51;
+ }
+
+ _gfxBackUpRect = new uint8[_screen->getRectSize(32, 32)];
+ _itemList = new Item[30];
+ resetItemList();
+ //loadButtonShapes();
+ _loadedZTable = 1;
+ loadZShapes(_loadedZTable);
+ loadInventoryShapes();
+
+ _res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300);
+ _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0);
+ _screen->copyPage(3, 0);
+ _screen->showMouse();
+ _screen->hideMouse();
+
+ clearAnimObjects();
+
+ // XXX
+
+ _sceneList = new SceneDesc[86];
+ runStartScript(1, 0);
+ loadNPCScript();
+
+ // XXX
+
+ enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1);
+ _screen->showMouse();
+
+ //sub_20EE8(1);
+ //setNextIdleAnimTimer();
+ //XXX
+ _timer->setDelay(0, 5);
+}
+
+void KyraEngine_v2::runLoop() {
+ _screen->updateScreen();
+
+ _quitFlag = false;
+ while (!_quitFlag) {
+ //XXX
+ int inputFlag = checkInput(0/*dword_324C5*/);
+ update();
+ if (inputFlag == 198 || inputFlag == 199) {
+ _unk3 = _handItemSet;
+ Common::Point mouse = getMousePos();
+ handleInput(mouse.x, mouse.y);
+ }
+ //XXX
+ }
+}
+
+void KyraEngine_v2::handleInput(int x, int y) {
+ //setNextIdleAnimTimer();
+ if (_unk5) {
+ _unk5 = 0;
+ return;
+ }
+
+ if (!_screen->isMouseVisible())
+ return;
+
+ if (_unk3 == -2) {
+ //snd_playSfx(13);
+ return;
+ }
+
+ //setNextIdleAnimTimer();
+
+ if (x <= 6 || x >= 312 || y <= 6 || y >= 135) {
+ bool exitOk = false;
+ assert(_unk3 + 6 >= 0);
+ switch (_unk3 + 6) {
+ case 0:
+ if (_sceneExit1 != 0xFFFF)
+ exitOk = true;
+ break;
+
+ case 1:
+ if (_sceneExit2 != 0xFFFF)
+ exitOk = true;
+ break;
+
+ case 2:
+ if (_sceneExit3 != 0xFFFF)
+ exitOk = true;
+ break;
+
+ case 3:
+ if (_sceneExit4 != 0xFFFF)
+ exitOk = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (exitOk) {
+ inputSceneChange(x, y, 1, 1);
+ return;
+ }
+ }
+
+ if (checkCharCollision(x, y) >= 0 && _unk3 >= -1) {
+ runSceneScript2();
+ return;
+ } else {
+ //XXX
+ }
+
+ //XXX
+
+ inputSceneChange(x, y, 1, 1);
+}
+
+int KyraEngine_v2::update() {
+ refreshAnimObjectsIfNeed();
+ updateMouse();
+ updateSpecialSceneScripts();
+ _timer->update();
+ //sub_274C0();
+ //updateInvWsa();
+ //sub_1574C();
+ //XXX
+ _screen->updateScreen();
+ return 0;
+}
+
+void KyraEngine_v2::updateMouse() {
+ int shapeIndex = 0;
+ int type = 0;
+ int xOffset = 0, yOffset = 0;
+ Common::Point mouse = getMousePos();
+
+ if (mouse.y <= 145) {
+ if (mouse.x <= 6) {
+ if (_sceneExit4 != 0xFFFF) {
+ type = -3;
+ shapeIndex = 4;
+ xOffset = 1;
+ yOffset = 5;
+ } else {
+ type = -2;
+ }
+ } else if (mouse.x >= 312) {
+ if (_sceneExit2 != 0xFFFF) {
+ type = -5;
+ shapeIndex = 2;
+ xOffset = 7;
+ yOffset = 5;
+ } else {
+ type = -2;
+ }
+ } else if (mouse.y >= 135) {
+ if (_sceneExit3 != 0xFFFF) {
+ type = -4;
+ shapeIndex = 3;
+ xOffset = 5;
+ yOffset = 10;
+ } else {
+ type = -2;
+ }
+ } else if (mouse.y <= 6) {
+ if (_sceneExit1 != 0xFFFF) {
+ type = -6;
+ shapeIndex = 1;
+ xOffset = 5;
+ yOffset = 1;
+ } else {
+ type = -2;
+ }
+ }
+ }
+
+ for (int i = 0; i < _specialExitCount; ++i) {
+ if (checkSpecialSceneExit(i, mouse.x, mouse.y)) {
+ switch (_specialExitTable[20+i]) {
+ case 0:
+ type = -6;
+ shapeIndex = 1;
+ xOffset = 5;
+ yOffset = 1;
+ break;
+
+ case 2:
+ type = -5;
+ shapeIndex = 2;
+ xOffset = 7;
+ yOffset = 5;
+ break;
+
+ case 4:
+ type = -4;
+ shapeIndex = 3;
+ xOffset = 5;
+ yOffset = 7;
+ break;
+
+ case 6:
+ type = -3;
+ shapeIndex = 4;
+ xOffset = 1;
+ yOffset = 5;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (type == -2) {
+ shapeIndex = 5;
+ xOffset = 5;
+ yOffset = 9;
+ }
+
+ if (type != 0 && _handItemSet != type) {
+ _handItemSet = type;
+ _screen->hideMouse();
+ _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex));
+ _screen->showMouse();
+ }
+
+ if (type == 0 && _handItemSet != _itemInHand) {
+ if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) {
+ _handItemSet = _itemInHand;
+ _screen->hideMouse();
+ if (_itemInHand == -1)
+ _screen->setMouseCursor(0, 0, getShapePtr(0));
+ else
+ _screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64));
+ _screen->showMouse();
+ }
+ }
+}
+
+int KyraEngine_v2::checkInput(void *p) {
+ Common::Event event;
+ int keys = 0;
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_RETURN)
+ keys = 199;
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ keys = 198;
+ break;
+
+ case Common::EVENT_QUIT:
+ _quitFlag = true;
+ break;
+
+ default:
+ break;
+ }
+
+ //if ( _debugger->isAttached())
+ // _debugger->onFrame();
+ }
+
+ _system->delayMillis(10);
+ return keys;
+}
+
+void KyraEngine_v2::cleanup() {
+ delete [] _gamePlayBuffer;
+ delete [] _unkBuf500Bytes;
+ delete [] _screenBuffer;
+ delete [] _unkBuf200kByte;
+
+ for (int i = 0; i < ARRAYSIZE(_defaultShapeTable); ++i)
+ delete [] _defaultShapeTable[i];
+ freeSceneShapePtrs();
+
+ delete [] _cCodeBuffer;
+ delete [] _optionsBuffer;
+ delete [] _chapterBuffer;
+
+ delete [] _objectList;
+ delete [] _shapeDescTable;
+
+ delete [] _gfxBackUpRect;
+
+ delete [] _sceneList;
+
+ for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i)
+ delete _sceneAnimMovie[i];
+ for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i)
+ delete _wsaSlots[i];
+}
+
+#pragma mark - Localization
+
+void KyraEngine_v2::loadCCodeBuffer(const char *file) {
+ char tempString[13];
+ strcpy(tempString, file);
+ changeFileExtension(tempString);
+
+ delete [] _cCodeBuffer;
+ _cCodeBuffer = _res->fileData(tempString, 0);
+}
+
+void KyraEngine_v2::loadOptionsBuffer(const char *file) {
+ char tempString[13];
+ strcpy(tempString, file);
+ changeFileExtension(tempString);
+
+ delete [] _optionsBuffer;
+ _optionsBuffer = _res->fileData(tempString, 0);
+}
+
+void KyraEngine_v2::loadChapterBuffer(int chapter) {
+ char tempString[14];
+
+ static const char *chapterFilenames[] = {
+ "CH1.XXX", "CH2.XXX", "CH3.XXX", "CH4.XXX", "CH5.XXX"
+ };
+
+ assert(chapter >= 1 && chapter <= ARRAYSIZE(chapterFilenames));
+ strcpy(tempString, chapterFilenames[chapter-1]);
+ changeFileExtension(tempString);
+
+ delete [] _chapterBuffer;
+ _chapterBuffer = _res->fileData(tempString, 0);
+ _currentChapter = chapter;
+}
+
+void KyraEngine_v2::changeFileExtension(char *buffer) {
+ while (*buffer != '.') ++buffer;
+
+ ++buffer;
+ strcpy(buffer, _languageExtension[_lang]);
+}
+
+const uint8 *KyraEngine_v2::getTableEntry(const uint8 *buffer, int id) {
+ return buffer + READ_LE_UINT16(buffer + (id<<1));
+}
+
+const char *KyraEngine_v2::getTableString(int id, const uint8 *buffer, int decode) {
+ const char *string = (const char*)getTableEntry(buffer, id);
+
+ if (decode) {
+ decodeString1(string, _internStringBuf);
+ decodeString2(_internStringBuf, _internStringBuf);
+ string = _internStringBuf;
+ }
+
+ return string;
+}
+
+const char *KyraEngine_v2::getChapterString(int id) {
+ if (_currentChapter != _newChapterFile)
+ loadChapterBuffer(_newChapterFile);
+
+ return getTableString(id, _chapterBuffer, 1);
+}
+
+int KyraEngine_v2::decodeString1(const char *src, char *dst) {
+ static const uint8 decodeTable1[] = {
+ 0x20, 0x65, 0x74, 0x61, 0x69, 0x6E, 0x6F, 0x73, 0x72, 0x6C, 0x68,
+ 0x63, 0x64, 0x75, 0x70, 0x6D
+ };
+
+ static const uint8 decodeTable2[] = {
+ 0x74, 0x61, 0x73, 0x69, 0x6F, 0x20, 0x77, 0x62, 0x20, 0x72, 0x6E,
+ 0x73, 0x64, 0x61, 0x6C, 0x6D, 0x68, 0x20, 0x69, 0x65, 0x6F, 0x72,
+ 0x61, 0x73, 0x6E, 0x72, 0x74, 0x6C, 0x63, 0x20, 0x73, 0x79, 0x6E,
+ 0x73, 0x74, 0x63, 0x6C, 0x6F, 0x65, 0x72, 0x20, 0x64, 0x74, 0x67,
+ 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x72, 0x20, 0x75, 0x66, 0x6D, 0x73,
+ 0x77, 0x20, 0x74, 0x65, 0x70, 0x2E, 0x69, 0x63, 0x61, 0x65, 0x20,
+ 0x6F, 0x69, 0x61, 0x64, 0x75, 0x72, 0x20, 0x6C, 0x61, 0x65, 0x69,
+ 0x79, 0x6F, 0x64, 0x65, 0x69, 0x61, 0x20, 0x6F, 0x74, 0x72, 0x75,
+ 0x65, 0x74, 0x6F, 0x61, 0x6B, 0x68, 0x6C, 0x72, 0x20, 0x65, 0x69,
+ 0x75, 0x2C, 0x2E, 0x6F, 0x61, 0x6E, 0x73, 0x72, 0x63, 0x74, 0x6C,
+ 0x61, 0x69, 0x6C, 0x65, 0x6F, 0x69, 0x72, 0x61, 0x74, 0x70, 0x65,
+ 0x61, 0x6F, 0x69, 0x70, 0x20, 0x62, 0x6D
+ };
+
+ int size = 0;
+ uint cChar = 0;
+ while ((cChar = *src++) != 0) {
+ if (cChar & 0x80) {
+ cChar &= 0x7F;
+ int index = (cChar & 0x78) >> 3;
+ *dst++ = decodeTable1[index];
+ ++size;
+ assert(cChar < sizeof(decodeTable2));
+ cChar = decodeTable2[cChar];
+ }
+
+ *dst++ = cChar;
+ ++size;
+ }
+
+ *dst++ = 0;
+ return size;
+}
+
+void KyraEngine_v2::decodeString2(const char *src, char *dst) {
+ if (!src || !dst)
+ return;
+
+ char out = 0;
+ while ((out = *src) != 0) {
+ if (*src == 0x1B) {
+ ++src;
+ out = *src + 0x7F;
+ }
+ *dst++ = out;
+ ++src;
+ }
+
+ *dst = 0;
+}
+
+#pragma mark -
+
+void KyraEngine_v2::showMessageFromCCode(int id, int16 palIndex, int) {
+ const char *string = getTableString(id, _cCodeBuffer, 1);
+ showMessage(string, palIndex);
+}
+
+void KyraEngine_v2::showMessage(const char *string, int16 palIndex) {
+ _shownMessage = string;
+ _screen->hideMouse();
+ _screen->fillRect(0, 190, 319, 199, 0xCF);
+
+ if (string) {
+ if (palIndex != -1 || _msgUnk1) {
+ palIndex *= 3;
+ memcpy(_messagePal, _screen->_currentPalette + palIndex, 3);
+ memmove(_screen->_currentPalette + 765, _screen->_currentPalette + palIndex, 3);
+ _screen->setScreenPalette(_screen->_currentPalette);
+ }
+
+ int x = _text->getCenterStringX(string, 0, 320);
+ _text->printText(string, x, 190, 255, 207, 0);
+
+ setTimer1DelaySecs(7);
+ }
+
+ _msgUnk1 = 0;
+ _screen->showMouse();
+}
+
+void KyraEngine_v2::showChapterMessage(int id, int16 palIndex) {
+ showMessage(getChapterString(id), palIndex);
+}
+
+void KyraEngine_v2::loadMouseShapes() {
+ _screen->loadBitmap("_MOUSE.CSH", 3, 3, 0);
+
+ for (int i = 0; i <= 8; ++i) {
+ _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i);
+ assert(_defaultShapeTable[i]);
+ }
+}
+
+void KyraEngine_v2::loadItemShapes() {
+ _screen->loadBitmap("_ITEMS.CSH", 3, 3, 0);
+
+ for (int i = 64; i <= 239; ++i) {
+ _defaultShapeTable[i] = _screen->makeShapeCopy(_screen->getCPagePtr(3), i-64);
+ assert(_defaultShapeTable[i]);
+ }
+
+ _res->loadFileToBuf("_ITEMHT.DAT", _itemHtDat, sizeof(_itemHtDat));
+ assert(_res->getFileSize("_ITEMHT.DAT") == sizeof(_itemHtDat));
+
+ _screen->_curPage = 0;
+}
+
+void KyraEngine_v2::loadZShapes(int shapes) {
+ char file[10];
+ strcpy(file, "_ZX.SHP");
+
+ _loadedZTable = shapes;
+ file[2] = '0' + shapes;
+
+ uint8 *data = _res->fileData(file, 0);
+ for (int i = 9; i <= 32; ++i) {
+ delete [] _defaultShapeTable[i];
+ _defaultShapeTable[i] = _screen->makeShapeCopy(data, i-9);
+ }
+ delete [] data;
+
+ _loadedZTable = shapes;
+}
+
+void KyraEngine_v2::loadInventoryShapes() {
+ int curPageBackUp = _screen->_curPage;
+ _screen->_curPage = 2;
+
+ _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0);
+
+ for (int i = 0; i < 10; ++i)
+ _defaultShapeTable[240+i] = _screen->encodeShape(_inventoryX[i], _inventoryY[i], 16, 16, 0);
+
+ _screen->_curPage = curPageBackUp;
+}
+
+void KyraEngine_v2::runStartScript(int script, int unk1) {
+ char filename[14];
+ strcpy(filename, "_START0X.EMC");
+ filename[7] = script + '0';
+
+ ScriptData scriptData;
+ ScriptState scriptState;
+
+ _scriptInterpreter->loadScript(filename, &scriptData, &_opcodes);
+ _scriptInterpreter->initScript(&scriptState, &scriptData);
+ scriptState.regs[6] = unk1;
+ _scriptInterpreter->startScript(&scriptState, 0);
+ while (_scriptInterpreter->validScript(&scriptState))
+ _scriptInterpreter->runScript(&scriptState);
+ _scriptInterpreter->unloadScript(&scriptData);
+}
+
+void KyraEngine_v2::loadNPCScript() {
+ char filename[12];
+ strcpy(filename, "_NPC.EMC");
+
+ switch (_lang) {
+ case 0:
+ filename[5] = 'E';
+ break;
+
+ case 1:
+ filename[5] = 'F';
+ break;
+
+ case 2:
+ filename[5] = 'G';
+ break;
+
+ default:
+ break;
+ };
+
+ _scriptInterpreter->loadScript(filename, &_npcScriptData, &_opcodes);
+}
+
+void KyraEngine_v2::resetScaleTable() {
+ for (int i = 0; i < ARRAYSIZE(_scaleTable); ++i)
+ _scaleTable[i] = 0x100;
+}
+
+void KyraEngine_v2::setScaleTableItem(int item, int data) {
+ if (item >= 1 || item <= 15)
+ _scaleTable[item-1] = (data << 8) / 100;
+}
+
+int KyraEngine_v2::getScale(int x, int y) {
+ return _scaleTable[_screen->getLayer(x, y) - 1];
+}
+
+void KyraEngine_v2::setDrawLayerTableEntry(int entry, int data) {
+ if (entry >= 1 || entry <= 15)
+ _drawLayerTable[entry-1] = data;
+}
+
+int KyraEngine_v2::getDrawLayer(int x, int y) {
+ int layer = _screen->getLayer(x, y);
+ layer = _drawLayerTable[layer-1];
+ if (layer < 0)
+ layer = 0;
+ else if (layer >= 7)
+ layer = 6;
+ return layer;
+}
+
+void KyraEngine_v2::restorePage3() {
+ _screen->copyBlockToPage(2, 0, 0, 320, 144, _gamePlayBuffer);
+}
+
+void KyraEngine_v2::updateCharPal(int unk1) {
+ static bool unkVar1 = false;
+
+ if (!_useCharPal)
+ return;
+
+ int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1);
+ int palEntry = _charPalTable[layer];
+
+ if (palEntry != _charPalEntry && unk1) {
+ const uint8 *src = &_scenePal[(palEntry << 4) * 3];
+ uint8 *ptr = _screen->getPalette(0) + 336;
+ for (int i = 0; i < 48; ++i) {
+ *ptr -= (*ptr - *src) >> 1;
+ ++ptr;
+ ++src;
+ }
+ _screen->setScreenPalette(_screen->getPalette(0));
+ unkVar1 = true;
+ _charPalEntry = palEntry;
+ } else if (unkVar1 && !unk1) {
+ memcpy(_screen->getPalette(0) + 336, &_scenePal[(palEntry << 4) * 3], 48);
+ _screen->setScreenPalette(_screen->getPalette(0));
+ unkVar1 = false;
+ }
+}
+
+int KyraEngine_v2::inputSceneChange(int x, int y, int unk1, int unk2) {
+ bool refreshNPC = false;
+ uint16 curScene = _mainCharacter.sceneId;
+ _pathfinderFlag = 15;
+
+ if (!_unkHandleSceneChangeFlag) {
+ if (_unk3 == -3) {
+ if (_sceneList[curScene].exit4 != 0xFFFF) {
+ x = 4;
+ y = _sceneEnterY4;
+ _pathfinderFlag = 7;
+ }
+ } else if (_unk3 == -5) {
+ if (_sceneList[curScene].exit2 != 0xFFFF) {
+ x = 316;
+ y = _sceneEnterY2;
+ _pathfinderFlag = 7;
+ }
+ } else if (_unk3 == -6) {
+ if (_sceneList[curScene].exit1 != 0xFFFF) {
+ x = _sceneEnterX1;
+ y = _sceneEnterY1 - 2;
+ _pathfinderFlag = 14;
+ }
+ } else if (_unk3 == -4) {
+ if (_sceneList[curScene].exit3 != 0xFFFF) {
+ x = _sceneEnterX3;
+ y = 147;
+ _pathfinderFlag = 11;
+ }
+ }
+ }
+
+ if (_pathfinderFlag) {
+ if (findItem(curScene, 13) >= 0 && _unk3 <= -3) {
+ //XXX
+ _pathfinderFlag = 0;
+ return 0;
+ } else if (_itemInHand == 72) {
+ //XXX
+ _pathfinderFlag = 0;
+ return 0;
+ } else if (findItem(curScene, 72) >= 0 && _unk3 <= -3) {
+ //XXX
+ _pathfinderFlag = 0;
+ return 0;
+ } else if (0/*XXX*/) {
+ //XXX
+ _pathfinderFlag = 0;
+ return 0;
+ }
+ }
+
+ if (ABS(_mainCharacter.x1 - x) < 4 || ABS(_mainCharacter.y1 - y) < 2)
+ return 0;
+
+ int curX = _mainCharacter.x1 & ~3;
+ int curY = _mainCharacter.y1 & ~1;
+ int dstX = x & ~3;
+ int dstY = y & ~1;
+
+ int wayLength = findWay(curX, curY, dstX, dstY, _movFacingTable, 600);
+ _pathfinderFlag = 0;
+ _timer->disable(5);
+
+ if (wayLength != 0 && wayLength != 0x7D00)
+ refreshNPC = trySceneChange(_movFacingTable, unk1, unk2);
+
+ //XXX
+
+ if (refreshNPC)
+ enterNewSceneUnk2(0);
+
+ _pathfinderFlag = 0;
+ return refreshNPC;
+}
+
+bool KyraEngine_v2::checkSpecialSceneExit(int num, int x, int y) {
+ if (_specialExitTable[0+num] > x || _specialExitTable[5+num] > y ||
+ _specialExitTable[10+num] < x || _specialExitTable[15+num] < y)
+ return 0;
+ return 1;
+}
+
+void KyraEngine_v2::moveCharacter(int facing, int x, int y) {
+ _mainCharacter.facing = facing;
+ x &= ~3;
+ y &= ~1;
+
+ _screen->hideMouse();
+ switch (facing) {
+ case 0:
+ while (y < _mainCharacter.y1)
+ updateCharPosWithUpdate();
+ break;
+
+ case 2:
+ while (_mainCharacter.x1 < x)
+ updateCharPosWithUpdate();
+ break;
+
+ case 4:
+ while (y > _mainCharacter.y1)
+ updateCharPosWithUpdate();
+ break;
+
+ case 6:
+ while (_mainCharacter.x1 > x)
+ updateCharPosWithUpdate();
+ break;
+
+ default:
+ break;
+ }
+
+ _screen->showMouse();
+}
+
+int KyraEngine_v2::updateCharPos(int *table) {
+ static uint32 nextUpdate = 0;
+ static const int updateX[] = { 0, 4, 4, 4, 0, -4, -4, -4 };
+ static const int updateY[] = { -2, -2, 0, 2, 2, 2, 0, -2 };
+
+ if (_system->getMillis() < nextUpdate)
+ return 0;
+
+ int facing = _mainCharacter.facing;
+ _mainCharacter.x1 += updateX[facing];
+ _mainCharacter.y1 += updateY[facing];
+ updateCharAnimFrame(0, table);
+ nextUpdate = _system->getMillis() + _timer->getDelay(0) * _tickLength;
+ return 1;
+}
+
+void KyraEngine_v2::updateCharPosWithUpdate() {
+ updateCharPos(0);
+ update();
+}
+
+void KyraEngine_v2::updateCharAnimFrame(int charId, int *table) {
+ static int unkTable1[] = { 0, 0 };
+ static const int unkTable2[] = { 17, 0 };
+ static const int unkTable3[] = { 10, 0 };
+ static const int unkTable4[] = { 24, 0 };
+ static const int unkTable5[] = { 19, 0 };
+ static const int unkTable6[] = { 21, 0 };
+ static const int unkTable7[] = { 31, 0 };
+ static const int unkTable8[] = { 26, 0 };
+
+ Character *character = &_mainCharacter;
+ ++character->animFrame;
+ int facing = character->facing;
+
+ if (table) {
+ if (table[0] != table[-1] && table[-1] == table[1]) {
+ facing = getOppositeFacingDirection(table[-1]);
+ table[0] = table[-1];
+ }
+ }
+
+ if (!facing) {
+ ++unkTable1[charId];
+ } else if (facing == 4) {
+ ++unkTable1[charId+1];
+ } else if (facing == 7 || facing == 1 || facing == 5 || facing == 3) {
+ if (facing == 7 || facing == 1) {
+ if (unkTable1[charId] > 2)
+ facing = 0;
+ } else {
+ if (unkTable1[charId+1] > 2)
+ facing = 4;
+ }
+
+ unkTable1[charId] = 0;
+ unkTable1[charId+1] = 0;
+ }
+
+ if (facing == 0) {
+ if (character->animFrame < unkTable8[charId])
+ character->animFrame = unkTable8[charId];
+
+ if (character->animFrame > unkTable7[charId])
+ character->animFrame = unkTable8[charId];
+ } else if (facing == 4) {
+ if (character->animFrame < unkTable5[charId])
+ character->animFrame = unkTable5[charId];
+
+ if (character->animFrame > unkTable4[charId])
+ character->animFrame = unkTable5[charId];
+ } else {
+ if (character->animFrame > unkTable5[charId])
+ character->animFrame = unkTable6[charId];
+
+ if (character->animFrame == unkTable2[charId])
+ character->animFrame = unkTable3[charId];
+
+ if (character->animFrame > unkTable2[charId])
+ character->animFrame = unkTable3[charId] + 2;
+ }
+
+ updateCharacterAnim(charId);
+}
+
+int KyraEngine_v2::checkCharCollision(int x, int y) {
+ int scale1 = 0, scale2 = 0, scale3 = 0;
+ int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
+ scale1 = getScale(_mainCharacter.x1, _mainCharacter.y1);
+ scale2 = (scale1 * 24) >> 8;
+ scale3 = (scale1 * 48) >> 8;
+
+ x1 = _mainCharacter.x1 - (scale2 >> 1);
+ x2 = _mainCharacter.x1 + (scale2 >> 1);
+ y1 = _mainCharacter.y1 - scale3;
+ y2 = _mainCharacter.y1;
+
+ if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
+ return 0;
+
+ return -1;
+}
+
+#pragma mark -
+
+typedef Functor1Mem<ScriptState*, int, KyraEngine_v2> OpcodeV2;
+#define Opcode(x) OpcodeV2(this, &KyraEngine_v2::x)
+#define OpcodeUnImpl() OpcodeV2(this, 0)
+void KyraEngine_v2::setupOpcodeTable() {
+ static const OpcodeV2 opcodeTable[] = {
+ // 0x00
+ Opcode(o2_setCharacterFacingRefresh),
+ OpcodeUnImpl(),
+ Opcode(o2_defineObject),
+ Opcode(o2_refreshCharacter),
+ // 0x04
+ Opcode(o2_getCharacterX),
+ Opcode(o2_getCharacterY),
+ Opcode(o2_getCharacterFacing),
+ OpcodeUnImpl(),
+ // 0x08
+ Opcode(o2_setSceneComment),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x0c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x10
+ OpcodeUnImpl(),
+ Opcode(o2_showChapterMessage),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x14
+ Opcode(o2_wsaClose),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_displayWsaFrame),
+ // 0x18
+ Opcode(o2_displayWsaSequentialFrames),
+ Opcode(o2_wsaOpen),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x1c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x20
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_defineItem),
+ // 0x24
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_queryGameFlag),
+ // 0x28
+ Opcode(o2_resetGameFlag),
+ Opcode(o2_setGameFlag),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x2c
+ OpcodeUnImpl(),
+ Opcode(o2_hideMouse),
+ Opcode(o2_addSpecialExit),
+ OpcodeUnImpl(),
+ // 0x30
+ Opcode(o2_showMouse),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x34
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x38
+ Opcode(o2_dummy),
+ OpcodeUnImpl(),
+ Opcode(o2_setScaleTableItem),
+ Opcode(o2_setDrawLayerTableItem),
+ // 0x3c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_drawSceneShapeOnPage),
+ // 0x40
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_dummy),
+ OpcodeUnImpl(),
+ // 0x44
+ OpcodeUnImpl(),
+ Opcode(o2_restoreBackBuffer),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x48
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x4c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_dummy),
+ Opcode(o2_dummy),
+ // 0x50
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x54
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x58
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x5c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x60
+ Opcode(o2_getRand),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x64
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x68
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x6c
+ Opcode(o2_encodeShape),
+ Opcode(o2_defineRoomEntrance),
+ OpcodeUnImpl(),
+ Opcode(o2_setSpecialSceneScriptRunTime),
+ // 0x70
+ Opcode(o2_defineSceneAnim),
+ Opcode(o2_updateSceneAnim),
+ Opcode(o2_updateSceneAnim),
+ OpcodeUnImpl(),
+ // 0x74
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x78
+ OpcodeUnImpl(),
+ Opcode(o2_defineRoom),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x7c
+ OpcodeUnImpl(),
+ Opcode(o2_dummy),
+ Opcode(o2_dummy),
+ OpcodeUnImpl(),
+ // 0x80
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x84
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x88
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x8c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_setSpecialSceneScriptState),
+ // 0x90
+ Opcode(o2_clearSpecialSceneScriptState),
+ Opcode(o2_querySpecialSceneScriptState),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x94
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_wsaClose),
+ OpcodeUnImpl(),
+ // 0x98
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0x9c
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0xa0
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0xa4
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0xa8
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ // 0xac
+ OpcodeUnImpl(),
+ OpcodeUnImpl(),
+ Opcode(o2_dummy),
+ Opcode(o2_dummy),
+ };
+
+ for (int i = 0; i < ARRAYSIZE(opcodeTable); ++i)
+ _opcodes.push_back(&opcodeTable[i]);
}
} // end of namespace Kyra
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index df73118376..fb8fd2c454 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -27,6 +27,7 @@
#define KYRA_KYRA_V2_H
#include "kyra/kyra.h"
+#include "kyra/script.h"
#include "kyra/screen_v2.h"
namespace Kyra {
@@ -87,7 +88,7 @@ public:
~KyraEngine_v2();
virtual Screen *screen() { return _screen; }
- Screen *screen_v2() { return _screen; }
+ Screen_v2 *screen_v2() { return _screen; }
Movie *createWSAMovie();
protected:
@@ -103,8 +104,7 @@ protected:
void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...);
- void setupOpcodeTable() {}
-
+ // intro
void seq_playSequences(int startSeq, int endSeq = -1);
int seq_introWestwood(int seqNum);
int seq_introTitle(int seqNum);
@@ -136,7 +136,6 @@ protected:
ActiveWSA *_activeWSA;
ActiveChat *_activeChat;
- uint8 *_gameShapes[50];
uint8 *_mouseSHPBuf;
static const char *_introSoundList[];
@@ -145,6 +144,351 @@ protected:
static const int _introStringsSize;
int _introStringsDuration[21];
+
+protected:
+ // game initialization
+ void startup();
+ void runLoop();
+ void cleanup();
+
+ void setupTimers();
+ void setupOpcodeTable();
+
+ void loadMouseShapes();
+ void loadItemShapes();
+
+ // run
+ int update();
+ void updateMouse();
+
+ int checkInput(void *p);
+ void handleInput(int x, int y);
+
+ int inputSceneChange(int x, int y, int unk1, int unk2);
+
+ // gfx/animation specific
+ uint8 *_gamePlayBuffer;
+ void restorePage3();
+
+ uint8 *_screenBuffer;
+ uint8 *_maskPage;
+ uint8 *_gfxBackUpRect;
+
+ uint8 *getShapePtr(int index) { return _defaultShapeTable[index]; }
+ uint8 *_defaultShapeTable[250];
+ uint8 *_sceneShapeTable[50];
+
+ WSAMovieV2 *_wsaSlots[10];
+
+ void freeSceneShapePtrs();
+
+ struct ShapeDesc {
+ uint8 unk0, unk1, unk2, unk3, unk4;
+ uint16 unk5, unk7;
+ int16 xAdd, yAdd;
+ };
+
+ ShapeDesc *_shapeDescTable;
+
+ struct SceneAnim {
+ uint16 flags;
+ int16 x, y;
+ int16 x2, y2;
+ int16 width, height;
+ uint16 unkE;
+ uint16 specialSize;
+ uint16 unk12;
+ int16 shapeIndex;
+ uint16 wsaFlag;
+ char filename[14];
+ };
+
+ SceneAnim _sceneAnims[10];
+ WSAMovieV2 *_sceneAnimMovie[10];
+ bool _specialSceneScriptState[10];
+ ScriptState _sceneSpecialScripts[10];
+ uint32 _sceneSpecialScriptsTimer[10];
+ int _lastProcessedSceneScript;
+ bool _specialSceneScriptRunFlag;
+
+ void updateSpecialSceneScripts();
+ void freeSceneAnims();
+
+ int _loadedZTable;
+ void loadZShapes(int shapes);
+ void loadInventoryShapes();
+
+ void resetScaleTable();
+ void setScaleTableItem(int item, int data);
+ int getScale(int x, int y);
+ uint16 _scaleTable[15];
+
+ void setDrawLayerTableEntry(int entry, int data);
+ int getDrawLayer(int x, int y);
+ int _drawLayerTable[15];
+
+ // animator
+ struct AnimObj {
+ uint16 index;
+ uint16 type;
+ uint16 enabled;
+ uint16 needRefresh;
+ uint16 unk8;
+ uint16 animFlags;
+ uint16 flags;
+ int16 xPos1, yPos1;
+ uint8 *shapePtr;
+ uint16 shapeIndex1;
+ uint16 animNum;
+ uint16 shapeIndex3;
+ uint16 shapeIndex2;
+ uint16 unk1E;
+ uint8 unk20;
+ uint8 unk21;
+ uint8 unk22;
+ uint8 unk23;
+ int16 xPos2, yPos2;
+ int16 xPos3, yPos3;
+ int16 width, height;
+ int16 width2, height2;
+ AnimObj *nextObject;
+ };
+
+ AnimObj _animObjects[42];
+ void clearAnimObjects();
+
+ AnimObj *_animList;
+ bool _drawNoShapeFlag;
+ AnimObj *initAnimList(AnimObj *list, AnimObj *entry);
+ AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry);
+ AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry);
+
+ void drawAnimObjects();
+ void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer);
+ void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer);
+
+ void refreshAnimObjects(int force);
+ void refreshAnimObjectsIfNeed();
+
+ void updateCharacterAnim(int);
+ void updateSceneAnim(int anim, int newFrame);
+
+ // scene
+ struct SceneDesc {
+ char filename[10];
+ uint16 exit1, exit2, exit3, exit4;
+ uint8 flags;
+ uint8 sound;
+ };
+
+ SceneDesc *_sceneList;
+ const char *_sceneCommentString;
+ uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4;
+ int _sceneEnterX1, _sceneEnterY1, _sceneEnterX2, _sceneEnterY2,
+ _sceneEnterX3, _sceneEnterY3, _sceneEnterX4, _sceneEnterY4;
+ int _specialExitCount;
+ uint16 _specialExitTable[25];
+ bool checkSpecialSceneExit(int num, int x, int y);
+ uint8 _scenePal[688];
+ bool _overwriteSceneFacing;
+
+ void enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3);
+ void enterNewSceneUnk1(int facing, int unk1, int unk2);
+ void enterNewSceneUnk2(int unk1);
+ void unloadScene();
+
+ void loadScenePal();
+ void loadSceneMsc();
+
+ void startSceneScript(int unk1);
+ void runSceneScript2();
+ void runSceneScript4(int unk1);
+ void runSceneScript7();
+
+ void initSceneAnims(int unk1);
+ void initSceneScreen(int unk1);
+
+ int trySceneChange(int *moveTable, int unk1, int updateChar);
+ int checkSceneChange();
+
+ // pathfinder
+ int _movFacingTable[600];
+ int findWay(int curX, int curY, int dstX, int dstY, int *moveTable, int moveTableSize);
+ bool lineIsPassable(int x, int y);
+ bool directLinePassable(int x, int y, int toX, int toY);
+
+ int pathfinderUnk1(int *moveTable);
+ int pathfinderUnk2(int index, int v1, int v2);
+ int pathfinderUnk3(int tableLen, int x, int y);
+ int pathfinderUnk4(int index, int v);
+ void pathfinderUnk5(int *moveTable, int unk1, int x, int y, int moveTableSize);
+
+ int _pathfinderUnkTable1[400];
+ int _pathfinderUnkTable2[200];
+
+ // item
+ uint8 _itemHtDat[176];
+
+ struct Item {
+ uint16 id;
+ uint16 sceneId;
+ int16 x;
+ int8 y;
+ uint16 unk7;
+ };
+ Item *_itemList;
+
+ int findFreeItem();
+ int findItem(uint16 sceneId, int id);
+ void resetItemList();
+
+ int _itemInHand;
+ int _handItemSet;
+
+ // inventroy
+ static int _inventoryX[];
+ static int _inventoryY[];
+
+ // localization
+ void loadCCodeBuffer(const char *file);
+ void loadOptionsBuffer(const char *file);
+ void loadChapterBuffer(int chapter);
+ uint8 *_optionsBuffer;
+ uint8 *_cCodeBuffer;
+
+ uint8 *_chapterBuffer;
+ int _currentChapter;
+ int _newChapterFile;
+
+ const uint8 *getTableEntry(const uint8 *buffer, int id);
+ const char *getTableString(int id, const uint8 *buffer, int decode);
+ const char *getChapterString(int id);
+ int decodeString1(const char *src, char *dst);
+ void decodeString2(const char *src, char *dst);
+
+ void changeFileExtension(char *buffer);
+
+ char _internStringBuf[200];
+ static const char *_languageExtension[];
+ static const char *_scriptLangExt[];
+
+ // character
+ struct Character {
+ uint16 sceneId;
+ uint16 unk2;
+ uint8 height;
+ uint8 facing;
+ uint16 animFrame;
+ uint8 unk8;
+ uint8 unk9;
+ uint8 unkA;
+ uint16 inventory[20];
+ int16 x1, y1;
+ int16 x2, y2;
+ };
+
+ Character _mainCharacter;
+ bool _useCharPal;
+ int _charPalEntry;
+ uint8 _charPalTable[16];
+ void updateCharPal(int unk1);
+
+ void moveCharacter(int facing, int x, int y);
+ int updateCharPos(int *table);
+ void updateCharPosWithUpdate();
+ void updateCharAnimFrame(int num, int *table);
+
+ int checkCharCollision(int x, int y);
+
+ int _mainCharX, _mainCharY;
+ int _charScaleX, _charScaleY;
+
+ static int _characterFrameTable[];
+
+ // text
+ void showMessageFromCCode(int id, int16 palIndex, int);
+ void showMessage(const char *string, int16 palIndex);
+ void showChapterMessage(int id, int16 palIndex);
+
+ const char *_shownMessage;
+
+ byte _messagePal[3];
+ int _msgUnk1;
+
+ // timer
+ void timerFunc2(int);
+ void timerFunc3(int);
+ void timerFunc4(int);
+ void timerFunc5(int);
+ void timerFunc6(int);
+
+ void setTimer1DelaySecs(int secs);
+
+ // opcodes
+ int o2_setCharacterFacingRefresh(ScriptState *script);
+ int o2_defineObject(ScriptState *script);
+ int o2_refreshCharacter(ScriptState *script);
+ int o2_getCharacterX(ScriptState *script);
+ int o2_getCharacterY(ScriptState *script);
+ int o2_getCharacterFacing(ScriptState *script);
+ int o2_setSceneComment(ScriptState *script);
+ int o2_showChapterMessage(ScriptState *script);
+ int o2_wsaClose(ScriptState *script);
+ int o2_displayWsaFrame(ScriptState *script);
+ int o2_displayWsaSequentialFrames(ScriptState *script);
+ int o2_wsaOpen(ScriptState *script);
+ int o2_defineItem(ScriptState *script);
+ int o2_queryGameFlag(ScriptState *script);
+ int o2_resetGameFlag(ScriptState *script);
+ int o2_setGameFlag(ScriptState *script);
+ int o2_hideMouse(ScriptState *script);
+ int o2_addSpecialExit(ScriptState *script);
+ int o2_showMouse(ScriptState *script);
+ int o2_setScaleTableItem(ScriptState *script);
+ int o2_setDrawLayerTableItem(ScriptState *script);
+ int o2_drawSceneShapeOnPage(ScriptState *script);
+ int o2_restoreBackBuffer(ScriptState *script);
+ int o2_getRand(ScriptState *script);
+ int o2_encodeShape(ScriptState *script);
+ int o2_defineRoomEntrance(ScriptState *script);
+ int o2_setSpecialSceneScriptRunTime(ScriptState *script);
+ int o2_defineSceneAnim(ScriptState *script);
+ int o2_updateSceneAnim(ScriptState *script);
+ int o2_defineRoom(ScriptState *script);
+ int o2_setSpecialSceneScriptState(ScriptState *script);
+ int o2_clearSpecialSceneScriptState(ScriptState *script);
+ int o2_querySpecialSceneScriptState(ScriptState *script);
+ int o2_dummy(ScriptState *script);
+
+ // script
+ void runStartScript(int script, int unk1);
+ void loadNPCScript();
+
+ bool _noScriptEnter;
+
+ ScriptData _npcScriptData;
+
+ ScriptData _sceneScriptData;
+ ScriptState _sceneScriptState;
+
+ // pathfinder
+ int _pathfinderFlag;
+
+ // unk
+ struct Object {
+ char filename[13];
+ uint8 scriptId;
+ int16 x, y;
+ int8 unk12;
+ };
+ Object *_objectList;
+
+ uint8 *_unkBuf500Bytes;
+ uint8 *_unkBuf200kByte;
+ bool _unkFlag1;
+ int _unk3, _unk4, _unk5;
+ bool _unkSceneScreenFlag1;
+ bool _unkHandleSceneChangeFlag;
};
} // end of namespace Kyra
diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp
index b49635ab2d..9aa4b1f4da 100644
--- a/engines/kyra/kyra_v3.cpp
+++ b/engines/kyra/kyra_v3.cpp
@@ -290,14 +290,14 @@ void KyraEngine_v3::stopMusicTrack() {
int KyraEngine_v3::musicUpdate(int forceRestart) {
debugC(9, kDebugLevelMain, "KyraEngine::unkUpdate(%d)", forceRestart);
- static uint32 timer = 0;
+ static uint32 mTimer = 0;
static uint16 lock = 0;
- if (ABS<int>(_system->getMillis() - timer) > (int)(0x0F * _tickLength)) {
- timer = _system->getMillis();
+ if (ABS<int>(_system->getMillis() - mTimer) > (int)(0x0F * _tickLength)) {
+ mTimer = _system->getMillis();
}
- if (_system->getMillis() < timer && !forceRestart) {
+ if (_system->getMillis() < mTimer && !forceRestart) {
return 1;
}
@@ -311,7 +311,7 @@ int KyraEngine_v3::musicUpdate(int forceRestart) {
}
}
lock = 0;
- timer = _system->getMillis() + 0x0F * _tickLength;
+ mTimer = _system->getMillis() + 0x0F * _tickLength;
}
return 1;
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 0ddcc1bf7f..0517c393a1 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -2,22 +2,27 @@ MODULE := engines/kyra
MODULE_OBJS := \
animator_v1.o \
+ animator_v2.o \
debugger.o \
detection.o \
gui_v1.o \
gui_v2.o \
items_v1.o \
+ items_v2.o \
kyra.o \
kyra_v1.o \
kyra_v2.o \
kyra_v3.o \
resource.o \
saveload_v1.o \
+ scene.o \
scene_v1.o \
+ scene_v2.o \
screen.o \
screen_v1.o \
screen_v2.o \
script_v1.o \
+ script_v2.o \
script.o \
seqplayer.o \
sequences_v1.o \
@@ -31,7 +36,9 @@ MODULE_OBJS := \
staticres.o \
text.o \
text_v1.o \
+ timer.o \
timer_v1.o \
+ timer_v2.o \
vqa.o \
wsamovie.o
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index 3ff8dd984c..fa333bf8bd 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -42,11 +42,11 @@
namespace Kyra {
namespace {
-struct ResFilenameEqual : public Common::BinaryFunction<ResourceFile*, uint, bool> {
+struct ResFilenameEqual : public Common::UnaryFunction<ResourceFile*, bool> {
uint _filename;
ResFilenameEqual(uint file) : _filename(file) {}
- bool operator()(ResourceFile *f) {
+ bool operator()(const ResourceFile *f) {
return f->filename() == _filename;
}
};
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 19855ed9c9..139a7fa72c 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -122,9 +122,8 @@ public:
uint32 getFileSize(const char *file) const;
uint8* fileData(const char *file, uint32 *size) const;
- // it gives back a file handle (used for the speech player)
- // it could be that the needed file is embedded in the returned
- // handle
+ // gives back a file handle
+ // it is possible that the needed file is embedded in the returned handle
bool getFileHandle(const char *file, uint32 *size, Common::File &filehandle);
bool loadFileToBuf(const char *file, void *buf, uint32 maxSize);
diff --git a/engines/kyra/saveload_v1.cpp b/engines/kyra/saveload_v1.cpp
index d28a0b3f8b..c2ceee1d3b 100644
--- a/engines/kyra/saveload_v1.cpp
+++ b/engines/kyra/saveload_v1.cpp
@@ -33,8 +33,9 @@
#include "kyra/screen.h"
#include "kyra/resource.h"
#include "kyra/sound.h"
+#include "kyra/timer.h"
-#define CURRENT_VERSION 7
+#define CURRENT_VERSION 8
// TODO: our current savefiles still use the old
// flag system to check the version, we should
@@ -147,14 +148,7 @@ void KyraEngine_v1::loadGame(const char *fileName) {
_poisonDeathCounter = in->readByte();
_animator->_brandonDrawFrame = in->readUint16BE();
- for (int i = 0; i < 32; i++) {
- _timers[i].active = in->readByte();
- _timers[i].countdown = in->readSint32BE();
- _timers[i].nextRun = in->readUint32BE();
- if (_timers[i].nextRun != 0)
- _timers[i].nextRun += _system->getMillis();
- }
- _timerNextRun = 0;
+ _timer->loadDataFromFile(in, version);
memset(_flagsTable, 0, sizeof(_flagsTable));
uint32 flagsSize = in->readUint32BE();
@@ -206,7 +200,7 @@ void KyraEngine_v1::loadGame(const char *fileName) {
if (version >= 7) {
_curSfxFile = in->readByte();
- // In the first version there this entry was introduced,
+ // In the first version when this entry was introduced,
// it wasn't made sure that _curSfxFile was initialized
// so if it's out of bounds we just set it to 0.
if (_curSfxFile >= _soundFilesTownsCount || _curSfxFile < 0)
@@ -323,14 +317,7 @@ void KyraEngine_v1::saveGame(const char *fileName, const char *saveName) {
out->writeByte(_poisonDeathCounter);
out->writeUint16BE(_animator->_brandonDrawFrame);
- for (int i = 0; i < 32; i++) {
- out->writeByte(_timers[i].active);
- out->writeSint32BE(_timers[i].countdown);
- if (_system->getMillis() >= _timers[i].nextRun)
- out->writeUint32BE(0);
- else
- out->writeUint32BE(_timers[i].nextRun - _system->getMillis());
- }
+ _timer->saveDataToFile(out);
out->writeUint32BE(sizeof(_flagsTable));
out->write(_flagsTable, sizeof(_flagsTable));
diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp
new file mode 100644
index 0000000000..bf85ab1474
--- /dev/null
+++ b/engines/kyra/scene.cpp
@@ -0,0 +1,383 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/screen.h"
+
+namespace Kyra {
+
+int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
+ debugC(9, kDebugLevelMain, "KyraEngine::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize);
+ x &= 0xFFFC; toX &= 0xFFFC;
+ y &= 0xFFFE; toY &= 0xFFFE;
+ x = (int16)x; y = (int16)y; toX = (int16)toX; toY = (int16)toY;
+
+ if (x == toY && y == toY) {
+ moveTable[0] = 8;
+ return 0;
+ }
+
+ int curX = x;
+ int curY = y;
+ int tempValue = 0;
+ int lastUsedEntry = 0;
+ int *pathTable1 = new int[0x7D0];
+ int *pathTable2 = new int[0x7D0];
+ assert(pathTable1 && pathTable2);
+
+ while (true) {
+ int newFacing = getFacingFromPointToPoint(x, y, toX, toY);
+ changePosTowardsFacing(curX, curY, newFacing);
+
+ if (curX == toX && curY == toY) {
+ if (!lineIsPassable(curX, curY))
+ break;
+ moveTable[lastUsedEntry++] = newFacing;
+ break;
+ }
+
+ if (lineIsPassable(curX, curY)) {
+ if (lastUsedEntry == moveTableSize) {
+ delete [] pathTable1;
+ delete [] pathTable2;
+ return 0x7D00;
+ }
+ // debug drawing
+ //if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) {
+ // _screen->setPagePixel(0, curX, curY, 11);
+ // _screen->updateScreen();
+ // waitTicks(5);
+ //}
+ moveTable[lastUsedEntry++] = newFacing;
+ x = curX;
+ y = curY;
+ continue;
+ }
+
+ int temp = 0;
+ while (true) {
+ newFacing = getFacingFromPointToPoint(curX, curY, toX, toY);
+ changePosTowardsFacing(curX, curY, newFacing);
+ // debug drawing
+ //if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) {
+ // _screen->setPagePixel(0, curX, curY, 8);
+ // _screen->updateScreen();
+ // waitTicks(5);
+ //}
+
+ if (!lineIsPassable(curX, curY)) {
+ if (curX != toX || curY != toY)
+ continue;
+ }
+
+ if (curX == toX && curY == toY) {
+ if (!lineIsPassable(curX, curY)) {
+ tempValue = 0;
+ temp = 0;
+ break;
+ }
+ }
+
+ temp = findSubPath(x, y, curX, curY, pathTable1, 1, 0x7D0);
+ tempValue = findSubPath(x, y, curX, curY, pathTable2, 0, 0x7D0);
+ if (curX == toX && curY == toY) {
+ if (temp == 0x7D00 && tempValue == 0x7D00) {
+ delete [] pathTable1;
+ delete [] pathTable2;
+ return 0x7D00;
+ }
+ }
+
+ if (temp != 0x7D00 || tempValue != 0x7D00)
+ break;
+ }
+
+ if (temp < tempValue) {
+ if (lastUsedEntry + temp > moveTableSize) {
+ delete [] pathTable1;
+ delete [] pathTable2;
+ return 0x7D00;
+ }
+ memcpy(&moveTable[lastUsedEntry], pathTable1, temp*sizeof(int));
+ lastUsedEntry += temp;
+ } else {
+ if (lastUsedEntry + tempValue > moveTableSize) {
+ delete [] pathTable1;
+ delete [] pathTable2;
+ return 0x7D00;
+ }
+ memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue*sizeof(int));
+ lastUsedEntry += tempValue;
+ }
+ x = curX;
+ y = curY;
+ if (curX == toX && curY == toY)
+ break;
+ }
+
+ delete [] pathTable1;
+ delete [] pathTable2;
+ moveTable[lastUsedEntry] = 8;
+ return lastUsedEntry;
+}
+
+int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) {
+ debugC(9, kDebugLevelMain, "KyraEngine::findSubPath(%d, %d, %d, %d, %p, %d, %d)", x, y, toX, toY, (const void *)moveTable, start, end);
+ // only used for debug specific code
+ //static uint16 unkTable[] = { 8, 5 };
+ static const int8 facingTable1[] = { 7, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 0 };
+ static const int8 facingTable2[] = { -1, 0, -1, 2, -1, 4, -1, 6, -1, 2, -1, 4, -1, 6, -1, 0 };
+ static const int8 facingTable3[] = { 2, 4, 4, 6, 6, 0, 0, 2, 6, 6, 0, 0, 2, 2, 4, 4 };
+ static const int8 addPosTableX[] = { -1, 0, -1, 4, -1, 0, -1, -4, -1, -4, -1, 0, -1, 4, -1, 0 };
+ static const int8 addPosTableY[] = { -1, 2, -1, 0, -1, -2, -1, 0, -1, 0, -1, 2, -1, 0, -1, -2 };
+
+ // debug specific
+ /*++unkTable[start];
+ while (screen()->getPalette(0)[unkTable[start]] != 0x0F) {
+ ++unkTable[start];
+ }*/
+
+ int xpos1 = x, xpos2 = x;
+ int ypos1 = y, ypos2 = y;
+ int newFacing = getFacingFromPointToPoint(x, y, toX, toY);
+ int position = 0;
+
+ while (position != end) {
+ int newFacing2 = newFacing;
+ while (true) {
+ changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]);
+ if (!lineIsPassable(xpos1, ypos1)) {
+ if (facingTable1[start*8 + newFacing2] == newFacing)
+ return 0x7D00;
+ newFacing2 = facingTable1[start*8 + newFacing2];
+ xpos1 = x;
+ ypos1 = y;
+ continue;
+ }
+ newFacing = facingTable1[start*8 + newFacing2];
+ break;
+ }
+ // debug drawing
+ /*if (xpos1 >= 0 && ypos1 >= 0 && xpos1 < 320 && ypos1 < 200) {
+ screen()->setPagePixel(0, xpos1, ypos1, unkTable[start]);
+ screen()->updateScreen();
+ //waitTicks(5);
+ }*/
+ if (newFacing & 1) {
+ int temp = xpos1 + addPosTableX[newFacing + start * 8];
+ if (toX == temp) {
+ temp = ypos1 + addPosTableY[newFacing + start * 8];
+ if (toY == temp) {
+ moveTable[position++] = facingTable2[newFacing + start * 8];
+ return position;
+ }
+ }
+ }
+
+ moveTable[position++] = newFacing;
+ x = xpos1;
+ y = ypos1;
+
+ if (x == toX && y == toY)
+ return position;
+
+ if (xpos1 == xpos2 && ypos1 == ypos2)
+ break;
+
+ newFacing = facingTable3[start*8 + newFacing];
+ }
+
+ return 0x7D00;
+}
+
+int KyraEngine::getFacingFromPointToPoint(int x, int y, int toX, int toY) {
+ debugC(9, kDebugLevelMain, "KyraEngine::getFacingFromPointToPoint(%d, %d, %d, %d)", x, y, toX, toY);
+ static const int facingTable[] = {
+ 1, 0, 1, 2, 3, 4, 3, 2, 7, 0, 7, 6, 5, 4, 5, 6
+ };
+
+ int facingEntry = 0;
+ int ydiff = y - toY;
+ if (ydiff < 0) {
+ ++facingEntry;
+ ydiff = -ydiff;
+ }
+ facingEntry <<= 1;
+
+ int xdiff = toX - x;
+ if (xdiff < 0) {
+ ++facingEntry;
+ xdiff = -xdiff;
+ }
+
+ if (xdiff >= ydiff) {
+ int temp = ydiff;
+ ydiff = xdiff;
+ xdiff = temp;
+
+ facingEntry <<= 1;
+ } else {
+ facingEntry <<= 1;
+ facingEntry += 1;
+ }
+ int temp = (ydiff + 1) >> 1;
+
+ if (xdiff < temp) {
+ facingEntry <<= 1;
+ facingEntry += 1;
+ } else {
+ facingEntry <<= 1;
+ }
+
+ assert(facingEntry < ARRAYSIZE(facingTable));
+ return facingTable[facingEntry];
+}
+
+
+int KyraEngine::getOppositeFacingDirection(int dir) {
+ debugC(9, kDebugLevelMain, "KyraEngine::getOppositeFacingDirection(%d)", dir);
+ switch (dir) {
+ case 0:
+ return 2;
+ case 1:
+ return 1;
+ case 3:
+ return 7;
+ case 4:
+ return 6;
+ case 5:
+ return 5;
+ case 6:
+ return 4;
+ case 7:
+ return 3;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void KyraEngine::changePosTowardsFacing(int &x, int &y, int facing) {
+ debugC(9, kDebugLevelMain, "KyraEngine::changePosTowardsFacing(%d, %d, %d)", x, y, facing);
+ x += _addXPosTable[facing];
+ y += _addYPosTable[facing];
+}
+
+int KyraEngine::getMoveTableSize(int *moveTable) {
+ debugC(9, kDebugLevelMain, "KyraEngine::getMoveTableSize(%p)", (const void *)moveTable);
+ int retValue = 0;
+ if (moveTable[0] == 8)
+ return 0;
+
+ static const int facingTable[] = {
+ 4, 5, 6, 7, 0, 1, 2, 3
+ };
+ static const int unkTable[] = {
+ -1, -1, 1, 2, -1, 6, 7, -1,
+ -1, -1, -1, -1, 2, -1, 0, -1,
+ 1, -1, -1, -1, 3, 4, -1, 0,
+ 2, -1, -1, -1, -1, -1, 4, -1,
+ -1, 2, 3, -1, -1, -1, 5, 6,
+ 6, -1, 4, -1, -1, -1, -1, -1,
+ 7, 0, -1, 4, 5, -1, -1, -1,
+ -1, -1, 0, -1, 6, -1, -1, -1
+ };
+
+ int *oldPosition = moveTable;
+ int *tempPosition = moveTable;
+ int *curPosition = moveTable + 1;
+ retValue = 1;
+
+ while (*curPosition != 8) {
+ if (*oldPosition == facingTable[*curPosition]) {
+ retValue -= 2;
+ *oldPosition = 9;
+ *curPosition = 9;
+
+ while (tempPosition != moveTable) {
+ --tempPosition;
+ if (*tempPosition != 9)
+ break;
+ }
+
+ if (tempPosition == moveTable && *tempPosition == 9) {
+ while (*tempPosition != 8 && *tempPosition == 9)
+ ++tempPosition;
+
+ if (*tempPosition == 8)
+ return 0;
+ }
+
+ oldPosition = tempPosition;
+ curPosition = oldPosition+1;
+
+ while (*curPosition != 8 && *curPosition == 9)
+ ++curPosition;
+
+ continue;
+ }
+
+ if (unkTable[*curPosition+((*oldPosition)*8)] != -1) {
+ --retValue;
+ *oldPosition = unkTable[*curPosition+((*oldPosition)*8)];
+ *curPosition = 9;
+
+ if (tempPosition != oldPosition) {
+ curPosition = oldPosition;
+ oldPosition = tempPosition;
+ while (true) {
+ if (tempPosition == moveTable)
+ break;
+
+ --tempPosition;
+ if (*tempPosition != 9)
+ break;
+
+ }
+ } else {
+ while (true) {
+ ++curPosition;
+ if (*curPosition != 9)
+ break;
+ }
+ }
+ continue;
+ }
+
+ tempPosition = oldPosition;
+ oldPosition = curPosition;
+ ++retValue;
+
+ while (true) {
+ ++curPosition;
+ if (*curPosition != 9)
+ break;
+ }
+ }
+
+ return retValue;
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp
index e01bb98e18..3754d5e2ab 100644
--- a/engines/kyra/scene_v1.cpp
+++ b/engines/kyra/scene_v1.cpp
@@ -33,6 +33,7 @@
#include "kyra/animator_v1.h"
#include "kyra/text.h"
#include "kyra/script.h"
+#include "kyra/timer.h"
#include "common/system.h"
#include "common/savefile.h"
@@ -230,15 +231,15 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int
_screen->hideMouse();
xpos = (int16)(xpos & 0xFFFC);
ypos = (int16)(ypos & 0xFFFE);
- disableTimer(19);
- disableTimer(14);
- disableTimer(18);
+ _timer->disable(19);
+ _timer->disable(14);
+ _timer->disable(18);
uint32 nextFrame = 0;
switch (facing) {
case 0:
while (ypos < ch->y1) {
- nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
setCharacterPositionWithUpdate(character);
delayUntil(nextFrame, true);
}
@@ -246,7 +247,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int
case 2:
while (ch->x1 < xpos) {
- nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
setCharacterPositionWithUpdate(character);
delayUntil(nextFrame, true);
}
@@ -254,7 +255,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int
case 4:
while (ypos > ch->y1) {
- nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
setCharacterPositionWithUpdate(character);
delayUntil(nextFrame, true);
}
@@ -262,7 +263,7 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int
case 6:
while (ch->x1 > xpos) {
- nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
setCharacterPositionWithUpdate(character);
delayUntil(nextFrame, true);
}
@@ -272,9 +273,9 @@ void KyraEngine_v1::moveCharacterToPos(int character, int facing, int xpos, int
break;
}
- enableTimer(19);
- enableTimer(14);
- enableTimer(18);
+ _timer->enable(19);
+ _timer->enable(14);
+ _timer->enable(18);
_screen->showMouse();
}
@@ -282,7 +283,7 @@ void KyraEngine_v1::setCharacterPositionWithUpdate(int character) {
debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionWithUpdate(%d)", character);
setCharacterPosition(character, 0);
_sprites->updateSceneAnims();
- updateGameTimers();
+ _timer->update();
_animator->updateAllObjectShapes();
updateTextFade();
@@ -391,29 +392,6 @@ void KyraEngine_v1::setCharacterPositionHelper(int character, int *facingTable)
_animator->animRefreshNPC(character);
}
-int KyraEngine_v1::getOppositeFacingDirection(int dir) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::getOppositeFacingDirection(%d)", dir);
- switch (dir) {
- case 0:
- return 2;
- case 1:
- return 1;
- case 3:
- return 7;
- case 4:
- return 6;
- case 5:
- return 5;
- case 6:
- return 4;
- case 7:
- return 3;
- default:
- break;
- }
- return 0;
-}
-
void KyraEngine_v1::loadSceneMsc() {
assert(_currentCharacter->sceneId < _roomTableSize);
int tableId = _roomTable[_currentCharacter->sceneId].nameIndex;
@@ -998,9 +976,9 @@ int KyraEngine_v1::processSceneChange(int *table, int unk1, int frameReset) {
if (temp)
++table;
- nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5) * _tickLength + _system->getMillis();
while (_system->getMillis() < nextFrame) {
- updateGameTimers();
+ _timer->update();
if (_currentCharacter->sceneId == 210) {
updateKyragemFading();
@@ -1188,237 +1166,10 @@ void KyraEngine_v1::setCharactersPositions(int character) {
int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
debugC(9, kDebugLevelMain, "KyraEngine_v1::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize);
- x &= 0xFFFC; toX &= 0xFFFC;
- y &= 0xFFFE; toY &= 0xFFFE;
- x = (int16)x; y = (int16)y; toX = (int16)toX; toY = (int16)toY;
-
- if (x == toY && y == toY) {
- moveTable[0] = 8;
- return 0;
- }
-
- int curX = x;
- int curY = y;
- int lastUsedEntry = 0;
- int tempValue = 0;
- int *pathTable1 = new int[0x7D0];
- int *pathTable2 = new int[0x7D0];
- assert(pathTable1 && pathTable2);
-
- while (true) {
- int newFacing = getFacingFromPointToPoint(x, y, toX, toY);
- changePosTowardsFacing(curX, curY, newFacing);
-
- if (curX == toX && curY == toY) {
- if (!lineIsPassable(curX, curY))
- break;
- moveTable[lastUsedEntry++] = newFacing;
- break;
- }
-
- if (lineIsPassable(curX, curY)) {
- if (lastUsedEntry == moveTableSize) {
- delete [] pathTable1;
- delete [] pathTable2;
- return 0x7D00;
- }
- // debug drawing
- //if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) {
- // _screen->setPagePixel(0, curX, curY, 11);
- // _screen->updateScreen();
- // waitTicks(5);
- //}
- moveTable[lastUsedEntry++] = newFacing;
- x = curX;
- y = curY;
- continue;
- }
-
- int temp = 0;
- while (true) {
- newFacing = getFacingFromPointToPoint(curX, curY, toX, toY);
- changePosTowardsFacing(curX, curY, newFacing);
- // debug drawing
- //if (curX >= 0 && curY >= 0 && curX < 320 && curY < 200) {
- // _screen->setPagePixel(0, curX, curY, 8);
- // _screen->updateScreen();
- // waitTicks(5);
- //}
-
- if (!lineIsPassable(curX, curY)) {
- if (curX != toX || curY != toY)
- continue;
- }
-
- if (curX == toX && curY == toY) {
- if (!lineIsPassable(curX, curY)) {
- tempValue = 0;
- temp = 0;
- break;
- }
- }
-
- temp = findSubPath(x, y, curX, curY, pathTable1, 1, 0x7D0);
- tempValue = findSubPath(x, y, curX, curY, pathTable2, 0, 0x7D0);
- if (curX == toX && curY == toY) {
- if (temp == 0x7D00 && tempValue == 0x7D00) {
- delete [] pathTable1;
- delete [] pathTable2;
- return 0x7D00;
- }
- }
-
- if (temp != 0x7D00 || tempValue != 0x7D00)
- break;
- }
-
- if (temp < tempValue) {
- if (lastUsedEntry + temp > moveTableSize) {
- delete [] pathTable1;
- delete [] pathTable2;
- return 0x7D00;
- }
- memcpy(&moveTable[lastUsedEntry], pathTable1, temp*sizeof(int));
- lastUsedEntry += temp;
- } else {
- if (lastUsedEntry + tempValue > moveTableSize) {
- delete [] pathTable1;
- delete [] pathTable2;
- return 0x7D00;
- }
- memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue*sizeof(int));
- lastUsedEntry += tempValue;
- }
- x = curX;
- y = curY;
- if (curX == toX && curY == toY)
- break;
- }
-
- delete [] pathTable1;
- delete [] pathTable2;
- moveTable[lastUsedEntry] = 8;
+ KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize);
return getMoveTableSize(moveTable);
}
-int KyraEngine_v1::findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::findSubPath(%d, %d, %d, %d, %p, %d, %d)", x, y, toX, toY, (const void *)moveTable, start, end);
- // only used for debug specific code
- //static uint16 unkTable[] = { 8, 5 };
- static const int8 facingTable1[] = { 7, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 0 };
- static const int8 facingTable2[] = { -1, 0, -1, 2, -1, 4, -1, 6, -1, 2, -1, 4, -1, 6, -1, 0 };
- static const int8 facingTable3[] = { 2, 4, 4, 6, 6, 0, 0, 2, 6, 6, 0, 0, 2, 2, 4, 4 };
- static const int8 addPosTableX[] = { -1, 0, -1, 4, -1, 0, -1, -4, -1, -4, -1, 0, -1, 4, -1, 0 };
- static const int8 addPosTableY[] = { -1, 2, -1, 0, -1, -2, -1, 0, -1, 0, -1, 2, -1, 0, -1, -2 };
-
- // debug specific
- //++unkTable[start];
- //while (_screen->getPalette(0)[unkTable[start]] != 0x0F) {
- // ++unkTable[start];
- //}
-
- int xpos1 = x, xpos2 = x;
- int ypos1 = y, ypos2 = y;
- int newFacing = getFacingFromPointToPoint(x, y, toX, toY);
- int position = 0;
-
- while (position != end) {
- int newFacing2 = newFacing;
- while (true) {
- changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]);
- if (!lineIsPassable(xpos1, ypos1)) {
- if (facingTable1[start*8 + newFacing2] == newFacing)
- return 0x7D00;
- newFacing2 = facingTable1[start*8 + newFacing2];
- xpos1 = x;
- ypos1 = y;
- continue;
- }
- newFacing = facingTable1[start*8 + newFacing2];
- break;
- }
- // debug drawing
- //if (xpos1 >= 0 && ypos1 >= 0 && xpos1 < 320 && ypos1 < 200) {
- // _screen->setPagePixel(0, xpos1, ypos1, unkTable[start]);
- // _screen->updateScreen();
- // waitTicks(5);
- //}
- if (newFacing & 1) {
- int temp = xpos1 + addPosTableX[newFacing + start * 8];
- if (toX == temp) {
- temp = ypos1 + addPosTableY[newFacing + start * 8];
- if (toY == temp) {
- moveTable[position++] = facingTable2[newFacing + start * 8];
- return position;
- }
- }
- }
-
- moveTable[position++] = newFacing;
- x = xpos1;
- y = ypos1;
-
- if (x == toX && y == toY)
- return position;
-
- if (xpos1 == xpos2 && ypos1 == ypos2)
- break;
-
- newFacing = facingTable3[start*8 + newFacing];
- }
-
- return 0x7D00;
-}
-
-int KyraEngine_v1::getFacingFromPointToPoint(int x, int y, int toX, int toY) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::getFacingFromPointToPoint(%d, %d, %d, %d)", x, y, toX, toY);
- static const int facingTable[] = {
- 1, 0, 1, 2, 3, 4, 3, 2, 7, 0, 7, 6, 5, 4, 5, 6
- };
-
- int facingEntry = 0;
- int ydiff = y - toY;
- if (ydiff < 0) {
- ++facingEntry;
- ydiff = -ydiff;
- }
- facingEntry <<= 1;
-
- int xdiff = toX - x;
- if (xdiff < 0) {
- ++facingEntry;
- xdiff = -xdiff;
- }
-
- if (xdiff >= ydiff) {
- int temp = ydiff;
- ydiff = xdiff;
- xdiff = temp;
-
- facingEntry <<= 1;
- } else {
- facingEntry <<= 1;
- facingEntry += 1;
- }
- int temp = (ydiff + 1) >> 1;
-
- if (xdiff < temp) {
- facingEntry <<= 1;
- facingEntry += 1;
- } else {
- facingEntry <<= 1;
- }
-
- assert(facingEntry < ARRAYSIZE(facingTable));
- return facingTable[facingEntry];
-}
-
-void KyraEngine_v1::changePosTowardsFacing(int &x, int &y, int facing) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::changePosTowardsFacing(%d, %d, %d)", x, y, facing);
- x += _addXPosTable[facing];
- y += _addYPosTable[facing];
-}
-
bool KyraEngine_v1::lineIsPassable(int x, int y) {
debugC(9, kDebugLevelMain, "KyraEngine_v1::lineIsPassable(%d, %d)", x, y);
if (queryGameFlag(0xEF)) {
@@ -1478,100 +1229,7 @@ bool KyraEngine_v1::lineIsPassable(int x, int y) {
return true;
}
-int KyraEngine_v1::getMoveTableSize(int *moveTable) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::getMoveTableSize(%p)", (const void *)moveTable);
- int retValue = 0;
- if (moveTable[0] == 8)
- return 0;
-
- static const int facingTable[] = {
- 4, 5, 6, 7, 0, 1, 2, 3
- };
- static const int unkTable[] = {
- -1, -1, 1, 2, -1, 6, 7, -1,
- -1, -1, -1, -1, 2, -1, 0, -1,
- 1, -1, -1, -1, 3, 4, -1, 0,
- 2, -1, -1, -1, -1, -1, 4, -1,
- -1, 2, 3, -1, -1, -1, 5, 6,
- 6, -1, 4, -1, -1, -1, -1, -1,
- 7, 0, -1, 4, 5, -1, -1, -1,
- -1, -1, 0, -1, 6, -1, -1, -1
- };
-
- int *oldPosition = moveTable;
- int *tempPosition = moveTable;
- int *curPosition = moveTable + 1;
- retValue = 1;
-
- while (*curPosition != 8) {
- if (*oldPosition == facingTable[*curPosition]) {
- retValue -= 2;
- *oldPosition = 9;
- *curPosition = 9;
-
- while (tempPosition != moveTable) {
- --tempPosition;
- if (*tempPosition != 9)
- break;
- }
-
- if (tempPosition == moveTable && *tempPosition == 9) {
- while (*tempPosition != 8 && *tempPosition == 9)
- ++tempPosition;
-
- if (*tempPosition == 8)
- return 0;
- }
-
- oldPosition = tempPosition;
- curPosition = oldPosition+1;
-
- while (*curPosition != 8 && *curPosition == 9)
- ++curPosition;
-
- continue;
- }
-
- if (unkTable[*curPosition+((*oldPosition)*8)] != -1) {
- --retValue;
- *oldPosition = unkTable[*curPosition+((*oldPosition)*8)];
- *curPosition = 9;
-
- if (tempPosition != oldPosition) {
- curPosition = oldPosition;
- oldPosition = tempPosition;
- while (true) {
- if (tempPosition == moveTable)
- break;
-
- --tempPosition;
- if (*tempPosition != 9)
- break;
-
- }
- } else {
- while (true) {
- ++curPosition;
- if (*curPosition != 9)
- break;
- }
- }
- continue;
- }
-
- tempPosition = oldPosition;
- oldPosition = curPosition;
- ++retValue;
-
- while (true) {
- ++curPosition;
- if (*curPosition != 9)
- break;
- }
- }
-
- return retValue;
-}
+#pragma mark -
void KyraEngine_v1::setupSceneResource(int sceneId) {
debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneResource(%d)", sceneId);
diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp
new file mode 100644
index 0000000000..fbda1f8455
--- /dev/null
+++ b/engines/kyra/scene_v2.cpp
@@ -0,0 +1,865 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra_v2.h"
+#include "kyra/screen_v2.h"
+#include "kyra/wsamovie.h"
+
+#include "common/func.h"
+
+namespace Kyra {
+
+void KyraEngine_v2::enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) {
+ // XXX
+ _screen->hideMouse();
+
+ if (!unk3) {
+ //updateSpecialItems();
+ //displayInvWsaLastFrame();
+ }
+
+ if (unk1) {
+ int x = _mainCharacter.x1;
+ int y = _mainCharacter.y1;
+
+ switch (facing) {
+ case 0:
+ y -= 6;
+ break;
+
+ case 2:
+ x = 335;
+ break;
+
+ case 4:
+ y = 147;
+ break;
+
+ case 6:
+ x = -16;
+ break;
+
+ default:
+ break;
+ }
+
+ moveCharacter(facing, x, y);
+ }
+
+ //XXX sound
+
+ _unkFlag1 = false;
+
+ if (!unk3) {
+ _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData);
+ _scriptInterpreter->startScript(&_sceneScriptState, 5);
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+ }
+
+ Common::for_each(_wsaSlots, _wsaSlots+ARRAYSIZE(_wsaSlots), Common::mem_fun(&WSAMovieV2::close));
+ _specialExitCount = 0;
+ memset(_specialExitTable, -1, sizeof(_specialExitTable));
+
+ _mainCharacter.sceneId = newScene;
+ _sceneList[newScene].flags &= ~1;
+ loadScenePal();
+ unloadScene();
+ loadSceneMsc();
+
+ SceneDesc &scene = _sceneList[newScene];
+ _sceneExit1 = scene.exit1;
+ _sceneExit2 = scene.exit2;
+ _sceneExit3 = scene.exit3;
+ _sceneExit4 = scene.exit4;
+
+ //XXX sound
+
+ startSceneScript(unk3);
+
+ if (_overwriteSceneFacing) {
+ facing = _mainCharacter.facing;
+ _overwriteSceneFacing = false;
+ }
+
+ enterNewSceneUnk1(facing, unk2, unk3);
+
+ setTimer1DelaySecs(-1);
+ _sceneScriptState.regs[3] = 1;
+ enterNewSceneUnk2(unk3);
+ _screen->showMouse();
+ _unk5 = 0;
+ //setNextIdleAnimTimer();
+}
+
+void KyraEngine_v2::enterNewSceneUnk1(int facing, int unk1, int unk2) {
+ int x = 0, y = 0;
+ int x2 = 0, y2 = 0;
+ bool needProc = true;
+
+ if (_mainCharX == -1 && _mainCharY == -1) {
+ switch (facing+1) {
+ case 1: case 2: case 8:
+ x2 = _sceneEnterX3;
+ y2 = _sceneEnterY3;
+ break;
+
+ case 3:
+ x2 = _sceneEnterX4;
+ y2 = _sceneEnterY4;
+ break;
+
+ case 4: case 5: case 6:
+ x2 = _sceneEnterX1;
+ y2 = _sceneEnterY1;
+ break;
+
+ case 7:
+ x2 = _sceneEnterX2;
+ y2 = _sceneEnterY2;
+ break;
+
+ default:
+ x2 = y2 = -1;
+ break;
+ }
+
+ if (x2 >= 316)
+ x2 = 312;
+ if (y2 >= 141)
+ y2 = 139;
+ if (x2 <= 4)
+ x2 = 8;
+ }
+
+ if (_mainCharX >= 0) {
+ x = x2 = _mainCharX;
+ needProc = false;
+ }
+
+ if (_mainCharY >= 0) {
+ y = y2 = _mainCharY;
+ needProc = false;
+ }
+
+ _mainCharX = _mainCharY = -1;
+
+ if (unk1 && needProc) {
+ x = x2;
+ y = y2;
+
+ switch (facing) {
+ case 0:
+ y2 = 147;
+ break;
+
+ case 2:
+ x2 = -16;
+ break;
+
+ case 4:
+ y2 = y - 4;
+ break;
+
+ case 6:
+ x2 = 335;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ x2 &= ~3;
+ x &= ~3;
+ y2 &= ~1;
+ y &= ~1;
+
+ _mainCharacter.facing = facing;
+ _mainCharacter.x1 = _mainCharacter.x2 = x2;
+ _mainCharacter.y1 = _mainCharacter.y2 = y2;
+ initSceneAnims(unk2);
+
+ if (!unk2) {
+ //XXX sound
+ }
+
+ if (unk1 && !unk2 && _mainCharacter.animFrame != 32)
+ moveCharacter(facing, x, y);
+}
+
+void KyraEngine_v2::enterNewSceneUnk2(int unk1) {
+ _unk3 = -1;
+
+ if (_mainCharX == -1 && _mainCharY == -1 && _mainCharacter.sceneId != 61 &&
+ !queryGameFlag(0x1F1) && !queryGameFlag(0x192) && !queryGameFlag(0x193) &&
+ _mainCharacter.sceneId != 70 && !queryGameFlag(0x159) && _mainCharacter.sceneId != 37) {
+ _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+ updateCharacterAnim(0);
+ refreshAnimObjectsIfNeed();
+ }
+
+ if (!unk1) {
+ runSceneScript4(0);
+ //XXX sub_27158
+ }
+
+ _unk4 = 0;
+ _unk3 = -1;
+}
+
+int KyraEngine_v2::trySceneChange(int *moveTable, int unk1, int updateChar) {
+ bool running = true;
+ bool unkFlag = false;
+ int8 updateType = -1;
+ int changedScene = 0;
+ const int *moveTableStart = moveTable;
+ _unk4 = 0;
+ while (running) {
+ if (*moveTable >= 0 && *moveTable <= 7) {
+ _mainCharacter.facing = getOppositeFacingDirection(*moveTable);
+ unkFlag = true;
+ } else {
+ if (*moveTable == 8) {
+ running = false;
+ } else {
+ ++moveTable;
+ unkFlag = false;
+ }
+ }
+
+ if (checkSceneChange()) {
+ running = false;
+ changedScene = 1;
+ }
+
+ if (unk1) {
+ //XXX
+ }
+
+ if (!unkFlag || !running)
+ continue;
+
+ int ret = 0;
+ if (moveTable == moveTableStart || moveTable[1] == 8)
+ ret = updateCharPos(0);
+ else
+ ret = updateCharPos(moveTable);
+
+ if (ret)
+ ++moveTable;
+
+ ++updateType;
+ if (!updateType) {
+ update();
+ } else if (updateType == 1) {
+ refreshAnimObjectsIfNeed();
+ updateType = -1;
+ }
+ }
+
+ if (updateChar)
+ _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+
+ updateCharacterAnim(0);
+ refreshAnimObjectsIfNeed();
+
+ if (!changedScene && !_unk4) {
+ //XXX
+ }
+ return changedScene;
+}
+
+int KyraEngine_v2::checkSceneChange() {
+ SceneDesc &curScene = _sceneList[_mainCharacter.sceneId];
+ int charX = _mainCharacter.x1, charY = _mainCharacter.y1;
+ int facing = 0;
+ int process = 0;
+
+ if (_screen->getLayer(charX, charY) == 1 && _unk3 == -6) {
+ facing = 0;
+ process = 1;
+ } else if (charX >= 316 && _unk3 == -5) {
+ facing = 2;
+ process = 1;
+ } else if (charY >= 142 && _unk3 == -4) {
+ facing = 4;
+ process = 1;
+ } else if (charX <= 4 && _unk3 == -3) {
+ facing = 6;
+ process = 1;
+ }
+
+ if (!process)
+ return 0;
+
+ uint16 newScene = 0xFFFF;
+ switch (facing) {
+ case 0:
+ newScene = curScene.exit1;
+ break;
+
+ case 2:
+ newScene = curScene.exit2;
+ break;
+
+ case 4:
+ newScene = curScene.exit3;
+ break;
+
+ case 6:
+ newScene = curScene.exit4;
+ break;
+
+ default:
+ newScene = _mainCharacter.sceneId;
+ break;
+ }
+
+ if (newScene == 0xFFFF)
+ return 0;
+
+ enterNewScene(newScene, facing, 1, 1, 0);
+ return 1;
+}
+
+void KyraEngine_v2::unloadScene() {
+ _scriptInterpreter->unloadScript(&_sceneScriptData);
+ freeSceneShapePtrs();
+ freeSceneAnims();
+}
+
+void KyraEngine_v2::loadScenePal() {
+ uint16 sceneId = _mainCharacter.sceneId;
+ memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
+
+ char filename[14];
+ strcpy(filename, _sceneList[sceneId].filename);
+ strcat(filename, ".COL");
+ _screen->loadBitmap(filename, 3, 3, 0);
+ memcpy(_screen->getPalette(1), _screen->getCPagePtr(3), 384);
+ memset(_screen->getPalette(1), 0, 3);
+ memcpy(_scenePal, _screen->getCPagePtr(3)+336, 432);
+}
+
+void KyraEngine_v2::loadSceneMsc() {
+ uint16 sceneId = _mainCharacter.sceneId;
+ char filename[14];
+ strcpy(filename, _sceneList[sceneId].filename);
+ strcat(filename, ".MSC");
+ _screen->loadBitmap(filename, 3, 5, 0);
+}
+
+void KyraEngine_v2::startSceneScript(int unk1) {
+ uint16 sceneId = _mainCharacter.sceneId;
+ char filename[14];
+
+ strcpy(filename, _sceneList[sceneId].filename);
+ if (sceneId == 68 && (queryGameFlag(0x1BC) || queryGameFlag(0x1DC)))
+ strcpy(filename, "DOORX");
+ strcat(filename, ".CPS");
+
+ _screen->loadBitmap(filename, 3, 3, 0);
+ resetScaleTable();
+ _useCharPal = false;
+ memset(_charPalTable, 0, sizeof(_charPalTable));
+ //XXX _unkTable33
+ memset(_specialSceneScriptState, 0, sizeof(_specialSceneScriptState));
+
+ _sceneEnterX1 = 160;
+ _sceneEnterY1 = 0;
+ _sceneEnterX2 = 296;
+ _sceneEnterY2 = 72;
+ _sceneEnterX3 = 160;
+ _sceneEnterY3 = 128;
+ _sceneEnterX4 = 24;
+ _sceneEnterY4 = 72;
+
+ _sceneCommentString = "Undefined scene comment string!";
+ _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData);
+
+ strcpy(filename, _sceneList[sceneId].filename);
+ strcat(filename, ".");
+ strcat(filename, _scriptLangExt[_lang]);
+
+ assert(_res->getFileSize(filename));
+ _scriptInterpreter->loadScript(filename, &_sceneScriptData, &_opcodes);
+ runSceneScript7();
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 0);
+ _sceneScriptState.regs[0] = sceneId;
+ _sceneScriptState.regs[5] = unk1;
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+
+ memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
+
+ for (int i = 0; i < 10; ++i) {
+ _scriptInterpreter->initScript(&_sceneSpecialScripts[i], &_sceneScriptData);
+ _scriptInterpreter->startScript(&_sceneSpecialScripts[i], i+8);
+ _sceneSpecialScriptsTimer[i] = 0;
+ }
+
+ _sceneEnterX1 &= ~3;
+ _sceneEnterX2 &= ~3;
+ _sceneEnterX3 &= ~3;
+ _sceneEnterX4 &= ~3;
+ _sceneEnterY1 &= ~1;
+ _sceneEnterY2 &= ~1;
+ _sceneEnterY3 &= ~1;
+ _sceneEnterY4 &= ~1;
+}
+
+void KyraEngine_v2::runSceneScript2() {
+ _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData);
+ _sceneScriptState.regs[4] = _itemInHand;
+ _scriptInterpreter->startScript(&_sceneScriptState, 2);
+
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+}
+
+void KyraEngine_v2::runSceneScript4(int unk1) {
+ _sceneScriptState.regs[4] = _itemInHand;
+ _sceneScriptState.regs[5] = unk1;
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 4);
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+}
+
+void KyraEngine_v2::runSceneScript7() {
+ int oldPage = _screen->_curPage;
+ _screen->_curPage = 2;
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 7);
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+
+ _screen->_curPage = oldPage;
+}
+
+void KyraEngine_v2::initSceneAnims(int unk1) {
+ for (int i = 0; i < ARRAYSIZE(_animObjects); ++i)
+ _animObjects[i].enabled = 0;
+
+ bool animInit = false;
+
+ AnimObj *animState = &_animObjects[0];
+
+ if (_mainCharacter.animFrame != 32)
+ _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+
+ animState->enabled = 1;
+ animState->xPos1 = _mainCharacter.x1;
+ animState->yPos1 = _mainCharacter.y1;
+ animState->shapePtr = _defaultShapeTable[_mainCharacter.animFrame];
+ animState->shapeIndex1 = animState->shapeIndex2 = _mainCharacter.animFrame;
+
+ int frame = _mainCharacter.animFrame - 9;
+ int shapeX = _shapeDescTable[frame].xAdd;
+ int shapeY = _shapeDescTable[frame].yAdd;
+
+ animState->xPos2 = _mainCharacter.x1;
+ animState->yPos2 = _mainCharacter.y1;
+
+ _charScaleX = _charScaleY = getScale(_mainCharacter.x1, _mainCharacter.y1);
+
+ int shapeXScaled = (shapeX * _charScaleX) >> 8;
+ int shapeYScaled = (shapeY * _charScaleY) >> 8;
+
+ animState->xPos2 += shapeXScaled;
+ animState->yPos2 += shapeYScaled;
+ animState->xPos3 = animState->xPos2;
+ animState->yPos3 = animState->yPos2;
+ animState->needRefresh = 1;
+ animState->unk8 = 1;
+
+ _animList = 0;
+
+ AnimObj *charAnimState = animState;
+
+ for (int i = 0; i < 10; ++i) {
+ animState = &_animObjects[i+1];
+ animState->enabled = 0;
+ animState->needRefresh = 0;
+ animState->unk8 = 0;
+
+ if (_sceneAnims[i].flags & 1) {
+ animState->enabled = 1;
+ animState->needRefresh = 1;
+ animState->unk8 = 1;
+ }
+
+ animState->animFlags = _sceneAnims[i].flags & 8;
+
+ if (_sceneAnims[i].flags & 2)
+ animState->flags = 0x800;
+ else
+ animState->flags = 0;
+
+ if (_sceneAnims[i].flags & 4)
+ animState->flags |= 1;
+
+ animState->xPos1 = _sceneAnims[i].x;
+ animState->yPos1 = _sceneAnims[i].y;
+
+ if (_sceneAnims[i].flags & 0x20)
+ animState->shapePtr = _sceneShapeTable[_sceneAnims[i].shapeIndex];
+ else
+ animState->shapePtr = 0;
+
+ if (_sceneAnims[i].flags & 0x40) {
+ animState->shapeIndex3 = _sceneAnims[i].shapeIndex;
+ animState->animNum = i;
+ } else {
+ animState->shapeIndex3 = 0xFFFF;
+ animState->animNum = 0xFFFF;
+ }
+
+ animState->shapeIndex2 = 0xFFFF;
+
+ animState->xPos3 = animState->xPos2 = _sceneAnims[i].x2;
+ animState->yPos3 = animState->yPos2 = _sceneAnims[i].y2;
+ animState->width = _sceneAnims[i].width;
+ animState->height = _sceneAnims[i].height;
+ animState->width2 = animState->height2 = _sceneAnims[i].specialSize;
+
+ if (_sceneAnims[i].flags & 1) {
+ if (animInit) {
+ _animList = addToAnimListSorted(_animList, animState);
+ } else {
+ _animList = initAnimList(_animList, animState);
+ animInit = true;
+ }
+ }
+ }
+
+ if (animInit) {
+ _animList = addToAnimListSorted(_animList, charAnimState);
+ } else {
+ _animList = initAnimList(_animList, charAnimState);
+ animInit = true;
+ }
+
+ for (int i = 0; i < 30; ++i) {
+ animState = &_animObjects[i+11];
+
+ uint16 shapeIndex = _itemList[i].id;
+ if (shapeIndex == 0xFFFF || _itemList[i].sceneId != _mainCharacter.sceneId) {
+ animState->enabled = 0;
+ animState->needRefresh = 0;
+ animState->unk8 = 0;
+ } else {
+ animState->xPos1 = _itemList[i].x;
+ animState->yPos1 = _itemList[i].y;
+ animState->shapePtr = _defaultShapeTable[64+shapeIndex];
+ animState->shapeIndex1 = animState->shapeIndex2 = shapeIndex+64;
+
+ animState->xPos2 = _itemList[i].x;
+ animState->yPos2 = _itemList[i].y;
+ int objectScale = getScale(animState->xPos2, animState->yPos2);
+
+ const uint8 *shape = getShapePtr(animState->shapeIndex1);
+ animState->xPos2 -= (_screen->getShapeScaledWidth(shape, objectScale) >> 1);
+ animState->yPos2 -= (_screen->getShapeScaledHeight(shape, objectScale) >> 1);
+ animState->xPos3 = animState->xPos2;
+ animState->yPos3 = animState->yPos2;
+
+ animState->enabled = 1;
+ animState->needRefresh = 1;
+ animState->unk8 = 1;
+
+ if (animInit) {
+ _animList = addToAnimListSorted(_animList, animState);
+ } else {
+ _animList = initAnimList(_animList, animState);
+ animInit = true;
+ }
+ }
+ }
+
+ _animObjects[0].unk8 = 1;
+ _animObjects[0].needRefresh = 1;
+
+ for (int i = 1; i < 41; ++i) {
+ if (_animObjects[i].enabled) {
+ _animObjects[i].needRefresh = 1;
+ _animObjects[i].unk8 = 1;
+ }
+ }
+
+ restorePage3();
+ drawAnimObjects();
+ _screen->hideMouse();
+ initSceneScreen(unk1);
+ _screen->showMouse();
+ refreshAnimObjects(0);
+}
+
+void KyraEngine_v2::initSceneScreen(int unk1) {
+ if (_unkSceneScreenFlag1) {
+ _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0);
+ return;
+ }
+
+ if (_noScriptEnter) {
+ memset(_screen->getPalette(0), 0, 384);
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
+
+ _screen->copyRegion(0, 0, 0, 0, 320, 144, 2, 0);
+
+ if (_noScriptEnter)
+ memcpy(_screen->getPalette(0), _screen->getPalette(1), 384);
+
+ updateCharPal(0);
+
+ _scriptInterpreter->startScript(&_sceneScriptState, 3);
+ _sceneScriptState.regs[5] = unk1;
+ while (_scriptInterpreter->validScript(&_sceneScriptState))
+ _scriptInterpreter->runScript(&_sceneScriptState);
+}
+
+void KyraEngine_v2::updateSpecialSceneScripts() {
+ uint32 nextTime = _system->getMillis() + _tickLength;
+ const int startScript = _lastProcessedSceneScript;
+
+ while (_system->getMillis() <= nextTime) {
+ if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() &&
+ !_specialSceneScriptState[_lastProcessedSceneScript]) {
+ _specialSceneScriptRunFlag = true;
+
+ while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis())
+ _specialSceneScriptRunFlag = _scriptInterpreter->runScript(&_sceneSpecialScripts[_lastProcessedSceneScript]) != 0;
+ }
+
+ if (!_scriptInterpreter->validScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) {
+ _scriptInterpreter->startScript(&_sceneSpecialScripts[_lastProcessedSceneScript], 8+_lastProcessedSceneScript);
+ _specialSceneScriptRunFlag = false;
+ }
+
+ ++_lastProcessedSceneScript;
+ if (_lastProcessedSceneScript >= 10)
+ _lastProcessedSceneScript = 0;
+
+ if (_lastProcessedSceneScript == startScript)
+ return;
+ }
+}
+
+void KyraEngine_v2::freeSceneShapePtrs() {
+ for (int i = 0; i < ARRAYSIZE(_sceneShapeTable); ++i)
+ delete [] _sceneShapeTable[i];
+ memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable));
+}
+
+void KyraEngine_v2::freeSceneAnims() {
+ Common::for_each(_sceneAnimMovie, _sceneAnimMovie+ARRAYSIZE(_sceneAnimMovie), Common::mem_fun(&WSAMovieV2::close));
+}
+
+#pragma mark -
+#pragma mark - Pathfinder
+#pragma mark -
+
+int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v2::findWay(%d, %d, %d, %d, %p, %d)", x, y, toX, toY, (const void *)moveTable, moveTableSize);
+ x &= ~3; toX &= ~3;
+ y &= ~1; toY &= ~1;
+ int size = KyraEngine::findWay(x, y, toX, toY, moveTable, moveTableSize);
+ /*if (size) {
+ int temp = pathfinderUnk1(moveTable);
+ temp = pathfinderUnk3(temp, x, y);
+ pathfinderUnk5(moveTable, temp, x, y, moveTableSize);
+ }*/
+ return getMoveTableSize(moveTable);
+}
+
+bool KyraEngine_v2::lineIsPassable(int x, int y) {
+ debugC(9, kDebugLevelMain, "KyraEngine_v2::lineIsPassable(%d, %d)", x, y);
+ static int unkTable[] = { 1, 1, 1, 1, 1, 2, 4, 6, 8 };
+
+ if (_pathfinderFlag & 2) {
+ if (x >= 320)
+ return false;
+ }
+
+ if (_pathfinderFlag & 4) {
+ if (y >= 144)
+ return false;
+ }
+
+ if (_pathfinderFlag & 8) {
+ if (x < 0)
+ return false;
+ }
+
+ if (y > 143)
+ return false;
+
+ int unk1 = unkTable[getScale(x, y) >> 5];
+
+ if (y < 0)
+ y = 0;
+ x -= unk1 >> 1;
+ if (x < 0)
+ x = 0;
+ int x2 = x + unk1;
+ if (x2 > 320)
+ x2 = 320;
+
+ for (;x < x2; ++x)
+ if (!_screen->getShapeFlag1(x, y))
+ return false;
+
+ return true;
+}
+
+bool KyraEngine_v2::directLinePassable(int x, int y, int toX, int toY) {
+ while (x != toX && y != toY) {
+ int facing = getFacingFromPointToPoint(x, y, toX, toY);
+ x += _addXPosTable[facing];
+ y += _addYPosTable[facing];
+ if (!_screen->getShapeFlag1(x, y))
+ return false;
+ }
+ return true;
+}
+
+int KyraEngine_v2::pathfinderUnk1(int *moveTable) {
+ bool breakLoop = false;
+ int *moveTableCur = moveTable;
+ int oldEntry = *moveTableCur, curEntry = *moveTableCur;
+ int oldX = 0, newX = 0, oldY = 0, newY = 0;
+ int lastEntry = 0;
+ lastEntry = pathfinderUnk2(lastEntry, 0, 0);
+
+ while (*moveTableCur != 8) {
+ oldEntry = curEntry;
+
+ while (true) {
+ curEntry = *moveTableCur;
+ if (curEntry >= 0 && curEntry <= 7)
+ break;
+
+ if (curEntry == 8) {
+ breakLoop = true;
+ break;
+ } else {
+ ++moveTableCur;
+ }
+ }
+
+ if (breakLoop)
+ break;
+
+ oldX = newX;
+ oldY = newY;
+
+ newX += _addXPosTable[curEntry];
+ newY += _addYPosTable[curEntry];
+
+ int temp = ABS(curEntry - oldEntry);
+ if (temp > 4) {
+ temp = 8 - temp;
+ }
+
+ if (temp > 1 || oldEntry != curEntry)
+ lastEntry = pathfinderUnk2(lastEntry, oldX, oldY);
+
+ ++moveTableCur;
+ }
+
+ lastEntry = pathfinderUnk2(lastEntry, newX, newY);
+ _pathfinderUnkTable1[lastEntry*2+0] = -1;
+ _pathfinderUnkTable1[lastEntry*2+1] = -1;
+ return lastEntry;
+}
+
+int KyraEngine_v2::pathfinderUnk2(int index, int v1, int v2) {
+ _pathfinderUnkTable1[index<<1] = v1;
+ _pathfinderUnkTable1[(index<<1)+1] = v2;
+ ++index;
+ if (index >= 199)
+ --index;
+ return index;
+}
+
+int KyraEngine_v2::pathfinderUnk3(int tableLen, int x, int y) {
+ int x1 = 0, y1 = 0;
+ int x2 = 0, y2 = 0;
+ int lastEntry = 0;
+ int index2 = tableLen-1, index1 = 0;
+ while (index2 > index1) {
+ x1 = _pathfinderUnkTable1[index1*2+0] + x;
+ y1 = _pathfinderUnkTable1[index1*2+1] + y;
+ x2 = _pathfinderUnkTable1[index2*2+0] + x;
+ y2 = _pathfinderUnkTable1[index2*2+0] + x;
+
+ if (directLinePassable(x1, y1, x2, y2)) {
+ lastEntry = pathfinderUnk4(lastEntry, index2);
+ if (tableLen-1 == index2)
+ break;
+ index1 = index2;
+ index2 = tableLen-1;
+ } else if (index1+1 == index2) {
+ lastEntry = pathfinderUnk4(lastEntry, index2);
+ index1 = index2;
+ index2 = tableLen-1;
+ } else {
+ --index2;
+ }
+ }
+ return lastEntry;
+}
+
+int KyraEngine_v2::pathfinderUnk4(int index, int v) {
+ _pathfinderUnkTable2[index] = v;
+ ++index;
+ if (index >= 199)
+ --index;
+ return index;
+}
+
+void KyraEngine_v2::pathfinderUnk5(int *moveTable, int tableLen, int x, int y, int moveTableSize) {
+ int x1 = 0, y1 = 0;
+ int x2 = 0, y2 = 0;
+ int index1 = 0, index2 = 0;
+ int sizeLeft = moveTableSize;
+ for (int i = 0; i < tableLen; ++i) {
+ index2 = _pathfinderUnkTable2[i];
+ x1 = _pathfinderUnkTable1[index1*2+0] + x;
+ y1 = _pathfinderUnkTable1[index1*2+1] + y;
+ x2 = _pathfinderUnkTable1[index2*2+0] + x;
+ y2 = _pathfinderUnkTable1[index2*2+0] + x;
+
+ int wayLen = findWay(x1, y1, x2, y2, moveTable, sizeLeft);
+ moveTable += wayLen;
+ sizeLeft -= wayLen; // unlike the original we want to be sure that the size left is correct
+ index1 = index2;
+ }
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 0e01801369..a7e9c90824 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -355,33 +355,6 @@ void Screen::fadeToBlack(int delay) {
fadePalette(blackPal, delay);
}
-void Screen::k2IntroFadeToGrey(int delay) {
- debugC(9, kDebugLevelScreen, "Screen::k2IntroFadeToGrey()");
-
- for (int i = 0; i <= 50; ++i) {
- if (i <= 8 || i >= 30) {
- _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
- _currentPalette[3 * i + 1] +
- _currentPalette[3 * i + 2]) / 3;
- _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0];
- _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0];
- }
- }
-
- // color 71 is the same in both the overview and closeup scenes
- // Converting it to greyscale makes the trees in the closeup look dull
- for (int i = 71; i < 200; ++i) {
- _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
- _currentPalette[3 * i + 1] +
- _currentPalette[3 * i + 2]) / 3;
- _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0];
- _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0];
- }
- fadePalette(_currentPalette, delay);
- // Make the font color white again
- setPaletteIndex(254, 254, 254, 254);
-}
-
void Screen::fadePalette(const uint8 *palData, int delay) {
debugC(9, kDebugLevelScreen, "Screen::fadePalette(%p, %d)", (const void *)palData, delay);
updateScreen();
@@ -1057,13 +1030,8 @@ void Screen::drawCharANSI(uint8 c, int x, int y) {
void Screen::setScreenDim(int dim) {
debugC(9, kDebugLevelScreen, "Screen::setScreenDim(%d)", dim);
- if (_vm->game() == GI_KYRA1) {
- assert(dim < _screenDimTableCount);
- _curDim = &_screenDimTable[dim];
- } else {
- assert(dim < _screenDimTableCountK3);
- _curDim = &_screenDimTableK3[dim];
- }
+ assert(dim < _screenDimTableCount);
+ _curDim = &_screenDimTable[dim];
// XXX
}
@@ -2680,38 +2648,6 @@ void Screen::loadPalette(const byte *data, uint8 *palData, int bytes) {
}
}
-// kyra3 specific
-
-const uint8 *Screen::getPtrToShape(const uint8 *shpFile, int shape) {
- debugC(9, kDebugLevelScreen, "KyraEngine::getPtrToShape(%p, %d)", (const void *)shpFile, shape);
- uint16 shapes = READ_LE_UINT16(shpFile);
-
- if (shapes <= shape)
- return 0;
-
- uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
-
- return shpFile + offset + 2;
-}
-
-uint8 *Screen::getPtrToShape(uint8 *shpFile, int shape) {
- debugC(9, kDebugLevelScreen, "KyraEngine::getPtrToShape(%p, %d)", (void *)shpFile, shape);
- uint16 shapes = READ_LE_UINT16(shpFile);
-
- if (shapes <= shape)
- return 0;
-
- uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
-
- return shpFile + offset + 2;
-}
-
-uint16 Screen::getShapeSize(const uint8 *shp) {
- debugC(9, kDebugLevelScreen, "KyraEngine::getShapeSize(%p)", (const void *)shp);
-
- return READ_LE_UINT16(shp+6);
-}
-
// dirty rect handling
void Screen::addDirtyRect(int x, int y, int w, int h) {
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 355407a330..b1a1eb7b1a 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -133,8 +133,6 @@ public:
void fadeFromBlack(int delay=0x54);
void fadeToBlack(int delay=0x54);
- void k2IntroFadeToGrey(int delay=0x54);
-
void fadePalette(const uint8 *palData, int delay);
void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue);
@@ -162,7 +160,7 @@ public:
void setTextColorMap(const uint8 *cmap);
void setTextColor(const uint8 *cmap, int a, int b);
- void setScreenDim(int dim);
+ virtual void setScreenDim(int dim);
// shape handling
uint8 *encodeShape(int x, int y, int w, int h, int flags);
@@ -170,7 +168,7 @@ public:
int setNewShapeHeight(uint8 *shape, int height);
int resetShapeHeight(uint8 *shape);
- void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
+ virtual void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
// mouse handling
void hideMouse();
@@ -178,7 +176,7 @@ public:
void setMouseCursor(int x, int y, byte *shape);
// rect handling
- int getRectSize(int w, int h);
+ virtual int getRectSize(int w, int h);
void rectClip(int &x, int &y, int w, int h);
@@ -208,6 +206,7 @@ public:
void copyBackgroundBlock(int x, int page, int flag);
void copyBackgroundBlock2(int x);
+ // kyra1 specific?
int getDrawLayer(int x, int y);
int getDrawLayer2(int x, int y, int height);
@@ -232,15 +231,6 @@ public:
static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true);
static void convertAmigaMsc(uint8 *data);
- // maybe subclass screen for kyra3
- static const ScreenDim _screenDimTableK3[];
- static const int _screenDimTableCountK3;
-
- uint8 *getPtrToShape(uint8 *shpFile, int shape);
- const uint8 *getPtrToShape(const uint8 *shpFile, int shape);
-
- uint16 getShapeSize(const uint8 *shp);
-
protected:
uint8 *getPagePtr(int pageNum);
void updateDirtyRects();
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index 3e98cdbe5b..3ad69818c6 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -11,7 +11,7 @@
* 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
+ * 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
@@ -24,6 +24,7 @@
*/
#include "common/stdafx.h"
+#include "common/endian.h"
#include "kyra/kyra_v2.h"
#include "kyra/screen_v2.h"
@@ -38,4 +39,523 @@ Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system)
Screen_v2::~Screen_v2() {
}
+void Screen_v2::setScreenDim(int dim) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::setScreenDim(%d)", dim);
+ if (_vm->game() == GI_KYRA2) {
+ assert(dim < _screenDimTableCount);
+ _curDim = &_screenDimTable[dim];
+ } else {
+ assert(dim < _screenDimTableCountK3);
+ _curDim = &_screenDimTableK3[dim];
+ }
+}
+
+const ScreenDim *Screen_v2::getScreenDim(int dim) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::getScreenDim(%d)", dim);
+ if (_vm->game() == GI_KYRA2) {
+ assert(dim < _screenDimTableCount);
+ return &_screenDimTable[dim];
+ } else {
+ assert(dim < _screenDimTableCountK3);
+ return &_screenDimTableK3[dim];
+ }
+}
+
+void Screen_v2::k2IntroFadeToGrey(int delay) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::k2IntroFadeToGrey(%d)", delay);
+
+ for (int i = 0; i <= 50; ++i) {
+ if (i <= 8 || i >= 30) {
+ _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
+ _currentPalette[3 * i + 1] +
+ _currentPalette[3 * i + 2]) / 3;
+ _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0];
+ _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0];
+ }
+ }
+
+ // color 71 is the same in both the overview and closeup scenes
+ // Converting it to greyscale makes the trees in the closeup look dull
+ for (int i = 71; i < 200; ++i) {
+ _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
+ _currentPalette[3 * i + 1] +
+ _currentPalette[3 * i + 2]) / 3;
+ _currentPalette[3 * i + 1] = _currentPalette[3 * i + 0];
+ _currentPalette[3 * i + 2] = _currentPalette[3 * i + 0];
+ }
+ fadePalette(_currentPalette, delay);
+ // Make the font color white again
+ setPaletteIndex(254, 254, 254, 254);
+}
+
+void Screen_v2::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
+ int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) {
+ uint8 *dstPtr = getPagePtr(_curPage);
+ uint8 *origDst = dstPtr;
+
+ const ScreenDim *dim = getScreenDim(dimState);
+ int dimX1 = dim->sx << 3;
+ int dimX2 = dim->w << 3;
+ dimX2 += dimX1;
+
+ int dimY1 = dim->sy;
+ int dimY2 = dim->h;
+ dimY2 += dimY1;
+
+ int temp = y - dimY1;
+ if (temp < 0) {
+ if ((temp += h) <= 0)
+ return;
+ else {
+ SWAP(temp, h);
+ y += temp - h;
+ src += (temp - h) * w;
+ }
+ }
+
+ temp = dimY2 - y;
+ if (temp <= 0)
+ return;
+
+ if (temp < h)
+ h = temp;
+
+ int srcOffset = 0;
+ temp = x - dimX1;
+ if (temp < 0) {
+ temp = -temp;
+ srcOffset = temp;
+ x += temp;
+ w -= temp;
+ }
+
+ int srcAdd = 0;
+
+ temp = dimX2 - x;
+ if (temp <= 0)
+ return;
+
+ if (temp < w) {
+ SWAP(w, temp);
+ temp -= w;
+ srcAdd = temp;
+ }
+
+ dstPtr += y * SCREEN_W + x;
+ uint8 *dst = dstPtr;
+
+ if (_curPage == 0 || _curPage == 1)
+ addDirtyRect(x, y, w, h);
+
+ clearOverlayRect(_curPage, x, y, w, h);
+
+ temp = h;
+ while (h--) {
+ src += srcOffset;
+ int cW = w;
+
+ switch (plotFunc) {
+ case 0:
+ memcpy(dst, src, cW);
+ dst += cW; src += cW;
+ break;
+
+ case 1:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst++ = d;
+ }
+ break;
+
+ case 4:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d)
+ *dst = d;
+ ++dst;
+ }
+ break;
+
+ case 5:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst = d;
+ }
+ ++dst;
+ }
+ break;
+
+ case 8:
+ case 9:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t)
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ break;
+
+ case 12:
+ case 13:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t)
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ } else {
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dst = (dstPtr += SCREEN_W);
+ src += srcAdd;
+ }
+}
+
+const uint8 *Screen_v2::getPtrToShape(const uint8 *shpFile, int shape) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (const void *)shpFile, shape);
+ uint16 shapes = READ_LE_UINT16(shpFile);
+
+ if (shapes <= shape)
+ return 0;
+
+ uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
+
+ return shpFile + offset + 2;
+}
+
+uint8 *Screen_v2::getPtrToShape(uint8 *shpFile, int shape) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (void *)shpFile, shape);
+ uint16 shapes = READ_LE_UINT16(shpFile);
+
+ if (shapes <= shape)
+ return 0;
+
+ uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
+
+ return shpFile + offset + 2;
+}
+
+int Screen_v2::getShapeScaledWidth(const uint8 *shpFile, int scale) {
+ int width = READ_LE_UINT16(shpFile+3);
+ return (width * scale) >> 8;
+}
+
+int Screen_v2::getShapeScaledHeight(const uint8 *shpFile, int scale) {
+ int height = shpFile[2];
+ return (height * scale) >> 8;
+}
+
+uint16 Screen_v2::getShapeSize(const uint8 *shp) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::getShapeSize(%p)", (const void *)shp);
+
+ return READ_LE_UINT16(shp+6);
+}
+
+uint8 *Screen_v2::makeShapeCopy(const uint8 *src, int index) {
+ debugC(9, kDebugLevelScreen, "Screen_v2::makeShapeCopy(%p, %d)", (const void *)src, index);
+
+ const uint8 *shape = getPtrToShape(src, index);
+ int size = getShapeSize(shape);
+
+ uint8 *copy = new uint8[size];
+ assert(copy);
+ memcpy(copy, shape, size);
+
+ return copy;
+}
+
+void Screen_v2::drawShape(uint8 page, const uint8 *shape, int x, int y, int sd, int flags, ...) {
+ if (!shape)
+ return;
+
+ if (*shape & 1)
+ flags |= 0x400;
+
+ va_list args;
+ va_start(args, flags);
+
+ static int drawShapeVar1 = 0;
+ static int drawShapeVar2[] = {
+ 1, 3, 2, 5, 4, 3, 2, 1
+ };
+ static int drawShapeVar3 = 1;
+ static int drawShapeVar4 = 0;
+ static int drawShapeVar5 = 0;
+
+ uint8 *table = 0;
+ int tableLoopCount = 0;
+ int drawLayer = 0;
+ const uint8 *table2 = 0;
+ uint8 *table3 = 0;
+ uint8 *table4 = 0;
+
+ if (flags & 0x8000) {
+ table2 = va_arg(args, uint8*);
+ }
+ if (flags & 0x100) {
+ table = va_arg(args, uint8*);
+ tableLoopCount = va_arg(args, int);
+ if (!tableLoopCount)
+ flags &= 0xFFFFFEFF;
+ }
+ if (flags & 0x1000) {
+ table3 = va_arg(args, uint8*);
+ table4 = va_arg(args, uint8*);
+ }
+ if (flags & 0x200) {
+ drawShapeVar1 += 1;
+ drawShapeVar1 &= 7;
+ drawShapeVar3 = drawShapeVar2[drawShapeVar1];
+ drawShapeVar4 = 0;
+ drawShapeVar5 = 256;
+ }
+ if (flags & 0x4000) {
+ drawShapeVar5 = va_arg(args, int);
+ }
+ if (flags & 0x800) {
+ drawLayer = va_arg(args, int);
+ }
+ int scale_w, scale_h;
+ if (flags & 0x04) {
+ scale_w = va_arg(args, int);
+ scale_h = va_arg(args, int);
+ } else {
+ scale_w = 0x100;
+ scale_h = 0x100;
+ }
+
+ int ppc = (flags >> 8) & 0x3F;
+
+ const uint8 *src = shape;
+ uint16 shapeFlags = READ_LE_UINT16(src); src += 2;
+
+ int shapeHeight = *src++;
+ int scaledShapeHeight = (shapeHeight * scale_h) >> 8;
+ if (scaledShapeHeight == 0) {
+ va_end(args);
+ return;
+ }
+
+ int shapeWidth = READ_LE_UINT16(src); src += 2;
+ int scaledShapeWidth = (shapeWidth * scale_w) >> 8;
+ if (scaledShapeWidth == 0) {
+ va_end(args);
+ return;
+ }
+
+ if (flags & 0x20) {
+ x -= scaledShapeWidth >> 1;
+ y -= scaledShapeHeight >> 1;
+ }
+
+ src += 3;
+
+ uint16 frameSize = READ_LE_UINT16(src); src += 2;
+ int colorTableColors = 0x10;
+
+ if (shapeFlags & 4)
+ colorTableColors = *src++;
+
+ if (!(flags & 0x8000) && (shapeFlags & 1))
+ table2 = src;
+
+ if ((shapeFlags & 1) || (flags & 0x400))
+ src += colorTableColors;
+
+ if (!(shapeFlags & 2)) {
+ decodeFrame4(src, _animBlockPtr, frameSize);
+ src = _animBlockPtr;
+ }
+
+ int shapeSize = shapeWidth * shapeHeight;
+ if (_decodeShapeBufferSize < shapeSize) {
+ delete [] _decodeShapeBuffer;
+ _decodeShapeBuffer = new uint8[shapeSize];
+ _decodeShapeBufferSize = shapeSize;
+ }
+ if (!_decodeShapeBuffer) {
+ _decodeShapeBufferSize = 0;
+ va_end(args);
+ return;
+ }
+ memset(_decodeShapeBuffer, 0, _decodeShapeBufferSize);
+ uint8 *decodedShapeFrame = _decodeShapeBuffer;
+
+ for (int j = 0; j < shapeHeight; ++j) {
+ uint8 *dsbNextLine = decodedShapeFrame + shapeWidth;
+ int count = shapeWidth;
+ while (count > 0) {
+ uint8 code = *src++;
+ if (code != 0) {
+ *decodedShapeFrame++ = code;
+ --count;
+ } else {
+ code = *src++;
+ decodedShapeFrame += code;
+ count -= code;
+ }
+ }
+ decodedShapeFrame = dsbNextLine;
+ }
+
+ uint16 sx1 = getScreenDim(sd)->sx << 3;
+ uint16 sy1 = getScreenDim(sd)->sy;
+ uint16 sx2 = sx1 + getScreenDim(sd)->w << 3;
+ uint16 sy2 = sy1 + getScreenDim(sd)->h;
+ if (flags & 0x10) {
+ x += sx1;
+ y += sy1;
+ }
+
+ int x1, x2;
+ if (x >= 0) {
+ x1 = 0;
+ if (x + scaledShapeWidth < sx2) {
+ x2 = scaledShapeWidth;
+ } else {
+ x2 = sx2 - x;
+ }
+ } else {
+ x2 = scaledShapeWidth;
+ x1 = -x;
+ x = 0;
+ if (x2 > sx2) {
+ x2 = sx2;
+ }
+ }
+
+ int y1, y2;
+ if (y >= 0) {
+ y1 = 0;
+ if (y + scaledShapeHeight < sy2) {
+ y2 = scaledShapeHeight;
+ } else {
+ y2 = sy2 - y;
+ }
+ } else {
+ y2 = scaledShapeHeight;
+ y1 = -y;
+ y = 0;
+ if (y2 > sy2) {
+ y2 = sy2;
+ }
+ }
+
+ uint8 *dst = getPagePtr(page) + y * 320 + x;
+ uint8 *dstStart = getPagePtr(page);
+
+ int scaleYTable[200];
+ for (y = y1; y < y2; ++y) {
+ scaleYTable[y] = (y << 8) / scale_h;
+ }
+ int scaleXTable[320];
+ for (x = x1; x < x2; ++x) {
+ scaleXTable[x] = (x << 8) / scale_w;
+ }
+
+ const uint8 *shapeBuffer = _decodeShapeBuffer;
+ if (flags & 0x02) {
+ shapeBuffer += shapeWidth * (shapeHeight - 1);
+ }
+ if (flags & 0x01) {
+ shapeBuffer += shapeWidth - 1;
+ }
+
+ for (y = y1; y < y2; ++y) {
+ uint8 *dstNextLine = dst + 320;
+ int j = scaleYTable[y];
+ if (flags & 0x02) {
+ j = -j;
+ }
+ for (x = x1; x < x2; ++x) {
+ int xpos = scaleXTable[x];
+ if (flags & 0x01)
+ xpos = -xpos;
+ uint8 color = shapeBuffer[j * shapeWidth + xpos];
+ if (color != 0) {
+ switch (ppc) {
+ case 0:
+ *dst = color;
+ break;
+
+ case 4:
+ *dst = table2[color];
+ break;
+
+ case 8: {
+ int layer = _shapePages[0][dst - dstStart] & 7;
+ if (drawLayer > layer)
+ color = _shapePages[1][dst - dstStart];
+ *dst = color;
+ } break;
+
+ case 12: {
+ int layer = _shapePages[0][dst - dstStart] & 7;
+ if (drawLayer < layer)
+ color = _shapePages[1][dst - dstStart];
+ else
+ color = table2[color];
+ *dst = color;
+ } break;
+
+ default:
+ warning("unhandled ppc: %d", ppc);
+ break;
+ }
+ }
+ ++dst;
+ }
+ dst = dstNextLine;
+ }
+ va_end(args);
+}
+
+int Screen_v2::getRectSize(int w, int h) {
+ if (w > 320 || h > 200)
+ return 0;
+ return w*h;
+}
+
+int Screen_v2::getLayer(int x, int y) {
+ if (x < 0)
+ x = 0;
+ else if (x >= 320)
+ x = 319;
+ if (y < 0)
+ y = 0;
+ else if (y >= 144)
+ y = 143;
+
+ uint8 pixel = *(getCPagePtr(5) + y * 320 + x);
+ pixel &= 0x7F;
+ pixel >>= 3;
+
+ if (pixel < 1)
+ pixel = 1;
+ else if (pixel > 15)
+ pixel = 15;
+ return pixel;
+}
+
+bool Screen_v2::isMouseVisible() const {
+ return _mouseLockCount == 0;
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h
index e45d44d3ff..7912d6b999 100644
--- a/engines/kyra/screen_v2.h
+++ b/engines/kyra/screen_v2.h
@@ -11,7 +11,7 @@
* 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
+ * 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
@@ -36,8 +36,47 @@ class Screen_v2 : public Screen {
public:
Screen_v2(KyraEngine_v2 *vm, OSystem *system);
virtual ~Screen_v2();
+
+ virtual void setScreenDim(int dim);
+ const ScreenDim *getScreenDim(int dim);
+
+ // palette handling
+ void k2IntroFadeToGrey(int delay=0x54);
+
+ // screen page handling
+ void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
+ int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2);
+
+ // shape handling
+ uint8 *getPtrToShape(uint8 *shpFile, int shape);
+ const uint8 *getPtrToShape(const uint8 *shpFile, int shape);
+
+ int getShapeScaledWidth(const uint8 *shpFile, int scale);
+ int getShapeScaledHeight(const uint8 *shpFile, int scale);
+
+ uint16 getShapeSize(const uint8 *shp);
+
+ uint8 *makeShapeCopy(const uint8 *src, int index);
+
+ void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
+
+ // rect handling
+ virtual int getRectSize(int w, int h);
+
+ // layer handling
+ int getLayer(int x, int y);
+
+ // mouse handling
+ bool isMouseVisible() const;
private:
KyraEngine_v2 *_vm;
+
+ static const ScreenDim _screenDimTable[];
+ static const int _screenDimTableCount;
+
+ // maybe subclass screen for kyra3
+ static const ScreenDim _screenDimTableK3[];
+ static const int _screenDimTableCountK3;
};
} // End of namespace Kyra
diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp
index b43cd3b471..739e92feda 100644
--- a/engines/kyra/script.cpp
+++ b/engines/kyra/script.cpp
@@ -40,64 +40,62 @@
namespace Kyra {
ScriptHelper::ScriptHelper(KyraEngine *vm) : _vm(vm) {
#define COMMAND(x) { &ScriptHelper::x, #x }
- // now we create a list of all Command/Opcode procs and so
static CommandEntry commandProcs[] = {
// 0x00
- COMMAND(c1_jmpTo),
- COMMAND(c1_setRetValue),
- COMMAND(c1_pushRetOrPos),
- COMMAND(c1_push),
+ COMMAND(cmd_jmpTo),
+ COMMAND(cmd_setRetValue),
+ COMMAND(cmd_pushRetOrPos),
+ COMMAND(cmd_push),
// 0x04
- COMMAND(c1_push),
- COMMAND(c1_pushReg),
- COMMAND(c1_pushBPNeg),
- COMMAND(c1_pushBPAdd),
+ COMMAND(cmd_push),
+ COMMAND(cmd_pushReg),
+ COMMAND(cmd_pushBPNeg),
+ COMMAND(cmd_pushBPAdd),
// 0x08
- COMMAND(c1_popRetOrPos),
- COMMAND(c1_popReg),
- COMMAND(c1_popBPNeg),
- COMMAND(c1_popBPAdd),
+ COMMAND(cmd_popRetOrPos),
+ COMMAND(cmd_popReg),
+ COMMAND(cmd_popBPNeg),
+ COMMAND(cmd_popBPAdd),
// 0x0C
- COMMAND(c1_addSP),
- COMMAND(c1_subSP),
- COMMAND(c1_execOpcode),
- COMMAND(c1_ifNotJmp),
+ COMMAND(cmd_addSP),
+ COMMAND(cmd_subSP),
+ COMMAND(cmd_execOpcode),
+ COMMAND(cmd_ifNotJmp),
// 0x10
- COMMAND(c1_negate),
- COMMAND(c1_eval),
- COMMAND(c1_setRetAndJmp)
+ COMMAND(cmd_negate),
+ COMMAND(cmd_eval),
+ COMMAND(cmd_setRetAndJmp)
};
_commands = commandProcs;
#undef COMMAND
}
bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, const Common::Array<const Opcode*> *opcodes) {
- uint32 size = 0;
- uint8 *data = _vm->resource()->fileData(filename, &size);
- const byte *curData = data;
+ ScriptFileParser file(filename, _vm->resource());
+ if (!file) {
+ error("Couldn't open script file '%s'", filename);
+ return false;
+ }
- uint32 formBlockSize = getFORMBlockSize(curData);
+ uint32 formBlockSize = file.getFORMBlockSize();
if (formBlockSize == (uint32)-1) {
- delete [] data;
error("No FORM chunk found in file: '%s'", filename);
return false;
}
- uint32 chunkSize = getIFFBlockSize(data, curData, size, TEXT_CHUNK);
+ uint32 chunkSize = file.getIFFBlockSize(TEXT_CHUNK);
if (chunkSize != (uint32)-1) {
scriptData->text = new byte[chunkSize];
- if (!loadIFFBlock(data, curData, size, TEXT_CHUNK, scriptData->text, chunkSize)) {
- delete [] data;
+ if (!file.loadIFFBlock(TEXT_CHUNK, scriptData->text, chunkSize)) {
unloadScript(scriptData);
error("Couldn't load TEXT chunk from file: '%s'", filename);
return false;
}
}
- chunkSize = getIFFBlockSize(data, curData, size, ORDR_CHUNK);
+ chunkSize = file.getIFFBlockSize(ORDR_CHUNK);
if (chunkSize == (uint32)-1) {
- delete [] data;
unloadScript(scriptData);
error("No ORDR chunk found in file: '%s'", filename);
return false;
@@ -106,8 +104,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons
scriptData->ordr = new uint16[chunkSize];
- if (!loadIFFBlock(data, curData, size, ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) {
- delete [] data;
+ if (!file.loadIFFBlock(ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) {
unloadScript(scriptData);
error("Couldn't load ORDR chunk from file: '%s'", filename);
return false;
@@ -116,9 +113,8 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons
while (chunkSize--)
scriptData->ordr[chunkSize] = READ_BE_UINT16(&scriptData->ordr[chunkSize]);
- chunkSize = getIFFBlockSize(data, curData, size, DATA_CHUNK);
+ chunkSize = file.getIFFBlockSize(DATA_CHUNK);
if (chunkSize == (uint32)-1) {
- delete [] data;
unloadScript(scriptData);
error("No DATA chunk found in file: '%s'", filename);
return false;
@@ -127,8 +123,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons
scriptData->data = new uint16[chunkSize];
- if (!loadIFFBlock(data, curData, size, DATA_CHUNK, scriptData->data, chunkSize << 1)) {
- delete [] data;
+ if (!file.loadIFFBlock(DATA_CHUNK, scriptData->data, chunkSize << 1)) {
unloadScript(scriptData);
error("Couldn't load DATA chunk from file: '%s'", filename);
return false;
@@ -139,8 +134,7 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, cons
scriptData->data[chunkSize] = READ_BE_UINT16(&scriptData->data[chunkSize]);
scriptData->opcodes = opcodes;
-
- delete [] data;
+
return true;
}
@@ -172,10 +166,14 @@ bool ScriptHelper::startScript(ScriptState *script, int function) {
if (functionOffset == 0xFFFF)
return false;
- if (_vm->gameFlags().platform == Common::kPlatformFMTowns)
+ if (_vm->game() == GI_KYRA1) {
+ if (_vm->gameFlags().platform == Common::kPlatformFMTowns)
+ script->ip = &script->dataPtr->data[functionOffset+1];
+ else
+ script->ip = &script->dataPtr->data[functionOffset];
+ } else {
script->ip = &script->dataPtr->data[functionOffset+1];
- else
- script->ip = &script->dataPtr->data[functionOffset];
+ }
return true;
}
@@ -217,37 +215,51 @@ bool ScriptHelper::runScript(ScriptState *script) {
return _continue;
}
-uint32 ScriptHelper::getFORMBlockSize(const byte *&data) const {
- static const uint32 chunkName = FORM_CHUNK;
+#pragma mark -
+#pragma mark - ScriptFileParser implementation
+#pragma mark -
+
+void ScriptFileParser::setFile(const char *filename, Resource *res) {
+ destroy();
+
+ if (!res->getFileHandle(filename, &_endOffset, _scriptFile))
+ return;
+ _startOffset = _scriptFile.pos();
+ _endOffset += _startOffset;
+}
+
+void ScriptFileParser::destroy() {
+ _scriptFile.close();
+ _startOffset = _endOffset = 0;
+}
+
+uint32 ScriptFileParser::getFORMBlockSize() {
+ uint32 oldOffset = _scriptFile.pos();
+
+ uint32 data = _scriptFile.readUint32LE();
- if (READ_LE_UINT32(data) != chunkName)
+ if (data != FORM_CHUNK) {
+ _scriptFile.seek(oldOffset);
return (uint32)-1;
+ }
- data += 4;
- uint32 retValue = READ_BE_UINT32(data); data += 4;
- return retValue;
+ data = _scriptFile.readUint32BE();
+ return data;
}
-uint32 ScriptHelper::getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName) const {
+uint32 ScriptFileParser::getIFFBlockSize(const uint32 chunkName) {
uint32 size = (uint32)-1;
- bool special = false;
- if (data == (start + maxSize))
- data = start + 0x0C;
+ _scriptFile.seek(_startOffset + 0x0C);
- while (data < (start + maxSize)) {
- uint32 chunk = READ_LE_UINT32(data); data += 4;
- uint32 size_temp = READ_BE_UINT32(data); data += 4;
+ while (_scriptFile.pos() < _endOffset) {
+ uint32 chunk = _scriptFile.readUint32LE();
+ uint32 size_temp = _scriptFile.readUint32BE();
+
if (chunk != chunkName) {
- if (special) {
- data += (size_temp + 1) & 0xFFFFFFFE;
- } else {
- data = start + 0x0C;
- special = true;
- }
+ _scriptFile.seek((size_temp + 1) & (~1), SEEK_CUR);
+ assert(_scriptFile.pos() <= _endOffset);
} else {
- // kill our data
- data = start;
size = size_temp;
break;
}
@@ -256,32 +268,21 @@ uint32 ScriptHelper::getIFFBlockSize(const byte *start, const byte *&data, uint3
return size;
}
-bool ScriptHelper::loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName, void *loadTo, uint32 ptrSize) const {
- bool special = false;
-
- if (data == (start + maxSize))
- data = start + 0x0C;
+bool ScriptFileParser::loadIFFBlock(const uint32 chunkName, void *loadTo, uint32 ptrSize) {
+ _scriptFile.seek(_startOffset + 0x0C);
+
+ while (_scriptFile.pos() < _endOffset) {
+ uint32 chunk = _scriptFile.readUint32LE();
+ uint32 chunkSize = _scriptFile.readUint32BE();
- while (data < (start + maxSize)) {
- uint32 chunk = READ_LE_UINT32(data); data += 4;
- uint32 chunkSize = READ_BE_UINT32(data); data += 4;
if (chunk != chunkName) {
- if (special) {
- data += (chunkSize + 1) & 0xFFFFFFFE;
- } else {
- data = start + 0x0C;
- special = true;
- }
+ _scriptFile.seek((chunkSize + 1) & (~1), SEEK_CUR);
+ assert(_scriptFile.pos() <= _endOffset);
} else {
uint32 loadSize = 0;
- if (chunkSize < ptrSize)
- loadSize = chunkSize;
- else
- loadSize = ptrSize;
- memcpy(loadTo, data, loadSize);
- chunkSize = (chunkSize + 1) & 0xFFFFFFFE;
- if (chunkSize > loadSize)
- data += (chunkSize - loadSize);
+
+ loadSize = MIN(ptrSize, chunkSize);
+ _scriptFile.read(loadTo, loadSize);
return true;
}
}
@@ -293,15 +294,15 @@ bool ScriptHelper::loadIFFBlock(const byte *start, const byte *&data, uint32 max
#pragma mark - Command implementations
#pragma mark -
-void ScriptHelper::c1_jmpTo(ScriptState* script) {
+void ScriptHelper::cmd_jmpTo(ScriptState* script) {
script->ip = script->dataPtr->data + _parameter;
}
-void ScriptHelper::c1_setRetValue(ScriptState* script) {
+void ScriptHelper::cmd_setRetValue(ScriptState* script) {
script->retValue = _parameter;
}
-void ScriptHelper::c1_pushRetOrPos(ScriptState* script) {
+void ScriptHelper::cmd_pushRetOrPos(ScriptState* script) {
switch (_parameter) {
case 0:
script->stack[--script->sp] = script->retValue;
@@ -320,23 +321,23 @@ void ScriptHelper::c1_pushRetOrPos(ScriptState* script) {
}
}
-void ScriptHelper::c1_push(ScriptState* script) {
+void ScriptHelper::cmd_push(ScriptState* script) {
script->stack[--script->sp] = _parameter;
}
-void ScriptHelper::c1_pushReg(ScriptState* script) {
+void ScriptHelper::cmd_pushReg(ScriptState* script) {
script->stack[--script->sp] = script->regs[_parameter];
}
-void ScriptHelper::c1_pushBPNeg(ScriptState* script) {
+void ScriptHelper::cmd_pushBPNeg(ScriptState* script) {
script->stack[--script->sp] = script->stack[(-(int32)(_parameter + 2)) + script->bp];
}
-void ScriptHelper::c1_pushBPAdd(ScriptState* script) {
+void ScriptHelper::cmd_pushBPAdd(ScriptState* script) {
script->stack[--script->sp] = script->stack[(_parameter - 1) + script->bp];
}
-void ScriptHelper::c1_popRetOrPos(ScriptState* script) {
+void ScriptHelper::cmd_popRetOrPos(ScriptState* script) {
switch (_parameter) {
case 0:
script->retValue = script->stack[script->sp++];
@@ -359,48 +360,48 @@ void ScriptHelper::c1_popRetOrPos(ScriptState* script) {
}
}
-void ScriptHelper::c1_popReg(ScriptState* script) {
+void ScriptHelper::cmd_popReg(ScriptState* script) {
script->regs[_parameter] = script->stack[script->sp++];
}
-void ScriptHelper::c1_popBPNeg(ScriptState* script) {
+void ScriptHelper::cmd_popBPNeg(ScriptState* script) {
script->stack[(-(int32)(_parameter + 2)) + script->bp] = script->stack[script->sp++];
}
-void ScriptHelper::c1_popBPAdd(ScriptState* script) {
+void ScriptHelper::cmd_popBPAdd(ScriptState* script) {
script->stack[(_parameter - 1) + script->bp] = script->stack[script->sp++];
}
-void ScriptHelper::c1_addSP(ScriptState* script) {
+void ScriptHelper::cmd_addSP(ScriptState* script) {
script->sp += _parameter;
}
-void ScriptHelper::c1_subSP(ScriptState* script) {
+void ScriptHelper::cmd_subSP(ScriptState* script) {
script->sp -= _parameter;
}
-void ScriptHelper::c1_execOpcode(ScriptState* script) {
+void ScriptHelper::cmd_execOpcode(ScriptState* script) {
uint8 opcode = _parameter;
assert(script->dataPtr->opcodes);
assert(opcode < script->dataPtr->opcodes->size());
- if ((*script->dataPtr->opcodes)[opcode]) {
+ if ((*script->dataPtr->opcodes)[opcode] && *(*script->dataPtr->opcodes)[opcode]) {
script->retValue = (*(*script->dataPtr->opcodes)[opcode])(script);
} else {
script->retValue = 0;
- warning("calling unimplemented opcode(0x%.02X)", opcode);
+ warning("calling unimplemented opcode(0x%.02X/%d)", opcode, opcode);
}
}
-void ScriptHelper::c1_ifNotJmp(ScriptState* script) {
+void ScriptHelper::cmd_ifNotJmp(ScriptState* script) {
if (!script->stack[script->sp++]) {
_parameter &= 0x7FFF;
script->ip = script->dataPtr->data + _parameter;
}
}
-void ScriptHelper::c1_negate(ScriptState* script) {
+void ScriptHelper::cmd_negate(ScriptState* script) {
int16 value = script->stack[script->sp];
switch (_parameter) {
case 0:
@@ -424,7 +425,7 @@ void ScriptHelper::c1_negate(ScriptState* script) {
}
}
-void ScriptHelper::c1_eval(ScriptState* script) {
+void ScriptHelper::cmd_eval(ScriptState* script) {
int16 ret = 0;
bool error = false;
@@ -542,7 +543,7 @@ void ScriptHelper::c1_eval(ScriptState* script) {
}
}
-void ScriptHelper::c1_setRetAndJmp(ScriptState* script) {
+void ScriptHelper::cmd_setRetAndJmp(ScriptState* script) {
if (script->sp >= 60) {
_continue = false;
script->ip = 0;
diff --git a/engines/kyra/script.h b/engines/kyra/script.h
index 5e43039110..3396712a24 100644
--- a/engines/kyra/script.h
+++ b/engines/kyra/script.h
@@ -27,33 +27,11 @@
#define KYRA_SCRIPT_H
#include "kyra/kyra.h"
+#include "kyra/util.h"
-namespace Kyra {
-
-struct ScriptState;
-
-struct Opcode {
- virtual ~Opcode() {}
-
- virtual operator bool() const = 0;
-
- virtual int operator()(ScriptState*) const = 0;
-};
+#include "common/file.h"
-template<class T>
-struct OpcodeImpl : public Opcode {
- T *vm;
- typedef int (T::*Callback)(ScriptState*);
- Callback callback;
-
- OpcodeImpl(T *v, Callback c) : Opcode(), vm(v), callback(c) {}
-
- operator bool() const { return callback != 0; }
-
- int operator()(ScriptState *state) const {
- return (vm->*callback)(state);
- }
-};
+namespace Kyra {
struct ScriptData {
byte *text;
@@ -74,6 +52,31 @@ struct ScriptState {
int16 stack[61]; // VM stack
};
+#define stackPos(x) script->stack[script->sp+x]
+#define stackPosString(x) (const char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])]
+
+class ScriptFileParser {
+public:
+ ScriptFileParser() : _scriptFile(), _startOffset(0), _endOffset(0) {}
+ ScriptFileParser(const char *filename, Resource *res) : _scriptFile(), _startOffset(0), _endOffset(0) { setFile(filename, res); }
+ ~ScriptFileParser() { destroy(); }
+
+ // 'script' must be allocated with new!
+ void setFile(const char *filename, Resource *res);
+
+ operator bool() const { return (_startOffset != _endOffset) && _scriptFile.isOpen(); }
+
+ uint32 getFORMBlockSize();
+ uint32 getIFFBlockSize(const uint32 chunk);
+ bool loadIFFBlock(const uint32 chunk, void *loadTo, uint32 ptrSize);
+private:
+ void destroy();
+
+ Common::File _scriptFile;
+ uint32 _startOffset;
+ uint32 _endOffset;
+};
+
class ScriptHelper {
public:
ScriptHelper(KyraEngine *vm);
@@ -88,10 +91,6 @@ public:
bool runScript(ScriptState *script);
protected:
- uint32 getFORMBlockSize(const byte *&data) const;
- uint32 getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk) const;
- bool loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk, void *loadTo, uint32 ptrSize) const;
-
KyraEngine *_vm;
int16 _parameter;
bool _continue;
@@ -104,25 +103,24 @@ protected:
const CommandEntry *_commands;
private:
- void c1_jmpTo(ScriptState*);
- void c1_setRetValue(ScriptState*);
- void c1_pushRetOrPos(ScriptState*);
- void c1_push(ScriptState*);
- //void c1_push(); same as 03
- void c1_pushReg(ScriptState*);
- void c1_pushBPNeg(ScriptState*);
- void c1_pushBPAdd(ScriptState*);
- void c1_popRetOrPos(ScriptState*);
- void c1_popReg(ScriptState*);
- void c1_popBPNeg(ScriptState*);
- void c1_popBPAdd(ScriptState*);
- void c1_addSP(ScriptState*);
- void c1_subSP(ScriptState*);
- void c1_execOpcode(ScriptState*);
- void c1_ifNotJmp(ScriptState*);
- void c1_negate(ScriptState*);
- void c1_eval(ScriptState*);
- void c1_setRetAndJmp(ScriptState*);
+ void cmd_jmpTo(ScriptState*);
+ void cmd_setRetValue(ScriptState*);
+ void cmd_pushRetOrPos(ScriptState*);
+ void cmd_push(ScriptState*);
+ void cmd_pushReg(ScriptState*);
+ void cmd_pushBPNeg(ScriptState*);
+ void cmd_pushBPAdd(ScriptState*);
+ void cmd_popRetOrPos(ScriptState*);
+ void cmd_popReg(ScriptState*);
+ void cmd_popBPNeg(ScriptState*);
+ void cmd_popBPAdd(ScriptState*);
+ void cmd_addSP(ScriptState*);
+ void cmd_subSP(ScriptState*);
+ void cmd_execOpcode(ScriptState*);
+ void cmd_ifNotJmp(ScriptState*);
+ void cmd_negate(ScriptState*);
+ void cmd_eval(ScriptState*);
+ void cmd_setRetAndJmp(ScriptState*);
};
} // end of namespace Kyra
diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp
index 14edf5fff8..bd776e2046 100644
--- a/engines/kyra/script_v1.cpp
+++ b/engines/kyra/script_v1.cpp
@@ -25,6 +25,8 @@
#include "common/stdafx.h"
#include "common/endian.h"
+#include "common/system.h"
+
#include "kyra/kyra_v1.h"
#include "kyra/script.h"
#include "kyra/screen.h"
@@ -32,14 +34,11 @@
#include "kyra/wsamovie.h"
#include "kyra/animator_v1.h"
#include "kyra/text.h"
-#include "common/system.h"
+#include "kyra/timer.h"
namespace Kyra {
-#define stackPos(x) script->stack[script->sp+x]
-#define stackPosString(x) (const char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])]
-
int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
magicInMouseItem(stackPos(0), stackPos(1), -1);
return 0;
}
@@ -47,10 +46,10 @@ int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) {
int KyraEngine_v1::o1_characterSays(ScriptState *script) {
_skipFlag = false;
if (_flags.isTalkie) {
- debugC(3, kDebugLevelScriptFuncs, "o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
characterSays(stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
} else {
- debugC(3, kDebugLevelScriptFuncs, "o1_characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1characterSays(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2));
const char *string = stackPosString(0);
if (_flags.platform == Common::kPlatformFMTowns && _flags.lang == Common::JA_JPN) {
@@ -76,7 +75,7 @@ int KyraEngine_v1::o1_characterSays(ScriptState *script) {
}
int KyraEngine_v1::o1_pauseTicks(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
if (stackPos(1)) {
warning("STUB: special o1_pauseTicks");
// delete this after correct implementing
@@ -88,23 +87,23 @@ int KyraEngine_v1::o1_pauseTicks(ScriptState *script) {
}
int KyraEngine_v1::o1_drawSceneAnimShape(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
_screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0);
return 0;
}
int KyraEngine_v1::o1_queryGameFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return queryGameFlag(stackPos(0));
}
int KyraEngine_v1::o1_setGameFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return setGameFlag(stackPos(0));
}
int KyraEngine_v1::o1_resetGameFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return resetGameFlag(stackPos(0));
}
@@ -114,7 +113,7 @@ int KyraEngine_v1::o1_runNPCScript(ScriptState *script) {
}
int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
for (int i = 0; i < 10; ++i)
_exitList[i] = stackPos(i);
@@ -124,33 +123,33 @@ int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) {
}
int KyraEngine_v1::o1_blockInWalkableRegion(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
return 0;
}
int KyraEngine_v1::o1_blockOutWalkableRegion(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
return 0;
}
int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int normalTimers = stackPos(2);
if (!normalTimers) {
- disableTimer(19);
- disableTimer(14);
- disableTimer(18);
+ _timer->disable(19);
+ _timer->disable(14);
+ _timer->disable(18);
}
int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
if (!normalTimers) {
- enableTimer(19);
- enableTimer(14);
- enableTimer(18);
+ _timer->enable(19);
+ _timer->enable(14);
+ _timer->enable(18);
}
if (reinitScript)
@@ -164,7 +163,7 @@ int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) {
}
int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
int item = stackPos(0);
int xpos = stackPos(1);
int ypos = stackPos(2);
@@ -189,7 +188,7 @@ int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) {
}
int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_screen->hideMouse();
_animator->restoreAllObjectBackgrounds();
int shape = stackPos(0);
@@ -207,49 +206,49 @@ int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) {
}
int KyraEngine_v1::o1_createMouseItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1createMouseItem(%p) (%d)", (const void *)script, stackPos(0));
createMouseItem(stackPos(0));
return 0;
}
int KyraEngine_v1::o1_savePageToDisk(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
_screen->savePageToDisk(stackPosString(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_sceneAnimOn(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0));
_sprites->_anims[stackPos(0)].play = true;
return 0;
}
int KyraEngine_v1::o1_sceneAnimOff(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0));
_sprites->_anims[stackPos(0)].play = false;
return 0;
}
int KyraEngine_v1::o1_getElapsedSeconds(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getElapsedSeconds(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getElapsedSeconds(%p) ()", (const void *)script);
return _system->getMillis() / 1000;
}
int KyraEngine_v1::o1_mouseIsPointer(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_mouseIsPointer(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1mouseIsPointer(%p) ()", (const void *)script);
if (_itemInHand == -1)
return 1;
return 0;
}
int KyraEngine_v1::o1_destroyMouseItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_destroyMouseItem(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1destroyMouseItem(%p) ()", (const void *)script);
destroyMouseItem();
return 0;
}
int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0));
_screen->hideMouse();
_animator->restoreAllObjectBackgrounds();
_sprites->_anims[stackPos(0)].play = true;
@@ -268,59 +267,59 @@ int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) {
int KyraEngine_v1::o1_fadeSpecialPalette(ScriptState *script) {
if (_flags.platform == Common::kPlatformAmiga) {
- debugC(3, kDebugLevelScriptFuncs, "o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
if (_currentCharacter->sceneId != 45) {
if (stackPos(0) == 13) {
memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3);
_screen->setScreenPalette(_screen->getPalette(0));
}
} else {
- warning("o1_fadeSpecialPalette not implemented");
+ warning("KyraEngine_v1::o1fadeSpecialPalette not implemented");
}
} else {
- debugC(3, kDebugLevelScriptFuncs, "o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_screen->fadeSpecialPalette(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
}
return 0;
}
int KyraEngine_v1::o1_playAdlibSound(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playAdlibSound(%p) (%d)", (const void *)script, stackPos(0));
snd_playSoundEffect(stackPos(0));
return 0;
}
int KyraEngine_v1::o1_playAdlibScore(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
snd_playWanderScoreViaMap(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_phaseInSameScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
transcendScenes(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_setScenePhasingFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setScenePhasingFlag(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScenePhasingFlag(%p) ()", (const void *)script);
_scenePhasingFlag = 1;
return 1;
}
int KyraEngine_v1::o1_resetScenePhasingFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_resetScenePhasingFlag(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetScenePhasingFlag(%p) ()", (const void *)script);
_scenePhasingFlag = 0;
return 0;
}
int KyraEngine_v1::o1_queryScenePhasingFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_queryScenePhasingFlag(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryScenePhasingFlag(%p) ()", (const void *)script);
return _scenePhasingFlag;
}
int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) < _roomTableSize);
Room *curRoom = &_roomTable[stackPos(0)];
uint16 returnValue = 0xFFFF;
@@ -350,7 +349,7 @@ int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) {
}
int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int index = stackPos(0);
if (index < 4 && index >= 0) {
_birthstoneGemTable[index] = stackPos(1);
@@ -360,19 +359,19 @@ int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) {
}
int KyraEngine_v1::o1_placeItemInGenericMapScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
placeItemInGenericMapScene(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_setBrandonStatusBit(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0));
_brandonStatusBit |= stackPos(0);
return 0;
}
int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseSeconds(%p) (%d)", (const void *)script, stackPos(0));
if (stackPos(0) > 0 && !_skipFlag)
delay(stackPos(0)*1000, true);
_skipFlag = false;
@@ -380,7 +379,7 @@ int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) {
}
int KyraEngine_v1::o1_getCharactersLocation(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0));
return _characterList[stackPos(0)].sceneId;
}
@@ -390,31 +389,31 @@ int KyraEngine_v1::o1_runNPCSubscript(ScriptState *script) {
}
int KyraEngine_v1::o1_magicOutMouseItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0));
magicOutMouseItem(stackPos(0), -1);
return 0;
}
int KyraEngine_v1::o1_internalAnimOn(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1internalAnimOn(%p) (%d)", (const void *)script, stackPos(0));
_animator->sprites()[stackPos(0)].active = 1;
return 0;
}
int KyraEngine_v1::o1_forceBrandonToNormal(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_forceBrandonToNormal(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1forceBrandonToNormal(%p) ()", (const void *)script);
checkAmuletAnimFlags();
return 0;
}
int KyraEngine_v1::o1_poisonDeathNow(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_poisonDeathNow(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1poisonDeathNow(%p) ()", (const void *)script);
seq_poisonDeathNow(1);
return 0;
}
int KyraEngine_v1::o1_setScaleMode(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int len = stackPos(0);
int setValue1 = stackPos(1);
int start2 = stackPos(2);
@@ -432,7 +431,7 @@ int KyraEngine_v1::o1_setScaleMode(ScriptState *script) {
}
int KyraEngine_v1::o1_openWSAFile(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3));
const char *filename = stackPosString(0);
int wsaIndex = stackPos(1);
@@ -444,7 +443,7 @@ int KyraEngine_v1::o1_openWSAFile(ScriptState *script) {
}
int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1closeWSAFile(%p) (%d)", (const void *)script, stackPos(0));
int wsaIndex = stackPos(0);
if (_movieObjects[wsaIndex])
@@ -454,7 +453,7 @@ int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) {
}
int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
_screen->hideMouse();
@@ -495,7 +494,7 @@ int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) {
}
int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
int frame = stackPos(0);
int xpos = stackPos(1);
int ypos = stackPos(2);
@@ -522,13 +521,13 @@ int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) {
}
int KyraEngine_v1::o1_enterNewScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
return 0;
}
int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_brandonPosX = stackPos(0);
_brandonPosY = stackPos(1);
if (_brandonPosX + 1 == 0 && _brandonPosY + 1 == 0)
@@ -537,7 +536,7 @@ int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) {
}
int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int xpos = stackPos(0);
int ypos = stackPos(1);
int delayTime = stackPos(2);
@@ -564,7 +563,7 @@ int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) {
}
int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int changeScaleMode = stackPos(3);
int xpos = (int16)(stackPos(0) & 0xFFFC);
int ypos = (int16)(stackPos(1) & 0xFFFE);
@@ -613,7 +612,7 @@ int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) {
}
int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0));
int disable = stackPos(0);
int activeBackup = 0;
if (disable) {
@@ -627,13 +626,13 @@ int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) {
}
int KyraEngine_v1::o1_setCustomPaletteRange(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3);
return 0;
}
int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
_screen->loadPageFromDisk(stackPosString(0), stackPos(1));
_animator->_updateScreen = true;
return 0;
@@ -641,7 +640,7 @@ int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) {
int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) {
if (_flags.isTalkie) {
- debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
if (speechEnabled()) {
snd_voiceWaitForFinish();
@@ -651,7 +650,7 @@ int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) {
if (textEnabled())
_text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
} else {
- debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1customPrintTalkString(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF);
_skipFlag = false;
_text->printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2);
}
@@ -660,7 +659,7 @@ int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) {
}
int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_restoreCustomPrintBackground(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreCustomPrintBackground(%p) ()", (const void *)script);
snd_voiceWaitForFinish();
snd_stopVoice();
_text->restoreTalkTextMessageBkgd(2, 0);
@@ -668,29 +667,29 @@ int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) {
}
int KyraEngine_v1::o1_hideMouse(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_hideMouse(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1hideMouse(%p) ()", (const void *)script);
_screen->hideMouse();
return 0;
}
int KyraEngine_v1::o1_showMouse(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_showMouse(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1showMouse(%p) ()", (const void *)script);
_screen->showMouse();
return 0;
}
int KyraEngine_v1::o1_getCharacterX(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharacterX(%p) (%d)", (const void *)script, stackPos(0));
return _characterList[stackPos(0)].x1;
}
int KyraEngine_v1::o1_getCharacterY(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharacterY(%p) (%d)", (const void *)script, stackPos(0));
return _characterList[stackPos(0)].y1;
}
int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
int character = stackPos(0);
int facing = stackPos(1);
int newAnimFrame = stackPos(2);
@@ -708,7 +707,7 @@ int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) {
}
int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int xpos = stackPos(0);
int ypos = stackPos(1);
int width = stackPos(2);
@@ -721,7 +720,7 @@ int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) {
}
int KyraEngine_v1::o1_printText(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
if (_flags.lang == Common::JA_JPN && stackPos(3) == 7)
_screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80);
else
@@ -731,7 +730,7 @@ int KyraEngine_v1::o1_printText(ScriptState *script) {
}
int KyraEngine_v1::o1_random(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) < stackPos(1));
return _rnd.getRandomNumberRng(stackPos(0), stackPos(1));
}
@@ -742,7 +741,7 @@ int KyraEngine_v1::o1_loadSoundFile(ScriptState *script) {
}
int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
int frame = stackPos(0);
int xpos = stackPos(1);
int ypos = stackPos(2);
@@ -771,7 +770,7 @@ int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) {
}
int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6));
int startFrame = stackPos(0);
int endFrame = stackPos(1);
int xpos = stackPos(2);
@@ -847,7 +846,7 @@ int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) {
}
int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int character = stackPos(0);
int animFrame = stackPos(1);
int newFacing = stackPos(2);
@@ -862,13 +861,13 @@ int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) {
}
int KyraEngine_v1::o1_internalAnimOff(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1internalAnimOff(%p) (%d)", (const void *)script, stackPos(0));
_animator->sprites()[stackPos(0)].active = 0;
return 0;
}
int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
Character *ch = &_characterList[stackPos(0)];
int16 x = stackPos(1);
int16 y = stackPos(2);
@@ -884,25 +883,25 @@ int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) {
}
int KyraEngine_v1::o1_clearSceneAnimatorBeacon(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1clearSceneAnimatorBeacon(%p) ()", (const void *)script);
_sprites->_sceneAnimatorBeaconFlag = 0;
return 0;
}
int KyraEngine_v1::o1_querySceneAnimatorBeacon(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_querySceneAnimatorBeacon(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1querySceneAnimatorBeacon(%p) ()", (const void *)script);
return _sprites->_sceneAnimatorBeaconFlag;
}
int KyraEngine_v1::o1_refreshSceneAnimator(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_refreshSceneAnimator(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1refreshSceneAnimator(%p) ()", (const void *)script);
_sprites->updateSceneAnims();
_animator->updateAllObjectShapes();
return 0;
}
int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int item = stackPos(0);
int xpos = stackPos(1);
int ypos = stackPos(2);
@@ -921,7 +920,7 @@ int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) {
}
int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
_screen->hideMouse();
wipeDownMouseItem(stackPos(1), stackPos(2));
destroyMouseItem();
@@ -930,7 +929,7 @@ int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) {
}
int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int id = stackPos(0);
int sceneId = stackPos(1);
int xpos = (int16)(stackPos(2) & 0xFFFC);
@@ -947,7 +946,7 @@ int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) {
}
int KyraEngine_v1::o1_getKey(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getKey(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getKey(%p) ()", (const void *)script);
waitForEvent();
return 0;
}
@@ -958,7 +957,7 @@ int KyraEngine_v1::o1_specificItemInInventory(ScriptState *script) {
}
int KyraEngine_v1::o1_popMobileNPCIntoScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE));
int character = stackPos(0);
int sceneId = stackPos(1);
int animFrame = stackPos(2);
@@ -994,7 +993,7 @@ int KyraEngine_v1::o1_unhideMobileCharacter(ScriptState *script) {
}
int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
Character *ch = &_characterList[stackPos(0)];
AnimObject *animObj = &_animator->actors()[stackPos(0)];
int newScene = stackPos(1);
@@ -1011,7 +1010,7 @@ int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) {
}
int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
int character = stackPos(0);
int toX = stackPos(1);
int toY = stackPos(2);
@@ -1078,11 +1077,11 @@ int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) {
setCharacterPosition(character, 0);
++curPos;
- nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
+ nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis();
while (_system->getMillis() < nextFrame) {
_sprites->updateSceneAnims();
updateMousePointer();
- updateGameTimers();
+ _timer->update();
_animator->updateAllObjectShapes();
updateTextFade();
if ((nextFrame - _system->getMillis()) >= 10)
@@ -1093,7 +1092,7 @@ int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) {
}
int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1specialEventDisplayBrynnsNote(%p) ()", (const void *)script);
_screen->hideMouse();
_screen->savePageToDisk("HIDPAGE.TMP", 2);
_screen->savePageToDisk("SEENPAGE.TMP", 0);
@@ -1115,7 +1114,7 @@ int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) {
}
int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1specialEventRemoveBrynnsNote(%p) ()", (const void *)script);
_screen->hideMouse();
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
_screen->loadPageFromDisk("HIDPAGE.TMP", 2);
@@ -1126,13 +1125,13 @@ int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) {
}
int KyraEngine_v1::o1_setLogicPage(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setLogicPage(%p) (%d)", (const void *)script, stackPos(0));
_screen->_curPage = stackPos(0);
return stackPos(0);
}
int KyraEngine_v1::o1_fatPrint(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
// Workround for bug #1582672 ("KYRA1: Text crippled and drawn wrong")
// I'm not sure how the original handels this, since it seems to call
@@ -1145,13 +1144,13 @@ int KyraEngine_v1::o1_fatPrint(ScriptState *script) {
}
int KyraEngine_v1::o1_preserveAllObjectBackgrounds(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1preserveAllObjectBackgrounds(%p) ()", (const void *)script);
_animator->preserveAllBackgrounds();
return 0;
}
int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0));
int times = stackPos(0);
while (times--) {
_sprites->updateSceneAnims();
@@ -1161,23 +1160,23 @@ int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) {
}
int KyraEngine_v1::o1_sceneAnimationActive(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0));
return _sprites->_anims[stackPos(0)].play;
}
int KyraEngine_v1::o1_setCharactersMovementDelay(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- setTimerDelay(stackPos(0)+5, stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ _timer->setDelay(stackPos(0)+5, stackPos(1));
return 0;
}
int KyraEngine_v1::o1_getCharactersFacing(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0));
return _characterList[stackPos(0)].facing;
}
int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0));
_screen->copyBackgroundBlock(stackPos(0), 2, 0);
_screen->copyBackgroundBlock2(stackPos(0));
// update the whole screen
@@ -1187,13 +1186,13 @@ int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) {
}
int KyraEngine_v1::o1_dispelMagicAnimation(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_dispelMagicAnimation(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dispelMagicAnimation(%p) ()", (const void *)script);
seq_dispelMagicAnimation();
return 0;
}
int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_findBrightestFireberry(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1findBrightestFireberry(%p) ()", (const void *)script);
if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198)
return 29;
@@ -1237,7 +1236,7 @@ int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) {
}
int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0));
int palIndex = 0;
switch (stackPos(0)) {
case 0x1E:
@@ -1274,19 +1273,19 @@ int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) {
}
int KyraEngine_v1::o1_setDeathHandlerFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0));
_deathHandler = stackPos(0);
return 0;
}
int KyraEngine_v1::o1_drinkPotionAnimation(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2));
return 0;
}
int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_makeAmuletAppear(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1makeAmuletAppear(%p) ()", (const void *)script);
WSAMovieV1 amulet(this);
amulet.open("AMULET.WSA", 1, 0);
amulet.setX(224);
@@ -1327,7 +1326,7 @@ int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) {
}
int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
int item = stackPos(0);
int x = stackPos(1);
int y = stackPos(2);
@@ -1354,13 +1353,13 @@ int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) {
}
int KyraEngine_v1::o1_setCharactersCurrentFrame(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_characterList[stackPos(0)].currentAnimFrame = stackPos(1);
return 0;
}
int KyraEngine_v1::o1_waitForConfirmationMouseClick(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_waitForConfirmationMouseClick(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1waitForConfirmationMouseClick(%p) ()", (const void *)script);
// if (mouseEnabled) {
while (!_mousePressFlag) {
updateMousePointer();
@@ -1390,18 +1389,18 @@ int KyraEngine_v1::o1_pageFlip(ScriptState *script) {
}
int KyraEngine_v1::o1_setSceneFile(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
setSceneFile(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_getItemInMarbleVase(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getItemInMarbleVase(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getItemInMarbleVase(%p) ()", (const void *)script);
return _marbleVaseItem;
}
int KyraEngine_v1::o1_setItemInMarbleVase(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0));
_marbleVaseItem = stackPos(0);
return 0;
}
@@ -1417,7 +1416,7 @@ int KyraEngine_v1::o1_intPrint(ScriptState *script) {
}
int KyraEngine_v1::o1_shakeScreen(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int waitTicks = stackPos(1);
int times = stackPos(0);
@@ -1430,57 +1429,57 @@ int KyraEngine_v1::o1_shakeScreen(ScriptState *script) {
}
int KyraEngine_v1::o1_createAmuletJewel(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0));
seq_createAmuletJewel(stackPos(0), 0, 0, 0);
return 0;
}
int KyraEngine_v1::o1_setSceneAnimCurrXY(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
_sprites->_anims[stackPos(0)].x = stackPos(1);
_sprites->_anims[stackPos(0)].y = stackPos(2);
return 0;
}
int KyraEngine_v1::o1_poisonBrandonAndRemaps(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_poisonBrandonAndRemaps(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1poisonBrandonAndRemaps(%p) ()", (const void *)script);
setBrandonPoisonFlags(1);
return 0;
}
int KyraEngine_v1::o1_fillFlaskWithWater(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
seq_fillFlaskWithWater(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_getCharactersMovementDelay(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0));
- return getTimerDelay(stackPos(0)+5);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0));
+ return _timer->getDelay(stackPos(0)+5);
}
int KyraEngine_v1::o1_getBirthstoneGem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0));
if (stackPos(0) < 4)
return _birthstoneGemTable[stackPos(0)];
return 0;
}
int KyraEngine_v1::o1_queryBrandonStatusBit(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0));
if (_brandonStatusBit & stackPos(0))
return 1;
return 0;
}
int KyraEngine_v1::o1_playFluteAnimation(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_playFluteAnimation(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playFluteAnimation(%p) ()", (const void *)script);
seq_playFluteAnimation();
return 0;
}
int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0));
if (!stackPos(0))
seq_winterScroll2();
else
@@ -1489,40 +1488,40 @@ int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) {
}
int KyraEngine_v1::o1_getIdolGem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getIdolGem(%p) (%d)", (const void *)script, stackPos(0));
return _idolGemsTable[stackPos(0)];
}
int KyraEngine_v1::o1_setIdolGem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_idolGemsTable[stackPos(0)] = stackPos(1);
return 0;
}
int KyraEngine_v1::o1_totalItemsInScene(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0));
return countItemsInScene(stackPos(0));
}
int KyraEngine_v1::o1_restoreBrandonsMovementDelay(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1restoreBrandonsMovementDelay(%p) ()", (const void *)script);
setWalkspeed(_configWalkspeed);
return 0;
}
int KyraEngine_v1::o1_setMousePos(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_system->warpMouse(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_getMouseState(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getMouseState(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getMouseState(%p) ()", (const void *)script);
return _mouseState;
}
int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
_entranceMouseCursorTracks[0] = stackPos(0);
_entranceMouseCursorTracks[1] = stackPos(1);
_entranceMouseCursorTracks[2] = stackPos(0) + stackPos(2) - 1;
@@ -1532,19 +1531,19 @@ int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) {
}
int KyraEngine_v1::o1_itemAppearsOnGround(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0);
return 0;
}
int KyraEngine_v1::o1_setNoDrawShapesFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0));
_animator->_noDrawShapesFlag = stackPos(0);
return 0;
}
int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int cmd = stackPos(0);
uint8 *fadePal = 0;
@@ -1584,7 +1583,7 @@ int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) {
}
int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) < _roomTableSize);
Room *curRoom = &_roomTable[stackPos(0)];
for (int i = 0; i < 12; ++i) {
@@ -1595,18 +1594,18 @@ int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) {
}
int KyraEngine_v1::o1_queryCauldronState(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_queryCauldronState(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryCauldronState(%p) ()", (const void *)script);
return _cauldronState;
}
int KyraEngine_v1::o1_setCauldronState(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCauldronState(%p) (%d)", (const void *)script, stackPos(0));
_cauldronState = stackPos(0);
return _cauldronState;
}
int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1queryCrystalState(%p) (%d)", (const void *)script, stackPos(0));
if (!stackPos(0))
return _crystalState[0];
else if (stackPos(0) == 1)
@@ -1615,7 +1614,7 @@ int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) {
}
int KyraEngine_v1::o1_setCrystalState(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
if (!stackPos(0))
_crystalState[0] = stackPos(1);
else if (stackPos(0) == 1)
@@ -1629,7 +1628,7 @@ int KyraEngine_v1::o1_setPaletteRange(ScriptState *script) {
}
int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0));
int delayTime = stackPos(0);
checkAmuletAnimFlags();
int scaleValue = _scaleTable[_currentCharacter->y1];
@@ -1655,7 +1654,7 @@ int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) {
}
int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_growBrandonUp(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1growBrandonUp(%p) ()", (const void *)script);
int scaleValue = _scaleTable[_currentCharacter->y1];
int scale = 0;
if (_scaleMode)
@@ -1676,26 +1675,26 @@ int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) {
}
int KyraEngine_v1::o1_setBrandonScaleXAndY(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_animator->_brandonScaleX = stackPos(0);
_animator->_brandonScaleY = stackPos(1);
return 0;
}
int KyraEngine_v1::o1_resetScaleMode(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_resetScaleMode(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1resetScaleMode(%p) ()", (const void *)script);
_scaleMode = 0;
return 0;
}
int KyraEngine_v1::o1_getScaleDepthTableValue(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0));
assert(stackPos(0) < ARRAYSIZE(_scaleTable));
return _scaleTable[stackPos(0)];
}
int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) < ARRAYSIZE(_scaleTable));
_scaleTable[stackPos(0)] = stackPos(1);
return stackPos(1);
@@ -1703,10 +1702,10 @@ int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) {
int KyraEngine_v1::o1_message(ScriptState *script) {
if (_flags.isTalkie) {
- debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2));
drawSentenceCommand(stackPosString(1), stackPos(2));
} else {
- debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1message(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
drawSentenceCommand(stackPosString(0), stackPos(1));
}
@@ -1714,38 +1713,38 @@ int KyraEngine_v1::o1_message(ScriptState *script) {
}
int KyraEngine_v1::o1_checkClickOnNPC(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
return checkForNPCScriptRun(stackPos(0), stackPos(1));
}
int KyraEngine_v1::o1_getFoyerItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1getFoyerItem(%p) (%d)", (const void *)script, stackPos(0));
assert(stackPos(0) < ARRAYSIZE(_foyerItemTable));
return _foyerItemTable[stackPos(0)];
}
int KyraEngine_v1::o1_setFoyerItem(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) < ARRAYSIZE(_foyerItemTable));
_foyerItemTable[stackPos(0)] = stackPos(1);
return stackPos(1);
}
int KyraEngine_v1::o1_setNoItemDropRegion(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
return 0;
}
int KyraEngine_v1::o1_walkMalcolmOn(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_walkMalcolmOn(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1walkMalcolmOn(%p) ()", (const void *)script);
if (!_malcolmFlag)
_malcolmFlag = 1;
return 0;
}
int KyraEngine_v1::o1_passiveProtection(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_passiveProtection(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1passiveProtection(%p) ()", (const void *)script);
return 1;
}
@@ -1755,24 +1754,24 @@ int KyraEngine_v1::o1_setPlayingLoop(ScriptState *script) {
}
int KyraEngine_v1::o1_brandonToStoneSequence(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_brandonToStoneSequence(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1brandonToStoneSequence(%p) ()", (const void *)script);
seq_brandonToStone();
return 0;
}
int KyraEngine_v1::o1_brandonHealingSequence(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_brandonHealingSequence(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1brandonHealingSequence(%p) ()", (const void *)script);
seq_brandonHealing();
return 0;
}
int KyraEngine_v1::o1_protectCommandLine(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1protectCommandLine(%p) (%d)", (const void *)script, stackPos(0));
return stackPos(0);
}
int KyraEngine_v1::o1_pauseMusicSeconds(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_pauseMusicSeconds(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1pauseMusicSeconds(%p) ()", (const void *)script);
// if music disabled
// return
o1_pauseSeconds(script);
@@ -1785,13 +1784,13 @@ int KyraEngine_v1::o1_resetMaskRegion(ScriptState *script) {
}
int KyraEngine_v1::o1_setPaletteChangeFlag(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0));
_paletteChanged = stackPos(0);
return _paletteChanged;
}
int KyraEngine_v1::o1_fillRect(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int videoPageBackup = _screen->_curPage;
_screen->_curPage = stackPos(0);
_screen->fillRect(stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
@@ -1800,19 +1799,19 @@ int KyraEngine_v1::o1_fillRect(ScriptState *script) {
}
int KyraEngine_v1::o1_vocUnload(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_vocUnload(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1vocUnload(%p) ()", (const void *)script);
// this should unload all voc files (not needed)
return 0;
}
int KyraEngine_v1::o1_vocLoad(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0));
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1vocLoad(%p) (%d)", (const void *)script, stackPos(0));
// this should load the specified voc file (not needed)
return 0;
}
int KyraEngine_v1::o1_dummy(ScriptState *script) {
- debugC(3, kDebugLevelScriptFuncs, "o1_dummy(%p) ()", (const void *)script);
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1dummy(%p) ()", (const void *)script);
return 0;
}
diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp
new file mode 100644
index 0000000000..ce1cd99e03
--- /dev/null
+++ b/engines/kyra/script_v2.cpp
@@ -0,0 +1,430 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra_v2.h"
+#include "kyra/wsamovie.h"
+
+#include "common/endian.h"
+
+namespace Kyra {
+
+int KyraEngine_v2::o2_setCharacterFacingRefresh(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
+ int animFrame = stackPos(2);
+ if (animFrame >= 0)
+ _mainCharacter.animFrame = animFrame;
+ _mainCharacter.facing = stackPos(1);
+ updateCharacterAnim(0);
+ refreshAnimObjectsIfNeed();
+ return 0;
+}
+
+int KyraEngine_v2::o2_defineObject(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_defineObject(%p) (%d, '%s', %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ Object *object = &_objectList[stackPos(0)];
+ strcpy(object->filename, stackPosString(1));
+ object->scriptId = stackPos(2);
+ object->x = stackPos(3);
+ object->y = stackPos(4);
+ object->unk12 = stackPos(5);
+ return 0;
+}
+
+int KyraEngine_v2::o2_refreshCharacter(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_refreshCharacter(%p) (-, %d, %d, %d)", (const void *)script, stackPos(1), stackPos(2), stackPos(3));
+ int unk = stackPos(1);
+ int facing = stackPos(2);
+ int refresh = stackPos(3);
+ if (facing >= 0)
+ _mainCharacter.facing = facing;
+ if (unk >= 0 && unk != 32)
+ _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
+ updateCharacterAnim(0);
+ if (refresh)
+ refreshAnimObjectsIfNeed();
+ return 0;
+}
+
+int KyraEngine_v2::o2_getCharacterX(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterX(%p) ()", (const void *)script);
+ return _mainCharacter.x1;
+}
+
+int KyraEngine_v2::o2_getCharacterY(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterY(%p) ()", (const void *)script);
+ return _mainCharacter.y1;
+}
+
+int KyraEngine_v2::o2_getCharacterFacing(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_getCharacterFacing(%p) ()", (const void *)script);
+ return _mainCharacter.facing;
+}
+
+int KyraEngine_v2::o2_setSceneComment(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setSceneComment(%p) ('%s')", (const void *)script, stackPosString(0));
+ _sceneCommentString = stackPosString(0);
+ return 0;
+}
+
+int KyraEngine_v2::o2_showChapterMessage(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ showChapterMessage(stackPos(0), stackPos(1));
+ return 0;
+}
+
+int KyraEngine_v2::o2_wsaClose(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0));
+ assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots));
+ _wsaSlots[stackPos(0)]->close();
+ return 0;
+}
+
+int KyraEngine_v2::o2_displayWsaFrame(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_displayWsaFrame(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8));
+ int frame = stackPos(0);
+ int x = stackPos(1);
+ int y = stackPos(2);
+ int waitTime = stackPos(3);
+ int slot = stackPos(4);
+ int copyParam = stackPos(5);
+ int doUpdate = stackPos(6);
+ int dstPage = stackPos(7);
+ int backUp = stackPos(8);
+
+ _screen->hideMouse();
+ uint32 endTime = _system->getMillis() + waitTime * _tickLength;
+ _wsaSlots[slot]->setX(x);
+ _wsaSlots[slot]->setY(y);
+ _wsaSlots[slot]->setDrawPage(dstPage);
+ _wsaSlots[slot]->displayFrame(frame, copyParam | 0xC000);
+ _screen->updateScreen();
+
+ if (backUp)
+ memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
+
+ while (_system->getMillis() < endTime) {
+ if (doUpdate)
+ update();
+
+ if (endTime - _system->getMillis() >= 10)
+ delay(10);
+ }
+ _screen->showMouse();
+ return 0;
+}
+
+int KyraEngine_v2::o2_displayWsaSequentialFrames(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_displayWsaSequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ int startFrame = stackPos(0);
+ int endFrame = stackPos(1);
+ int x = stackPos(2);
+ int y = stackPos(3);
+ int waitTime = stackPos(4);
+ int slot = stackPos(5);
+ int maxTimes = stackPos(6);
+ int copyFlags = stackPos(7);
+
+ if (maxTimes > 1)
+ maxTimes = 1;
+
+ _wsaSlots[slot]->setX(x);
+ _wsaSlots[slot]->setY(y);
+ _wsaSlots[slot]->setDrawPage(0);
+
+ _screen->hideMouse();
+ int curTime = 0;
+ while (curTime < maxTimes) {
+ if (startFrame < endFrame) {
+ for (int i = startFrame; i <= endFrame; ++i) {
+ uint32 endTime = _system->getMillis() + waitTime * _tickLength;
+ _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags);
+ _screen->updateScreen();
+
+ do {
+ update();
+
+ if (endTime - _system->getMillis() >= 10)
+ delay(10);
+ } while (_system->getMillis() < endTime);
+ }
+ } else {
+ for (int i = startFrame; i >= endFrame; --i) {
+ uint32 endTime = _system->getMillis() + waitTime * _tickLength;
+ _wsaSlots[slot]->displayFrame(i, 0xC000 | copyFlags);
+ _screen->updateScreen();
+
+ do {
+ update();
+
+ if (endTime - _system->getMillis() >= 10)
+ delay(10);
+ } while (_system->getMillis() < endTime);
+ }
+ }
+
+ ++curTime;
+ }
+ _screen->showMouse();
+ return 0;
+}
+
+int KyraEngine_v2::o2_wsaOpen(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_wsaOpen(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
+ assert(stackPos(1) >= 0 && stackPos(1) < ARRAYSIZE(_wsaSlots));
+ _wsaSlots[stackPos(1)]->open(stackPosString(0), 1, 0);
+ return 0;
+}
+
+int KyraEngine_v2::o2_defineItem(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ int freeItem = findFreeItem();
+
+ if (freeItem >= 0) {
+ _itemList[freeItem].id = stackPos(0);
+ _itemList[freeItem].x = stackPos(1);
+ _itemList[freeItem].y = stackPos(2);
+ _itemList[freeItem].sceneId = stackPos(3);
+ }
+
+ return freeItem;
+}
+
+int KyraEngine_v2::o2_queryGameFlag(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_queryGameFlag(%p) (%d)", (const void *)script, stackPos(0));
+ return queryGameFlag(stackPos(0));
+}
+
+int KyraEngine_v2::o2_resetGameFlag(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_resetGameFlag(%p) (%d)", (const void *)script, stackPos(0));
+ return resetGameFlag(stackPos(0));
+}
+
+int KyraEngine_v2::o2_setGameFlag(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0));
+ return setGameFlag(stackPos(0));
+}
+
+int KyraEngine_v2::o2_hideMouse(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_hideMouse(%p) ()", (const void *)script);
+ _screen->hideMouse();
+ return 0;
+}
+
+int KyraEngine_v2::o2_addSpecialExit(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ if (_specialExitCount < 5) {
+ _specialExitTable[_specialExitCount+0] = stackPos(0);
+ _specialExitTable[_specialExitCount+5] = stackPos(1);
+ _specialExitTable[_specialExitCount+10] = stackPos(2);
+ _specialExitTable[_specialExitCount+15] = stackPos(3);
+ _specialExitTable[_specialExitCount+20] = stackPos(4);
+ ++_specialExitCount;
+ }
+ return 0;
+}
+
+int KyraEngine_v2::o2_showMouse(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_showMouse(%p) ()", (const void *)script);
+ _screen->showMouse();
+ return 0;
+}
+
+int KyraEngine_v2::o2_setScaleTableItem(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setScaleTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ setScaleTableItem(stackPos(0), stackPos(1));
+ return 0;
+}
+
+int KyraEngine_v2::o2_setDrawLayerTableItem(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setDrawLayerTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ setDrawLayerTableEntry(stackPos(0), stackPos(1));
+ return 0;
+}
+
+int KyraEngine_v2::o2_drawSceneShapeOnPage(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_drawSceneShapeOnPage(%p) (%d, %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ int shape = stackPos(0);
+ int x = stackPos(1);
+ int y = stackPos(2);
+ int flag = stackPos(3);
+ int drawPage = stackPos(4);
+ _screen->drawShape(drawPage, _sceneShapeTable[shape], x, y, 2, flag ? 1 : 0);
+ return 0;
+}
+
+int KyraEngine_v2::o2_restoreBackBuffer(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_restoreBackBuffer(%p) (%d, %d)", (const void *)script, stackPos(0));
+ int disable = stackPos(0);
+ int oldState = 0;
+ if (disable) {
+ oldState = _animObjects[0].enabled;
+ _animObjects[0].enabled = 0;
+ }
+ restorePage3();
+ if (disable)
+ _animObjects[0].enabled = oldState;
+ return 0;
+}
+
+int KyraEngine_v2::o2_getRand(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ assert(stackPos(0) < stackPos(1));
+ return _rnd.getRandomNumberRng(stackPos(0), stackPos(1));
+}
+
+int KyraEngine_v2::o2_encodeShape(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_encodeShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1),
+ stackPos(2), stackPos(3), stackPos(4));
+ _sceneShapeTable[stackPos(0)] = _screen->encodeShape(stackPos(1), stackPos(2), stackPos(3), stackPos(4), 2);
+ return 0;
+}
+
+int KyraEngine_v2::o2_defineRoomEntrance(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+ switch (stackPos(0)) {
+ case 0:
+ _sceneEnterX1 = stackPos(1);
+ _sceneEnterY1 = stackPos(2);
+ break;
+
+ case 1:
+ _sceneEnterX2 = stackPos(1);
+ _sceneEnterY2 = stackPos(2);
+ break;
+
+ case 2:
+ _sceneEnterX3 = stackPos(1);
+ _sceneEnterY3 = stackPos(2);
+ break;
+
+ case 3:
+ _sceneEnterX4 = stackPos(1);
+ _sceneEnterY4 = stackPos(2);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ assert(stackPos(0) >= 0 && stackPos(0) < 10);
+ _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength;
+ return 0;
+}
+
+int KyraEngine_v2::o2_defineSceneAnim(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script,
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8),
+ stackPos(9), stackPos(10), stackPos(11), stackPosString(12));
+ int animId = stackPos(0);
+ SceneAnim &anim = _sceneAnims[animId];
+ anim.flags = stackPos(1);
+ anim.x = stackPos(2);
+ anim.y = stackPos(3);
+ anim.x2 = stackPos(4);
+ anim.y2 = stackPos(5);
+ anim.width = stackPos(6);
+ anim.height = stackPos(7);
+ anim.unkE = stackPos(8);
+ anim.specialSize = stackPos(9);
+ anim.unk12 = stackPos(10);
+ anim.shapeIndex = stackPos(11);
+ if (stackPosString(12) != 0)
+ strcpy(anim.filename, stackPosString(12));
+
+ if (anim.flags & 0x40) {
+ if (!_sceneAnimMovie[animId]->open(anim.filename, 1, 0))
+ error("couldn't load '%s'", anim.filename);
+
+ if (_sceneAnimMovie[animId]->xAdd() || _sceneAnimMovie[animId]->yAdd())
+ anim.wsaFlag = 1;
+ else
+ anim.wsaFlag = 0;
+ }
+
+ return 0;
+}
+
+int KyraEngine_v2::o2_updateSceneAnim(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ updateSceneAnim(stackPos(0), stackPos(1));
+ _specialSceneScriptRunFlag = false;
+ return 0;
+}
+
+int KyraEngine_v2::o2_defineRoom(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script,
+ stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ SceneDesc *scene = &_sceneList[stackPos(0)];
+ strcpy(scene->filename, stackPosString(1));
+ scene->exit1 = stackPos(2);
+ scene->exit2 = stackPos(3);
+ scene->exit3 = stackPos(4);
+ scene->exit4 = stackPos(5);
+ scene->flags = stackPos(6);
+ scene->sound = stackPos(7);
+
+ if (_mainCharacter.sceneId == stackPos(0)) {
+ _sceneExit1 = scene->exit1;
+ _sceneExit2 = scene->exit2;
+ _sceneExit3 = scene->exit3;
+ _sceneExit4 = scene->exit4;
+ }
+
+ return 0;
+}
+
+int KyraEngine_v2::o2_setSpecialSceneScriptState(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
+ _specialSceneScriptState[stackPos(0)] = 1;
+ return 1;
+}
+
+int KyraEngine_v2::o2_clearSpecialSceneScriptState(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
+ _specialSceneScriptState[stackPos(0)] = 0;
+ return 0;
+}
+
+int KyraEngine_v2::o2_querySpecialSceneScriptState(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
+ return _specialSceneScriptState[stackPos(0)];
+}
+
+int KyraEngine_v2::o2_dummy(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_dummy(%p) ()", (const void *)script);
+ return 0;
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp
index 55c294fb1c..3bba3406a8 100644
--- a/engines/kyra/sequences_v1.cpp
+++ b/engines/kyra/sequences_v1.cpp
@@ -32,6 +32,7 @@
#include "kyra/wsamovie.h"
#include "kyra/animator_v1.h"
#include "kyra/text.h"
+#include "kyra/timer.h"
#include "common/events.h"
#include "common/system.h"
@@ -654,7 +655,7 @@ void KyraEngine_v1::seq_makeBrandonInv() {
_screen->hideMouse();
checkAmuletAnimFlags();
_brandonStatusBit |= 0x20;
- setTimerCountdown(18, 2700);
+ _timer->setCountdown(18, 2700);
_brandonStatusBit |= 0x40;
snd_playSoundEffect(0x77);
_brandonInvFlag = 0;
@@ -732,9 +733,9 @@ void KyraEngine_v1::seq_makeBrandonWisp() {
_brandonStatusBit |= 2;
if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198)
- setTimerCountdown(14, 18000);
+ _timer->setCountdown(14, 18000);
else
- setTimerCountdown(14, 7200);
+ _timer->setCountdown(14, 7200);
_animator->_brandonDrawFrame = 113;
_brandonStatusBit0x02Flag = 1;
@@ -1858,7 +1859,7 @@ void KyraEngine_v1::drawJewelsFadeOutEnd(int jewel) {
}
setGameFlag(0xF1);
- setTimerCountdown(19, newDelay);
+ _timer->setCountdown(19, newDelay);
_screen->hideMouse();
for (int i = 0; jewelTable[i] != 0xFFFF; ++i) {
uint16 shape = jewelTable[i];
diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp
index afda1091e6..1c098bf887 100644
--- a/engines/kyra/sequences_v2.cpp
+++ b/engines/kyra/sequences_v2.cpp
@@ -569,6 +569,7 @@ void KyraEngine_v2::seq_loadWSA(int wsaNum, const char *filename, int frameDelay
_activeWSA[wsaNum].movie = new WSAMovieV2(this);
assert(_activeWSA[wsaNum].movie);
_activeWSA[wsaNum].endFrame = _activeWSA[wsaNum].movie->open(filename, 0, _screen->_currentPalette);
+ _activeWSA[wsaNum].movie->flagOldOff(true);
assert(_activeWSA[wsaNum].movie->opened());
_activeWSA[wsaNum].currentFrame = 0;
_activeWSA[wsaNum].frameDelay = frameDelay;
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 68e5401481..3cf8648aa8 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -868,16 +868,41 @@ const ScreenDim Screen::_screenDimTable[] = {
{ 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 }
};
-const int Screen::_screenDimTableCount = ARRAYSIZE(_screenDimTable);
+const int Screen::_screenDimTableCount = ARRAYSIZE(Screen::_screenDimTable);
+
+const ScreenDim Screen_v2::_screenDimTable[] = {
+ { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x08, 0x48, 0x18, 0x38, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x00, 0x00, 0x28, 0x90, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x00, 0xC2, 0x28, 0x06, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x00, 0x90, 0x28, 0x38, 0x96, 0xCF, 0x00, 0x00 },
+ { 0x01, 0x94, 0x26, 0x30, 0x96, 0x1B, 0x00, 0x00 },
+ { 0x00, 0x90, 0x28, 0x38, 0xC7, 0xCC, 0x00, 0x00 },
+ { 0x01, 0x96, 0x26, 0x32, 0xC7, 0xCC, 0x00, 0x00 },
+ { 0x00, 0x00, 0x28, 0x88, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x00, 0x08, 0x28, 0xB8, 0xC7, 0xCF, 0x00, 0x00 },
+ { 0x01, 0x28, 0x26, 0x46, 0xC7, 0xCC, 0x00, 0x00 },
+ { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } // menu, just present for current menu code
+};
+
+const int Screen_v2::_screenDimTableCount = ARRAYSIZE(Screen_v2::_screenDimTable);
-const ScreenDim Screen::_screenDimTableK3[] = {
+const ScreenDim Screen_v2::_screenDimTableK3[] = {
{ 0x00, 0x00, 0x28, 0xC8, 0xFF, 0xF0, 0x00, 0x00 },
{ 0x08, 0x48, 0x18, 0x38, 0xFF, 0xF0, 0x00, 0x00 },
{ 0x00, 0x00, 0x28, 0xBC, 0xFF, 0xF0, 0x00, 0x00 },
{ 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 }
};
-const int Screen::_screenDimTableCountK3 = ARRAYSIZE(_screenDimTableK3);
+const int Screen_v2::_screenDimTableCountK3 = ARRAYSIZE(Screen_v2::_screenDimTableK3);
+
+const int8 KyraEngine::_addXPosTable[] = {
+ 4, 4, 0, -4, -4, -4, 0, 4
+};
+
+const int8 KyraEngine::_addYPosTable[] = {
+ 0, -2, -2, -2, 0, 2, 2, 2
+};
const char *KyraEngine_v1::_soundFiles[] = {
"INTRO",
@@ -909,18 +934,10 @@ const int8 KyraEngine_v1::_charXPosTable[] = {
0, 4, 4, 4, 0, -4, -4, -4
};
-const int8 KyraEngine_v1::_addXPosTable[] = {
- 4, 4, 0, -4, -4, -4, 0, 4
-};
-
const int8 KyraEngine_v1::_charYPosTable[] = {
-2, -2, 0, 2, 2, 2, 0, -2
};
-const int8 KyraEngine_v1::_addYPosTable[] = {
- 0, -2, -2, -2, 0, 2, 2, 2
-};
-
const uint16 KyraEngine_v1::_itemPosX[] = {
95, 115, 135, 155, 175, 95, 115, 135, 155, 175
};
@@ -1196,6 +1213,34 @@ const char *KyraEngine_v2::_introSoundList[] = {
const int KyraEngine_v2::_introSoundListSize = ARRAYSIZE(KyraEngine_v2::_introSoundList);
+const char *KyraEngine_v2::_languageExtension[] = {
+ "ENG",
+ "FRE",
+ "GER"/*,
+ "ITA", Italian and Spanish was never included
+ "SPA"*/
+};
+
+const char *KyraEngine_v2::_scriptLangExt[] = {
+ "EMC",
+ "FMC",
+ "GMC"/*,
+ "IMC", Italian and Spanish was never included
+ "SMC"*/
+};
+
+int KyraEngine_v2::_characterFrameTable[] = {
+ 0x19, 0x09, 0x09, 0x12, 0x12, 0x12, 0x09, 0x09
+};
+
+int KyraEngine_v2::_inventoryX[] = {
+ 0x4F, 0x63, 0x77, 0x8B, 0x9F, 0x4F, 0x63, 0x77, 0x8B, 0x9F
+};
+
+int KyraEngine_v2::_inventoryY[] = {
+ 0x95, 0x95, 0x95, 0x95, 0x95, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
// kyra 3 static res
const char *KyraEngine_v3::_soundList[] = {
diff --git a/engines/kyra/text_v1.cpp b/engines/kyra/text_v1.cpp
index 3ca986adf8..c04aa2105f 100644
--- a/engines/kyra/text_v1.cpp
+++ b/engines/kyra/text_v1.cpp
@@ -28,6 +28,7 @@
#include "kyra/text.h"
#include "kyra/animator_v1.h"
#include "kyra/sprites.h"
+#include "kyra/timer.h"
namespace Kyra {
@@ -66,9 +67,9 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c
snd_playVoiceFile(vocFile);
}
- disableTimer(14);
- disableTimer(18);
- disableTimer(19);
+ _timer->disable(14);
+ _timer->disable(18);
+ _timer->disable(19);
uint32 timeAtStart = _system->getMillis();
uint32 loopStart;
@@ -80,7 +81,7 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c
if (_system->getMillis() > timeToEnd && !hasUpdatedNPCs) {
hasUpdatedNPCs = true;
- disableTimer(15);
+ _timer->disable(15);
_currHeadShape = 4;
_animator->animRefreshNPC(0);
_animator->animRefreshNPC(_talkingCharNum);
@@ -92,7 +93,7 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c
}
}
- updateGameTimers();
+ _timer->update();
_sprites->updateSceneAnims();
_animator->restoreAllObjectBackgrounds();
_animator->preserveAnyChangedBackgrounds();
@@ -146,10 +147,10 @@ void KyraEngine_v1::waitForChatToFinish(int vocFile, int16 chatDuration, const c
snd_voiceWaitForFinish();
snd_stopVoice();
- enableTimer(14);
- enableTimer(15);
- enableTimer(18);
- enableTimer(19);
+ _timer->enable(14);
+ _timer->enable(15);
+ _timer->enable(18);
+ _timer->enable(19);
//clearKyrandiaButtonIO();
}
@@ -374,7 +375,7 @@ void KyraEngine_v1::updateTextFade() {
return;
bool finished = false;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
if (_currSentenceColor[i] > 4)
_currSentenceColor[i] -= 4;
else
@@ -382,7 +383,8 @@ void KyraEngine_v1::updateTextFade() {
_currSentenceColor[i] = 0;
finished = true;
}
-
+ }
+
_screen->_currentPalette[765] = _currSentenceColor[0];
_screen->_currentPalette[766] = _currSentenceColor[1];
_screen->_currentPalette[767] = _currSentenceColor[2];
diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp
new file mode 100644
index 0000000000..dff191cbe0
--- /dev/null
+++ b/engines/kyra/timer.cpp
@@ -0,0 +1,251 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra.h"
+#include "kyra/timer.h"
+
+#include "common/func.h"
+#include "common/savefile.h"
+
+namespace Kyra {
+
+namespace {
+struct TimerResync : public Common::UnaryFunction<TimerEntry&, void> {
+ uint32 _tickLength, _curTime;
+ TimerResync(KyraEngine *vm, uint32 curTime) : _tickLength(vm->tickLength()), _curTime(curTime) {}
+
+ void operator()(TimerEntry &entry) const {
+ if (entry.lastUpdate < 0) {
+ if ((entry.lastUpdate + _curTime) <= 0)
+ entry.nextRun = 0;
+ else
+ entry.nextRun = _curTime + entry.lastUpdate + entry.countdown * _tickLength;
+ } else {
+ uint32 nextRun = entry.lastUpdate + entry.countdown * _tickLength;
+ if (_curTime < nextRun)
+ nextRun = 0;
+ entry.nextRun = nextRun;
+ }
+ }
+};
+
+struct TimerEqual : public Common::UnaryFunction<const TimerEntry&, bool> {
+ uint8 _id;
+
+ TimerEqual(uint8 id) : _id(id) {}
+
+ bool operator()(const TimerEntry &entry) const {
+ return entry.id == _id;
+ }
+};
+} // end of anonymous namespace
+
+void TimerManager::reset() {
+ for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ delete pos->func;
+ }
+
+ _timers.clear();
+}
+
+void TimerManager::addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled) {
+ debugC(9, kDebugLevelTimer, "TimerManager::addTimer(%d, %p, %d, %d)", id, (const void*)func, countdown, enabled);
+
+ TimerEntry newTimer;
+
+ newTimer.id = id;
+ newTimer.countdown = countdown;
+ newTimer.enabled = enabled ? 1 : 0;
+ newTimer.lastUpdate = newTimer.nextRun = 0;
+ newTimer.func = func;
+
+ _timers.push_back(newTimer);
+}
+
+void TimerManager::update() {
+ debugC(9, kDebugLevelTimer, "TimerManager::update()");
+
+ if (_system->getMillis() < _nextRun)
+ return;
+
+ _nextRun += 99999;
+
+ for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ if (pos->enabled && pos->countdown >= 0 && pos->nextRun <= _system->getMillis()) {
+ if (pos->func && *pos->func)
+ (*pos->func)(pos->id);
+
+ uint32 curTime = _system->getMillis();
+ pos->lastUpdate = curTime;
+ pos->nextRun = curTime + pos->countdown * _vm->tickLength();
+
+ _nextRun = MIN(_nextRun, pos->nextRun);
+ }
+ }
+}
+
+void TimerManager::resync() {
+ debugC(9, kDebugLevelTimer, "TimerManager::resync()");
+
+ _nextRun = 0; // force rerun
+ Common::for_each(_timers.begin(), _timers.end(), TimerResync(_vm, _system->getMillis()));
+}
+
+void TimerManager::resetNextRun() {
+ debugC(9, kDebugLevelTimer, "TimerManager::resetNextRun()");
+ _nextRun = 0;
+}
+
+void TimerManager::setCountdown(uint8 id, int32 countdown) {
+ debugC(9, kDebugLevelTimer, "TimerManager::setCountdown(%d, %d)", id, countdown);
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ timer->countdown = countdown;
+
+ if (countdown >= 0) {
+ uint32 curTime = _system->getMillis();
+ timer->lastUpdate = curTime;
+ timer->nextRun = curTime + countdown * _vm->tickLength();
+
+ _nextRun = MIN(_nextRun, timer->nextRun);
+ }
+ } else {
+ warning("TimerManager::setCountdown: No timer %d", id);
+ }
+}
+
+void TimerManager::setDelay(uint8 id, int32 countdown) {
+ debugC(9, kDebugLevelTimer, "TimerManager::setDelay(%d, %d)", id, countdown);
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->countdown = countdown;
+ else
+ warning("TimerManager::setDelay: No timer %d", id);
+}
+
+int32 TimerManager::getDelay(uint8 id) const {
+ debugC(9, kDebugLevelTimer, "TimerManager::getDelay(%d)", id);
+
+ CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ return timer->countdown;
+
+ warning("TimerManager::getDelay: No timer %d", id);
+ return -1;
+}
+
+bool TimerManager::isEnabled(uint8 id) const {
+ debugC(9, kDebugLevelTimer, "TimerManager::isEnabled(%d)", id);
+
+ CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ return (timer->enabled == 1);
+
+ warning("TimerManager::isEnabled: No timer %d", id);
+ return false;
+}
+
+void TimerManager::enable(uint8 id) {
+ debugC(9, kDebugLevelTimer, "TimerManager::enable(%d)", id);
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->enabled = 1;
+ else
+ warning("TimerManager::enable: No timer %d", id);
+}
+
+void TimerManager::disable(uint8 id) {
+ debugC(9, kDebugLevelTimer, "TimerManager::disable(%d)", id);
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->enabled = 0;
+ else
+ warning("TimerManager::disable: No timer %d", id);
+}
+
+void TimerManager::loadDataFromFile(Common::InSaveFile *file, int version) {
+ debugC(9, kDebugLevelTimer, "TimerManager::loadDataFromFile(%p, %d)", (const void*)file, version);
+
+ if (version <= 7) {
+ _nextRun = 0;
+ for (int i = 0; i < 32; ++i) {
+ uint8 enabled = file->readByte();
+ int32 countdown = file->readSint32BE();
+ uint32 nextRun = file->readUint32BE();
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(i));
+ if (timer != _timers.end()) {
+ timer->enabled = enabled;
+ timer->countdown = countdown;
+
+ if (nextRun) {
+ timer->nextRun = nextRun + _system->getMillis();
+ timer->lastUpdate = timer->nextRun - countdown * _vm->tickLength();
+ } else {
+ uint32 curTime = _system->getMillis();
+ timer->nextRun = curTime;
+ timer->lastUpdate = curTime - countdown * _vm->tickLength();
+ }
+ } else {
+ warning("Loading timer data for non existing timer %d", i);
+ }
+ }
+ } else {
+ int entries = file->readByte();
+ for (int i = 0; i < entries; ++i) {
+ uint8 id = file->readByte();
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ timer->enabled = file->readByte();
+ timer->countdown = file->readSint32BE();
+ timer->lastUpdate = file->readSint32BE();
+ } else {
+ warning("Loading timer data for non existing timer %d", id);
+ file->seek(7, SEEK_CUR);
+ }
+ }
+
+ resync();
+ }
+}
+
+void TimerManager::saveDataToFile(Common::OutSaveFile *file) const {
+ debugC(9, kDebugLevelTimer, "TimerManager::saveDataToFile(%p)", (const void*)file);
+
+ file->writeByte(count());
+ for (CIterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ file->writeByte(pos->id);
+ file->writeByte(pos->enabled);
+ file->writeSint32BE(pos->countdown);
+ file->writeSint32BE(pos->lastUpdate - _system->getMillis());
+ }
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/timer.h b/engines/kyra/timer.h
new file mode 100644
index 0000000000..1edeb92a42
--- /dev/null
+++ b/engines/kyra/timer.h
@@ -0,0 +1,93 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef KYRA_TIMER_H
+#define KYRA_TIMER_H
+
+#include "kyra/kyra.h"
+#include "kyra/util.h"
+
+#include "common/list.h"
+
+namespace Common {
+class InSaveFile;
+class OutSaveFile;
+} // end of namespace Common
+
+namespace Kyra {
+
+typedef Functor1<int, void> TimerFunc;
+
+struct TimerEntry {
+ uint8 id;
+ int32 countdown;
+ int8 enabled;
+
+ int32 lastUpdate;
+ uint32 nextRun;
+
+ TimerFunc *func;
+};
+
+class TimerManager {
+public:
+ TimerManager(KyraEngine *vm, OSystem *sys) : _vm(vm), _system(sys), _timers(), _nextRun(0) {}
+ ~TimerManager() { reset(); }
+
+ void reset();
+
+ void addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled);
+
+ int count() const { return _timers.size(); }
+
+ void update();
+
+ void resetNextRun();
+
+ void setCountdown(uint8 id, int32 countdown);
+ void setDelay(uint8 id, int32 countdown);
+ int32 getDelay(uint8 id) const;
+
+ bool isEnabled(uint8 id) const;
+ void enable(uint8 id);
+ void disable(uint8 id);
+
+ void resync();
+
+ void loadDataFromFile(Common::InSaveFile *file, int version);
+ void saveDataToFile(Common::OutSaveFile *file) const;
+private:
+ KyraEngine *_vm;
+ OSystem *_system;
+ Common::List<TimerEntry> _timers;
+ uint32 _nextRun;
+
+ typedef Common::List<TimerEntry>::iterator Iterator;
+ typedef Common::List<TimerEntry>::const_iterator CIterator;
+};
+
+} // end of namespace Kyra
+
+#endif
diff --git a/engines/kyra/timer_v1.cpp b/engines/kyra/timer_v1.cpp
index 0b5184fe5a..55dab4413f 100644
--- a/engines/kyra/timer_v1.cpp
+++ b/engines/kyra/timer_v1.cpp
@@ -11,7 +11,7 @@
* 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
+ * 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
@@ -23,126 +23,58 @@
*
*/
+#include "kyra/kyra.h"
#include "kyra/kyra_v1.h"
#include "kyra/screen.h"
#include "kyra/animator_v1.h"
+#include "kyra/timer.h"
#include "common/system.h"
namespace Kyra {
-void KyraEngine_v1::setupTimers() {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::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_v1::timerCheckAnimFlag2; //_nullsub52;
- _timers[15].func = &KyraEngine_v1::timerUpdateHeadAnims; //_nullsub48;
- _timers[16].func = &KyraEngine_v1::timerSetFlags1; //_nullsub47;
- _timers[17].func = 0; //sub_15120;
- _timers[18].func = &KyraEngine_v1::timerCheckAnimFlag1; //_nullsub53;
- _timers[19].func = &KyraEngine_v1::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_v1::timerFadeText; //sub_151F8;
- _timers[32].func = &KyraEngine_v1::updateAnimFlag1; //_nullsub61;
- _timers[33].func = &KyraEngine_v1::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_v1::updateGameTimers() {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::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_v1::clearNextEventTickCount() {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::clearNextEventTickCount()");
- _timerNextRun = 0;
-}
-
-void KyraEngine_v1::setTimerDelay(uint8 timer, int32 countdown) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::setTimerDelay(%i, %d)", timer, countdown);
- _timers[timer].countdown = countdown;
-}
-int16 KyraEngine_v1::getTimerDelay(uint8 timer) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::getTimerDelay(%i)", timer);
- return _timers[timer].countdown;
-}
+#define TimerV1(x) new Functor1Mem<int, void, KyraEngine_v1>(this, &KyraEngine_v1::x)
-void KyraEngine_v1::setTimerCountdown(uint8 timer, int32 countdown) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::setTimerCountdown(%i, %i)", timer, countdown);
- _timers[timer].countdown = countdown;
- _timers[timer].nextRun = _system->getMillis() + countdown * _tickLength;
+void KyraEngine_v1::setupTimers() {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setupTimers()");
- uint32 nextRun = _system->getMillis() + countdown * _tickLength;
- if (nextRun < _timerNextRun)
- _timerNextRun = nextRun;
-}
+ for (int i = 0; i <= 4; ++i)
+ _timer->addTimer(i, 0, -1, 1);
-void KyraEngine_v1::enableTimer(uint8 timer) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::enableTimer(%i)", timer);
- _timers[timer].active = 1;
-}
+ _timer->addTimer(5, 0, 5, 1);
+ _timer->addTimer(6, 0, 7, 1);
+ _timer->addTimer(7, 0, 8, 1);
+ _timer->addTimer(8, 0, 9, 1);
+ _timer->addTimer(9, 0, 7, 1);
+
+ for (int i = 10; i <= 13; ++i)
+ _timer->addTimer(i, 0, 420, 1);
+
+ _timer->addTimer(14, TimerV1(timerCheckAnimFlag2), 600, 1);
+ _timer->addTimer(15, TimerV1(timerUpdateHeadAnims), 11, 1);
+ _timer->addTimer(16, TimerV1(timerSetFlags1), 7200, 1);
+ _timer->addTimer(17, 0 /*sub_15120*/, 7200, 1);
+ _timer->addTimer(18, TimerV1(timerCheckAnimFlag1), 600, 1);
+ _timer->addTimer(19, TimerV1(timerRedrawAmulet), 600, 1);
+
+ _timer->addTimer(20, 0, 7200, 1);
+ _timer->addTimer(21, 0/*sub_1517C*/, 18000, 1);
+ _timer->addTimer(22, 0, 7200, 1);
+
+ for (int i = 23; i <= 27; ++i)
+ _timer->addTimer(i, 0, 10800, 1);
-void KyraEngine_v1::disableTimer(uint8 timer) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::disableTimer(%i)", timer);
- _timers[timer].active = 0;
+ _timer->addTimer(28, 0, 21600, 1);
+ _timer->addTimer(29, 0, 7200, 1);
+ _timer->addTimer(30, 0, 10800, 1);
+
+ _timer->addTimer(31, TimerV1(timerFadeText), -1, 1);
+ _timer->addTimer(32, TimerV1(updateAnimFlag1), 9, 1);
+ _timer->addTimer(33, TimerV1(updateAnimFlag2), 3, 1);
}
void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerUpdateHeadAnims(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::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};
@@ -161,7 +93,7 @@ void KyraEngine_v1::timerUpdateHeadAnims(int timerNum) {
}
void KyraEngine_v1::timerSetFlags1(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerSetFlags(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags(%i)", timerNum);
if (_currentCharacter->sceneId == 0x1C)
return;
@@ -180,112 +112,68 @@ void KyraEngine_v1::timerSetFlags1(int timerNum) {
}
void KyraEngine_v1::timerFadeText(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerFadeText(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerFadeText(%i)", timerNum);
_fadeText = true;
}
void KyraEngine_v1::updateAnimFlag1(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag1(%d)", timerNum);
if (_brandonStatusBit & 2) {
_brandonStatusBit0x02Flag = 1;
}
}
void KyraEngine_v1::updateAnimFlag2(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::updateAnimFlag2(%d)", timerNum);
if (_brandonStatusBit & 0x20) {
_brandonStatusBit0x20Flag = 1;
}
}
void KyraEngine_v1::setTextFadeTimerCountdown(int16 countdown) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown);
- //if (countdown == -1)
- //countdown = 32000;
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setTextFadeTimerCountdown(%i)", countdown);
+ if (countdown == -1)
+ countdown = 32000;
- setTimerCountdown(31, countdown*60);
+ _timer->setCountdown(31, countdown*60);
}
void KyraEngine_v1::timerSetFlags2(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerSetFlags2(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerSetFlags2(%i)", timerNum);
if (!((uint32*)(_flagsTable+0x2D))[timerNum])
((uint32*)(_flagsTable+0x2D))[timerNum] = 1;
}
void KyraEngine_v1::timerCheckAnimFlag1(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum);
if (_brandonStatusBit & 0x20) {
checkAmuletAnimFlags();
- setTimerCountdown(18, -1);
+ _timer->setCountdown(18, -1);
}
}
void KyraEngine_v1::timerCheckAnimFlag2(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerCheckAnimFlag1(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerCheckAnimFlag2(%i)", timerNum);
if (_brandonStatusBit & 0x2) {
checkAmuletAnimFlags();
- setTimerCountdown(14, -1);
- }
-}
-
-void KyraEngine_v1::checkAmuletAnimFlags() {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::checkSpecialAnimFlags()");
- if (_brandonStatusBit & 2) {
- seq_makeBrandonNormal2();
- setTimerCountdown(19, 300);
- }
-
- if (_brandonStatusBit & 0x20) {
- seq_makeBrandonNormal();
- setTimerCountdown(19, 300);
+ _timer->setCountdown(14, -1);
}
}
void KyraEngine_v1::timerRedrawAmulet(int timerNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::timerRedrawAmulet(%i)", timerNum);
if (queryGameFlag(0xF1)) {
drawAmulet();
- setTimerCountdown(19, -1);
- }
-}
-
-void KyraEngine_v1::drawAmulet() {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::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[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0);
-
- if (queryGameFlag(89))
- _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0);
-
- if (queryGameFlag(86))
- _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0);
-
- if (queryGameFlag(88))
- _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0);
-
- _screen->updateScreen();
- delayWithTicks(3);
- i++;
+ _timer->setCountdown(19, -1);
}
- _screen->showMouse();
}
void KyraEngine_v1::setWalkspeed(uint8 newSpeed) {
- debugC(9, kDebugLevelMain, "KyraEngine_v1::setWalkspeed(%i)", newSpeed);
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v1::setWalkspeed(%i)", newSpeed);
static const uint8 speeds[] = {11, 9, 6, 5, 3};
assert(newSpeed < ARRAYSIZE(speeds));
- setTimerDelay(5, speeds[newSpeed]);
+ _timer->setDelay(5, speeds[newSpeed]);
}
} // end of namespace Kyra
diff --git a/engines/kyra/timer_v2.cpp b/engines/kyra/timer_v2.cpp
new file mode 100644
index 0000000000..2db90f6ecc
--- /dev/null
+++ b/engines/kyra/timer_v2.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/kyra_v2.h"
+#include "kyra/timer.h"
+
+namespace Kyra {
+
+#define TimerV2(x) new Functor1Mem<int, void, KyraEngine_v2>(this, &KyraEngine_v2::x)
+
+void KyraEngine_v2::setupTimers() {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setupTimers()");
+
+ _timer->addTimer(0, 0, 5, 1);
+ _timer->addTimer(1, TimerV2(timerFunc2), -1, 1);
+ _timer->addTimer(2, TimerV2(timerFunc3), 1, 1);
+ _timer->addTimer(3, TimerV2(timerFunc4), 1, 0);
+ _timer->addTimer(4, TimerV2(timerFunc5), 1, 0);
+ _timer->addTimer(5, TimerV2(timerFunc6), 1, 0);
+}
+
+void KyraEngine_v2::timerFunc2(int arg) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc2(%d)", arg);
+ if (_shownMessage)
+ _msgUnk1 = 1;
+}
+
+void KyraEngine_v2::timerFunc3(int arg) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc3(%d)", arg);
+ // XXX
+}
+
+void KyraEngine_v2::timerFunc4(int arg) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc4(%d)", arg);
+ _timer->disable(3);
+ setGameFlag(0xD8);
+}
+
+void KyraEngine_v2::timerFunc5(int arg) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc5(%d)", arg);
+ // XXX
+}
+
+void KyraEngine_v2::timerFunc6(int arg) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::timerFunc6(%d)", arg);
+ // XXX
+}
+
+void KyraEngine_v2::setTimer1DelaySecs(int secs) {
+ debugC(9, kDebugLevelMain | kDebugLevelTimer, "KyraEngine_v2::setTimer1DelaySecs(%d)", secs);
+
+ if (secs == -1)
+ secs = 32000;
+
+ _timer->setCountdown(1, secs * 60);
+}
+
+} // end of namespace Kyra
diff --git a/engines/kyra/util.h b/engines/kyra/util.h
new file mode 100644
index 0000000000..edb2ca454a
--- /dev/null
+++ b/engines/kyra/util.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef KYRA_UTIL_H
+#define KYRA_UTIL_H
+
+#include "common/func.h"
+
+namespace Kyra {
+
+template<class Arg, class Res>
+struct Functor1 : public Common::UnaryFunction<Arg, Res> {
+ virtual operator bool() const = 0;
+ virtual Res operator()(Arg) const = 0;
+};
+
+template<class Arg, class Res, class T>
+class Functor1Mem : public Functor1<Arg, Res> {
+public:
+ typedef Res (T::*FuncType)(Arg);
+
+ Functor1Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
+
+ operator bool() const { return _func != 0; }
+ Res operator()(Arg v1) const {
+ return (_t->*_func)(v1);
+ }
+private:
+ mutable T *_t;
+ Res (T::*_func)(Arg);
+};
+
+struct ScriptState;
+
+typedef Functor1<ScriptState*, int> Opcode;
+
+} // end of namespace Kyra
+
+#endif
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index f0119101fd..7e9ec9b78b 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -28,10 +28,11 @@
#include "common/system.h"
#include "kyra/kyra.h"
+#include "kyra/kyra_v2.h"
#include "kyra/screen.h"
+#include "kyra/screen_v2.h"
#include "kyra/wsamovie.h"
-
namespace Kyra {
WSAMovieV1::WSAMovieV1(KyraEngine *vm) : Movie(vm) {}
WSAMovieV1::~WSAMovieV1() { close(); }
@@ -132,8 +133,8 @@ void WSAMovieV1::close() {
}
}
-void WSAMovieV1::displayFrame(int frameNum) {
- debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d)", frameNum);
+void WSAMovieV1::displayFrame(int frameNum, ...) {
+ debugC(9, kDebugLevelMovie, "WSAMovieV1::displayFrame(%d, ...)", frameNum);
if (frameNum >= _numFrames || !_opened)
return;
@@ -234,7 +235,7 @@ void WSAMovieAmiga::close() {
WSAMovieV1::close();
}
-void WSAMovieAmiga::displayFrame(int frameNum) {
+void WSAMovieAmiga::displayFrame(int frameNum, ...) {
debugC(9, kDebugLevelMovie, "WSAMovieAmiga::displayFrame(%d)", frameNum);
if (frameNum >= _numFrames || !_opened)
return;
@@ -340,7 +341,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
#pragma mark -
-WSAMovieV2::WSAMovieV2(KyraEngine *vm) : WSAMovieV1(vm), _xAdd(0), _yAdd(0) {}
+WSAMovieV2::WSAMovieV2(KyraEngine_v2 *vm) : WSAMovieV1(vm), _vm(vm), _xAdd(0), _yAdd(0), _oldOff(false) {}
int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) {
debugC(9, kDebugLevelMovie, "WSAMovieV2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf);
@@ -419,5 +420,95 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) {
return _numFrames;
}
+void WSAMovieV2::displayFrame(int frameNum, ...) {
+ debugC(9, kDebugLevelMovie, "WSAMovieV2::displayFrame(%d, ...)", frameNum);
+ if (frameNum >= _numFrames || !_opened)
+ return;
+
+ uint8 *dst = 0;
+ if (_flags & WF_OFFSCREEN_DECODE)
+ dst = _offscreenBuffer;
+ else
+ dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height);
+
+ if (_currentFrame == _numFrames) {
+ if (!(_flags & WF_NO_FIRST_FRAME)) {
+ if (_flags & WF_OFFSCREEN_DECODE)
+ Screen::decodeFrameDelta(dst, _deltaBuffer);
+ else
+ Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, (_flags & WF_XOR) == 0);
+ }
+ _currentFrame = 0;
+ }
+
+ // try to reduce the number of needed frame operations
+ int diffCount = ABS(_currentFrame - frameNum);
+ int frameStep = 1;
+ int frameCount;
+ if (_currentFrame < frameNum) {
+ frameCount = _numFrames - frameNum + _currentFrame;
+ if (diffCount > frameCount)
+ frameStep = -1;
+ else
+ frameCount = diffCount;
+ } else {
+ frameCount = _numFrames - _currentFrame + frameNum;
+ if (frameCount >= diffCount) {
+ frameStep = -1;
+ frameCount = diffCount;
+ }
+ }
+
+ // process
+ if (frameStep > 0) {
+ uint16 cf = _currentFrame;
+ while (frameCount--) {
+ cf += frameStep;
+ processFrame(cf, dst);
+ if (cf == _numFrames)
+ cf = 0;
+ }
+ } else {
+ uint16 cf = _currentFrame;
+ while (frameCount--) {
+ if (cf == 0)
+ cf = _numFrames;
+ processFrame(cf, dst);
+ cf += frameStep;
+ }
+ }
+
+ // display
+ _currentFrame = frameNum;
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ if (_oldOff) {
+ // Kyrandia 1 offscreen buffer -> screen copy method of Kyrandia 1, needs to be present
+ // for our intro code that doesn't supply all the needed parameters for the Kyrandia 2 method
+ _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer);
+ } else {
+ // This is the offscreen buffer -> screen copy method of Kyrandia 2 as it's implemented
+ // in the original, we use this in game
+ Screen_v2 *screen = _vm->screen_v2();
+ int pageBackUp = screen->_curPage;
+ screen->_curPage = _drawPage;
+
+ va_list args;
+ va_start(args, frameNum);
+
+ int copyParam = va_arg(args, int);
+ int plotFunc = (copyParam & 0xFF00) >> 12;
+ int unk1 = copyParam & 0xFF;
+
+ const uint8 *unkPtr1 = va_arg(args, const uint8*);
+ const uint8 *unkPtr2 = va_arg(args, const uint8*);
+ va_end(args);
+
+ screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, unkPtr1, unkPtr2);
+
+ screen->_curPage = pageBackUp;
+ }
+ }
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h
index a3af9f16b7..0e93bd2a93 100644
--- a/engines/kyra/wsamovie.h
+++ b/engines/kyra/wsamovie.h
@@ -35,6 +35,7 @@ class SoundHandle;
namespace Kyra {
class KyraEngine;
+class KyraEngine_v2;
class Movie {
public:
@@ -48,7 +49,7 @@ public:
virtual int frames() = 0;
- virtual void displayFrame(int frameNum) = 0;
+ virtual void displayFrame(int frameNum, ...) = 0;
virtual void setX(int x) { _x = x; }
virtual void setY(int y) { _y = y; }
@@ -71,7 +72,7 @@ public:
virtual int frames() { return _opened ? _numFrames : -1; }
- virtual void displayFrame(int frameNum);
+ virtual void displayFrame(int frameNum, ...);
enum WSAFlags {
WF_OFFSCREEN_DECODE = 0x10,
@@ -101,7 +102,7 @@ public:
int open(const char *filename, int offscreen, uint8 *palette);
void close();
- void displayFrame(int frameNum);
+ void displayFrame(int frameNum, ...);
private:
void processFrame(int frameNum, uint8 *dst);
@@ -110,9 +111,11 @@ private:
class WSAMovieV2 : public WSAMovieV1 {
public:
- WSAMovieV2(KyraEngine *vm);
+ WSAMovieV2(KyraEngine_v2 *vm);
int open(const char *filename, int unk1, uint8 *palette);
+
+ virtual void displayFrame(int frameNum, ...);
void setX(int x) { _x = x + _xAdd; }
void setY(int y) { _y = y + _yAdd; }
@@ -122,10 +125,15 @@ public:
int width() const { return _width; }
int height() const { return _height; }
-protected:
+ // HACK for our intro code
+ void flagOldOff(bool enabled) { _oldOff = enabled; }
+protected:
+ KyraEngine_v2 *_vm;
+
int16 _xAdd;
int16 _yAdd;
+ bool _oldOff; // old offscreen copy, HACK for our intro code
};
} // end of namespace Kyra