[Scummvm-cvs-logs] SF.net SVN: scummvm: [28297] scummvm/trunk/engines/kyra
lordhoto at users.sourceforge.net
lordhoto at users.sourceforge.net
Sun Jul 29 18:33:12 CEST 2007
Revision: 28297
http://scummvm.svn.sourceforge.net/scummvm/?rev=28297&view=rev
Author: lordhoto
Date: 2007-07-29 09:33:11 -0700 (Sun, 29 Jul 2007)
Log Message:
-----------
- 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
Modified Paths:
--------------
scummvm/trunk/engines/kyra/debugger.cpp
scummvm/trunk/engines/kyra/gui_v1.cpp
scummvm/trunk/engines/kyra/gui_v2.cpp
scummvm/trunk/engines/kyra/kyra.cpp
scummvm/trunk/engines/kyra/kyra.h
scummvm/trunk/engines/kyra/kyra_v1.cpp
scummvm/trunk/engines/kyra/kyra_v1.h
scummvm/trunk/engines/kyra/kyra_v2.cpp
scummvm/trunk/engines/kyra/kyra_v2.h
scummvm/trunk/engines/kyra/kyra_v3.cpp
scummvm/trunk/engines/kyra/module.mk
scummvm/trunk/engines/kyra/resource.cpp
scummvm/trunk/engines/kyra/resource.h
scummvm/trunk/engines/kyra/saveload_v1.cpp
scummvm/trunk/engines/kyra/scene_v1.cpp
scummvm/trunk/engines/kyra/screen.cpp
scummvm/trunk/engines/kyra/screen.h
scummvm/trunk/engines/kyra/screen_v2.cpp
scummvm/trunk/engines/kyra/screen_v2.h
scummvm/trunk/engines/kyra/script.cpp
scummvm/trunk/engines/kyra/script.h
scummvm/trunk/engines/kyra/script_v1.cpp
scummvm/trunk/engines/kyra/sequences_v1.cpp
scummvm/trunk/engines/kyra/sequences_v2.cpp
scummvm/trunk/engines/kyra/staticres.cpp
scummvm/trunk/engines/kyra/text_v1.cpp
scummvm/trunk/engines/kyra/timer_v1.cpp
scummvm/trunk/engines/kyra/wsamovie.cpp
scummvm/trunk/engines/kyra/wsamovie.h
Added Paths:
-----------
scummvm/trunk/engines/kyra/animator_v2.cpp
scummvm/trunk/engines/kyra/items_v2.cpp
scummvm/trunk/engines/kyra/scene.cpp
scummvm/trunk/engines/kyra/scene_v2.cpp
scummvm/trunk/engines/kyra/script_v2.cpp
scummvm/trunk/engines/kyra/timer.cpp
scummvm/trunk/engines/kyra/timer.h
scummvm/trunk/engines/kyra/timer_v2.cpp
scummvm/trunk/engines/kyra/util.h
Added: scummvm/trunk/engines/kyra/animator_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/animator_v2.cpp (rev 0)
+++ scummvm/trunk/engines/kyra/animator_v2.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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
Property changes on: scummvm/trunk/engines/kyra/animator_v2.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: scummvm/trunk/engines/kyra/debugger.cpp
===================================================================
--- scummvm/trunk/engines/kyra/debugger.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/debugger.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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_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 @@
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");
}
Modified: scummvm/trunk/engines/kyra/gui_v1.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_v1.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/gui_v1.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -1469,5 +1469,38 @@
_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
Modified: scummvm/trunk/engines/kyra/gui_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_v2.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/gui_v2.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 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;
Added: scummvm/trunk/engines/kyra/items_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/items_v2.cpp (rev 0)
+++ scummvm/trunk/engines/kyra/items_v2.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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
Property changes on: scummvm/trunk/engines/kyra/items_v2.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: scummvm/trunk/engines/kyra/kyra.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -35,17 +35,24 @@
#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;
_skipFlag = false;
@@ -63,6 +70,7 @@
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 @@
_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 @@
delete _res;
delete _sound;
delete _text;
+ delete _timer;
+ delete _scriptInterpreter;
}
void KyraEngine::quitGame() {
Modified: scummvm/trunk/engines/kyra/kyra.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra.h 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra.h 2007-07-29 16:33:11 UTC (rev 28297)
@@ -31,10 +31,10 @@
#include "common/array.h"
#include "common/events.h"
+#include "kyra/util.h"
+
namespace Kyra {
-struct Opcode;
-
struct GameFlags {
Common::Language lang;
Common::Platform platform;
@@ -59,16 +59,17 @@
// 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 Movie;
class TextDisplayer;
class StaticResource;
+class TimerManager;
+class ScriptHelper;
class KyraEngine : public Engine {
public:
@@ -94,6 +97,7 @@
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 @@
// 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 @@
// 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
Modified: scummvm/trunk/engines/kyra/kyra_v1.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v1.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra_v1.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 @@
_sprites = 0;
_animator = 0;
_seq = 0;
- _scriptInterpreter = 0;
_npcScriptData = 0;
_scriptMain = 0;
_scriptClickData = 0;
@@ -124,8 +124,7 @@
delete _sprites;
delete _animator;
delete _seq;
- delete _scriptInterpreter;
-
+
delete _npcScriptData;
delete _scriptMain;
@@ -181,18 +180,18 @@
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 @@
_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 @@
_pathfinderFlag = _pathfinderFlag2 = 0;
_lastFindWayRet = 0;
_sceneChangeState = _loopFlag2 = 0;
- _timerNextRun = 0;
_movFacingTable = new int[150];
assert(_movFacingTable);
@@ -309,9 +304,6 @@
_menuDirectlyToLoad = false;
_lastMusicCommand = 0;
-
- _gameSpeed = 60;
- _tickLength = (uint8)(1000.0 / _gameSpeed);
return 0;
}
@@ -456,7 +448,7 @@
processButtonList(_buttonList);
updateMousePointer();
- updateGameTimers();
+ _timer->update();
updateTextFade();
_handleInput = true;
@@ -470,7 +462,7 @@
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 @@
_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 @@
Opcode(o1_fillRect),
Opcode(o1_vocUnload),
Opcode(o1_vocLoad),
+ // 0x9c
Opcode(o1_dummy)
};
Modified: scummvm/trunk/engines/kyra/kyra_v1.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v1.h 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra_v1.h 2007-07-29 16:33:11 UTC (rev 28297)
@@ -36,7 +36,6 @@
class SoundDigital;
class SeqPlayer;
class Sprites;
-class ScriptHelper;
class Debugger;
class ScreenAnimator;
class TextDisplayer;
@@ -105,13 +104,6 @@
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 @@
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 @@
// -> 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 @@
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 @@
void freePanPages();
void closeFinalWsa();
- void setTimer19();
+ //void setTimer19();
void setupTimers();
void timerUpdateHeadAnims(int timerNum);
void timerSetFlags1(int timerNum);
@@ -535,7 +514,6 @@
int8 _mouseWheel;
uint8 *_itemBkgBackUp[2];
uint8 *_shapes[373];
- uint16 _gameSpeed;
int8 _itemInHand;
int _mouseState;
bool _handleInput;
@@ -632,7 +610,6 @@
SeqPlayer *_seq;
Sprites *_sprites;
Screen_v1 *_screen;
- ScriptHelper *_scriptInterpreter;
Debugger *_debugger;
ScriptState *_scriptMain;
@@ -790,18 +767,13 @@
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 @@
static const uint16 _amuletX2[];
static const uint16 _amuletY2[];
protected:
- typedef OpcodeImpl<KyraEngine_v1> OpcodeV1;
void setupOpcodeTable();
// Opcodes
Modified: scummvm/trunk/engines/kyra/kyra_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra_v2.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 @@
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 @@
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 @@
_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 @@
switch (gui_handleMainMenu()) {
case 0:
+ _screen->showMouse();*/
+ startup();
+ runLoop();
+ cleanup();
+ /*running = false;
break;
case 1:
seq_playSequences(kSequenceOverview, kSequenceZanFaun);
@@ -133,8 +163,1131 @@
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
Modified: scummvm/trunk/engines/kyra/kyra_v2.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.h 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra_v2.h 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 @@
~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 @@
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 @@
ActiveWSA *_activeWSA;
ActiveChat *_activeChat;
- uint8 *_gameShapes[50];
uint8 *_mouseSHPBuf;
static const char *_introSoundList[];
@@ -145,6 +144,351 @@
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
Modified: scummvm/trunk/engines/kyra/kyra_v3.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v3.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/kyra_v3.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -290,14 +290,14 @@
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 @@
}
}
lock = 0;
- timer = _system->getMillis() + 0x0F * _tickLength;
+ mTimer = _system->getMillis() + 0x0F * _tickLength;
}
return 1;
Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/module.mk 2007-07-29 16:33:11 UTC (rev 28297)
@@ -2,22 +2,27 @@
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 @@
staticres.o \
text.o \
text_v1.o \
+ timer.o \
timer_v1.o \
+ timer_v2.o \
vqa.o \
wsamovie.o
Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/resource.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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;
}
};
Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/resource.h 2007-07-29 16:33:11 UTC (rev 28297)
@@ -122,9 +122,8 @@
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);
Modified: scummvm/trunk/engines/kyra/saveload_v1.cpp
===================================================================
--- scummvm/trunk/engines/kyra/saveload_v1.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/saveload_v1.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 @@
_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 @@
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 @@
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));
Added: scummvm/trunk/engines/kyra/scene.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene.cpp (rev 0)
+++ scummvm/trunk/engines/kyra/scene.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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
Property changes on: scummvm/trunk/engines/kyra/scene.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: scummvm/trunk/engines/kyra/scene_v1.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_v1.cpp 2007-07-29 16:31:29 UTC (rev 28296)
+++ scummvm/trunk/engines/kyra/scene_v1.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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 @@
_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 @@
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 @@
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 @@
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 @@
break;
}
- enableTimer(19);
- enableTimer(14);
- enableTimer(18);
+ _timer->enable(19);
+ _timer->enable(14);
+ _timer->enable(18);
_screen->showMouse();
}
@@ -282,7 +283,7 @@
debugC(9, kDebugLevelMain, "KyraEngine_v1::setCharacterPositionWithUpdate(%d)", character);
setCharacterPosition(character, 0);
_sprites->updateSceneAnims();
- updateGameTimers();
+ _timer->update();
_animator->updateAllObjectShapes();
updateTextFade();
@@ -391,29 +392,6 @@
_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 @@
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 @@
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,101 +1229,8 @@
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;
+#pragma mark -
- 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;
-}
-
void KyraEngine_v1::setupSceneResource(int sceneId) {
debugC(9, kDebugLevelMain, "KyraEngine_v1::setupSceneResource(%d)", sceneId);
if (!_flags.isTalkie)
Added: scummvm/trunk/engines/kyra/scene_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_v2.cpp (rev 0)
+++ scummvm/trunk/engines/kyra/scene_v2.cpp 2007-07-29 16:33:11 UTC (rev 28297)
@@ -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) {
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list