[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